Merge branch 'linus' into x86/paravirt-spinlocks
This commit is contained in:
commit
1c29dd9a9e
|
@ -308,9 +308,31 @@ Who: Matthew Wilcox <willy@linux.intel.com>
|
||||||
|
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
What: SCTP_GET_PEER_ADDRS_NUM_OLD, SCTP_GET_PEER_ADDRS_OLD,
|
||||||
|
SCTP_GET_LOCAL_ADDRS_NUM_OLD, SCTP_GET_LOCAL_ADDRS_OLD
|
||||||
|
When: June 2009
|
||||||
|
Why: A newer version of the options have been introduced in 2005 that
|
||||||
|
removes the limitions of the old API. The sctp library has been
|
||||||
|
converted to use these new options at the same time. Any user
|
||||||
|
space app that directly uses the old options should convert to using
|
||||||
|
the new options.
|
||||||
|
Who: Vlad Yasevich <vladislav.yasevich@hp.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
What: CONFIG_THERMAL_HWMON
|
What: CONFIG_THERMAL_HWMON
|
||||||
When: January 2009
|
When: January 2009
|
||||||
Why: This option was introduced just to allow older lm-sensors userspace
|
Why: This option was introduced just to allow older lm-sensors userspace
|
||||||
to keep working over the upgrade to 2.6.26. At the scheduled time of
|
to keep working over the upgrade to 2.6.26. At the scheduled time of
|
||||||
removal fixed lm-sensors (2.x or 3.x) should be readily available.
|
removal fixed lm-sensors (2.x or 3.x) should be readily available.
|
||||||
Who: Rene Herman <rene.herman@gmail.com>
|
Who: Rene Herman <rene.herman@gmail.com>
|
||||||
|
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
|
||||||
|
(in net/core/net-sysfs.c)
|
||||||
|
When: After the only user (hal) has seen a release with the patches
|
||||||
|
for enough time, probably some time in 2010.
|
||||||
|
Why: Over 1K .text/.data size reduction, data is available in other
|
||||||
|
ways (ioctls)
|
||||||
|
Who: Johannes Berg <johannes@sipsolutions.net>
|
||||||
|
|
|
@ -233,12 +233,10 @@ accomplished via the group operations specified on the group's
|
||||||
config_item_type.
|
config_item_type.
|
||||||
|
|
||||||
struct configfs_group_operations {
|
struct configfs_group_operations {
|
||||||
int (*make_item)(struct config_group *group,
|
struct config_item *(*make_item)(struct config_group *group,
|
||||||
const char *name,
|
const char *name);
|
||||||
struct config_item **new_item);
|
struct config_group *(*make_group)(struct config_group *group,
|
||||||
int (*make_group)(struct config_group *group,
|
const char *name);
|
||||||
const char *name,
|
|
||||||
struct config_group **new_group);
|
|
||||||
int (*commit_item)(struct config_item *item);
|
int (*commit_item)(struct config_item *item);
|
||||||
void (*disconnect_notify)(struct config_group *group,
|
void (*disconnect_notify)(struct config_group *group,
|
||||||
struct config_item *item);
|
struct config_item *item);
|
||||||
|
|
|
@ -273,13 +273,13 @@ static inline struct simple_children *to_simple_children(struct config_item *ite
|
||||||
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
return item ? container_of(to_config_group(item), struct simple_children, group) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int simple_children_make_item(struct config_group *group, const char *name, struct config_item **new_item)
|
static struct config_item *simple_children_make_item(struct config_group *group, const char *name)
|
||||||
{
|
{
|
||||||
struct simple_child *simple_child;
|
struct simple_child *simple_child;
|
||||||
|
|
||||||
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||||
if (!simple_child)
|
if (!simple_child)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
|
||||||
config_item_init_type_name(&simple_child->item, name,
|
config_item_init_type_name(&simple_child->item, name,
|
||||||
|
@ -287,8 +287,7 @@ static int simple_children_make_item(struct config_group *group, const char *nam
|
||||||
|
|
||||||
simple_child->storeme = 0;
|
simple_child->storeme = 0;
|
||||||
|
|
||||||
*new_item = &simple_child->item;
|
return &simple_child->item;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct configfs_attribute simple_children_attr_description = {
|
static struct configfs_attribute simple_children_attr_description = {
|
||||||
|
@ -360,21 +359,20 @@ static struct configfs_subsystem simple_children_subsys = {
|
||||||
* children of its own.
|
* children of its own.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int group_children_make_group(struct config_group *group, const char *name, struct config_group **new_group)
|
static struct config_group *group_children_make_group(struct config_group *group, const char *name)
|
||||||
{
|
{
|
||||||
struct simple_children *simple_children;
|
struct simple_children *simple_children;
|
||||||
|
|
||||||
simple_children = kzalloc(sizeof(struct simple_children),
|
simple_children = kzalloc(sizeof(struct simple_children),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!simple_children)
|
if (!simple_children)
|
||||||
return -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
|
|
||||||
config_group_init_type_name(&simple_children->group, name,
|
config_group_init_type_name(&simple_children->group, name,
|
||||||
&simple_children_type);
|
&simple_children_type);
|
||||||
|
|
||||||
*new_group = &simple_children->group;
|
return &simple_children->group;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct configfs_attribute group_children_attr_description = {
|
static struct configfs_attribute group_children_attr_description = {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
Author: NetApp and Open Grid Computing
|
Author: NetApp and Open Grid Computing
|
||||||
Date: April 15, 2008
|
Date: May 29, 2008
|
||||||
|
|
||||||
Table of Contents
|
Table of Contents
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
@ -60,16 +60,18 @@ Installation
|
||||||
The procedures described in this document have been tested with
|
The procedures described in this document have been tested with
|
||||||
distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
|
distributions from Red Hat's Fedora Project (http://fedora.redhat.com/).
|
||||||
|
|
||||||
- Install nfs-utils-1.1.1 or greater on the client
|
- Install nfs-utils-1.1.2 or greater on the client
|
||||||
|
|
||||||
An NFS/RDMA mount point can only be obtained by using the mount.nfs
|
An NFS/RDMA mount point can be obtained by using the mount.nfs command in
|
||||||
command in nfs-utils-1.1.1 or greater. To see which version of mount.nfs
|
nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
|
||||||
you are using, type:
|
version with support for NFS/RDMA mounts, but for various reasons we
|
||||||
|
recommend using nfs-utils-1.1.2 or greater). To see which version of
|
||||||
|
mount.nfs you are using, type:
|
||||||
|
|
||||||
> /sbin/mount.nfs -V
|
$ /sbin/mount.nfs -V
|
||||||
|
|
||||||
If the version is less than 1.1.1 or the command does not exist,
|
If the version is less than 1.1.2 or the command does not exist,
|
||||||
then you will need to install the latest version of nfs-utils.
|
you should install the latest version of nfs-utils.
|
||||||
|
|
||||||
Download the latest package from:
|
Download the latest package from:
|
||||||
|
|
||||||
|
@ -77,22 +79,33 @@ Installation
|
||||||
|
|
||||||
Uncompress the package and follow the installation instructions.
|
Uncompress the package and follow the installation instructions.
|
||||||
|
|
||||||
If you will not be using GSS and NFSv4, the installation process
|
If you will not need the idmapper and gssd executables (you do not need
|
||||||
can be simplified by disabling these features when running configure:
|
these to create an NFS/RDMA enabled mount command), the installation
|
||||||
|
process can be simplified by disabling these features when running
|
||||||
|
configure:
|
||||||
|
|
||||||
> ./configure --disable-gss --disable-nfsv4
|
$ ./configure --disable-gss --disable-nfsv4
|
||||||
|
|
||||||
For more information on this see the package's README and INSTALL files.
|
To build nfs-utils you will need the tcp_wrappers package installed. For
|
||||||
|
more information on this see the package's README and INSTALL files.
|
||||||
|
|
||||||
After building the nfs-utils package, there will be a mount.nfs binary in
|
After building the nfs-utils package, there will be a mount.nfs binary in
|
||||||
the utils/mount directory. This binary can be used to initiate NFS v2, v3,
|
the utils/mount directory. This binary can be used to initiate NFS v2, v3,
|
||||||
or v4 mounts. To initiate a v4 mount, the binary must be called mount.nfs4.
|
or v4 mounts. To initiate a v4 mount, the binary must be called
|
||||||
The standard technique is to create a symlink called mount.nfs4 to mount.nfs.
|
mount.nfs4. The standard technique is to create a symlink called
|
||||||
|
mount.nfs4 to mount.nfs.
|
||||||
|
|
||||||
NOTE: mount.nfs and therefore nfs-utils-1.1.1 or greater is only needed
|
This mount.nfs binary should be installed at /sbin/mount.nfs as follows:
|
||||||
|
|
||||||
|
$ sudo cp utils/mount/mount.nfs /sbin/mount.nfs
|
||||||
|
|
||||||
|
In this location, mount.nfs will be invoked automatically for NFS mounts
|
||||||
|
by the system mount commmand.
|
||||||
|
|
||||||
|
NOTE: mount.nfs and therefore nfs-utils-1.1.2 or greater is only needed
|
||||||
on the NFS client machine. You do not need this specific version of
|
on the NFS client machine. You do not need this specific version of
|
||||||
nfs-utils on the server. Furthermore, only the mount.nfs command from
|
nfs-utils on the server. Furthermore, only the mount.nfs command from
|
||||||
nfs-utils-1.1.1 is needed on the client.
|
nfs-utils-1.1.2 is needed on the client.
|
||||||
|
|
||||||
- Install a Linux kernel with NFS/RDMA
|
- Install a Linux kernel with NFS/RDMA
|
||||||
|
|
||||||
|
@ -156,8 +169,8 @@ Check RDMA and NFS Setup
|
||||||
this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
|
this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
|
||||||
card:
|
card:
|
||||||
|
|
||||||
> modprobe ib_mthca
|
$ modprobe ib_mthca
|
||||||
> modprobe ib_ipoib
|
$ modprobe ib_ipoib
|
||||||
|
|
||||||
If you are using InfiniBand, make sure there is a Subnet Manager (SM)
|
If you are using InfiniBand, make sure there is a Subnet Manager (SM)
|
||||||
running on the network. If your IB switch has an embedded SM, you can
|
running on the network. If your IB switch has an embedded SM, you can
|
||||||
|
@ -166,7 +179,7 @@ Check RDMA and NFS Setup
|
||||||
|
|
||||||
If an SM is running on your network, you should see the following:
|
If an SM is running on your network, you should see the following:
|
||||||
|
|
||||||
> cat /sys/class/infiniband/driverX/ports/1/state
|
$ cat /sys/class/infiniband/driverX/ports/1/state
|
||||||
4: ACTIVE
|
4: ACTIVE
|
||||||
|
|
||||||
where driverX is mthca0, ipath5, ehca3, etc.
|
where driverX is mthca0, ipath5, ehca3, etc.
|
||||||
|
@ -174,10 +187,10 @@ Check RDMA and NFS Setup
|
||||||
To further test the InfiniBand software stack, use IPoIB (this
|
To further test the InfiniBand software stack, use IPoIB (this
|
||||||
assumes you have two IB hosts named host1 and host2):
|
assumes you have two IB hosts named host1 and host2):
|
||||||
|
|
||||||
host1> ifconfig ib0 a.b.c.x
|
host1$ ifconfig ib0 a.b.c.x
|
||||||
host2> ifconfig ib0 a.b.c.y
|
host2$ ifconfig ib0 a.b.c.y
|
||||||
host1> ping a.b.c.y
|
host1$ ping a.b.c.y
|
||||||
host2> ping a.b.c.x
|
host2$ ping a.b.c.x
|
||||||
|
|
||||||
For other device types, follow the appropriate procedures.
|
For other device types, follow the appropriate procedures.
|
||||||
|
|
||||||
|
@ -202,11 +215,11 @@ NFS/RDMA Setup
|
||||||
/vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
|
/vol0 192.168.0.47(fsid=0,rw,async,insecure,no_root_squash)
|
||||||
/vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
|
/vol0 192.168.0.0/255.255.255.0(fsid=0,rw,async,insecure,no_root_squash)
|
||||||
|
|
||||||
The IP address(es) is(are) the client's IPoIB address for an InfiniBand HCA or the
|
The IP address(es) is(are) the client's IPoIB address for an InfiniBand
|
||||||
cleint's iWARP address(es) for an RNIC.
|
HCA or the cleint's iWARP address(es) for an RNIC.
|
||||||
|
|
||||||
NOTE: The "insecure" option must be used because the NFS/RDMA client does not
|
NOTE: The "insecure" option must be used because the NFS/RDMA client does
|
||||||
use a reserved port.
|
not use a reserved port.
|
||||||
|
|
||||||
Each time a machine boots:
|
Each time a machine boots:
|
||||||
|
|
||||||
|
@ -214,43 +227,45 @@ NFS/RDMA Setup
|
||||||
|
|
||||||
For InfiniBand using a Mellanox adapter:
|
For InfiniBand using a Mellanox adapter:
|
||||||
|
|
||||||
> modprobe ib_mthca
|
$ modprobe ib_mthca
|
||||||
> modprobe ib_ipoib
|
$ modprobe ib_ipoib
|
||||||
> ifconfig ib0 a.b.c.d
|
$ ifconfig ib0 a.b.c.d
|
||||||
|
|
||||||
NOTE: use unique addresses for the client and server
|
NOTE: use unique addresses for the client and server
|
||||||
|
|
||||||
- Start the NFS server
|
- Start the NFS server
|
||||||
|
|
||||||
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||||
load the RDMA transport module:
|
kernel config), load the RDMA transport module:
|
||||||
|
|
||||||
> modprobe svcrdma
|
$ modprobe svcrdma
|
||||||
|
|
||||||
Regardless of how the server was built (module or built-in), start the server:
|
Regardless of how the server was built (module or built-in), start the
|
||||||
|
server:
|
||||||
|
|
||||||
> /etc/init.d/nfs start
|
$ /etc/init.d/nfs start
|
||||||
|
|
||||||
or
|
or
|
||||||
|
|
||||||
> service nfs start
|
$ service nfs start
|
||||||
|
|
||||||
Instruct the server to listen on the RDMA transport:
|
Instruct the server to listen on the RDMA transport:
|
||||||
|
|
||||||
> echo rdma 2050 > /proc/fs/nfsd/portlist
|
$ echo rdma 2050 > /proc/fs/nfsd/portlist
|
||||||
|
|
||||||
- On the client system
|
- On the client system
|
||||||
|
|
||||||
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||||
load the RDMA client module:
|
kernel config), load the RDMA client module:
|
||||||
|
|
||||||
> modprobe xprtrdma.ko
|
$ modprobe xprtrdma.ko
|
||||||
|
|
||||||
Regardless of how the client was built (module or built-in), issue the mount.nfs command:
|
Regardless of how the client was built (module or built-in), use this
|
||||||
|
command to mount the NFS/RDMA server:
|
||||||
|
|
||||||
> /path/to/your/mount.nfs <IPoIB-server-name-or-address>:/<export> /mnt -i -o rdma,port=2050
|
$ mount -o rdma,port=2050 <IPoIB-server-name-or-address>:/<export> /mnt
|
||||||
|
|
||||||
To verify that the mount is using RDMA, run "cat /proc/mounts" and check the
|
To verify that the mount is using RDMA, run "cat /proc/mounts" and check
|
||||||
"proto" field for the given mount.
|
the "proto" field for the given mount.
|
||||||
|
|
||||||
Congratulations! You're using NFS/RDMA!
|
Congratulations! You're using NFS/RDMA!
|
||||||
|
|
|
@ -289,35 +289,73 @@ downdelay
|
||||||
fail_over_mac
|
fail_over_mac
|
||||||
|
|
||||||
Specifies whether active-backup mode should set all slaves to
|
Specifies whether active-backup mode should set all slaves to
|
||||||
the same MAC address (the traditional behavior), or, when
|
the same MAC address at enslavement (the traditional
|
||||||
enabled, change the bond's MAC address when changing the
|
behavior), or, when enabled, perform special handling of the
|
||||||
active interface (i.e., fail over the MAC address itself).
|
bond's MAC address in accordance with the selected policy.
|
||||||
|
|
||||||
Fail over MAC is useful for devices that cannot ever alter
|
Possible values are:
|
||||||
their MAC address, or for devices that refuse incoming
|
|
||||||
broadcasts with their own source MAC (which interferes with
|
|
||||||
the ARP monitor).
|
|
||||||
|
|
||||||
The down side of fail over MAC is that every device on the
|
none or 0
|
||||||
network must be updated via gratuitous ARP, vs. just updating
|
|
||||||
a switch or set of switches (which often takes place for any
|
|
||||||
traffic, not just ARP traffic, if the switch snoops incoming
|
|
||||||
traffic to update its tables) for the traditional method. If
|
|
||||||
the gratuitous ARP is lost, communication may be disrupted.
|
|
||||||
|
|
||||||
When fail over MAC is used in conjuction with the mii monitor,
|
This setting disables fail_over_mac, and causes
|
||||||
devices which assert link up prior to being able to actually
|
bonding to set all slaves of an active-backup bond to
|
||||||
transmit and receive are particularly susecptible to loss of
|
the same MAC address at enslavement time. This is the
|
||||||
the gratuitous ARP, and an appropriate updelay setting may be
|
default.
|
||||||
required.
|
|
||||||
|
|
||||||
A value of 0 disables fail over MAC, and is the default. A
|
active or 1
|
||||||
value of 1 enables fail over MAC. This option is enabled
|
|
||||||
automatically if the first slave added cannot change its MAC
|
|
||||||
address. This option may be modified via sysfs only when no
|
|
||||||
slaves are present in the bond.
|
|
||||||
|
|
||||||
This option was added in bonding version 3.2.0.
|
The "active" fail_over_mac policy indicates that the
|
||||||
|
MAC address of the bond should always be the MAC
|
||||||
|
address of the currently active slave. The MAC
|
||||||
|
address of the slaves is not changed; instead, the MAC
|
||||||
|
address of the bond changes during a failover.
|
||||||
|
|
||||||
|
This policy is useful for devices that cannot ever
|
||||||
|
alter their MAC address, or for devices that refuse
|
||||||
|
incoming broadcasts with their own source MAC (which
|
||||||
|
interferes with the ARP monitor).
|
||||||
|
|
||||||
|
The down side of this policy is that every device on
|
||||||
|
the network must be updated via gratuitous ARP,
|
||||||
|
vs. just updating a switch or set of switches (which
|
||||||
|
often takes place for any traffic, not just ARP
|
||||||
|
traffic, if the switch snoops incoming traffic to
|
||||||
|
update its tables) for the traditional method. If the
|
||||||
|
gratuitous ARP is lost, communication may be
|
||||||
|
disrupted.
|
||||||
|
|
||||||
|
When this policy is used in conjuction with the mii
|
||||||
|
monitor, devices which assert link up prior to being
|
||||||
|
able to actually transmit and receive are particularly
|
||||||
|
susecptible to loss of the gratuitous ARP, and an
|
||||||
|
appropriate updelay setting may be required.
|
||||||
|
|
||||||
|
follow or 2
|
||||||
|
|
||||||
|
The "follow" fail_over_mac policy causes the MAC
|
||||||
|
address of the bond to be selected normally (normally
|
||||||
|
the MAC address of the first slave added to the bond).
|
||||||
|
However, the second and subsequent slaves are not set
|
||||||
|
to this MAC address while they are in a backup role; a
|
||||||
|
slave is programmed with the bond's MAC address at
|
||||||
|
failover time (and the formerly active slave receives
|
||||||
|
the newly active slave's MAC address).
|
||||||
|
|
||||||
|
This policy is useful for multiport devices that
|
||||||
|
either become confused or incur a performance penalty
|
||||||
|
when multiple ports are programmed with the same MAC
|
||||||
|
address.
|
||||||
|
|
||||||
|
|
||||||
|
The default policy is none, unless the first slave cannot
|
||||||
|
change its MAC address, in which case the active policy is
|
||||||
|
selected by default.
|
||||||
|
|
||||||
|
This option may be modified via sysfs only when no slaves are
|
||||||
|
present in the bond.
|
||||||
|
|
||||||
|
This option was added in bonding version 3.2.0. The "follow"
|
||||||
|
policy was added in bonding version 3.3.0.
|
||||||
|
|
||||||
lacp_rate
|
lacp_rate
|
||||||
|
|
||||||
|
@ -338,7 +376,8 @@ max_bonds
|
||||||
Specifies the number of bonding devices to create for this
|
Specifies the number of bonding devices to create for this
|
||||||
instance of the bonding driver. E.g., if max_bonds is 3, and
|
instance of the bonding driver. E.g., if max_bonds is 3, and
|
||||||
the bonding driver is not already loaded, then bond0, bond1
|
the bonding driver is not already loaded, then bond0, bond1
|
||||||
and bond2 will be created. The default value is 1.
|
and bond2 will be created. The default value is 1. Specifying
|
||||||
|
a value of 0 will load bonding, but will not create any devices.
|
||||||
|
|
||||||
miimon
|
miimon
|
||||||
|
|
||||||
|
@ -501,6 +540,17 @@ mode
|
||||||
swapped with the new curr_active_slave that was
|
swapped with the new curr_active_slave that was
|
||||||
chosen.
|
chosen.
|
||||||
|
|
||||||
|
num_grat_arp
|
||||||
|
|
||||||
|
Specifies the number of gratuitous ARPs to be issued after a
|
||||||
|
failover event. One gratuitous ARP is issued immediately after
|
||||||
|
the failover, subsequent ARPs are sent at a rate of one per link
|
||||||
|
monitor interval (arp_interval or miimon, whichever is active).
|
||||||
|
|
||||||
|
The valid range is 0 - 255; the default value is 1. This option
|
||||||
|
affects only the active-backup mode. This option was added for
|
||||||
|
bonding version 3.3.0.
|
||||||
|
|
||||||
primary
|
primary
|
||||||
|
|
||||||
A string (eth0, eth2, etc) specifying which slave is the
|
A string (eth0, eth2, etc) specifying which slave is the
|
||||||
|
|
|
@ -0,0 +1,167 @@
|
||||||
|
DM9000 Network driver
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Copyright 2008 Simtec Electronics,
|
||||||
|
Ben Dooks <ben@simtec.co.uk> <ben-linux@fluff.org>
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
------------
|
||||||
|
|
||||||
|
This file describes how to use the DM9000 platform-device based network driver
|
||||||
|
that is contained in the files drivers/net/dm9000.c and drivers/net/dm9000.h.
|
||||||
|
|
||||||
|
The driver supports three DM9000 variants, the DM9000E which is the first chip
|
||||||
|
supported as well as the newer DM9000A and DM9000B devices. It is currently
|
||||||
|
maintained and tested by Ben Dooks, who should be CC: to any patches for this
|
||||||
|
driver.
|
||||||
|
|
||||||
|
|
||||||
|
Defining the platform device
|
||||||
|
----------------------------
|
||||||
|
|
||||||
|
The minimum set of resources attached to the platform device are as follows:
|
||||||
|
|
||||||
|
1) The physical address of the address register
|
||||||
|
2) The physical address of the data register
|
||||||
|
3) The IRQ line the device's interrupt pin is connected to.
|
||||||
|
|
||||||
|
These resources should be specified in that order, as the ordering of the
|
||||||
|
two address regions is important (the driver expects these to be address
|
||||||
|
and then data).
|
||||||
|
|
||||||
|
An example from arch/arm/mach-s3c2410/mach-bast.c is:
|
||||||
|
|
||||||
|
static struct resource bast_dm9k_resource[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = S3C2410_CS5 + BAST_PA_DM9000,
|
||||||
|
.end = S3C2410_CS5 + BAST_PA_DM9000 + 3,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = S3C2410_CS5 + BAST_PA_DM9000 + 0x40,
|
||||||
|
.end = S3C2410_CS5 + BAST_PA_DM9000 + 0x40 + 0x3f,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
|
.start = IRQ_DM9000,
|
||||||
|
.end = IRQ_DM9000,
|
||||||
|
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHLEVEL,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device bast_device_dm9k = {
|
||||||
|
.name = "dm9000",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(bast_dm9k_resource),
|
||||||
|
.resource = bast_dm9k_resource,
|
||||||
|
};
|
||||||
|
|
||||||
|
Note the setting of the IRQ trigger flag in bast_dm9k_resource[2].flags,
|
||||||
|
as this will generate a warning if it is not present. The trigger from
|
||||||
|
the flags field will be passed to request_irq() when registering the IRQ
|
||||||
|
handler to ensure that the IRQ is setup correctly.
|
||||||
|
|
||||||
|
This shows a typical platform device, without the optional configuration
|
||||||
|
platform data supplied. The next example uses the same resources, but adds
|
||||||
|
the optional platform data to pass extra configuration data:
|
||||||
|
|
||||||
|
static struct dm9000_plat_data bast_dm9k_platdata = {
|
||||||
|
.flags = DM9000_PLATF_16BITONLY,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device bast_device_dm9k = {
|
||||||
|
.name = "dm9000",
|
||||||
|
.id = 0,
|
||||||
|
.num_resources = ARRAY_SIZE(bast_dm9k_resource),
|
||||||
|
.resource = bast_dm9k_resource,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &bast_dm9k_platdata,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
The platform data is defined in include/linux/dm9000.h and described below.
|
||||||
|
|
||||||
|
|
||||||
|
Platform data
|
||||||
|
-------------
|
||||||
|
|
||||||
|
Extra platform data for the DM9000 can describe the IO bus width to the
|
||||||
|
device, whether or not an external PHY is attached to the device and
|
||||||
|
the availability of an external configuration EEPROM.
|
||||||
|
|
||||||
|
The flags for the platform data .flags field are as follows:
|
||||||
|
|
||||||
|
DM9000_PLATF_8BITONLY
|
||||||
|
|
||||||
|
The IO should be done with 8bit operations.
|
||||||
|
|
||||||
|
DM9000_PLATF_16BITONLY
|
||||||
|
|
||||||
|
The IO should be done with 16bit operations.
|
||||||
|
|
||||||
|
DM9000_PLATF_32BITONLY
|
||||||
|
|
||||||
|
The IO should be done with 32bit operations.
|
||||||
|
|
||||||
|
DM9000_PLATF_EXT_PHY
|
||||||
|
|
||||||
|
The chip is connected to an external PHY.
|
||||||
|
|
||||||
|
DM9000_PLATF_NO_EEPROM
|
||||||
|
|
||||||
|
This can be used to signify that the board does not have an
|
||||||
|
EEPROM, or that the EEPROM should be hidden from the user.
|
||||||
|
|
||||||
|
DM9000_PLATF_SIMPLE_PHY
|
||||||
|
|
||||||
|
Switch to using the simpler PHY polling method which does not
|
||||||
|
try and read the MII PHY state regularly. This is only available
|
||||||
|
when using the internal PHY. See the section on link state polling
|
||||||
|
for more information.
|
||||||
|
|
||||||
|
The config symbol DM9000_FORCE_SIMPLE_PHY_POLL, Kconfig entry
|
||||||
|
"Force simple NSR based PHY polling" allows this flag to be
|
||||||
|
forced on at build time.
|
||||||
|
|
||||||
|
|
||||||
|
PHY Link state polling
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
The driver keeps track of the link state and informs the network core
|
||||||
|
about link (carrier) availablilty. This is managed by several methods
|
||||||
|
depending on the version of the chip and on which PHY is being used.
|
||||||
|
|
||||||
|
For the internal PHY, the original (and currently default) method is
|
||||||
|
to read the MII state, either when the status changes if we have the
|
||||||
|
necessary interrupt support in the chip or every two seconds via a
|
||||||
|
periodic timer.
|
||||||
|
|
||||||
|
To reduce the overhead for the internal PHY, there is now the option
|
||||||
|
of using the DM9000_FORCE_SIMPLE_PHY_POLL config, or DM9000_PLATF_SIMPLE_PHY
|
||||||
|
platform data option to read the summary information without the
|
||||||
|
expensive MII accesses. This method is faster, but does not print
|
||||||
|
as much information.
|
||||||
|
|
||||||
|
When using an external PHY, the driver currently has to poll the MII
|
||||||
|
link status as there is no method for getting an interrupt on link change.
|
||||||
|
|
||||||
|
|
||||||
|
DM9000A / DM9000B
|
||||||
|
-----------------
|
||||||
|
|
||||||
|
These chips are functionally similar to the DM9000E and are supported easily
|
||||||
|
by the same driver. The features are:
|
||||||
|
|
||||||
|
1) Interrupt on internal PHY state change. This means that the periodic
|
||||||
|
polling of the PHY status may be disabled on these devices when using
|
||||||
|
the internal PHY.
|
||||||
|
|
||||||
|
2) TCP/UDP checksum offloading, which the driver does not currently support.
|
||||||
|
|
||||||
|
|
||||||
|
ethtool
|
||||||
|
-------
|
||||||
|
|
||||||
|
The driver supports the ethtool interface for access to the driver
|
||||||
|
state information, the PHY state and the EEPROM.
|
|
@ -551,8 +551,9 @@ icmp_echo_ignore_broadcasts - BOOLEAN
|
||||||
icmp_ratelimit - INTEGER
|
icmp_ratelimit - INTEGER
|
||||||
Limit the maximal rates for sending ICMP packets whose type matches
|
Limit the maximal rates for sending ICMP packets whose type matches
|
||||||
icmp_ratemask (see below) to specific targets.
|
icmp_ratemask (see below) to specific targets.
|
||||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
0 to disable any limiting,
|
||||||
Default: 100
|
otherwise the minimal space between responses in milliseconds.
|
||||||
|
Default: 1000
|
||||||
|
|
||||||
icmp_ratemask - INTEGER
|
icmp_ratemask - INTEGER
|
||||||
Mask made of ICMP types for which rates are being limited.
|
Mask made of ICMP types for which rates are being limited.
|
||||||
|
@ -1023,11 +1024,23 @@ max_addresses - INTEGER
|
||||||
autoconfigured addresses.
|
autoconfigured addresses.
|
||||||
Default: 16
|
Default: 16
|
||||||
|
|
||||||
|
disable_ipv6 - BOOLEAN
|
||||||
|
Disable IPv6 operation.
|
||||||
|
Default: FALSE (enable IPv6 operation)
|
||||||
|
|
||||||
|
accept_dad - INTEGER
|
||||||
|
Whether to accept DAD (Duplicate Address Detection).
|
||||||
|
0: Disable DAD
|
||||||
|
1: Enable DAD (default)
|
||||||
|
2: Enable DAD, and disable IPv6 operation if MAC-based duplicate
|
||||||
|
link-local address has been found.
|
||||||
|
|
||||||
icmp/*:
|
icmp/*:
|
||||||
ratelimit - INTEGER
|
ratelimit - INTEGER
|
||||||
Limit the maximal rates for sending ICMPv6 packets.
|
Limit the maximal rates for sending ICMPv6 packets.
|
||||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
0 to disable any limiting,
|
||||||
Default: 100
|
otherwise the minimal space between responses in milliseconds.
|
||||||
|
Default: 1000
|
||||||
|
|
||||||
|
|
||||||
IPv6 Update by:
|
IPv6 Update by:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
Linux* Base Driver for the Intel(R) PRO/10GbE Family of Adapters
|
Linux Base Driver for 10 Gigabit Intel(R) Network Connection
|
||||||
================================================================
|
=============================================================
|
||||||
|
|
||||||
November 17, 2004
|
October 9, 2007
|
||||||
|
|
||||||
|
|
||||||
Contents
|
Contents
|
||||||
|
@ -9,94 +9,151 @@ Contents
|
||||||
|
|
||||||
- In This Release
|
- In This Release
|
||||||
- Identifying Your Adapter
|
- Identifying Your Adapter
|
||||||
|
- Building and Installation
|
||||||
- Command Line Parameters
|
- Command Line Parameters
|
||||||
- Improving Performance
|
- Improving Performance
|
||||||
|
- Additional Configurations
|
||||||
|
- Known Issues/Troubleshooting
|
||||||
- Support
|
- Support
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
In This Release
|
In This Release
|
||||||
===============
|
===============
|
||||||
|
|
||||||
This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family
|
This file describes the ixgb Linux Base Driver for the 10 Gigabit Intel(R)
|
||||||
of Adapters, version 1.0.x.
|
Network Connection. This driver includes support for Itanium(R)2-based
|
||||||
|
systems.
|
||||||
|
|
||||||
|
For questions related to hardware requirements, refer to the documentation
|
||||||
|
supplied with your 10 Gigabit adapter. All hardware requirements listed apply
|
||||||
|
to use with Linux.
|
||||||
|
|
||||||
|
The following features are available in this kernel:
|
||||||
|
- Native VLANs
|
||||||
|
- Channel Bonding (teaming)
|
||||||
|
- SNMP
|
||||||
|
|
||||||
|
Channel Bonding documentation can be found in the Linux kernel source:
|
||||||
|
/Documentation/networking/bonding.txt
|
||||||
|
|
||||||
|
The driver information previously displayed in the /proc filesystem is not
|
||||||
|
supported in this release. Alternatively, you can use ethtool (version 1.6
|
||||||
|
or later), lspci, and ifconfig to obtain the same information.
|
||||||
|
|
||||||
|
Instructions on updating ethtool can be found in the section "Additional
|
||||||
|
Configurations" later in this document.
|
||||||
|
|
||||||
For questions related to hardware requirements, refer to the documentation
|
|
||||||
supplied with your Intel PRO/10GbE adapter. All hardware requirements listed
|
|
||||||
apply to use with Linux.
|
|
||||||
|
|
||||||
Identifying Your Adapter
|
Identifying Your Adapter
|
||||||
========================
|
========================
|
||||||
|
|
||||||
To verify your Intel adapter is supported, find the board ID number on the
|
The following Intel network adapters are compatible with the drivers in this
|
||||||
adapter. Look for a label that has a barcode and a number in the format
|
release:
|
||||||
A12345-001.
|
|
||||||
|
|
||||||
Use the above information and the Adapter & Driver ID Guide at:
|
Controller Adapter Name Physical Layer
|
||||||
|
---------- ------------ --------------
|
||||||
|
82597EX Intel(R) PRO/10GbE LR/SR/CX4 10G Base-LR (1310 nm optical fiber)
|
||||||
|
Server Adapters 10G Base-SR (850 nm optical fiber)
|
||||||
|
10G Base-CX4(twin-axial copper cabling)
|
||||||
|
|
||||||
http://support.intel.com/support/network/adapter/pro100/21397.htm
|
For more information on how to identify your adapter, go to the Adapter &
|
||||||
|
Driver ID Guide at:
|
||||||
|
|
||||||
For the latest Intel network drivers for Linux, go to:
|
http://support.intel.com/support/network/sb/CS-012904.htm
|
||||||
|
|
||||||
|
|
||||||
|
Building and Installation
|
||||||
|
=========================
|
||||||
|
|
||||||
|
select m for "Intel(R) PRO/10GbE support" located at:
|
||||||
|
Location:
|
||||||
|
-> Device Drivers
|
||||||
|
-> Network device support (NETDEVICES [=y])
|
||||||
|
-> Ethernet (10000 Mbit) (NETDEV_10000 [=y])
|
||||||
|
1. make modules && make modules_install
|
||||||
|
|
||||||
|
2. Load the module:
|
||||||
|
|
||||||
|
modprobe ixgb <parameter>=<value>
|
||||||
|
|
||||||
|
The insmod command can be used if the full
|
||||||
|
path to the driver module is specified. For example:
|
||||||
|
|
||||||
|
insmod /lib/modules/<KERNEL VERSION>/kernel/drivers/net/ixgb/ixgb.ko
|
||||||
|
|
||||||
|
With 2.6 based kernels also make sure that older ixgb drivers are
|
||||||
|
removed from the kernel, before loading the new module:
|
||||||
|
|
||||||
|
rmmod ixgb; modprobe ixgb
|
||||||
|
|
||||||
|
3. Assign an IP address to the interface by entering the following, where
|
||||||
|
x is the interface number:
|
||||||
|
|
||||||
|
ifconfig ethx <IP_address>
|
||||||
|
|
||||||
|
4. Verify that the interface works. Enter the following, where <IP_address>
|
||||||
|
is the IP address for another machine on the same subnet as the interface
|
||||||
|
that is being tested:
|
||||||
|
|
||||||
|
ping <IP_address>
|
||||||
|
|
||||||
http://downloadfinder.intel.com/scripts-df/support_intel.asp
|
|
||||||
|
|
||||||
Command Line Parameters
|
Command Line Parameters
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
If the driver is built as a module, the following optional parameters are
|
If the driver is built as a module, the following optional parameters are
|
||||||
used by entering them on the command line with the modprobe or insmod command
|
used by entering them on the command line with the modprobe command using
|
||||||
using this syntax:
|
this syntax:
|
||||||
|
|
||||||
modprobe ixgb [<option>=<VAL1>,<VAL2>,...]
|
modprobe ixgb [<option>=<VAL1>,<VAL2>,...]
|
||||||
|
|
||||||
insmod ixgb [<option>=<VAL1>,<VAL2>,...]
|
For example, with two 10GbE PCI adapters, entering:
|
||||||
|
|
||||||
For example, with two PRO/10GbE PCI adapters, entering:
|
modprobe ixgb TxDescriptors=80,128
|
||||||
|
|
||||||
insmod ixgb TxDescriptors=80,128
|
loads the ixgb driver with 80 TX resources for the first adapter and 128 TX
|
||||||
|
|
||||||
loads the ixgb driver with 80 TX resources for the first adapter and 128 TX
|
|
||||||
resources for the second adapter.
|
resources for the second adapter.
|
||||||
|
|
||||||
The default value for each parameter is generally the recommended setting,
|
The default value for each parameter is generally the recommended setting,
|
||||||
unless otherwise noted. Also, if the driver is statically built into the
|
unless otherwise noted.
|
||||||
kernel, the driver is loaded with the default values for all the parameters.
|
|
||||||
Ethtool can be used to change some of the parameters at runtime.
|
|
||||||
|
|
||||||
FlowControl
|
FlowControl
|
||||||
Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
|
Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
|
||||||
Default: Read from the EEPROM
|
Default: Read from the EEPROM
|
||||||
If EEPROM is not detected, default is 3
|
If EEPROM is not detected, default is 1
|
||||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||||
Ethernet PAUSE frames.
|
Ethernet PAUSE frames. There are hardware bugs associated with enabling
|
||||||
|
Tx flow control so beware.
|
||||||
|
|
||||||
RxDescriptors
|
RxDescriptors
|
||||||
Valid Range: 64-512
|
Valid Range: 64-512
|
||||||
Default Value: 512
|
Default Value: 512
|
||||||
This value is the number of receive descriptors allocated by the driver.
|
This value is the number of receive descriptors allocated by the driver.
|
||||||
Increasing this value allows the driver to buffer more incoming packets.
|
Increasing this value allows the driver to buffer more incoming packets.
|
||||||
Each descriptor is 16 bytes. A receive buffer is also allocated for
|
Each descriptor is 16 bytes. A receive buffer is also allocated for
|
||||||
each descriptor and can be either 2048, 4056, 8192, or 16384 bytes,
|
each descriptor and can be either 2048, 4056, 8192, or 16384 bytes,
|
||||||
depending on the MTU setting. When the MTU size is 1500 or less, the
|
depending on the MTU setting. When the MTU size is 1500 or less, the
|
||||||
receive buffer size is 2048 bytes. When the MTU is greater than 1500 the
|
receive buffer size is 2048 bytes. When the MTU is greater than 1500 the
|
||||||
receive buffer size will be either 4056, 8192, or 16384 bytes. The
|
receive buffer size will be either 4056, 8192, or 16384 bytes. The
|
||||||
maximum MTU size is 16114.
|
maximum MTU size is 16114.
|
||||||
|
|
||||||
RxIntDelay
|
RxIntDelay
|
||||||
Valid Range: 0-65535 (0=off)
|
Valid Range: 0-65535 (0=off)
|
||||||
Default Value: 6
|
Default Value: 72
|
||||||
This value delays the generation of receive interrupts in units of
|
This value delays the generation of receive interrupts in units of
|
||||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||||
efficiency if properly tuned for specific network traffic. Increasing
|
efficiency if properly tuned for specific network traffic. Increasing
|
||||||
this value adds extra latency to frame reception and can end up
|
this value adds extra latency to frame reception and can end up
|
||||||
decreasing the throughput of TCP traffic. If the system is reporting
|
decreasing the throughput of TCP traffic. If the system is reporting
|
||||||
dropped receives, this value may be set too high, causing the driver to
|
dropped receives, this value may be set too high, causing the driver to
|
||||||
run out of available receive descriptors.
|
run out of available receive descriptors.
|
||||||
|
|
||||||
TxDescriptors
|
TxDescriptors
|
||||||
Valid Range: 64-4096
|
Valid Range: 64-4096
|
||||||
Default Value: 256
|
Default Value: 256
|
||||||
This value is the number of transmit descriptors allocated by the driver.
|
This value is the number of transmit descriptors allocated by the driver.
|
||||||
Increasing this value allows the driver to queue more transmits. Each
|
Increasing this value allows the driver to queue more transmits. Each
|
||||||
descriptor is 16 bytes.
|
descriptor is 16 bytes.
|
||||||
|
|
||||||
XsumRX
|
XsumRX
|
||||||
|
@ -105,51 +162,49 @@ Default Value: 1
|
||||||
A value of '1' indicates that the driver should enable IP checksum
|
A value of '1' indicates that the driver should enable IP checksum
|
||||||
offload for received packets (both UDP and TCP) to the adapter hardware.
|
offload for received packets (both UDP and TCP) to the adapter hardware.
|
||||||
|
|
||||||
XsumTX
|
|
||||||
Valid Range: 0-1
|
|
||||||
Default Value: 1
|
|
||||||
A value of '1' indicates that the driver should enable IP checksum
|
|
||||||
offload for transmitted packets (both UDP and TCP) to the adapter
|
|
||||||
hardware.
|
|
||||||
|
|
||||||
Improving Performance
|
Improving Performance
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
With the Intel PRO/10 GbE adapter, the default Linux configuration will very
|
With the 10 Gigabit server adapters, the default Linux configuration will
|
||||||
likely limit the total available throughput artificially. There is a set of
|
very likely limit the total available throughput artificially. There is a set
|
||||||
things that when applied together increase the ability of Linux to transmit
|
of configuration changes that, when applied together, will increase the ability
|
||||||
and receive data. The following enhancements were originally acquired from
|
of Linux to transmit and receive data. The following enhancements were
|
||||||
settings published at http://www.spec.org/web99 for various submitted results
|
originally acquired from settings published at http://www.spec.org/web99/ for
|
||||||
using Linux.
|
various submitted results using Linux.
|
||||||
|
|
||||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||||
tuning your network performance.
|
tuning your network performance.
|
||||||
|
|
||||||
The changes are made in three major ways, listed in order of greatest effect:
|
The changes are made in three major ways, listed in order of greatest effect:
|
||||||
- Use ifconfig to modify the mtu (maximum transmission unit) and the txqueuelen
|
- Use ifconfig to modify the mtu (maximum transmission unit) and the txqueuelen
|
||||||
parameter.
|
parameter.
|
||||||
- Use sysctl to modify /proc parameters (essentially kernel tuning)
|
- Use sysctl to modify /proc parameters (essentially kernel tuning)
|
||||||
- Use setpci to modify the MMRBC field in PCI-X configuration space to increase
|
- Use setpci to modify the MMRBC field in PCI-X configuration space to increase
|
||||||
transmit burst lengths on the bus.
|
transmit burst lengths on the bus.
|
||||||
|
|
||||||
NOTE: setpci modifies the adapter's configuration registers to allow it to read
|
NOTE: setpci modifies the adapter's configuration registers to allow it to read
|
||||||
up to 4k bytes at a time (for transmits). However, for some systems the
|
up to 4k bytes at a time (for transmits). However, for some systems the
|
||||||
behavior after modifying this register may be undefined (possibly errors of some
|
behavior after modifying this register may be undefined (possibly errors of
|
||||||
kind). A power-cycle, hard reset or explicitly setting the e6 register back to
|
some kind). A power-cycle, hard reset or explicitly setting the e6 register
|
||||||
22 (setpci -d 8086:1048 e6.b=22) may be required to get back to a stable
|
back to 22 (setpci -d 8086:1a48 e6.b=22) may be required to get back to a
|
||||||
configuration.
|
stable configuration.
|
||||||
|
|
||||||
- COPY these lines and paste them into ixgb_perf.sh:
|
- COPY these lines and paste them into ixgb_perf.sh:
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
echo "configuring network performance , edit this file to change the interface"
|
echo "configuring network performance , edit this file to change the interface
|
||||||
|
or device ID of 10GbE card"
|
||||||
# set mmrbc to 4k reads, modify only Intel 10GbE device IDs
|
# set mmrbc to 4k reads, modify only Intel 10GbE device IDs
|
||||||
setpci -d 8086:1048 e6.b=2e
|
# replace 1a48 with appropriate 10GbE device's ID installed on the system,
|
||||||
# set the MTU (max transmission unit) - it requires your switch and clients to change too!
|
# if needed.
|
||||||
|
setpci -d 8086:1a48 e6.b=2e
|
||||||
|
# set the MTU (max transmission unit) - it requires your switch and clients
|
||||||
|
# to change as well.
|
||||||
# set the txqueuelen
|
# set the txqueuelen
|
||||||
# your ixgb adapter should be loaded as eth1 for this to work, change if needed
|
# your ixgb adapter should be loaded as eth1 for this to work, change if needed
|
||||||
ifconfig eth1 mtu 9000 txqueuelen 1000 up
|
ifconfig eth1 mtu 9000 txqueuelen 1000 up
|
||||||
# call the sysctl utility to modify /proc/sys entries
|
# call the sysctl utility to modify /proc/sys entries
|
||||||
sysctl -p ./sysctl_ixgb.conf
|
sysctl -p ./sysctl_ixgb.conf
|
||||||
- END ixgb_perf.sh
|
- END ixgb_perf.sh
|
||||||
|
|
||||||
- COPY these lines and paste them into sysctl_ixgb.conf:
|
- COPY these lines and paste them into sysctl_ixgb.conf:
|
||||||
|
@ -159,54 +214,220 @@ sysctl -p ./sysctl_ixgb.conf
|
||||||
# several network benchmark tests, your mileage may vary
|
# several network benchmark tests, your mileage may vary
|
||||||
|
|
||||||
### IPV4 specific settings
|
### IPV4 specific settings
|
||||||
net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
|
# turn TCP timestamp support off, default 1, reduces CPU use
|
||||||
net.ipv4.tcp_sack = 0 # turn SACK support off, default on
|
net.ipv4.tcp_timestamps = 0
|
||||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
# turn SACK support off, default on
|
||||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
|
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
|
net.ipv4.tcp_sack = 0
|
||||||
net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
|
# set min/default/max TCP read buffer, default 4096 87380 174760
|
||||||
|
net.ipv4.tcp_rmem = 10000000 10000000 10000000
|
||||||
|
# set min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||||
|
net.ipv4.tcp_wmem = 10000000 10000000 10000000
|
||||||
|
# set min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||||
|
net.ipv4.tcp_mem = 10000000 10000000 10000000
|
||||||
|
|
||||||
### CORE settings (mostly for socket and UDP effect)
|
### CORE settings (mostly for socket and UDP effect)
|
||||||
net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
|
# set maximum receive socket buffer size, default 131071
|
||||||
net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
|
net.core.rmem_max = 524287
|
||||||
net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
|
# set maximum send socket buffer size, default 131071
|
||||||
net.core.wmem_default = 524287 # default send socket buffer size, default 65535
|
net.core.wmem_max = 524287
|
||||||
net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
|
# set default receive socket buffer size, default 65535
|
||||||
net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
|
net.core.rmem_default = 524287
|
||||||
|
# set default send socket buffer size, default 65535
|
||||||
|
net.core.wmem_default = 524287
|
||||||
|
# set maximum amount of option memory buffers, default 10240
|
||||||
|
net.core.optmem_max = 524287
|
||||||
|
# set number of unprocessed input packets before kernel starts dropping them; default 300
|
||||||
|
net.core.netdev_max_backlog = 300000
|
||||||
- END sysctl_ixgb.conf
|
- END sysctl_ixgb.conf
|
||||||
|
|
||||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||||
your ixgb driver is using.
|
your ixgb driver is using and/or replace '1a48' with appropriate 10GbE device's
|
||||||
|
ID installed on the system.
|
||||||
|
|
||||||
NOTE: Unless these scripts are added to the boot process, these changes will
|
NOTE: Unless these scripts are added to the boot process, these changes will
|
||||||
only last only until the next system reboot.
|
only last only until the next system reboot.
|
||||||
|
|
||||||
|
|
||||||
Resolving Slow UDP Traffic
|
Resolving Slow UDP Traffic
|
||||||
--------------------------
|
--------------------------
|
||||||
|
If your server does not seem to be able to receive UDP traffic as fast as it
|
||||||
|
can receive TCP traffic, it could be because Linux, by default, does not set
|
||||||
|
the network stack buffers as large as they need to be to support high UDP
|
||||||
|
transfer rates. One way to alleviate this problem is to allow more memory to
|
||||||
|
be used by the IP stack to store incoming data.
|
||||||
|
|
||||||
If your server does not seem to be able to receive UDP traffic as fast as it
|
For instance, use the commands:
|
||||||
can receive TCP traffic, it could be because Linux, by default, does not set
|
|
||||||
the network stack buffers as large as they need to be to support high UDP
|
|
||||||
transfer rates. One way to alleviate this problem is to allow more memory to
|
|
||||||
be used by the IP stack to store incoming data.
|
|
||||||
|
|
||||||
For instance, use the commands:
|
|
||||||
sysctl -w net.core.rmem_max=262143
|
sysctl -w net.core.rmem_max=262143
|
||||||
and
|
and
|
||||||
sysctl -w net.core.rmem_default=262143
|
sysctl -w net.core.rmem_default=262143
|
||||||
to increase the read buffer memory max and default to 262143 (256k - 1) from
|
to increase the read buffer memory max and default to 262143 (256k - 1) from
|
||||||
defaults of max=131071 (128k - 1) and default=65535 (64k - 1). These variables
|
defaults of max=131071 (128k - 1) and default=65535 (64k - 1). These variables
|
||||||
will increase the amount of memory used by the network stack for receives, and
|
will increase the amount of memory used by the network stack for receives, and
|
||||||
can be increased significantly more if necessary for your application.
|
can be increased significantly more if necessary for your application.
|
||||||
|
|
||||||
|
|
||||||
|
Additional Configurations
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Configuring the Driver on Different Distributions
|
||||||
|
-------------------------------------------------
|
||||||
|
Configuring a network driver to load properly when the system is started is
|
||||||
|
distribution dependent. Typically, the configuration process involves adding
|
||||||
|
an alias line to /etc/modprobe.conf as well as editing other system startup
|
||||||
|
scripts and/or configuration files. Many popular Linux distributions ship
|
||||||
|
with tools to make these changes for you. To learn the proper way to
|
||||||
|
configure a network device for your system, refer to your distribution
|
||||||
|
documentation. If during this process you are asked for the driver or module
|
||||||
|
name, the name for the Linux Base Driver for the Intel 10GbE Family of
|
||||||
|
Adapters is ixgb.
|
||||||
|
|
||||||
|
Viewing Link Messages
|
||||||
|
---------------------
|
||||||
|
Link messages will not be displayed to the console if the distribution is
|
||||||
|
restricting system messages. In order to see network driver link messages on
|
||||||
|
your console, set dmesg to eight by entering the following:
|
||||||
|
|
||||||
|
dmesg -n 8
|
||||||
|
|
||||||
|
NOTE: This setting is not saved across reboots.
|
||||||
|
|
||||||
|
|
||||||
|
Jumbo Frames
|
||||||
|
------------
|
||||||
|
The driver supports Jumbo Frames for all adapters. Jumbo Frames support is
|
||||||
|
enabled by changing the MTU to a value larger than the default of 1500.
|
||||||
|
The maximum value for the MTU is 16114. Use the ifconfig command to
|
||||||
|
increase the MTU size. For example:
|
||||||
|
|
||||||
|
ifconfig ethx mtu 9000 up
|
||||||
|
|
||||||
|
The maximum MTU setting for Jumbo Frames is 16114. This value coincides
|
||||||
|
with the maximum Jumbo Frames size of 16128.
|
||||||
|
|
||||||
|
|
||||||
|
Ethtool
|
||||||
|
-------
|
||||||
|
The driver utilizes the ethtool interface for driver configuration and
|
||||||
|
diagnostics, as well as displaying statistical information. Ethtool
|
||||||
|
version 1.6 or later is required for this functionality.
|
||||||
|
|
||||||
|
The latest release of ethtool can be found from
|
||||||
|
http://sourceforge.net/projects/gkernel
|
||||||
|
|
||||||
|
NOTE: Ethtool 1.6 only supports a limited set of ethtool options. Support
|
||||||
|
for a more complete ethtool feature set can be enabled by upgrading
|
||||||
|
to the latest version.
|
||||||
|
|
||||||
|
|
||||||
|
NAPI
|
||||||
|
----
|
||||||
|
|
||||||
|
NAPI (Rx polling mode) is supported in the ixgb driver. NAPI is enabled
|
||||||
|
or disabled based on the configuration of the kernel. see CONFIG_IXGB_NAPI
|
||||||
|
|
||||||
|
See www.cyberus.ca/~hadi/usenix-paper.tgz for more information on NAPI.
|
||||||
|
|
||||||
|
|
||||||
|
Known Issues/Troubleshooting
|
||||||
|
============================
|
||||||
|
|
||||||
|
NOTE: After installing the driver, if your Intel Network Connection is not
|
||||||
|
working, verify in the "In This Release" section of the readme that you have
|
||||||
|
installed the correct driver.
|
||||||
|
|
||||||
|
Intel(R) PRO/10GbE CX4 Server Adapter Cable Interoperability Issue with
|
||||||
|
Fujitsu XENPAK Module in SmartBits Chassis
|
||||||
|
---------------------------------------------------------------------
|
||||||
|
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4
|
||||||
|
Server adapter is connected to a Fujitsu XENPAK CX4 module in a SmartBits
|
||||||
|
chassis using 15 m/24AWG cable assemblies manufactured by Fujitsu or Leoni.
|
||||||
|
The CRC errors may be received either by the Intel(R) PRO/10GbE CX4
|
||||||
|
Server adapter or the SmartBits. If this situation occurs using a different
|
||||||
|
cable assembly may resolve the issue.
|
||||||
|
|
||||||
|
CX4 Server Adapter Cable Interoperability Issues with HP Procurve 3400cl
|
||||||
|
Switch Port
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
Excessive CRC errors may be observed if the Intel(R) PRO/10GbE CX4 Server
|
||||||
|
adapter is connected to an HP Procurve 3400cl switch port using short cables
|
||||||
|
(1 m or shorter). If this situation occurs, using a longer cable may resolve
|
||||||
|
the issue.
|
||||||
|
|
||||||
|
Excessive CRC errors may be observed using Fujitsu 24AWG cable assemblies that
|
||||||
|
Are 10 m or longer or where using a Leoni 15 m/24AWG cable assembly. The CRC
|
||||||
|
errors may be received either by the CX4 Server adapter or at the switch. If
|
||||||
|
this situation occurs, using a different cable assembly may resolve the issue.
|
||||||
|
|
||||||
|
|
||||||
|
Jumbo Frames System Requirement
|
||||||
|
-------------------------------
|
||||||
|
Memory allocation failures have been observed on Linux systems with 64 MB
|
||||||
|
of RAM or less that are running Jumbo Frames. If you are using Jumbo
|
||||||
|
Frames, your system may require more than the advertised minimum
|
||||||
|
requirement of 64 MB of system memory.
|
||||||
|
|
||||||
|
|
||||||
|
Performance Degradation with Jumbo Frames
|
||||||
|
-----------------------------------------
|
||||||
|
Degradation in throughput performance may be observed in some Jumbo frames
|
||||||
|
environments. If this is observed, increasing the application's socket buffer
|
||||||
|
size and/or increasing the /proc/sys/net/ipv4/tcp_*mem entry values may help.
|
||||||
|
See the specific application manual and /usr/src/linux*/Documentation/
|
||||||
|
networking/ip-sysctl.txt for more details.
|
||||||
|
|
||||||
|
|
||||||
|
Allocating Rx Buffers when Using Jumbo Frames
|
||||||
|
---------------------------------------------
|
||||||
|
Allocating Rx buffers when using Jumbo Frames on 2.6.x kernels may fail if
|
||||||
|
the available memory is heavily fragmented. This issue may be seen with PCI-X
|
||||||
|
adapters or with packet split disabled. This can be reduced or eliminated
|
||||||
|
by changing the amount of available memory for receive buffer allocation, by
|
||||||
|
increasing /proc/sys/vm/min_free_kbytes.
|
||||||
|
|
||||||
|
|
||||||
|
Multiple Interfaces on Same Ethernet Broadcast Network
|
||||||
|
------------------------------------------------------
|
||||||
|
Due to the default ARP behavior on Linux, it is not possible to have
|
||||||
|
one system on two IP networks in the same Ethernet broadcast domain
|
||||||
|
(non-partitioned switch) behave as expected. All Ethernet interfaces
|
||||||
|
will respond to IP traffic for any IP address assigned to the system.
|
||||||
|
This results in unbalanced receive traffic.
|
||||||
|
|
||||||
|
If you have multiple interfaces in a server, do either of the following:
|
||||||
|
|
||||||
|
- Turn on ARP filtering by entering:
|
||||||
|
echo 1 > /proc/sys/net/ipv4/conf/all/arp_filter
|
||||||
|
|
||||||
|
- Install the interfaces in separate broadcast domains - either in
|
||||||
|
different switches or in a switch partitioned to VLANs.
|
||||||
|
|
||||||
|
|
||||||
|
UDP Stress Test Dropped Packet Issue
|
||||||
|
--------------------------------------
|
||||||
|
Under small packets UDP stress test with 10GbE driver, the Linux system
|
||||||
|
may drop UDP packets due to the fullness of socket buffers. You may want
|
||||||
|
to change the driver's Flow Control variables to the minimum value for
|
||||||
|
controlling packet reception.
|
||||||
|
|
||||||
|
|
||||||
|
Tx Hangs Possible Under Stress
|
||||||
|
------------------------------
|
||||||
|
Under stress conditions, if TX hangs occur, turning off TSO
|
||||||
|
"ethtool -K eth0 tso off" may resolve the problem.
|
||||||
|
|
||||||
|
|
||||||
Support
|
Support
|
||||||
=======
|
=======
|
||||||
|
|
||||||
For general information and support, go to the Intel support website at:
|
For general information, go to the Intel support website at:
|
||||||
|
|
||||||
http://support.intel.com
|
http://support.intel.com
|
||||||
|
|
||||||
|
or the Intel Wired Networking project hosted by Sourceforge at:
|
||||||
|
|
||||||
|
http://sourceforge.net/projects/e1000
|
||||||
|
|
||||||
If an issue is identified with the released source code on the supported
|
If an issue is identified with the released source code on the supported
|
||||||
kernel with a supported adapter, email the specific information related to
|
kernel with a supported adapter, email the specific information related
|
||||||
the issue to linux.nics@intel.com.
|
to the issue to e1000-devel@lists.sf.net
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
mac80211_hwsim - software simulator of 802.11 radio(s) for mac80211
|
||||||
|
Copyright (c) 2008, Jouni Malinen <j@w1.fi>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License version 2 as
|
||||||
|
published by the Free Software Foundation.
|
||||||
|
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
|
||||||
|
mac80211_hwsim is a Linux kernel module that can be used to simulate
|
||||||
|
arbitrary number of IEEE 802.11 radios for mac80211. It can be used to
|
||||||
|
test most of the mac80211 functionality and user space tools (e.g.,
|
||||||
|
hostapd and wpa_supplicant) in a way that matches very closely with
|
||||||
|
the normal case of using real WLAN hardware. From the mac80211 view
|
||||||
|
point, mac80211_hwsim is yet another hardware driver, i.e., no changes
|
||||||
|
to mac80211 are needed to use this testing tool.
|
||||||
|
|
||||||
|
The main goal for mac80211_hwsim is to make it easier for developers
|
||||||
|
to test their code and work with new features to mac80211, hostapd,
|
||||||
|
and wpa_supplicant. The simulated radios do not have the limitations
|
||||||
|
of real hardware, so it is easy to generate an arbitrary test setup
|
||||||
|
and always reproduce the same setup for future tests. In addition,
|
||||||
|
since all radio operation is simulated, any channel can be used in
|
||||||
|
tests regardless of regulatory rules.
|
||||||
|
|
||||||
|
mac80211_hwsim kernel module has a parameter 'radios' that can be used
|
||||||
|
to select how many radios are simulated (default 2). This allows
|
||||||
|
configuration of both very simply setups (e.g., just a single access
|
||||||
|
point and a station) or large scale tests (multiple access points with
|
||||||
|
hundreds of stations).
|
||||||
|
|
||||||
|
mac80211_hwsim works by tracking the current channel of each virtual
|
||||||
|
radio and copying all transmitted frames to all other radios that are
|
||||||
|
currently enabled and on the same channel as the transmitting
|
||||||
|
radio. Software encryption in mac80211 is used so that the frames are
|
||||||
|
actually encrypted over the virtual air interface to allow more
|
||||||
|
complete testing of encryption.
|
||||||
|
|
||||||
|
A global monitoring netdev, hwsim#, is created independent of
|
||||||
|
mac80211. This interface can be used to monitor all transmitted frames
|
||||||
|
regardless of channel.
|
||||||
|
|
||||||
|
|
||||||
|
Simple example
|
||||||
|
|
||||||
|
This example shows how to use mac80211_hwsim to simulate two radios:
|
||||||
|
one to act as an access point and the other as a station that
|
||||||
|
associates with the AP. hostapd and wpa_supplicant are used to take
|
||||||
|
care of WPA2-PSK authentication. In addition, hostapd is also
|
||||||
|
processing access point side of association.
|
||||||
|
|
||||||
|
Please note that the current Linux kernel does not enable AP mode, so a
|
||||||
|
simple patch is needed to enable AP mode selection:
|
||||||
|
http://johannes.sipsolutions.net/patches/kernel/all/LATEST/006-allow-ap-vlan-modes.patch
|
||||||
|
|
||||||
|
|
||||||
|
# Build mac80211_hwsim as part of kernel configuration
|
||||||
|
|
||||||
|
# Load the module
|
||||||
|
modprobe mac80211_hwsim
|
||||||
|
|
||||||
|
# Run hostapd (AP) for wlan0
|
||||||
|
hostapd hostapd.conf
|
||||||
|
|
||||||
|
# Run wpa_supplicant (station) for wlan1
|
||||||
|
wpa_supplicant -Dwext -iwlan1 -c wpa_supplicant.conf
|
|
@ -0,0 +1,11 @@
|
||||||
|
interface=wlan0
|
||||||
|
driver=nl80211
|
||||||
|
|
||||||
|
hw_mode=g
|
||||||
|
channel=1
|
||||||
|
ssid=mac80211 test
|
||||||
|
|
||||||
|
wpa=2
|
||||||
|
wpa_key_mgmt=WPA-PSK
|
||||||
|
wpa_pairwise=CCMP
|
||||||
|
wpa_passphrase=12345678
|
|
@ -0,0 +1,10 @@
|
||||||
|
ctrl_interface=/var/run/wpa_supplicant
|
||||||
|
|
||||||
|
network={
|
||||||
|
ssid="mac80211 test"
|
||||||
|
psk="12345678"
|
||||||
|
key_mgmt=WPA-PSK
|
||||||
|
proto=WPA2
|
||||||
|
pairwise=CCMP
|
||||||
|
group=CCMP
|
||||||
|
}
|
|
@ -3,19 +3,11 @@
|
||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
Section 1: Base driver requirements for implementing multiqueue support
|
Section 1: Base driver requirements for implementing multiqueue support
|
||||||
Section 2: Qdisc support for multiqueue devices
|
|
||||||
Section 3: Brief howto using PRIO or RR for multiqueue devices
|
|
||||||
|
|
||||||
|
|
||||||
Intro: Kernel support for multiqueue devices
|
Intro: Kernel support for multiqueue devices
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
Kernel support for multiqueue devices is only an API that is presented to the
|
Kernel support for multiqueue devices is always present.
|
||||||
netdevice layer for base drivers to implement. This feature is part of the
|
|
||||||
core networking stack, and all network devices will be running on the
|
|
||||||
multiqueue-aware stack. If a base driver only has one queue, then these
|
|
||||||
changes are transparent to that driver.
|
|
||||||
|
|
||||||
|
|
||||||
Section 1: Base driver requirements for implementing multiqueue support
|
Section 1: Base driver requirements for implementing multiqueue support
|
||||||
-----------------------------------------------------------------------
|
-----------------------------------------------------------------------
|
||||||
|
@ -32,84 +24,4 @@ netif_{start|stop|wake}_subqueue() functions to manage each queue while the
|
||||||
device is still operational. netdev->queue_lock is still used when the device
|
device is still operational. netdev->queue_lock is still used when the device
|
||||||
comes online or when it's completely shut down (unregister_netdev(), etc.).
|
comes online or when it's completely shut down (unregister_netdev(), etc.).
|
||||||
|
|
||||||
Finally, the base driver should indicate that it is a multiqueue device. The
|
|
||||||
feature flag NETIF_F_MULTI_QUEUE should be added to the netdev->features
|
|
||||||
bitmap on device initialization. Below is an example from e1000:
|
|
||||||
|
|
||||||
#ifdef CONFIG_E1000_MQ
|
|
||||||
if ( (adapter->hw.mac.type == e1000_82571) ||
|
|
||||||
(adapter->hw.mac.type == e1000_82572) ||
|
|
||||||
(adapter->hw.mac.type == e1000_80003es2lan))
|
|
||||||
netdev->features |= NETIF_F_MULTI_QUEUE;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
Section 2: Qdisc support for multiqueue devices
|
|
||||||
-----------------------------------------------
|
|
||||||
|
|
||||||
Currently two qdiscs support multiqueue devices. A new round-robin qdisc,
|
|
||||||
sch_rr, and sch_prio. The qdisc is responsible for classifying the skb's to
|
|
||||||
bands and queues, and will store the queue mapping into skb->queue_mapping.
|
|
||||||
Use this field in the base driver to determine which queue to send the skb
|
|
||||||
to.
|
|
||||||
|
|
||||||
sch_rr has been added for hardware that doesn't want scheduling policies from
|
|
||||||
software, so it's a straight round-robin qdisc. It uses the same syntax and
|
|
||||||
classification priomap that sch_prio uses, so it should be intuitive to
|
|
||||||
configure for people who've used sch_prio.
|
|
||||||
|
|
||||||
In order to utilitize the multiqueue features of the qdiscs, the network
|
|
||||||
device layer needs to enable multiple queue support. This can be done by
|
|
||||||
selecting NETDEVICES_MULTIQUEUE under Drivers.
|
|
||||||
|
|
||||||
The PRIO qdisc naturally plugs into a multiqueue device. If
|
|
||||||
NETDEVICES_MULTIQUEUE is selected, then on qdisc load, the number of
|
|
||||||
bands requested is compared to the number of queues on the hardware. If they
|
|
||||||
are equal, it sets a one-to-one mapping up between the queues and bands. If
|
|
||||||
they're not equal, it will not load the qdisc. This is the same behavior
|
|
||||||
for RR. Once the association is made, any skb that is classified will have
|
|
||||||
skb->queue_mapping set, which will allow the driver to properly queue skb's
|
|
||||||
to multiple queues.
|
|
||||||
|
|
||||||
|
|
||||||
Section 3: Brief howto using PRIO and RR for multiqueue devices
|
|
||||||
---------------------------------------------------------------
|
|
||||||
|
|
||||||
The userspace command 'tc,' part of the iproute2 package, is used to configure
|
|
||||||
qdiscs. To add the PRIO qdisc to your network device, assuming the device is
|
|
||||||
called eth0, run the following command:
|
|
||||||
|
|
||||||
# tc qdisc add dev eth0 root handle 1: prio bands 4 multiqueue
|
|
||||||
|
|
||||||
This will create 4 bands, 0 being highest priority, and associate those bands
|
|
||||||
to the queues on your NIC. Assuming eth0 has 4 Tx queues, the band mapping
|
|
||||||
would look like:
|
|
||||||
|
|
||||||
band 0 => queue 0
|
|
||||||
band 1 => queue 1
|
|
||||||
band 2 => queue 2
|
|
||||||
band 3 => queue 3
|
|
||||||
|
|
||||||
Traffic will begin flowing through each queue if your TOS values are assigning
|
|
||||||
traffic across the various bands. For example, ssh traffic will always try to
|
|
||||||
go out band 0 based on TOS -> Linux priority conversion (realtime traffic),
|
|
||||||
so it will be sent out queue 0. ICMP traffic (pings) fall into the "normal"
|
|
||||||
traffic classification, which is band 1. Therefore pings will be send out
|
|
||||||
queue 1 on the NIC.
|
|
||||||
|
|
||||||
Note the use of the multiqueue keyword. This is only in versions of iproute2
|
|
||||||
that support multiqueue networking devices; if this is omitted when loading
|
|
||||||
a qdisc onto a multiqueue device, the qdisc will load and operate the same
|
|
||||||
if it were loaded onto a single-queue device (i.e. - sends all traffic to
|
|
||||||
queue 0).
|
|
||||||
|
|
||||||
Another alternative to multiqueue band allocation can be done by using the
|
|
||||||
multiqueue option and specify 0 bands. If this is the case, the qdisc will
|
|
||||||
allocate the number of bands to equal the number of queues that the device
|
|
||||||
reports, and bring the qdisc online.
|
|
||||||
|
|
||||||
The behavior of tc filters remains the same, where it will override TOS priority
|
|
||||||
classification.
|
|
||||||
|
|
||||||
|
|
||||||
Author: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>
|
Author: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com>
|
||||||
|
|
|
@ -52,13 +52,10 @@ d. MSI/MSI-X. Can be enabled on platforms which support this feature
|
||||||
(IA64, Xeon) resulting in noticeable performance improvement(upto 7%
|
(IA64, Xeon) resulting in noticeable performance improvement(upto 7%
|
||||||
on certain platforms).
|
on certain platforms).
|
||||||
|
|
||||||
e. NAPI. Compile-time option(CONFIG_S2IO_NAPI) for better Rx interrupt
|
e. Statistics. Comprehensive MAC-level and software statistics displayed
|
||||||
moderation.
|
|
||||||
|
|
||||||
f. Statistics. Comprehensive MAC-level and software statistics displayed
|
|
||||||
using "ethtool -S" option.
|
using "ethtool -S" option.
|
||||||
|
|
||||||
g. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
|
f. Multi-FIFO/Ring. Supports up to 8 transmit queues and receive rings,
|
||||||
with multiple steering options.
|
with multiple steering options.
|
||||||
|
|
||||||
4. Command line parameters
|
4. Command line parameters
|
||||||
|
|
|
@ -41,12 +41,24 @@ Table of Contents
|
||||||
VI - System-on-a-chip devices and nodes
|
VI - System-on-a-chip devices and nodes
|
||||||
1) Defining child nodes of an SOC
|
1) Defining child nodes of an SOC
|
||||||
2) Representing devices without a current OF specification
|
2) Representing devices without a current OF specification
|
||||||
a) PHY nodes
|
a) MDIO IO device
|
||||||
b) Interrupt controllers
|
b) Gianfar-compatible ethernet nodes
|
||||||
c) CFI or JEDEC memory-mapped NOR flash
|
c) PHY nodes
|
||||||
d) 4xx/Axon EMAC ethernet nodes
|
d) Interrupt controllers
|
||||||
e) Xilinx IP cores
|
e) I2C
|
||||||
f) USB EHCI controllers
|
f) Freescale SOC USB controllers
|
||||||
|
g) Freescale SOC SEC Security Engines
|
||||||
|
h) Board Control and Status (BCSR)
|
||||||
|
i) Freescale QUICC Engine module (QE)
|
||||||
|
j) CFI or JEDEC memory-mapped NOR flash
|
||||||
|
k) Global Utilities Block
|
||||||
|
l) Freescale Communications Processor Module
|
||||||
|
m) Chipselect/Local Bus
|
||||||
|
n) 4xx/Axon EMAC ethernet nodes
|
||||||
|
o) Xilinx IP cores
|
||||||
|
p) Freescale Synchronous Serial Interface
|
||||||
|
q) USB EHCI controllers
|
||||||
|
r) MDIO on GPIOs
|
||||||
|
|
||||||
VII - Marvell Discovery mv64[345]6x System Controller chips
|
VII - Marvell Discovery mv64[345]6x System Controller chips
|
||||||
1) The /system-controller node
|
1) The /system-controller node
|
||||||
|
@ -1815,6 +1827,60 @@ platforms are moved over to use the flattened-device-tree model.
|
||||||
big-endian;
|
big-endian;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
r) Freescale Display Interface Unit
|
||||||
|
|
||||||
|
The Freescale DIU is a LCD controller, with proper hardware, it can also
|
||||||
|
drive DVI monitors.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible : should be "fsl-diu".
|
||||||
|
- reg : should contain at least address and length of the DIU register
|
||||||
|
set.
|
||||||
|
- Interrupts : one DIU interrupt should be describe here.
|
||||||
|
|
||||||
|
Example (MPC8610HPCD)
|
||||||
|
display@2c000 {
|
||||||
|
compatible = "fsl,diu";
|
||||||
|
reg = <0x2c000 100>;
|
||||||
|
interrupts = <72 2>;
|
||||||
|
interrupt-parent = <&mpic>;
|
||||||
|
};
|
||||||
|
|
||||||
|
s) Freescale on board FPGA
|
||||||
|
|
||||||
|
This is the memory-mapped registers for on board FPGA.
|
||||||
|
|
||||||
|
Required properities:
|
||||||
|
- compatible : should be "fsl,fpga-pixis".
|
||||||
|
- reg : should contain the address and the lenght of the FPPGA register
|
||||||
|
set.
|
||||||
|
|
||||||
|
Example (MPC8610HPCD)
|
||||||
|
board-control@e8000000 {
|
||||||
|
compatible = "fsl,fpga-pixis";
|
||||||
|
reg = <0xe8000000 32>;
|
||||||
|
};
|
||||||
|
|
||||||
|
r) MDIO on GPIOs
|
||||||
|
|
||||||
|
Currently defined compatibles:
|
||||||
|
- virtual,gpio-mdio
|
||||||
|
|
||||||
|
MDC and MDIO lines connected to GPIO controllers are listed in the
|
||||||
|
gpios property as described in section VIII.1 in the following order:
|
||||||
|
|
||||||
|
MDC, MDIO.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
mdio {
|
||||||
|
compatible = "virtual,mdio-gpio";
|
||||||
|
#address-cells = <1>;
|
||||||
|
#size-cells = <0>;
|
||||||
|
gpios = <&qe_pio_a 11
|
||||||
|
&qe_pio_c 6>;
|
||||||
|
};
|
||||||
|
|
||||||
VII - Marvell Discovery mv64[345]6x System Controller chips
|
VII - Marvell Discovery mv64[345]6x System Controller chips
|
||||||
===========================================================
|
===========================================================
|
||||||
|
|
||||||
|
|
|
@ -1,89 +1,528 @@
|
||||||
rfkill - RF switch subsystem support
|
rfkill - RF switch subsystem support
|
||||||
====================================
|
====================================
|
||||||
|
|
||||||
1 Implementation details
|
1 Introduction
|
||||||
2 Driver support
|
2 Implementation details
|
||||||
3 Userspace support
|
3 Kernel driver guidelines
|
||||||
|
3.1 wireless device drivers
|
||||||
|
3.2 platform/switch drivers
|
||||||
|
3.3 input device drivers
|
||||||
|
4 Kernel API
|
||||||
|
5 Userspace support
|
||||||
|
|
||||||
|
|
||||||
|
1. Introduction:
|
||||||
|
|
||||||
|
The rfkill switch subsystem exists to add a generic interface to circuitry that
|
||||||
|
can enable or disable the signal output of a wireless *transmitter* of any
|
||||||
|
type. By far, the most common use is to disable radio-frequency transmitters.
|
||||||
|
|
||||||
|
Note that disabling the signal output means that the the transmitter is to be
|
||||||
|
made to not emit any energy when "blocked". rfkill is not about blocking data
|
||||||
|
transmissions, it is about blocking energy emission.
|
||||||
|
|
||||||
|
The rfkill subsystem offers support for keys and switches often found on
|
||||||
|
laptops to enable wireless devices like WiFi and Bluetooth, so that these keys
|
||||||
|
and switches actually perform an action in all wireless devices of a given type
|
||||||
|
attached to the system.
|
||||||
|
|
||||||
|
The buttons to enable and disable the wireless transmitters are important in
|
||||||
|
situations where the user is for example using his laptop on a location where
|
||||||
|
radio-frequency transmitters _must_ be disabled (e.g. airplanes).
|
||||||
|
|
||||||
|
Because of this requirement, userspace support for the keys should not be made
|
||||||
|
mandatory. Because userspace might want to perform some additional smarter
|
||||||
|
tasks when the key is pressed, rfkill provides userspace the possibility to
|
||||||
|
take over the task to handle the key events.
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
1: Implementation details
|
2: Implementation details
|
||||||
|
|
||||||
The rfkill switch subsystem offers support for keys often found on laptops
|
The rfkill subsystem is composed of various components: the rfkill class, the
|
||||||
to enable wireless devices like WiFi and Bluetooth.
|
rfkill-input module (an input layer handler), and some specific input layer
|
||||||
|
events.
|
||||||
|
|
||||||
This is done by providing the user 3 possibilities:
|
The rfkill class provides kernel drivers with an interface that allows them to
|
||||||
1 - The rfkill system handles all events; userspace is not aware of events.
|
know when they should enable or disable a wireless network device transmitter.
|
||||||
2 - The rfkill system handles all events; userspace is informed about the events.
|
This is enabled by the CONFIG_RFKILL Kconfig option.
|
||||||
3 - The rfkill system does not handle events; userspace handles all events.
|
|
||||||
|
|
||||||
The buttons to enable and disable the wireless radios are important in
|
The rfkill class support makes sure userspace will be notified of all state
|
||||||
situations where the user is for example using his laptop on a location where
|
changes on rfkill devices through uevents. It provides a notification chain
|
||||||
wireless radios _must_ be disabled (e.g. airplanes).
|
for interested parties in the kernel to also get notified of rfkill state
|
||||||
Because of this requirement, userspace support for the keys should not be
|
changes in other drivers. It creates several sysfs entries which can be used
|
||||||
made mandatory. Because userspace might want to perform some additional smarter
|
by userspace. See section "Userspace support".
|
||||||
tasks when the key is pressed, rfkill still provides userspace the possibility
|
|
||||||
to take over the task to handle the key events.
|
|
||||||
|
|
||||||
The system inside the kernel has been split into 2 separate sections:
|
The rfkill-input module provides the kernel with the ability to implement a
|
||||||
1 - RFKILL
|
basic response when the user presses a key or button (or toggles a switch)
|
||||||
2 - RFKILL_INPUT
|
related to rfkill functionality. It is an in-kernel implementation of default
|
||||||
|
policy of reacting to rfkill-related input events and neither mandatory nor
|
||||||
|
required for wireless drivers to operate. It is enabled by the
|
||||||
|
CONFIG_RFKILL_INPUT Kconfig option.
|
||||||
|
|
||||||
The first option enables rfkill support and will make sure userspace will
|
rfkill-input is a rfkill-related events input layer handler. This handler will
|
||||||
be notified of any events through the input device. It also creates several
|
listen to all rfkill key events and will change the rfkill state of the
|
||||||
sysfs entries which can be used by userspace. See section "Userspace support".
|
wireless devices accordingly. With this option enabled userspace could either
|
||||||
|
do nothing or simply perform monitoring tasks.
|
||||||
|
|
||||||
The second option provides an rfkill input handler. This handler will
|
The rfkill-input module also provides EPO (emergency power-off) functionality
|
||||||
listen to all rfkill key events and will toggle the radio accordingly.
|
for all wireless transmitters. This function cannot be overridden, and it is
|
||||||
With this option enabled userspace could either do nothing or simply
|
always active. rfkill EPO is related to *_RFKILL_ALL input layer events.
|
||||||
perform monitoring tasks.
|
|
||||||
|
|
||||||
|
|
||||||
|
Important terms for the rfkill subsystem:
|
||||||
|
|
||||||
|
In order to avoid confusion, we avoid the term "switch" in rfkill when it is
|
||||||
|
referring to an electronic control circuit that enables or disables a
|
||||||
|
transmitter. We reserve it for the physical device a human manipulates
|
||||||
|
(which is an input device, by the way):
|
||||||
|
|
||||||
|
rfkill switch:
|
||||||
|
|
||||||
|
A physical device a human manipulates. Its state can be perceived by
|
||||||
|
the kernel either directly (through a GPIO pin, ACPI GPE) or by its
|
||||||
|
effect on a rfkill line of a wireless device.
|
||||||
|
|
||||||
|
rfkill controller:
|
||||||
|
|
||||||
|
A hardware circuit that controls the state of a rfkill line, which a
|
||||||
|
kernel driver can interact with *to modify* that state (i.e. it has
|
||||||
|
either write-only or read/write access).
|
||||||
|
|
||||||
|
rfkill line:
|
||||||
|
|
||||||
|
An input channel (hardware or software) of a wireless device, which
|
||||||
|
causes a wireless transmitter to stop emitting energy (BLOCK) when it
|
||||||
|
is active. Point of view is extremely important here: rfkill lines are
|
||||||
|
always seen from the PoV of a wireless device (and its driver).
|
||||||
|
|
||||||
|
soft rfkill line/software rfkill line:
|
||||||
|
|
||||||
|
A rfkill line the wireless device driver can directly change the state
|
||||||
|
of. Related to rfkill_state RFKILL_STATE_SOFT_BLOCKED.
|
||||||
|
|
||||||
|
hard rfkill line/hardware rfkill line:
|
||||||
|
|
||||||
|
A rfkill line that works fully in hardware or firmware, and that cannot
|
||||||
|
be overridden by the kernel driver. The hardware device or the
|
||||||
|
firmware just exports its status to the driver, but it is read-only.
|
||||||
|
Related to rfkill_state RFKILL_STATE_HARD_BLOCKED.
|
||||||
|
|
||||||
|
The enum rfkill_state describes the rfkill state of a transmitter:
|
||||||
|
|
||||||
|
When a rfkill line or rfkill controller is in the RFKILL_STATE_UNBLOCKED state,
|
||||||
|
the wireless transmitter (radio TX circuit for example) is *enabled*. When the
|
||||||
|
it is in the RFKILL_STATE_SOFT_BLOCKED or RFKILL_STATE_HARD_BLOCKED, the
|
||||||
|
wireless transmitter is to be *blocked* from operating.
|
||||||
|
|
||||||
|
RFKILL_STATE_SOFT_BLOCKED indicates that a call to toggle_radio() can change
|
||||||
|
that state. RFKILL_STATE_HARD_BLOCKED indicates that a call to toggle_radio()
|
||||||
|
will not be able to change the state and will return with a suitable error if
|
||||||
|
attempts are made to set the state to RFKILL_STATE_UNBLOCKED.
|
||||||
|
|
||||||
|
RFKILL_STATE_HARD_BLOCKED is used by drivers to signal that the device is
|
||||||
|
locked in the BLOCKED state by a hardwire rfkill line (typically an input pin
|
||||||
|
that, when active, forces the transmitter to be disabled) which the driver
|
||||||
|
CANNOT override.
|
||||||
|
|
||||||
|
Full rfkill functionality requires two different subsystems to cooperate: the
|
||||||
|
input layer and the rfkill class. The input layer issues *commands* to the
|
||||||
|
entire system requesting that devices registered to the rfkill class change
|
||||||
|
state. The way this interaction happens is not complex, but it is not obvious
|
||||||
|
either:
|
||||||
|
|
||||||
|
Kernel Input layer:
|
||||||
|
|
||||||
|
* Generates KEY_WWAN, KEY_WLAN, KEY_BLUETOOTH, SW_RFKILL_ALL, and
|
||||||
|
other such events when the user presses certain keys, buttons, or
|
||||||
|
toggles certain physical switches.
|
||||||
|
|
||||||
|
THE INPUT LAYER IS NEVER USED TO PROPAGATE STATUS, NOTIFICATIONS OR THE
|
||||||
|
KIND OF STUFF AN ON-SCREEN-DISPLAY APPLICATION WOULD REPORT. It is
|
||||||
|
used to issue *commands* for the system to change behaviour, and these
|
||||||
|
commands may or may not be carried out by some kernel driver or
|
||||||
|
userspace application. It follows that doing user feedback based only
|
||||||
|
on input events is broken, as there is no guarantee that an input event
|
||||||
|
will be acted upon.
|
||||||
|
|
||||||
|
Most wireless communication device drivers implementing rfkill
|
||||||
|
functionality MUST NOT generate these events, and have no reason to
|
||||||
|
register themselves with the input layer. Doing otherwise is a common
|
||||||
|
misconception. There is an API to propagate rfkill status change
|
||||||
|
information, and it is NOT the input layer.
|
||||||
|
|
||||||
|
rfkill class:
|
||||||
|
|
||||||
|
* Calls a hook in a driver to effectively change the wireless
|
||||||
|
transmitter state;
|
||||||
|
* Keeps track of the wireless transmitter state (with help from
|
||||||
|
the driver);
|
||||||
|
* Generates userspace notifications (uevents) and a call to a
|
||||||
|
notification chain (kernel) when there is a wireless transmitter
|
||||||
|
state change;
|
||||||
|
* Connects a wireless communications driver with the common rfkill
|
||||||
|
control system, which, for example, allows actions such as
|
||||||
|
"switch all bluetooth devices offline" to be carried out by
|
||||||
|
userspace or by rfkill-input.
|
||||||
|
|
||||||
|
THE RFKILL CLASS NEVER ISSUES INPUT EVENTS. THE RFKILL CLASS DOES
|
||||||
|
NOT LISTEN TO INPUT EVENTS. NO DRIVER USING THE RFKILL CLASS SHALL
|
||||||
|
EVER LISTEN TO, OR ACT ON RFKILL INPUT EVENTS. Doing otherwise is
|
||||||
|
a layering violation.
|
||||||
|
|
||||||
|
Most wireless data communication drivers in the kernel have just to
|
||||||
|
implement the rfkill class API to work properly. Interfacing to the
|
||||||
|
input layer is not often required (and is very often a *bug*) on
|
||||||
|
wireless drivers.
|
||||||
|
|
||||||
|
Platform drivers often have to attach to the input layer to *issue*
|
||||||
|
(but never to listen to) rfkill events for rfkill switches, and also to
|
||||||
|
the rfkill class to export a control interface for the platform rfkill
|
||||||
|
controllers to the rfkill subsystem. This does NOT mean the rfkill
|
||||||
|
switch is attached to a rfkill class (doing so is almost always wrong).
|
||||||
|
It just means the same kernel module is the driver for different
|
||||||
|
devices (rfkill switches and rfkill controllers).
|
||||||
|
|
||||||
|
|
||||||
|
Userspace input handlers (uevents) or kernel input handlers (rfkill-input):
|
||||||
|
|
||||||
|
* Implements the policy of what should happen when one of the input
|
||||||
|
layer events related to rfkill operation is received.
|
||||||
|
* Uses the sysfs interface (userspace) or private rfkill API calls
|
||||||
|
to tell the devices registered with the rfkill class to change
|
||||||
|
their state (i.e. translates the input layer event into real
|
||||||
|
action).
|
||||||
|
* rfkill-input implements EPO by handling EV_SW SW_RFKILL_ALL 0
|
||||||
|
(power off all transmitters) in a special way: it ignores any
|
||||||
|
overrides and local state cache and forces all transmitters to the
|
||||||
|
RFKILL_STATE_SOFT_BLOCKED state (including those which are already
|
||||||
|
supposed to be BLOCKED). Note that the opposite event (power on all
|
||||||
|
transmitters) is handled normally.
|
||||||
|
|
||||||
|
Userspace uevent handler or kernel platform-specific drivers hooked to the
|
||||||
|
rfkill notifier chain:
|
||||||
|
|
||||||
|
* Taps into the rfkill notifier chain or to KOBJ_CHANGE uevents,
|
||||||
|
in order to know when a device that is registered with the rfkill
|
||||||
|
class changes state;
|
||||||
|
* Issues feedback notifications to the user;
|
||||||
|
* In the rare platforms where this is required, synthesizes an input
|
||||||
|
event to command all *OTHER* rfkill devices to also change their
|
||||||
|
statues when a specific rfkill device changes state.
|
||||||
|
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
3: Kernel driver guidelines
|
||||||
|
|
||||||
|
Remember: point-of-view is everything for a driver that connects to the rfkill
|
||||||
|
subsystem. All the details below must be measured/perceived from the point of
|
||||||
|
view of the specific driver being modified.
|
||||||
|
|
||||||
|
The first thing one needs to know is whether his driver should be talking to
|
||||||
|
the rfkill class or to the input layer. In rare cases (platform drivers), it
|
||||||
|
could happen that you need to do both, as platform drivers often handle a
|
||||||
|
variety of devices in the same driver.
|
||||||
|
|
||||||
|
Do not mistake input devices for rfkill controllers. The only type of "rfkill
|
||||||
|
switch" device that is to be registered with the rfkill class are those
|
||||||
|
directly controlling the circuits that cause a wireless transmitter to stop
|
||||||
|
working (or the software equivalent of them), i.e. what we call a rfkill
|
||||||
|
controller. Every other kind of "rfkill switch" is just an input device and
|
||||||
|
MUST NOT be registered with the rfkill class.
|
||||||
|
|
||||||
|
A driver should register a device with the rfkill class when ALL of the
|
||||||
|
following conditions are met (they define a rfkill controller):
|
||||||
|
|
||||||
|
1. The device is/controls a data communications wireless transmitter;
|
||||||
|
|
||||||
|
2. The kernel can interact with the hardware/firmware to CHANGE the wireless
|
||||||
|
transmitter state (block/unblock TX operation);
|
||||||
|
|
||||||
|
3. The transmitter can be made to not emit any energy when "blocked":
|
||||||
|
rfkill is not about blocking data transmissions, it is about blocking
|
||||||
|
energy emission;
|
||||||
|
|
||||||
|
A driver should register a device with the input subsystem to issue
|
||||||
|
rfkill-related events (KEY_WLAN, KEY_BLUETOOTH, KEY_WWAN, KEY_WIMAX,
|
||||||
|
SW_RFKILL_ALL, etc) when ALL of the folowing conditions are met:
|
||||||
|
|
||||||
|
1. It is directly related to some physical device the user interacts with, to
|
||||||
|
command the O.S./firmware/hardware to enable/disable a data communications
|
||||||
|
wireless transmitter.
|
||||||
|
|
||||||
|
Examples of the physical device are: buttons, keys and switches the user
|
||||||
|
will press/touch/slide/switch to enable or disable the wireless
|
||||||
|
communication device.
|
||||||
|
|
||||||
|
2. It is NOT slaved to another device, i.e. there is no other device that
|
||||||
|
issues rfkill-related input events in preference to this one.
|
||||||
|
|
||||||
|
Please refer to the corner cases and examples section for more details.
|
||||||
|
|
||||||
|
When in doubt, do not issue input events. For drivers that should generate
|
||||||
|
input events in some platforms, but not in others (e.g. b43), the best solution
|
||||||
|
is to NEVER generate input events in the first place. That work should be
|
||||||
|
deferred to a platform-specific kernel module (which will know when to generate
|
||||||
|
events through the rfkill notifier chain) or to userspace. This avoids the
|
||||||
|
usual maintenance problems with DMI whitelisting.
|
||||||
|
|
||||||
|
|
||||||
|
Corner cases and examples:
|
||||||
====================================
|
====================================
|
||||||
2: Driver support
|
|
||||||
|
|
||||||
To build a driver with rfkill subsystem support, the driver should
|
1. If the device is an input device that, because of hardware or firmware,
|
||||||
depend on the Kconfig symbol RFKILL; it should _not_ depend on
|
causes wireless transmitters to be blocked regardless of the kernel's will, it
|
||||||
RKFILL_INPUT.
|
is still just an input device, and NOT to be registered with the rfkill class.
|
||||||
|
|
||||||
Unless key events trigger an interrupt to which the driver listens, polling
|
2. If the wireless transmitter switch control is read-only, it is an input
|
||||||
will be required to determine the key state changes. For this the input
|
device and not to be registered with the rfkill class (and maybe not to be made
|
||||||
layer providers the input-polldev handler.
|
an input layer event source either, see below).
|
||||||
|
|
||||||
A driver should implement a few steps to correctly make use of the
|
3. If there is some other device driver *closer* to the actual hardware the
|
||||||
rfkill subsystem. First for non-polling drivers:
|
user interacted with (the button/switch/key) to issue an input event, THAT is
|
||||||
|
the device driver that should be issuing input events.
|
||||||
|
|
||||||
- rfkill_allocate()
|
E.g:
|
||||||
- input_allocate_device()
|
[RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
|
||||||
- rfkill_register()
|
(platform driver) (wireless card driver)
|
||||||
- input_register_device()
|
|
||||||
|
|
||||||
For polling drivers:
|
The user is closer to the RFKILL slide switch plaform driver, so the driver
|
||||||
|
which must issue input events is the platform driver looking at the GPIO
|
||||||
|
hardware, and NEVER the wireless card driver (which is just a slave). It is
|
||||||
|
very likely that there are other leaves than just the WLAN card rf-kill input
|
||||||
|
(e.g. a bluetooth card, etc)...
|
||||||
|
|
||||||
- rfkill_allocate()
|
On the other hand, some embedded devices do this:
|
||||||
- input_allocate_polled_device()
|
|
||||||
- rfkill_register()
|
|
||||||
- input_register_polled_device()
|
|
||||||
|
|
||||||
When a key event has been detected, the correct event should be
|
[RFKILL slider switch] -- [WLAN card rf-kill input]
|
||||||
sent over the input device which has been registered by the driver.
|
(wireless card driver)
|
||||||
|
|
||||||
|
In this situation, the wireless card driver *could* register itself as an input
|
||||||
|
device and issue rf-kill related input events... but in order to AVOID the need
|
||||||
|
for DMI whitelisting, the wireless card driver does NOT do it. Userspace (HAL)
|
||||||
|
or a platform driver (that exists only on these embedded devices) will do the
|
||||||
|
dirty job of issuing the input events.
|
||||||
|
|
||||||
|
|
||||||
|
COMMON MISTAKES in kernel drivers, related to rfkill:
|
||||||
====================================
|
====================================
|
||||||
3: Userspace support
|
|
||||||
|
|
||||||
For each key an input device will be created which will send out the correct
|
1. NEVER confuse input device keys and buttons with input device switches.
|
||||||
key event when the rfkill key has been pressed.
|
|
||||||
|
1a. Switches are always set or reset. They report the current state
|
||||||
|
(on position or off position).
|
||||||
|
|
||||||
|
1b. Keys and buttons are either in the pressed or not-pressed state, and
|
||||||
|
that's it. A "button" that latches down when you press it, and
|
||||||
|
unlatches when you press it again is in fact a switch as far as input
|
||||||
|
devices go.
|
||||||
|
|
||||||
|
Add the SW_* events you need for switches, do NOT try to emulate a button using
|
||||||
|
KEY_* events just because there is no such SW_* event yet. Do NOT try to use,
|
||||||
|
for example, KEY_BLUETOOTH when you should be using SW_BLUETOOTH instead.
|
||||||
|
|
||||||
|
2. Input device switches (sources of EV_SW events) DO store their current state
|
||||||
|
(so you *must* initialize it by issuing a gratuitous input layer event on
|
||||||
|
driver start-up and also when resuming from sleep), and that state CAN be
|
||||||
|
queried from userspace through IOCTLs. There is no sysfs interface for this,
|
||||||
|
but that doesn't mean you should break things trying to hook it to the rfkill
|
||||||
|
class to get a sysfs interface :-)
|
||||||
|
|
||||||
|
3. Do not issue *_RFKILL_ALL events by default, unless you are sure it is the
|
||||||
|
correct event for your switch/button. These events are emergency power-off
|
||||||
|
events when they are trying to turn the transmitters off. An example of an
|
||||||
|
input device which SHOULD generate *_RFKILL_ALL events is the wireless-kill
|
||||||
|
switch in a laptop which is NOT a hotkey, but a real switch that kills radios
|
||||||
|
in hardware, even if the O.S. has gone to lunch. An example of an input device
|
||||||
|
which SHOULD NOT generate *_RFKILL_ALL events by default, is any sort of hot
|
||||||
|
key that does nothing by itself, as well as any hot key that is type-specific
|
||||||
|
(e.g. the one for WLAN).
|
||||||
|
|
||||||
|
|
||||||
|
3.1 Guidelines for wireless device drivers
|
||||||
|
------------------------------------------
|
||||||
|
|
||||||
|
1. Each independent transmitter in a wireless device (usually there is only one
|
||||||
|
transmitter per device) should have a SINGLE rfkill class attached to it.
|
||||||
|
|
||||||
|
2. If the device does not have any sort of hardware assistance to allow the
|
||||||
|
driver to rfkill the device, the driver should emulate it by taking all actions
|
||||||
|
required to silence the transmitter.
|
||||||
|
|
||||||
|
3. If it is impossible to silence the transmitter (i.e. it still emits energy,
|
||||||
|
even if it is just in brief pulses, when there is no data to transmit and there
|
||||||
|
is no hardware support to turn it off) do NOT lie to the users. Do not attach
|
||||||
|
it to a rfkill class. The rfkill subsystem does not deal with data
|
||||||
|
transmission, it deals with energy emission. If the transmitter is emitting
|
||||||
|
energy, it is not blocked in rfkill terms.
|
||||||
|
|
||||||
|
4. It doesn't matter if the device has multiple rfkill input lines affecting
|
||||||
|
the same transmitter, their combined state is to be exported as a single state
|
||||||
|
per transmitter (see rule 1).
|
||||||
|
|
||||||
|
This rule exists because users of the rfkill subsystem expect to get (and set,
|
||||||
|
when possible) the overall transmitter rfkill state, not of a particular rfkill
|
||||||
|
line.
|
||||||
|
|
||||||
|
Example of a WLAN wireless driver connected to the rfkill subsystem:
|
||||||
|
--------------------------------------------------------------------
|
||||||
|
|
||||||
|
A certain WLAN card has one input pin that causes it to block the transmitter
|
||||||
|
and makes the status of that input pin available (only for reading!) to the
|
||||||
|
kernel driver. This is a hard rfkill input line (it cannot be overridden by
|
||||||
|
the kernel driver).
|
||||||
|
|
||||||
|
The card also has one PCI register that, if manipulated by the driver, causes
|
||||||
|
it to block the transmitter. This is a soft rfkill input line.
|
||||||
|
|
||||||
|
It has also a thermal protection circuitry that shuts down its transmitter if
|
||||||
|
the card overheats, and makes the status of that protection available (only for
|
||||||
|
reading!) to the kernel driver. This is also a hard rfkill input line.
|
||||||
|
|
||||||
|
If either one of these rfkill lines are active, the transmitter is blocked by
|
||||||
|
the hardware and forced offline.
|
||||||
|
|
||||||
|
The driver should allocate and attach to its struct device *ONE* instance of
|
||||||
|
the rfkill class (there is only one transmitter).
|
||||||
|
|
||||||
|
It can implement the get_state() hook, and return RFKILL_STATE_HARD_BLOCKED if
|
||||||
|
either one of its two hard rfkill input lines are active. If the two hard
|
||||||
|
rfkill lines are inactive, it must return RFKILL_STATE_SOFT_BLOCKED if its soft
|
||||||
|
rfkill input line is active. Only if none of the rfkill input lines are
|
||||||
|
active, will it return RFKILL_STATE_UNBLOCKED.
|
||||||
|
|
||||||
|
If it doesn't implement the get_state() hook, it must make sure that its calls
|
||||||
|
to rfkill_force_state() are enough to keep the status always up-to-date, and it
|
||||||
|
must do a rfkill_force_state() on resume from sleep.
|
||||||
|
|
||||||
|
Every time the driver gets a notification from the card that one of its rfkill
|
||||||
|
lines changed state (polling might be needed on badly designed cards that don't
|
||||||
|
generate interrupts for such events), it recomputes the rfkill state as per
|
||||||
|
above, and calls rfkill_force_state() to update it.
|
||||||
|
|
||||||
|
The driver should implement the toggle_radio() hook, that:
|
||||||
|
|
||||||
|
1. Returns an error if one of the hardware rfkill lines are active, and the
|
||||||
|
caller asked for RFKILL_STATE_UNBLOCKED.
|
||||||
|
|
||||||
|
2. Activates the soft rfkill line if the caller asked for state
|
||||||
|
RFKILL_STATE_SOFT_BLOCKED. It should do this even if one of the hard rfkill
|
||||||
|
lines are active, effectively double-blocking the transmitter.
|
||||||
|
|
||||||
|
3. Deactivates the soft rfkill line if none of the hardware rfkill lines are
|
||||||
|
active and the caller asked for RFKILL_STATE_UNBLOCKED.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
4: Kernel API
|
||||||
|
|
||||||
|
To build a driver with rfkill subsystem support, the driver should depend on
|
||||||
|
(or select) the Kconfig symbol RFKILL; it should _not_ depend on RKFILL_INPUT.
|
||||||
|
|
||||||
|
The hardware the driver talks to may be write-only (where the current state
|
||||||
|
of the hardware is unknown), or read-write (where the hardware can be queried
|
||||||
|
about its current state).
|
||||||
|
|
||||||
|
The rfkill class will call the get_state hook of a device every time it needs
|
||||||
|
to know the *real* current state of the hardware. This can happen often.
|
||||||
|
|
||||||
|
Some hardware provides events when its status changes. In these cases, it is
|
||||||
|
best for the driver to not provide a get_state hook, and instead register the
|
||||||
|
rfkill class *already* with the correct status, and keep it updated using
|
||||||
|
rfkill_force_state() when it gets an event from the hardware.
|
||||||
|
|
||||||
|
There is no provision for a statically-allocated rfkill struct. You must
|
||||||
|
use rfkill_allocate() to allocate one.
|
||||||
|
|
||||||
|
You should:
|
||||||
|
- rfkill_allocate()
|
||||||
|
- modify rfkill fields (flags, name)
|
||||||
|
- modify state to the current hardware state (THIS IS THE ONLY TIME
|
||||||
|
YOU CAN ACCESS state DIRECTLY)
|
||||||
|
- rfkill_register()
|
||||||
|
|
||||||
|
The only way to set a device to the RFKILL_STATE_HARD_BLOCKED state is through
|
||||||
|
a suitable return of get_state() or through rfkill_force_state().
|
||||||
|
|
||||||
|
When a device is in the RFKILL_STATE_HARD_BLOCKED state, the only way to switch
|
||||||
|
it to a different state is through a suitable return of get_state() or through
|
||||||
|
rfkill_force_state().
|
||||||
|
|
||||||
|
If toggle_radio() is called to set a device to state RFKILL_STATE_SOFT_BLOCKED
|
||||||
|
when that device is already at the RFKILL_STATE_HARD_BLOCKED state, it should
|
||||||
|
not return an error. Instead, it should try to double-block the transmitter,
|
||||||
|
so that its state will change from RFKILL_STATE_HARD_BLOCKED to
|
||||||
|
RFKILL_STATE_SOFT_BLOCKED should the hardware blocking cease.
|
||||||
|
|
||||||
|
Please refer to the source for more documentation.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
5: Userspace support
|
||||||
|
|
||||||
|
rfkill devices issue uevents (with an action of "change"), with the following
|
||||||
|
environment variables set:
|
||||||
|
|
||||||
|
RFKILL_NAME
|
||||||
|
RFKILL_STATE
|
||||||
|
RFKILL_TYPE
|
||||||
|
|
||||||
|
The ABI for these variables is defined by the sysfs attributes. It is best
|
||||||
|
to take a quick look at the source to make sure of the possible values.
|
||||||
|
|
||||||
|
It is expected that HAL will trap those, and bridge them to DBUS, etc. These
|
||||||
|
events CAN and SHOULD be used to give feedback to the user about the rfkill
|
||||||
|
status of the system.
|
||||||
|
|
||||||
|
Input devices may issue events that are related to rfkill. These are the
|
||||||
|
various KEY_* events and SW_* events supported by rfkill-input.c.
|
||||||
|
|
||||||
|
******IMPORTANT******
|
||||||
|
When rfkill-input is ACTIVE, userspace is NOT TO CHANGE THE STATE OF AN RFKILL
|
||||||
|
SWITCH IN RESPONSE TO AN INPUT EVENT also handled by rfkill-input, unless it
|
||||||
|
has set to true the user_claim attribute for that particular switch. This rule
|
||||||
|
is *absolute*; do NOT violate it.
|
||||||
|
******IMPORTANT******
|
||||||
|
|
||||||
|
Userspace must not assume it is the only source of control for rfkill switches.
|
||||||
|
Their state CAN and WILL change due to firmware actions, direct user actions,
|
||||||
|
and the rfkill-input EPO override for *_RFKILL_ALL.
|
||||||
|
|
||||||
|
When rfkill-input is not active, userspace must initiate a rfkill status
|
||||||
|
change by writing to the "state" attribute in order for anything to happen.
|
||||||
|
|
||||||
|
Take particular care to implement EV_SW SW_RFKILL_ALL properly. When that
|
||||||
|
switch is set to OFF, *every* rfkill device *MUST* be immediately put into the
|
||||||
|
RFKILL_STATE_SOFT_BLOCKED state, no questions asked.
|
||||||
|
|
||||||
The following sysfs entries will be created:
|
The following sysfs entries will be created:
|
||||||
|
|
||||||
name: Name assigned by driver to this key (interface or driver name).
|
name: Name assigned by driver to this key (interface or driver name).
|
||||||
type: Name of the key type ("wlan", "bluetooth", etc).
|
type: Name of the key type ("wlan", "bluetooth", etc).
|
||||||
state: Current state of the key. 1: On, 0: Off.
|
state: Current state of the transmitter
|
||||||
|
0: RFKILL_STATE_SOFT_BLOCKED
|
||||||
|
transmitter is forced off, but one can override it
|
||||||
|
by a write to the state attribute;
|
||||||
|
1: RFKILL_STATE_UNBLOCKED
|
||||||
|
transmiter is NOT forced off, and may operate if
|
||||||
|
all other conditions for such operation are met
|
||||||
|
(such as interface is up and configured, etc);
|
||||||
|
2: RFKILL_STATE_HARD_BLOCKED
|
||||||
|
transmitter is forced off by something outside of
|
||||||
|
the driver's control. One cannot set a device to
|
||||||
|
this state through writes to the state attribute;
|
||||||
claim: 1: Userspace handles events, 0: Kernel handles events
|
claim: 1: Userspace handles events, 0: Kernel handles events
|
||||||
|
|
||||||
Both the "state" and "claim" entries are also writable. For the "state" entry
|
Both the "state" and "claim" entries are also writable. For the "state" entry
|
||||||
this means that when 1 or 0 is written all radios, not yet in the requested
|
this means that when 1 or 0 is written, the device rfkill state (if not yet in
|
||||||
state, will be will be toggled accordingly.
|
the requested state), will be will be toggled accordingly.
|
||||||
|
|
||||||
For the "claim" entry writing 1 to it means that the kernel no longer handles
|
For the "claim" entry writing 1 to it means that the kernel no longer handles
|
||||||
key events even though RFKILL_INPUT input was enabled. When "claim" has been
|
key events even though RFKILL_INPUT input was enabled. When "claim" has been
|
||||||
set to 0, userspace should make sure that it listens for the input events or
|
set to 0, userspace should make sure that it listens for the input events or
|
||||||
check the sysfs "state" entry regularly to correctly perform the required
|
check the sysfs "state" entry regularly to correctly perform the required tasks
|
||||||
tasks when the rkfill key is pressed.
|
when the rkfill key is pressed.
|
||||||
|
|
||||||
|
A note about input devices and EV_SW events:
|
||||||
|
|
||||||
|
In order to know the current state of an input device switch (like
|
||||||
|
SW_RFKILL_ALL), you will need to use an IOCTL. That information is not
|
||||||
|
available through sysfs in a generic way at this time, and it is not available
|
||||||
|
through the rfkill class AT ALL.
|
||||||
|
|
|
@ -186,6 +186,17 @@ hardware.
|
||||||
Locking: port_sem taken.
|
Locking: port_sem taken.
|
||||||
Interrupts: caller dependent.
|
Interrupts: caller dependent.
|
||||||
|
|
||||||
|
flush_buffer(port)
|
||||||
|
Flush any write buffers, reset any DMA state and stop any
|
||||||
|
ongoing DMA transfers.
|
||||||
|
|
||||||
|
This will be called whenever the port->info->xmit circular
|
||||||
|
buffer is cleared.
|
||||||
|
|
||||||
|
Locking: port->lock taken.
|
||||||
|
Interrupts: locally disabled.
|
||||||
|
This call must not sleep
|
||||||
|
|
||||||
set_termios(port,termios,oldtermios)
|
set_termios(port,termios,oldtermios)
|
||||||
Change the port parameters, including word length, parity, stop
|
Change the port parameters, including word length, parity, stop
|
||||||
bits. Update read_status_mask and ignore_status_mask to indicate
|
bits. Update read_status_mask and ignore_status_mask to indicate
|
||||||
|
|
|
@ -8,3 +8,4 @@
|
||||||
7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
|
7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
|
||||||
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
|
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
|
||||||
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
|
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
|
||||||
|
10 -> DViCO FusionHDTV7 Dual Express [18ac:d618]
|
||||||
|
|
|
@ -8,10 +8,13 @@
|
||||||
7 -> Leadtek Winfast USB II (em2800)
|
7 -> Leadtek Winfast USB II (em2800)
|
||||||
8 -> Kworld USB2800 (em2800)
|
8 -> Kworld USB2800 (em2800)
|
||||||
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
9 -> Pinnacle Dazzle DVC 90/DVC 100 (em2820/em2840) [2304:0207,2304:021a]
|
||||||
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500,2040:6502]
|
10 -> Hauppauge WinTV HVR 900 (em2880) [2040:6500]
|
||||||
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
11 -> Terratec Hybrid XS (em2880) [0ccd:0042]
|
||||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||||
15 -> V-Gear PocketTV (em2800)
|
15 -> V-Gear PocketTV (em2800)
|
||||||
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
|
16 -> Hauppauge WinTV HVR 950 (em2880) [2040:6513,2040:6517,2040:651b,2040:651f]
|
||||||
|
17 -> Pinnacle PCTV HD Pro Stick (em2880) [2304:0227]
|
||||||
|
18 -> Hauppauge WinTV HVR 900 (R2) (em2880) [2040:6502]
|
||||||
|
19 -> PointNix Intra-Oral Camera (em2860)
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
36 -> UPMOST PURPLE TV [12ab:0800]
|
36 -> UPMOST PURPLE TV [12ab:0800]
|
||||||
37 -> Items MuchTV Plus / IT-005
|
37 -> Items MuchTV Plus / IT-005
|
||||||
38 -> Terratec Cinergy 200 TV [153b:1152]
|
38 -> Terratec Cinergy 200 TV [153b:1152]
|
||||||
39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212]
|
39 -> LifeView FlyTV Platinum Mini [5168:0212,4e42:0212,5169:1502]
|
||||||
40 -> Compro VideoMate TV PVR/FM [185b:c100]
|
40 -> Compro VideoMate TV PVR/FM [185b:c100]
|
||||||
41 -> Compro VideoMate TV Gold+ [185b:c100]
|
41 -> Compro VideoMate TV Gold+ [185b:c100]
|
||||||
42 -> Sabrent SBT-TVFM (saa7130)
|
42 -> Sabrent SBT-TVFM (saa7130)
|
||||||
|
@ -128,7 +128,7 @@
|
||||||
127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
|
127 -> Beholder BeholdTV 507 FM/RDS / BeholdTV 509 FM [0000:5071,0000:507B,5ace:5070,5ace:5090]
|
||||||
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
|
128 -> Beholder BeholdTV Columbus TVFM [0000:5201]
|
||||||
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
|
129 -> Beholder BeholdTV 607 / BeholdTV 609 [5ace:6070,5ace:6071,5ace:6072,5ace:6073,5ace:6090,5ace:6091,5ace:6092,5ace:6093]
|
||||||
130 -> Beholder BeholdTV M6 / BeholdTV M6 Extra [5ace:6190,5ace:6193,5ace:6191]
|
130 -> Beholder BeholdTV M6 [5ace:6190]
|
||||||
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
|
131 -> Twinhan Hybrid DTV-DVB 3056 PCI [1822:0022]
|
||||||
132 -> Genius TVGO AM11MCE
|
132 -> Genius TVGO AM11MCE
|
||||||
133 -> NXP Snake DVB-S reference design
|
133 -> NXP Snake DVB-S reference design
|
||||||
|
@ -141,3 +141,7 @@
|
||||||
140 -> Avermedia DVB-S Pro A700 [1461:a7a1]
|
140 -> Avermedia DVB-S Pro A700 [1461:a7a1]
|
||||||
141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2]
|
141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2]
|
||||||
142 -> Beholder BeholdTV H6 [5ace:6290]
|
142 -> Beholder BeholdTV H6 [5ace:6290]
|
||||||
|
143 -> Beholder BeholdTV M63 [5ace:6191]
|
||||||
|
144 -> Beholder BeholdTV M6 Extra [5ace:6193]
|
||||||
|
145 -> AVerMedia MiniPCI DVB-T Hybrid M103 [1461:f636]
|
||||||
|
146 -> ASUSTeK P7131 Analog
|
||||||
|
|
|
@ -1,36 +1,30 @@
|
||||||
Some notes regarding the cx18 driver for the Conexant CX23418 MPEG
|
Some notes regarding the cx18 driver for the Conexant CX23418 MPEG
|
||||||
encoder chip:
|
encoder chip:
|
||||||
|
|
||||||
1) The only hardware currently supported is the Hauppauge HVR-1600
|
1) Currently supported are:
|
||||||
card and the Compro VideoMate H900 (note that this card only
|
|
||||||
supports analog input, it has no digital tuner!).
|
|
||||||
|
|
||||||
2) Some people have problems getting the i2c bus to work. Cause unknown.
|
- Hauppauge HVR-1600
|
||||||
|
- Compro VideoMate H900
|
||||||
|
- Yuan MPC718
|
||||||
|
- Conexant Raptor PAL/SECAM devkit
|
||||||
|
|
||||||
|
2) Some people have problems getting the i2c bus to work.
|
||||||
The symptom is that the eeprom cannot be read and the card is
|
The symptom is that the eeprom cannot be read and the card is
|
||||||
unusable.
|
unusable. This is probably fixed, but if you have problems
|
||||||
|
then post to the video4linux or ivtv-users mailinglist.
|
||||||
|
|
||||||
3) The audio from the analog tuner is mono only. Probably caused by
|
3) VBI (raw or sliced) has not yet been implemented.
|
||||||
incorrect audio register information in the datasheet. We are
|
|
||||||
waiting for updated information from Conexant.
|
|
||||||
|
|
||||||
4) VBI (raw or sliced) has not yet been implemented.
|
4) MPEG indexing is not yet implemented.
|
||||||
|
|
||||||
5) MPEG indexing is not yet implemented.
|
5) The driver is still a bit rough around the edges, this should
|
||||||
|
|
||||||
6) The driver is still a bit rough around the edges, this should
|
|
||||||
improve over time.
|
improve over time.
|
||||||
|
|
||||||
|
|
||||||
Firmware:
|
Firmware:
|
||||||
|
|
||||||
The firmware needs to be extracted from the Windows Hauppauge HVR-1600
|
You can obtain the firmware files here:
|
||||||
driver, available here:
|
|
||||||
|
|
||||||
http://hauppauge.lightpath.net/software/install_cd/hauppauge_cd_3.4d1.zip
|
http://dl.ivtvdriver.org/ivtv/firmware/cx18-firmware.tar.gz
|
||||||
|
|
||||||
Unzip, then copy the following files to the firmware directory
|
Untar and copy the .fw files to your firmware directory.
|
||||||
and rename them as follows:
|
|
||||||
|
|
||||||
Drivers/Driver18/hcw18apu.rom -> v4l-cx23418-apu.fw
|
|
||||||
Drivers/Driver18/hcw18enc.rom -> v4l-cx23418-cpu.fw
|
|
||||||
Drivers/Driver18/hcw18mlC.rom -> v4l-cx23418-dig.fw
|
|
||||||
|
|
|
@ -0,0 +1,243 @@
|
||||||
|
List of the webcams know by gspca.
|
||||||
|
|
||||||
|
The modules are:
|
||||||
|
gspca_main main driver
|
||||||
|
gspca_xxxx subdriver module with xxxx as follows
|
||||||
|
|
||||||
|
xxxx vend:prod
|
||||||
|
----
|
||||||
|
spca501 0000:0000 MystFromOri Unknow Camera
|
||||||
|
spca501 040a:0002 Kodak DVC-325
|
||||||
|
spca500 040a:0300 Kodak EZ200
|
||||||
|
zc3xx 041e:041e Creative WebCam Live!
|
||||||
|
spca500 041e:400a Creative PC-CAM 300
|
||||||
|
sunplus 041e:400b Creative PC-CAM 600
|
||||||
|
sunplus 041e:4012 PC-Cam350
|
||||||
|
sunplus 041e:4013 Creative Pccam750
|
||||||
|
zc3xx 041e:4017 Creative Webcam Mobile PD1090
|
||||||
|
spca508 041e:4018 Creative Webcam Vista (PD1100)
|
||||||
|
spca561 041e:401a Creative Webcam Vista (PD1100)
|
||||||
|
zc3xx 041e:401c Creative NX
|
||||||
|
spca505 041e:401d Creative Webcam NX ULTRA
|
||||||
|
zc3xx 041e:401e Creative Nx Pro
|
||||||
|
zc3xx 041e:401f Creative Webcam Notebook PD1171
|
||||||
|
pac207 041e:4028 Creative Webcam Vista Plus
|
||||||
|
zc3xx 041e:4029 Creative WebCam Vista Pro
|
||||||
|
zc3xx 041e:4034 Creative Instant P0620
|
||||||
|
zc3xx 041e:4035 Creative Instant P0620D
|
||||||
|
zc3xx 041e:4036 Creative Live !
|
||||||
|
zc3xx 041e:403a Creative Nx Pro 2
|
||||||
|
spca561 041e:403b Creative Webcam Vista (VF0010)
|
||||||
|
zc3xx 041e:4051 Creative Live!Cam Notebook Pro (VF0250)
|
||||||
|
ov519 041e:4052 Creative Live! VISTA IM
|
||||||
|
zc3xx 041e:4053 Creative Live!Cam Video IM
|
||||||
|
ov519 041e:405f Creative Live! VISTA VF0330
|
||||||
|
ov519 041e:4060 Creative Live! VISTA VF0350
|
||||||
|
ov519 041e:4061 Creative Live! VISTA VF0400
|
||||||
|
ov519 041e:4064 Creative Live! VISTA VF0420
|
||||||
|
ov519 041e:4068 Creative Live! VISTA VF0470
|
||||||
|
spca561 0458:7004 Genius VideoCAM Express V2
|
||||||
|
sunplus 0458:7006 Genius Dsc 1.3 Smart
|
||||||
|
zc3xx 0458:7007 Genius VideoCam V2
|
||||||
|
zc3xx 0458:700c Genius VideoCam V3
|
||||||
|
zc3xx 0458:700f Genius VideoCam Web V2
|
||||||
|
sonixj 0458:7025 Genius Eye 311Q
|
||||||
|
sonixj 045e:00f5 MicroSoft VX3000
|
||||||
|
sonixj 045e:00f7 MicroSoft VX1000
|
||||||
|
ov519 045e:028c Micro$oft xbox cam
|
||||||
|
spca508 0461:0815 Micro Innovation IC200
|
||||||
|
sunplus 0461:0821 Fujifilm MV-1
|
||||||
|
zc3xx 0461:0a00 MicroInnovation WebCam320
|
||||||
|
spca500 046d:0890 Logitech QuickCam traveler
|
||||||
|
vc032x 046d:0892 Logitech Orbicam
|
||||||
|
vc032x 046d:0896 Logitech Orbicam
|
||||||
|
zc3xx 046d:08a0 Logitech QC IM
|
||||||
|
zc3xx 046d:08a1 Logitech QC IM 0x08A1 +sound
|
||||||
|
zc3xx 046d:08a2 Labtec Webcam Pro
|
||||||
|
zc3xx 046d:08a3 Logitech QC Chat
|
||||||
|
zc3xx 046d:08a6 Logitech QCim
|
||||||
|
zc3xx 046d:08a7 Logitech QuickCam Image
|
||||||
|
zc3xx 046d:08a9 Logitech Notebook Deluxe
|
||||||
|
zc3xx 046d:08aa Labtec Webcam Notebook
|
||||||
|
zc3xx 046d:08ac Logitech QuickCam Cool
|
||||||
|
zc3xx 046d:08ad Logitech QCCommunicate STX
|
||||||
|
zc3xx 046d:08ae Logitech QuickCam for Notebooks
|
||||||
|
zc3xx 046d:08af Logitech QuickCam Cool
|
||||||
|
zc3xx 046d:08b9 Logitech QC IM ???
|
||||||
|
zc3xx 046d:08d7 Logitech QCam STX
|
||||||
|
zc3xx 046d:08d9 Logitech QuickCam IM/Connect
|
||||||
|
zc3xx 046d:08d8 Logitech Notebook Deluxe
|
||||||
|
zc3xx 046d:08da Logitech QuickCam Messenger
|
||||||
|
zc3xx 046d:08dd Logitech QuickCam for Notebooks
|
||||||
|
spca500 046d:0900 Logitech Inc. ClickSmart 310
|
||||||
|
spca500 046d:0901 Logitech Inc. ClickSmart 510
|
||||||
|
sunplus 046d:0905 Logitech ClickSmart 820
|
||||||
|
tv8532 046d:0920 QC Express
|
||||||
|
tv8532 046d:0921 Labtec Webcam
|
||||||
|
spca561 046d:0928 Logitech QC Express Etch2
|
||||||
|
spca561 046d:0929 Labtec Webcam Elch2
|
||||||
|
spca561 046d:092a Logitech QC for Notebook
|
||||||
|
spca561 046d:092b Labtec Webcam Plus
|
||||||
|
spca561 046d:092c Logitech QC chat Elch2
|
||||||
|
spca561 046d:092d Logitech QC Elch2
|
||||||
|
spca561 046d:092e Logitech QC Elch2
|
||||||
|
spca561 046d:092f Logitech QC Elch2
|
||||||
|
sunplus 046d:0960 Logitech ClickSmart 420
|
||||||
|
sunplus 0471:0322 Philips DMVC1300K
|
||||||
|
zc3xx 0471:0325 Philips SPC 200 NC
|
||||||
|
zc3xx 0471:0326 Philips SPC 300 NC
|
||||||
|
sonixj 0471:0327 Philips SPC 600 NC
|
||||||
|
sonixj 0471:0328 Philips SPC 700 NC
|
||||||
|
zc3xx 0471:032d Philips spc210nc
|
||||||
|
zc3xx 0471:032e Philips spc315nc
|
||||||
|
sonixj 0471:0330 Philips SPC 710NC
|
||||||
|
spca501 0497:c001 Smile International
|
||||||
|
sunplus 04a5:3003 Benq DC 1300
|
||||||
|
sunplus 04a5:3008 Benq DC 1500
|
||||||
|
sunplus 04a5:300a Benq DC3410
|
||||||
|
spca500 04a5:300c Benq DC1016
|
||||||
|
sunplus 04f1:1001 JVC GC A50
|
||||||
|
spca561 04fc:0561 Flexcam 100
|
||||||
|
sunplus 04fc:500c Sunplus CA500C
|
||||||
|
sunplus 04fc:504a Aiptek Mini PenCam 1.3
|
||||||
|
sunplus 04fc:504b Maxell MaxPocket LE 1.3
|
||||||
|
sunplus 04fc:5330 Digitrex 2110
|
||||||
|
sunplus 04fc:5360 Sunplus Generic
|
||||||
|
spca500 04fc:7333 PalmPixDC85
|
||||||
|
sunplus 04fc:ffff Pure DigitalDakota
|
||||||
|
spca501 0506:00df 3Com HomeConnect Lite
|
||||||
|
sunplus 052b:1513 Megapix V4
|
||||||
|
tv8532 0545:808b Veo Stingray
|
||||||
|
tv8532 0545:8333 Veo Stingray
|
||||||
|
sunplus 0546:3155 Polaroid PDC3070
|
||||||
|
sunplus 0546:3191 Polaroid Ion 80
|
||||||
|
sunplus 0546:3273 Polaroid PDC2030
|
||||||
|
ov519 054c:0154 Sonny toy4
|
||||||
|
ov519 054c:0155 Sonny toy5
|
||||||
|
zc3xx 055f:c005 Mustek Wcam300A
|
||||||
|
spca500 055f:c200 Mustek Gsmart 300
|
||||||
|
sunplus 055f:c211 Kowa Bs888e Microcamera
|
||||||
|
spca500 055f:c220 Gsmart Mini
|
||||||
|
sunplus 055f:c230 Mustek Digicam 330K
|
||||||
|
sunplus 055f:c232 Mustek MDC3500
|
||||||
|
sunplus 055f:c360 Mustek DV4000 Mpeg4
|
||||||
|
sunplus 055f:c420 Mustek gSmart Mini 2
|
||||||
|
sunplus 055f:c430 Mustek Gsmart LCD 2
|
||||||
|
sunplus 055f:c440 Mustek DV 3000
|
||||||
|
sunplus 055f:c520 Mustek gSmart Mini 3
|
||||||
|
sunplus 055f:c530 Mustek Gsmart LCD 3
|
||||||
|
sunplus 055f:c540 Gsmart D30
|
||||||
|
sunplus 055f:c630 Mustek MDC4000
|
||||||
|
sunplus 055f:c650 Mustek MDC5500Z
|
||||||
|
zc3xx 055f:d003 Mustek WCam300A
|
||||||
|
zc3xx 055f:d004 Mustek WCam300 AN
|
||||||
|
conex 0572:0041 Creative Notebook cx11646
|
||||||
|
ov519 05a9:0519 OmniVision
|
||||||
|
ov519 05a9:0530 OmniVision
|
||||||
|
ov519 05a9:4519 OmniVision
|
||||||
|
ov519 05a9:8519 OmniVision
|
||||||
|
sunplus 05da:1018 Digital Dream Enigma 1.3
|
||||||
|
stk014 05e1:0893 Syntek DV4000
|
||||||
|
spca561 060b:a001 Maxell Compact Pc PM3
|
||||||
|
zc3xx 0698:2003 CTX M730V built in
|
||||||
|
spca500 06bd:0404 Agfa CL20
|
||||||
|
spca500 06be:0800 Optimedia
|
||||||
|
sunplus 06d6:0031 Trust 610 LCD PowerC@m Zoom
|
||||||
|
spca506 06e1:a190 ADS Instant VCD
|
||||||
|
spca508 0733:0110 ViewQuest VQ110
|
||||||
|
spca508 0130:0130 Clone Digital Webcam 11043
|
||||||
|
spca501 0733:0401 Intel Create and Share
|
||||||
|
spca501 0733:0402 ViewQuest M318B
|
||||||
|
spca505 0733:0430 Intel PC Camera Pro
|
||||||
|
sunplus 0733:1311 Digital Dream Epsilon 1.3
|
||||||
|
sunplus 0733:1314 Mercury 2.1MEG Deluxe Classic Cam
|
||||||
|
sunplus 0733:2211 Jenoptik jdc 21 LCD
|
||||||
|
sunplus 0733:2221 Mercury Digital Pro 3.1p
|
||||||
|
sunplus 0733:3261 Concord 3045 spca536a
|
||||||
|
sunplus 0733:3281 Cyberpix S550V
|
||||||
|
spca506 0734:043b 3DeMon USB Capture aka
|
||||||
|
spca500 084d:0003 D-Link DSC-350
|
||||||
|
spca500 08ca:0103 Aiptek PocketDV
|
||||||
|
sunplus 08ca:0104 Aiptek PocketDVII 1.3
|
||||||
|
sunplus 08ca:0106 Aiptek Pocket DV3100+
|
||||||
|
sunplus 08ca:2008 Aiptek Mini PenCam 2 M
|
||||||
|
sunplus 08ca:2010 Aiptek PocketCam 3M
|
||||||
|
sunplus 08ca:2016 Aiptek PocketCam 2 Mega
|
||||||
|
sunplus 08ca:2018 Aiptek Pencam SD 2M
|
||||||
|
sunplus 08ca:2020 Aiptek Slim 3000F
|
||||||
|
sunplus 08ca:2022 Aiptek Slim 3200
|
||||||
|
sunplus 08ca:2024 Aiptek DV3500 Mpeg4
|
||||||
|
sunplus 08ca:2028 Aiptek PocketCam4M
|
||||||
|
sunplus 08ca:2040 Aiptek PocketDV4100M
|
||||||
|
sunplus 08ca:2042 Aiptek PocketDV5100
|
||||||
|
sunplus 08ca:2050 Medion MD 41437
|
||||||
|
sunplus 08ca:2060 Aiptek PocketDV5300
|
||||||
|
tv8532 0923:010f ICM532 cams
|
||||||
|
mars 093a:050f Mars-Semi Pc-Camera
|
||||||
|
pac207 093a:2460 PAC207 Qtec Webcam 100
|
||||||
|
pac207 093a:2463 Philips spc200nc pac207
|
||||||
|
pac207 093a:2464 Labtec Webcam 1200
|
||||||
|
pac207 093a:2468 PAC207
|
||||||
|
pac207 093a:2470 Genius GF112
|
||||||
|
pac207 093a:2471 PAC207 Genius VideoCam ge111
|
||||||
|
pac207 093a:2472 PAC207 Genius VideoCam ge110
|
||||||
|
pac7311 093a:2600 PAC7311 Typhoon
|
||||||
|
pac7311 093a:2601 PAC7311 Phillips SPC610NC
|
||||||
|
pac7311 093a:2603 PAC7312
|
||||||
|
pac7311 093a:2608 PAC7311 Trust WB-3300p
|
||||||
|
pac7311 093a:260e PAC7311 Gigaware VGA PC Camera, Trust WB-3350p, SIGMA cam 2350
|
||||||
|
pac7311 093a:260f PAC7311 SnakeCam
|
||||||
|
pac7311 093a:2621 PAC731x
|
||||||
|
zc3xx 0ac8:0302 Z-star Vimicro zc0302
|
||||||
|
vc032x 0ac8:0321 Vimicro generic vc0321
|
||||||
|
vc032x 0ac8:0323 Vimicro Vc0323
|
||||||
|
vc032x 0ac8:0328 A4Tech PK-130MG
|
||||||
|
zc3xx 0ac8:301b Z-Star zc301b
|
||||||
|
zc3xx 0ac8:303b Vimicro 0x303b
|
||||||
|
zc3xx 0ac8:305b Z-star Vimicro zc0305b
|
||||||
|
zc3xx 0ac8:307b Ldlc VC302+Ov7620
|
||||||
|
vc032x 0ac8:c001 Sony embedded vimicro
|
||||||
|
vc032x 0ac8:c002 Sony embedded vimicro
|
||||||
|
spca508 0af9:0010 Hama USB Sightcam 100
|
||||||
|
spca508 0af9:0011 Hama USB Sightcam 100
|
||||||
|
sonixb 0c45:6001 Genius VideoCAM NB
|
||||||
|
sonixb 0c45:6005 Microdia Sweex Mini Webcam
|
||||||
|
sonixb 0c45:6007 Sonix sn9c101 + Tas5110D
|
||||||
|
sonixb 0c45:6009 spcaCam@120
|
||||||
|
sonixb 0c45:600d spcaCam@120
|
||||||
|
sonixb 0c45:6011 Microdia PC Camera (SN9C102)
|
||||||
|
sonixb 0c45:6019 Generic Sonix OV7630
|
||||||
|
sonixb 0c45:6024 Generic Sonix Tas5130c
|
||||||
|
sonixb 0c45:6025 Xcam Shanga
|
||||||
|
sonixb 0c45:6028 Sonix Btc Pc380
|
||||||
|
sonixb 0c45:6029 spcaCam@150
|
||||||
|
sonixb 0c45:602c Generic Sonix OV7630
|
||||||
|
sonixb 0c45:602d LIC-200 LG
|
||||||
|
sonixb 0c45:602e Genius VideoCam Messenger
|
||||||
|
sonixj 0c45:6040 Speed NVC 350K
|
||||||
|
sonixj 0c45:607c Sonix sn9c102p Hv7131R
|
||||||
|
sonixj 0c45:60c0 Sangha Sn535
|
||||||
|
sonixj 0c45:60ec SN9C105+MO4000
|
||||||
|
sonixj 0c45:60fb Surfer NoName
|
||||||
|
sonixj 0c45:60fc LG-LIC300
|
||||||
|
sonixj 0c45:612a Avant Camera
|
||||||
|
sonixj 0c45:612c Typhoon Rasy Cam 1.3MPix
|
||||||
|
sonixj 0c45:6130 Sonix Pccam
|
||||||
|
sonixj 0c45:6138 Sn9c120 Mo4000
|
||||||
|
sonixj 0c45:613b Surfer SN-206
|
||||||
|
sonixj 0c45:613c Sonix Pccam168
|
||||||
|
sunplus 0d64:0303 Sunplus FashionCam DXG
|
||||||
|
etoms 102c:6151 Qcam Sangha CIF
|
||||||
|
etoms 102c:6251 Qcam xxxxxx VGA
|
||||||
|
zc3xx 10fd:0128 Typhoon Webshot II USB 300k 0x0128
|
||||||
|
spca561 10fd:7e50 FlyCam Usb 100
|
||||||
|
zc3xx 10fd:8050 Typhoon Webshot II USB 300k
|
||||||
|
spca501 1776:501c Arowana 300K CMOS Camera
|
||||||
|
t613 17a1:0128 T613/TAS5130A
|
||||||
|
vc032x 17ef:4802 Lenovo Vc0323+MI1310_SOC
|
||||||
|
pac207 2001:f115 D-Link DSB-C120
|
||||||
|
spca500 2899:012c Toptro Industrial
|
||||||
|
spca508 8086:0110 Intel Easy PC Camera
|
||||||
|
spca500 8086:0630 Intel Pocket PC Camera
|
||||||
|
spca506 99fa:8988 Grandtec V.cap
|
||||||
|
spca561 abcd:cdee Petcam
|
18
MAINTAINERS
18
MAINTAINERS
|
@ -2189,6 +2189,8 @@ P: Jesse Brandeburg
|
||||||
M: jesse.brandeburg@intel.com
|
M: jesse.brandeburg@intel.com
|
||||||
P: Bruce Allan
|
P: Bruce Allan
|
||||||
M: bruce.w.allan@intel.com
|
M: bruce.w.allan@intel.com
|
||||||
|
P: PJ Waskiewicz
|
||||||
|
M: peter.p.waskiewicz.jr@intel.com
|
||||||
P: John Ronciak
|
P: John Ronciak
|
||||||
M: john.ronciak@intel.com
|
M: john.ronciak@intel.com
|
||||||
L: e1000-devel@lists.sourceforge.net
|
L: e1000-devel@lists.sourceforge.net
|
||||||
|
@ -2725,12 +2727,10 @@ L: libertas-dev@lists.infradead.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
MARVELL MV643XX ETHERNET DRIVER
|
MARVELL MV643XX ETHERNET DRIVER
|
||||||
P: Dale Farnsworth
|
P: Lennert Buytenhek
|
||||||
M: dale@farnsworth.org
|
M: buytenh@marvell.com
|
||||||
P: Manish Lachwani
|
|
||||||
M: mlachwani@mvista.com
|
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Odd Fixes for 2.4; Maintained for 2.6.
|
S: Supported
|
||||||
|
|
||||||
MATROX FRAMEBUFFER DRIVER
|
MATROX FRAMEBUFFER DRIVER
|
||||||
P: Petr Vandrovec
|
P: Petr Vandrovec
|
||||||
|
@ -3274,14 +3274,6 @@ L: linux-kernel@vger.kernel.org
|
||||||
T: git git.infradead.org/battery-2.6.git
|
T: git git.infradead.org/battery-2.6.git
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
POWERPC 4xx EMAC DRIVER
|
|
||||||
P: Eugene Surovegin
|
|
||||||
M: ebs@ebshome.net
|
|
||||||
W: http://kernel.ebshome.net/emac/
|
|
||||||
L: linuxppc-dev@ozlabs.org
|
|
||||||
L: netdev@vger.kernel.org
|
|
||||||
S: Maintained
|
|
||||||
|
|
||||||
PNP SUPPORT
|
PNP SUPPORT
|
||||||
P: Adam Belay
|
P: Adam Belay
|
||||||
M: ambx1@neo.rr.com
|
M: ambx1@neo.rr.com
|
||||||
|
|
|
@ -323,10 +323,15 @@ static struct platform_device smc91x_device = {
|
||||||
static struct resource dm9000_resources[] = {
|
static struct resource dm9000_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = 0x203FB800,
|
.start = 0x203FB800,
|
||||||
.end = 0x203FB800 + 8,
|
.end = 0x203FB800 + 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
[1] = {
|
[1] = {
|
||||||
|
.start = 0x203FB800 + 4,
|
||||||
|
.end = 0x203FB800 + 5,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
.start = IRQ_PF9,
|
.start = IRQ_PF9,
|
||||||
.end = IRQ_PF9,
|
.end = IRQ_PF9,
|
||||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||||
|
|
|
@ -65,10 +65,15 @@ static struct platform_device rtc_device = {
|
||||||
static struct resource dm9000_resources[] = {
|
static struct resource dm9000_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = 0x20300000,
|
.start = 0x20300000,
|
||||||
.end = 0x20300000 + 8,
|
.end = 0x20300000 + 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
[1] = {
|
[1] = {
|
||||||
|
.start = 0x20300000 + 4,
|
||||||
|
.end = 0x20300000 + 5,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
.start = IRQ_PF10,
|
.start = IRQ_PF10,
|
||||||
.end = IRQ_PF10,
|
.end = IRQ_PF10,
|
||||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||||
|
|
|
@ -166,10 +166,15 @@ static struct platform_device smc91x_device = {
|
||||||
static struct resource dm9000_resources[] = {
|
static struct resource dm9000_resources[] = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.start = 0x203FB800,
|
.start = 0x203FB800,
|
||||||
.end = 0x203FB800 + 8,
|
.end = 0x203FB800 + 1,
|
||||||
.flags = IORESOURCE_MEM,
|
.flags = IORESOURCE_MEM,
|
||||||
},
|
},
|
||||||
[1] = {
|
[1] = {
|
||||||
|
.start = 0x203FB800 + 4,
|
||||||
|
.end = 0x203FB800 + 5,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[2] = {
|
||||||
.start = IRQ_PF9,
|
.start = IRQ_PF9,
|
||||||
.end = IRQ_PF9,
|
.end = IRQ_PF9,
|
||||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# arch/cris/arch-v10/boot/Makefile
|
# arch/cris/arch-v10/boot/Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||||
|
|
||||||
subdir- := compressed rescue
|
subdir- := compressed rescue
|
||||||
|
|
|
@ -2,12 +2,10 @@
|
||||||
# arch/cris/arch-v10/boot/compressed/Makefile
|
# arch/cris/arch-v10/boot/compressed/Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
CC = gcc-cris -melf $(LINUXINCLUDE)
|
asflags-y += $(LINUXINCLUDE)
|
||||||
ccflags-y += -O2
|
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||||
LD = ld-cris
|
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||||
ldflags-y += -T $(obj)/decompress.ld
|
|
||||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||||
|
|
||||||
quiet_cmd_image = BUILD $@
|
quiet_cmd_image = BUILD $@
|
||||||
|
@ -21,12 +19,6 @@ $(obj)/decompress.o: $(OBJECTS) FORCE
|
||||||
$(obj)/decompress.bin: $(obj)/decompress.o FORCE
|
$(obj)/decompress.bin: $(obj)/decompress.o FORCE
|
||||||
$(call if_changed,objcopy)
|
$(call if_changed,objcopy)
|
||||||
|
|
||||||
$(obj)/head.o: $(obj)/head.S .config
|
|
||||||
@$(CC) -D__ASSEMBLY__ -traditional -c $< -o $@
|
|
||||||
|
|
||||||
$(obj)/misc.o: $(obj)/misc.c .config
|
|
||||||
@$(CC) -D__KERNEL__ -c $< -o $@
|
|
||||||
|
|
||||||
$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
|
$(obj)/vmlinux: $(obj)/piggy.gz $(obj)/decompress.bin FORCE
|
||||||
$(call if_changed,image)
|
$(call if_changed,image)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
OUTPUT_FORMAT(elf32-us-cris)
|
/* OUTPUT_FORMAT(elf32-us-cris) */
|
||||||
|
OUTPUT_FORMAT(elf32-cris)
|
||||||
|
|
||||||
MEMORY
|
MEMORY
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,77 +15,77 @@
|
||||||
#define COMMAND_LINE_MAGIC 0x87109563
|
#define COMMAND_LINE_MAGIC 0x87109563
|
||||||
|
|
||||||
;; Exported symbols
|
;; Exported symbols
|
||||||
|
|
||||||
.globl _input_data
|
|
||||||
|
|
||||||
|
.globl input_data
|
||||||
|
|
||||||
|
|
||||||
.text
|
.text
|
||||||
|
|
||||||
nop
|
nop
|
||||||
di
|
di
|
||||||
|
|
||||||
;; We need to initialze DRAM registers before we start using the DRAM
|
;; We need to initialze DRAM registers before we start using the DRAM
|
||||||
|
|
||||||
cmp.d RAM_INIT_MAGIC, r8 ; Already initialized?
|
cmp.d RAM_INIT_MAGIC, $r8 ; Already initialized?
|
||||||
beq dram_init_finished
|
beq dram_init_finished
|
||||||
nop
|
nop
|
||||||
|
|
||||||
#include "../../lib/dram_init.S"
|
#include "../../lib/dram_init.S"
|
||||||
|
|
||||||
dram_init_finished:
|
dram_init_finished:
|
||||||
|
|
||||||
;; Initiate the PA and PB ports
|
;; Initiate the PA and PB ports
|
||||||
|
|
||||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
|
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
|
||||||
move.b r0, [R_PORT_PA_DATA]
|
move.b $r0, [R_PORT_PA_DATA]
|
||||||
|
|
||||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
|
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
|
||||||
move.b r0, [R_PORT_PA_DIR]
|
move.b $r0, [R_PORT_PA_DIR]
|
||||||
|
|
||||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
|
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
|
||||||
move.b r0, [R_PORT_PB_DATA]
|
move.b $r0, [R_PORT_PB_DATA]
|
||||||
|
|
||||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
|
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
|
||||||
move.b r0, [R_PORT_PB_DIR]
|
move.b $r0, [R_PORT_PB_DIR]
|
||||||
|
|
||||||
;; Setup the stack to a suitably high address.
|
;; Setup the stack to a suitably high address.
|
||||||
;; We assume 8 MB is the minimum DRAM in an eLinux
|
;; We assume 8 MB is the minimum DRAM in an eLinux
|
||||||
;; product and put the sp at the top for now.
|
;; product and put the sp at the top for now.
|
||||||
|
|
||||||
move.d 0x40800000, sp
|
move.d 0x40800000, $sp
|
||||||
|
|
||||||
;; Figure out where the compressed piggyback image is
|
;; Figure out where the compressed piggyback image is
|
||||||
;; in the flash (since we wont try to copy it to DRAM
|
;; in the flash (since we wont try to copy it to DRAM
|
||||||
;; before unpacking). It is at _edata, but in flash.
|
;; before unpacking). It is at _edata, but in flash.
|
||||||
;; Use (_edata - basse) as offset to the current PC.
|
;; Use (_edata - basse) as offset to the current PC.
|
||||||
|
|
||||||
basse: move.d pc, r5
|
basse: move.d $pc, $r5
|
||||||
and.d 0x7fffffff, r5 ; strip any non-cache bit
|
and.d 0x7fffffff, $r5 ; strip any non-cache bit
|
||||||
subq 2, r5 ; compensate for the move.d pc instr
|
subq 2, $r5 ; compensate for the move.d $pc instr
|
||||||
move.d r5, r0 ; save for later - flash address of 'basse'
|
move.d $r5, $r0 ; save for later - flash address of 'basse'
|
||||||
add.d _edata, r5
|
add.d _edata, $r5
|
||||||
sub.d basse, r5 ; r5 = flash address of '_edata'
|
sub.d basse, $r5 ; $r5 = flash address of '_edata'
|
||||||
|
|
||||||
;; Copy text+data to DRAM
|
;; Copy text+data to DRAM
|
||||||
|
|
||||||
move.d basse, r1 ; destination
|
move.d basse, $r1 ; destination
|
||||||
move.d _edata, r2 ; end destination
|
move.d _edata, $r2 ; end destination
|
||||||
1: move.w [r0+], r3
|
1: move.w [$r0+], $r3
|
||||||
move.w r3, [r1+]
|
move.w $r3, [$r1+]
|
||||||
cmp.d r2, r1
|
cmp.d $r2, $r1
|
||||||
bcs 1b
|
bcs 1b
|
||||||
nop
|
nop
|
||||||
|
|
||||||
move.d r5, [_input_data] ; for the decompressor
|
move.d $r5, [input_data] ; for the decompressor
|
||||||
|
|
||||||
|
|
||||||
;; Clear the decompressors BSS (between _edata and _end)
|
;; Clear the decompressors BSS (between _edata and _end)
|
||||||
|
|
||||||
moveq 0, r0
|
moveq 0, $r0
|
||||||
move.d _edata, r1
|
move.d _edata, $r1
|
||||||
move.d _end, r2
|
move.d _end, $r2
|
||||||
1: move.w r0, [r1+]
|
1: move.w $r0, [$r1+]
|
||||||
cmp.d r2, r1
|
cmp.d $r2, $r1
|
||||||
bcs 1b
|
bcs 1b
|
||||||
nop
|
nop
|
||||||
|
|
||||||
|
@ -94,16 +94,16 @@ basse: move.d pc, r5
|
||||||
move.d $r10, [$r12]
|
move.d $r10, [$r12]
|
||||||
move.d _cmd_line_addr, $r12
|
move.d _cmd_line_addr, $r12
|
||||||
move.d $r11, [$r12]
|
move.d $r11, [$r12]
|
||||||
|
|
||||||
;; Do the decompression and save compressed size in _inptr
|
|
||||||
|
|
||||||
jsr _decompress_kernel
|
;; Do the decompression and save compressed size in inptr
|
||||||
|
|
||||||
;; Put start address of root partition in r9 so the kernel can use it
|
jsr decompress_kernel
|
||||||
|
|
||||||
|
;; Put start address of root partition in $r9 so the kernel can use it
|
||||||
;; when mounting from flash
|
;; when mounting from flash
|
||||||
|
|
||||||
move.d [_input_data], r9 ; flash address of compressed kernel
|
move.d [input_data], $r9 ; flash address of compressed kernel
|
||||||
add.d [_inptr], r9 ; size of compressed kernel
|
add.d [inptr], $r9 ; size of compressed kernel
|
||||||
|
|
||||||
;; Restore command line magic and address.
|
;; Restore command line magic and address.
|
||||||
move.d _cmd_line_magic, $r10
|
move.d _cmd_line_magic, $r10
|
||||||
|
@ -112,12 +112,12 @@ basse: move.d pc, r5
|
||||||
move.d [$r11], $r11
|
move.d [$r11], $r11
|
||||||
|
|
||||||
;; Enter the decompressed kernel
|
;; Enter the decompressed kernel
|
||||||
move.d RAM_INIT_MAGIC, r8 ; Tell kernel that DRAM is initialized
|
move.d RAM_INIT_MAGIC, $r8 ; Tell kernel that DRAM is initialized
|
||||||
jump 0x40004000 ; kernel is linked to this address
|
jump 0x40004000 ; kernel is linked to this address
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
_input_data:
|
input_data:
|
||||||
.dword 0 ; used by the decompressor
|
.dword 0 ; used by the decompressor
|
||||||
_cmd_line_magic:
|
_cmd_line_magic:
|
||||||
.dword 0
|
.dword 0
|
||||||
|
|
|
@ -29,12 +29,10 @@
|
||||||
#define OF(args) args
|
#define OF(args) args
|
||||||
#define STATIC static
|
#define STATIC static
|
||||||
|
|
||||||
void* memset(void* s, int c, size_t n);
|
void *memset(void *s, int c, size_t n);
|
||||||
void* memcpy(void* __dest, __const void* __src,
|
void *memcpy(void *__dest, __const void *__src, size_t __n);
|
||||||
size_t __n);
|
|
||||||
|
|
||||||
#define memzero(s, n) memset ((s), 0, (n))
|
|
||||||
|
|
||||||
|
#define memzero(s, n) memset((s), 0, (n))
|
||||||
|
|
||||||
typedef unsigned char uch;
|
typedef unsigned char uch;
|
||||||
typedef unsigned short ush;
|
typedef unsigned short ush;
|
||||||
|
@ -62,57 +60,69 @@ static unsigned outcnt = 0; /* bytes in output buffer */
|
||||||
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
#define ENCRYPTED 0x20 /* bit 5 set: file is encrypted */
|
||||||
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
#define RESERVED 0xC0 /* bit 6,7: reserved */
|
||||||
|
|
||||||
#define get_byte() inbuf[inptr++]
|
#define get_byte() (inbuf[inptr++])
|
||||||
|
|
||||||
/* Diagnostic functions */
|
/* Diagnostic functions */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# define Assert(cond,msg) {if(!(cond)) error(msg);}
|
# define Assert(cond, msg) do { \
|
||||||
|
if (!(cond)) \
|
||||||
|
error(msg); \
|
||||||
|
} while (0)
|
||||||
# define Trace(x) fprintf x
|
# define Trace(x) fprintf x
|
||||||
# define Tracev(x) {if (verbose) fprintf x ;}
|
# define Tracev(x) do { \
|
||||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
if (verbose) \
|
||||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
fprintf x; \
|
||||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
} while (0)
|
||||||
|
# define Tracevv(x) do { \
|
||||||
|
if (verbose > 1) \
|
||||||
|
fprintf x; \
|
||||||
|
} while (0)
|
||||||
|
# define Tracec(c, x) do { \
|
||||||
|
if (verbose && (c)) \
|
||||||
|
fprintf x; \
|
||||||
|
} while (0)
|
||||||
|
# define Tracecv(c, x) do { \
|
||||||
|
if (verbose > 1 && (c)) \
|
||||||
|
fprintf x; \
|
||||||
|
} while (0)
|
||||||
#else
|
#else
|
||||||
# define Assert(cond,msg)
|
# define Assert(cond, msg)
|
||||||
# define Trace(x)
|
# define Trace(x)
|
||||||
# define Tracev(x)
|
# define Tracev(x)
|
||||||
# define Tracevv(x)
|
# define Tracevv(x)
|
||||||
# define Tracec(c,x)
|
# define Tracec(c, x)
|
||||||
# define Tracecv(c,x)
|
# define Tracecv(c, x)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int fill_inbuf(void);
|
|
||||||
static void flush_window(void);
|
static void flush_window(void);
|
||||||
static void error(char *m);
|
static void error(char *m);
|
||||||
static void gzip_mark(void **);
|
|
||||||
static void gzip_release(void **);
|
|
||||||
|
|
||||||
extern char *input_data; /* lives in head.S */
|
extern char *input_data; /* lives in head.S */
|
||||||
|
|
||||||
static long bytes_out = 0;
|
static long bytes_out = 0;
|
||||||
static uch *output_data;
|
static uch *output_data;
|
||||||
static unsigned long output_ptr = 0;
|
static unsigned long output_ptr = 0;
|
||||||
|
|
||||||
static void *malloc(int size);
|
static void *malloc(int size);
|
||||||
static void free(void *where);
|
static void free(void *where);
|
||||||
static void error(char *m);
|
|
||||||
static void gzip_mark(void **);
|
static void gzip_mark(void **);
|
||||||
static void gzip_release(void **);
|
static void gzip_release(void **);
|
||||||
|
|
||||||
static void puts(const char *);
|
static void puts(const char *);
|
||||||
|
|
||||||
/* the "heap" is put directly after the BSS ends, at end */
|
/* the "heap" is put directly after the BSS ends, at end */
|
||||||
|
|
||||||
extern int end;
|
extern int _end;
|
||||||
static long free_mem_ptr = (long)&end;
|
static long free_mem_ptr = (long)&_end;
|
||||||
|
|
||||||
#include "../../../../../lib/inflate.c"
|
#include "../../../../../lib/inflate.c"
|
||||||
|
|
||||||
static void *malloc(int size)
|
static void *malloc(int size)
|
||||||
{
|
{
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
if (size <0) error("Malloc error");
|
if (size < 0)
|
||||||
|
error("Malloc error");
|
||||||
|
|
||||||
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
||||||
|
|
||||||
|
@ -142,44 +152,47 @@ static void
|
||||||
puts(const char *s)
|
puts(const char *s)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
||||||
while(*s) {
|
while (*s) {
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||||
while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||||
*R_SERIAL0_TR_DATA = *s++;
|
*R_SERIAL0_TR_DATA = *s++;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
||||||
while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
||||||
*R_SERIAL1_TR_DATA = *s++;
|
*R_SERIAL1_TR_DATA = *s++;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
||||||
while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
||||||
*R_SERIAL2_TR_DATA = *s++;
|
*R_SERIAL2_TR_DATA = *s++;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
||||||
while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
||||||
*R_SERIAL3_TR_DATA = *s++;
|
*R_SERIAL3_TR_DATA = *s++;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void *memset(void *s, int c, size_t n)
|
||||||
memset(void* s, int c, size_t n)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *ss = (char*)s;
|
char *ss = (char *)s;
|
||||||
|
|
||||||
for (i=0;i<n;i++) ss[i] = c;
|
for (i = 0; i < n; i++)
|
||||||
|
ss[i] = c;
|
||||||
|
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void*
|
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||||
memcpy(void* __dest, __const void* __src,
|
|
||||||
size_t __n)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char *d = (char *)__dest, *s = (char *)__src;
|
char *d = (char *)__dest, *s = (char *)__src;
|
||||||
|
|
||||||
for (i=0;i<__n;i++) d[i] = s[i];
|
for (i = 0; i < __n; i++)
|
||||||
|
d[i] = s[i];
|
||||||
|
|
||||||
|
return __dest;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===========================================================================
|
/* ===========================================================================
|
||||||
|
@ -187,46 +200,44 @@ memcpy(void* __dest, __const void* __src,
|
||||||
* (Used for the decompressed data only.)
|
* (Used for the decompressed data only.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
static void flush_window(void)
|
||||||
flush_window()
|
|
||||||
{
|
{
|
||||||
ulg c = crc; /* temporary variable */
|
ulg c = crc; /* temporary variable */
|
||||||
unsigned n;
|
unsigned n;
|
||||||
uch *in, *out, ch;
|
uch *in, *out, ch;
|
||||||
|
|
||||||
in = window;
|
in = window;
|
||||||
out = &output_data[output_ptr];
|
out = &output_data[output_ptr];
|
||||||
for (n = 0; n < outcnt; n++) {
|
for (n = 0; n < outcnt; n++) {
|
||||||
ch = *out++ = *in++;
|
ch = *out = *in;
|
||||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
out++;
|
||||||
}
|
in++;
|
||||||
crc = c;
|
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||||
bytes_out += (ulg)outcnt;
|
}
|
||||||
output_ptr += (ulg)outcnt;
|
crc = c;
|
||||||
outcnt = 0;
|
bytes_out += (ulg)outcnt;
|
||||||
|
output_ptr += (ulg)outcnt;
|
||||||
|
outcnt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void error(char *x)
|
||||||
error(char *x)
|
|
||||||
{
|
{
|
||||||
puts("\n\n");
|
puts("\n\n");
|
||||||
puts(x);
|
puts(x);
|
||||||
puts("\n\n -- System halted\n");
|
puts("\n\n -- System halted\n");
|
||||||
|
|
||||||
while(1); /* Halt */
|
while (1); /* Halt */
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void setup_normal_output_buffer(void)
|
||||||
setup_normal_output_buffer()
|
|
||||||
{
|
{
|
||||||
output_data = (char *)KERNEL_LOAD_ADR;
|
output_data = (char *)KERNEL_LOAD_ADR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void decompress_kernel(void)
|
||||||
decompress_kernel()
|
|
||||||
{
|
{
|
||||||
char revision;
|
char revision;
|
||||||
|
|
||||||
/* input_data is set in head.S */
|
/* input_data is set in head.S */
|
||||||
inbuf = input_data;
|
inbuf = input_data;
|
||||||
|
|
||||||
|
@ -257,11 +268,10 @@ decompress_kernel()
|
||||||
|
|
||||||
makecrc();
|
makecrc();
|
||||||
|
|
||||||
__asm__ volatile ("move vr,%0" : "=rm" (revision));
|
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
|
||||||
if (revision < 10)
|
if (revision < 10) {
|
||||||
{
|
|
||||||
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
||||||
while(1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
puts("Uncompressing Linux...\n");
|
puts("Uncompressing Linux...\n");
|
||||||
|
|
|
@ -2,12 +2,9 @@
|
||||||
# Makefile for rescue (bootstrap) code
|
# Makefile for rescue (bootstrap) code
|
||||||
#
|
#
|
||||||
|
|
||||||
CC = gcc-cris -mlinux $(LINUXINCLUDE)
|
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||||
ccflags-y += -O2
|
asflags-y += $(LINUXINCLUDE)
|
||||||
asflags-y += -traditional
|
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||||
LD = gcc-cris -mlinux -nostdlib
|
|
||||||
ldflags-y += -T $(obj)/rescue.ld
|
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
||||||
OBJECT := $(obj)/head.o
|
OBJECT := $(obj)/head.o
|
||||||
|
|
|
@ -233,7 +233,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||||
|
|
||||||
if (copy_to_user((struct rtc_time *) arg, &tm,
|
if (copy_to_user((struct rtc_time *) arg, &tm,
|
||||||
sizeof tm)) {
|
sizeof tm)) {
|
||||||
spin_unlock(&rtc_lock);
|
mutex_unlock(&rtc_lock);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -426,12 +426,18 @@ static int dummy_write(struct tty_struct * tty,
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int dummy_write_room(struct tty_struct *tty)
|
||||||
dummy_write_room(struct tty_struct *tty)
|
|
||||||
{
|
{
|
||||||
return 8192;
|
return 8192;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct tty_operations dummy_ops = {
|
||||||
|
.open = dummy_open,
|
||||||
|
.close = dummy_close,
|
||||||
|
.write = dummy_write,
|
||||||
|
.write_room = dummy_write_room,
|
||||||
|
};
|
||||||
|
|
||||||
void __init
|
void __init
|
||||||
init_dummy_console(void)
|
init_dummy_console(void)
|
||||||
{
|
{
|
||||||
|
@ -444,14 +450,14 @@ init_dummy_console(void)
|
||||||
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
|
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
|
||||||
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
|
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
|
||||||
dummy_driver.init_termios = tty_std_termios;
|
dummy_driver.init_termios = tty_std_termios;
|
||||||
|
/* Normally B9600 default... */
|
||||||
dummy_driver.init_termios.c_cflag =
|
dummy_driver.init_termios.c_cflag =
|
||||||
B115200 | CS8 | CREAD | HUPCL | CLOCAL; /* is normally B9600 default... */
|
B115200 | CS8 | CREAD | HUPCL | CLOCAL;
|
||||||
dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
dummy_driver.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
|
||||||
|
dummy_driver.init_termios.c_ispeed = 115200;
|
||||||
|
dummy_driver.init_termios.c_ospeed = 115200;
|
||||||
|
|
||||||
dummy_driver.open = dummy_open;
|
dummy_driver.ops = &dummy_ops;
|
||||||
dummy_driver.close = dummy_close;
|
|
||||||
dummy_driver.write = dummy_write;
|
|
||||||
dummy_driver.write_room = dummy_write_room;
|
|
||||||
if (tty_register_driver(&dummy_driver))
|
if (tty_register_driver(&dummy_driver))
|
||||||
panic("Couldn't register dummy serial driver\n");
|
panic("Couldn't register dummy serial driver\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
# arch/cris/arch-v32/boot/Makefile
|
# arch/cris/arch-v32/boot/Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary -R .note -R .comment
|
OBJCOPYFLAGS = -O binary -R .note -R .comment
|
||||||
|
|
||||||
subdir- := compressed rescue
|
subdir- := compressed rescue
|
||||||
|
|
|
@ -2,14 +2,10 @@
|
||||||
# arch/cris/arch-v32/boot/compressed/Makefile
|
# arch/cris/arch-v32/boot/compressed/Makefile
|
||||||
#
|
#
|
||||||
|
|
||||||
CC = gcc-cris -mlinux -march=v32 $(LINUXINCLUDE)
|
|
||||||
asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
asflags-y += -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
||||||
ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
||||||
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||||
ldflags-y += -T $(obj)/decompress.ld
|
|
||||||
obj-y = head.o misc.o
|
|
||||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||||
|
|
||||||
quiet_cmd_image = BUILD $@
|
quiet_cmd_image = BUILD $@
|
||||||
|
|
|
@ -7,9 +7,8 @@ ccflags-y += -O2 -I $(srctree)/include/asm/arch/mach/ \
|
||||||
-I $(srctree)/include/asm/arch
|
-I $(srctree)/include/asm/arch
|
||||||
asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
|
asflags-y += -I $(srctree)/include/asm/arch/mach/ -I $(srctree)/include/asm/arch
|
||||||
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
||||||
ldflags-y += -T $(obj)/rescue.ld
|
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||||
LDPOSTFLAGS = -lgcc
|
LDPOSTFLAGS = -lgcc
|
||||||
OBJCOPY = objcopy-cris
|
|
||||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = head.o
|
||||||
OBJECT := $(obj)/head.o
|
OBJECT := $(obj)/head.o
|
||||||
|
|
|
@ -229,7 +229,7 @@ int pcf8563_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
|
||||||
|
|
||||||
if (copy_to_user((struct rtc_time *) arg, &tm,
|
if (copy_to_user((struct rtc_time *) arg, &tm,
|
||||||
sizeof tm)) {
|
sizeof tm)) {
|
||||||
spin_unlock(&rtc_lock);
|
mutex_unlock(&rtc_lock);
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -193,18 +193,6 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
|
||||||
* -------------------------------------------------------------------
|
* -------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*
|
|
||||||
* not really used in our situation so keep them commented out for now
|
|
||||||
*/
|
|
||||||
static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
|
|
||||||
static void do_serial_bh(void)
|
|
||||||
{
|
|
||||||
run_task_queue(&tq_serial);
|
|
||||||
printk(KERN_ERR "do_serial_bh: called\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void do_softint(struct work_struct *private_)
|
static void do_softint(struct work_struct *private_)
|
||||||
{
|
{
|
||||||
printk(KERN_ERR "simserial: do_softint called\n");
|
printk(KERN_ERR "simserial: do_softint called\n");
|
||||||
|
@ -351,11 +339,7 @@ static void rs_flush_buffer(struct tty_struct *tty)
|
||||||
info->xmit.head = info->xmit.tail = 0;
|
info->xmit.head = info->xmit.tail = 0;
|
||||||
local_irq_restore(flags);
|
local_irq_restore(flags);
|
||||||
|
|
||||||
wake_up_interruptible(&tty->write_wait);
|
tty_wakeup(tty);
|
||||||
|
|
||||||
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
|
|
||||||
tty->ldisc.write_wakeup)
|
|
||||||
(tty->ldisc.write_wakeup)(tty);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -404,12 +388,6 @@ static void rs_unthrottle(struct tty_struct * tty)
|
||||||
printk(KERN_INFO "simrs_unthrottle called\n");
|
printk(KERN_INFO "simrs_unthrottle called\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* rs_break() --- routine which turns the break handling on or off
|
|
||||||
*/
|
|
||||||
static void rs_break(struct tty_struct *tty, int break_state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||||
unsigned int cmd, unsigned long arg)
|
unsigned int cmd, unsigned long arg)
|
||||||
|
@ -422,14 +400,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case TIOCMGET:
|
|
||||||
printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
|
|
||||||
return -EINVAL;
|
|
||||||
case TIOCMBIS:
|
|
||||||
case TIOCMBIC:
|
|
||||||
case TIOCMSET:
|
|
||||||
printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
|
|
||||||
return -EINVAL;
|
|
||||||
case TIOCGSERIAL:
|
case TIOCGSERIAL:
|
||||||
printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
|
printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -488,14 +458,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||||
|
|
||||||
static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
|
||||||
{
|
{
|
||||||
unsigned int cflag = tty->termios->c_cflag;
|
|
||||||
|
|
||||||
if ( (cflag == old_termios->c_cflag)
|
|
||||||
&& ( RELEVANT_IFLAG(tty->termios->c_iflag)
|
|
||||||
== RELEVANT_IFLAG(old_termios->c_iflag)))
|
|
||||||
return;
|
|
||||||
|
|
||||||
|
|
||||||
/* Handle turning off CRTSCTS */
|
/* Handle turning off CRTSCTS */
|
||||||
if ((old_termios->c_cflag & CRTSCTS) &&
|
if ((old_termios->c_cflag & CRTSCTS) &&
|
||||||
!(tty->termios->c_cflag & CRTSCTS)) {
|
!(tty->termios->c_cflag & CRTSCTS)) {
|
||||||
|
@ -623,9 +585,8 @@ static void rs_close(struct tty_struct *tty, struct file * filp)
|
||||||
* the line discipline to only process XON/XOFF characters.
|
* the line discipline to only process XON/XOFF characters.
|
||||||
*/
|
*/
|
||||||
shutdown(info);
|
shutdown(info);
|
||||||
if (tty->ops->flush_buffer)
|
rs_flush_buffer(tty);
|
||||||
tty->ops->flush_buffer(tty);
|
tty_ldisc_flush(tty);
|
||||||
if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
|
|
||||||
info->event = 0;
|
info->event = 0;
|
||||||
info->tty = NULL;
|
info->tty = NULL;
|
||||||
if (info->blocked_open) {
|
if (info->blocked_open) {
|
||||||
|
@ -955,7 +916,6 @@ static const struct tty_operations hp_ops = {
|
||||||
.stop = rs_stop,
|
.stop = rs_stop,
|
||||||
.start = rs_start,
|
.start = rs_start,
|
||||||
.hangup = rs_hangup,
|
.hangup = rs_hangup,
|
||||||
.break_ctl = rs_break,
|
|
||||||
.wait_until_sent = rs_wait_until_sent,
|
.wait_until_sent = rs_wait_until_sent,
|
||||||
.read_proc = rs_read_proc,
|
.read_proc = rs_read_proc,
|
||||||
};
|
};
|
||||||
|
|
|
@ -43,7 +43,8 @@ $(obj)/$(offsets-file): arch/ia64/kvm/asm-offsets.s
|
||||||
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
EXTRA_CFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
||||||
EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
EXTRA_AFLAGS += -Ivirt/kvm -Iarch/ia64/kvm/
|
||||||
|
|
||||||
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o)
|
common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o ioapic.o \
|
||||||
|
coalesced_mmio.o)
|
||||||
|
|
||||||
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
|
kvm-objs := $(common-objs) kvm-ia64.o kvm_fw.o
|
||||||
obj-$(CONFIG_KVM) += kvm.o
|
obj-$(CONFIG_KVM) += kvm.o
|
||||||
|
|
|
@ -187,6 +187,9 @@ int kvm_dev_ioctl_check_extension(long ext)
|
||||||
|
|
||||||
r = 1;
|
r = 1;
|
||||||
break;
|
break;
|
||||||
|
case KVM_CAP_COALESCED_MMIO:
|
||||||
|
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
r = 0;
|
r = 0;
|
||||||
}
|
}
|
||||||
|
@ -195,11 +198,11 @@ int kvm_dev_ioctl_check_extension(long ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
|
static struct kvm_io_device *vcpu_find_mmio_dev(struct kvm_vcpu *vcpu,
|
||||||
gpa_t addr)
|
gpa_t addr, int len, int is_write)
|
||||||
{
|
{
|
||||||
struct kvm_io_device *dev;
|
struct kvm_io_device *dev;
|
||||||
|
|
||||||
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr);
|
dev = kvm_io_bus_find_dev(&vcpu->kvm->mmio_bus, addr, len, is_write);
|
||||||
|
|
||||||
return dev;
|
return dev;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +234,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||||
kvm_run->exit_reason = KVM_EXIT_MMIO;
|
kvm_run->exit_reason = KVM_EXIT_MMIO;
|
||||||
return 0;
|
return 0;
|
||||||
mmio:
|
mmio:
|
||||||
mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr);
|
mmio_dev = vcpu_find_mmio_dev(vcpu, p->addr, p->size, !p->dir);
|
||||||
if (mmio_dev) {
|
if (mmio_dev) {
|
||||||
if (!p->dir)
|
if (!p->dir)
|
||||||
kvm_iodevice_write(mmio_dev, p->addr, p->size,
|
kvm_iodevice_write(mmio_dev, p->addr, p->size,
|
||||||
|
@ -1035,14 +1038,6 @@ static void kvm_free_vmm_area(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Make sure that a cpu that is being hot-unplugged does not have any vcpus
|
|
||||||
* cached on it. Leave it as blank for IA64.
|
|
||||||
*/
|
|
||||||
void decache_vcpus_on_cpu(int cpu)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
static void vti_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1460,6 +1455,9 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void kvm_arch_flush_shadow(struct kvm *kvm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
long kvm_arch_dev_ioctl(struct file *filp,
|
long kvm_arch_dev_ioctl(struct file *filp,
|
||||||
unsigned int ioctl, unsigned long arg)
|
unsigned int ioctl, unsigned long arg)
|
||||||
|
|
|
@ -490,28 +490,6 @@ config ATARI_MFPSER
|
||||||
Note for Falcon users: You also have an MFP port, it's just not
|
Note for Falcon users: You also have an MFP port, it's just not
|
||||||
wired to the outside... But you could use the port under Linux.
|
wired to the outside... But you could use the port under Linux.
|
||||||
|
|
||||||
config ATARI_SCC
|
|
||||||
tristate "Atari SCC serial support"
|
|
||||||
depends on ATARI
|
|
||||||
---help---
|
|
||||||
If you have serial ports based on a Zilog SCC chip (Modem2, Serial2,
|
|
||||||
LAN) and like to use them under Linux, say Y. All built-in SCC's are
|
|
||||||
supported (TT, MegaSTE, Falcon), and also the ST-ESCC. If you have
|
|
||||||
two connectors for channel A (Serial2 and LAN), they are visible as
|
|
||||||
two separate devices.
|
|
||||||
|
|
||||||
To compile this driver as a module, choose M here.
|
|
||||||
|
|
||||||
config ATARI_SCC_DMA
|
|
||||||
bool "Atari SCC serial DMA support"
|
|
||||||
depends on ATARI_SCC
|
|
||||||
help
|
|
||||||
This enables DMA support for receiving data on channel A of the SCC.
|
|
||||||
If you have a TT you may say Y here and read
|
|
||||||
drivers/char/atari_SCC.README. All other users should say N here,
|
|
||||||
because only the TT has SCC-DMA, even if your machine keeps claiming
|
|
||||||
so at boot time.
|
|
||||||
|
|
||||||
config ATARI_MIDI
|
config ATARI_MIDI
|
||||||
tristate "Atari MIDI serial support"
|
tristate "Atari MIDI serial support"
|
||||||
depends on ATARI
|
depends on ATARI
|
||||||
|
@ -578,18 +556,6 @@ config MAC_HID
|
||||||
depends on INPUT_ADBHID
|
depends on INPUT_ADBHID
|
||||||
default y
|
default y
|
||||||
|
|
||||||
config ADB_KEYBOARD
|
|
||||||
bool "Support for ADB keyboard (old driver)"
|
|
||||||
depends on MAC && !INPUT_ADBHID
|
|
||||||
help
|
|
||||||
This option allows you to use an ADB keyboard attached to your
|
|
||||||
machine. Note that this disables any other (ie. PS/2) keyboard
|
|
||||||
support, even if your machine is physically capable of using both at
|
|
||||||
the same time.
|
|
||||||
|
|
||||||
If you use an ADB keyboard (4 pin connector), say Y here.
|
|
||||||
If you use a PS/2 keyboard (6 pin connector), say N here.
|
|
||||||
|
|
||||||
config HPDCA
|
config HPDCA
|
||||||
tristate "HP DCA serial support"
|
tristate "HP DCA serial support"
|
||||||
depends on DIO && SERIAL_8250
|
depends on DIO && SERIAL_8250
|
||||||
|
@ -640,7 +606,7 @@ config DN_SERIAL
|
||||||
|
|
||||||
config SERIAL_CONSOLE
|
config SERIAL_CONSOLE
|
||||||
bool "Support for serial port console"
|
bool "Support for serial port console"
|
||||||
depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_SCC=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
|
depends on (AMIGA || ATARI || MAC || SUN3 || SUN3X || VME || APOLLO) && (ATARI_MFPSER=y || ATARI_MIDI=y || MAC_SCC=y || AMIGA_BUILTIN_SERIAL=y || GVPIOEXT=y || MULTIFACE_III_TTY=y || SERIAL=y || MVME147_SCC || SERIAL167 || MVME162_SCC || BVME6000_SCC || DN_SERIAL)
|
||||||
---help---
|
---help---
|
||||||
If you say Y here, it will be possible to use a serial port as the
|
If you say Y here, it will be possible to use a serial port as the
|
||||||
system console (the system console is the device which receives all
|
system console (the system console is the device which receives all
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
# Copyright (C) 1994 by Hamish Macdonald
|
# Copyright (C) 1994 by Hamish Macdonald
|
||||||
#
|
#
|
||||||
|
|
||||||
KBUILD_DEFCONFIG := amiga_defconfig
|
KBUILD_DEFCONFIG := multi_defconfig
|
||||||
|
|
||||||
# override top level makefile
|
# override top level makefile
|
||||||
AS += -m68020
|
AS += -m68020
|
||||||
|
|
|
@ -36,14 +36,11 @@
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
|
||||||
unsigned long amiga_model;
|
static unsigned long amiga_model;
|
||||||
EXPORT_SYMBOL(amiga_model);
|
|
||||||
|
|
||||||
unsigned long amiga_eclock;
|
unsigned long amiga_eclock;
|
||||||
EXPORT_SYMBOL(amiga_eclock);
|
EXPORT_SYMBOL(amiga_eclock);
|
||||||
|
|
||||||
unsigned long amiga_masterclock;
|
|
||||||
|
|
||||||
unsigned long amiga_colorclock;
|
unsigned long amiga_colorclock;
|
||||||
EXPORT_SYMBOL(amiga_colorclock);
|
EXPORT_SYMBOL(amiga_colorclock);
|
||||||
|
|
||||||
|
@ -51,7 +48,9 @@ unsigned long amiga_chipset;
|
||||||
EXPORT_SYMBOL(amiga_chipset);
|
EXPORT_SYMBOL(amiga_chipset);
|
||||||
|
|
||||||
unsigned char amiga_vblank;
|
unsigned char amiga_vblank;
|
||||||
unsigned char amiga_psfreq;
|
EXPORT_SYMBOL(amiga_vblank);
|
||||||
|
|
||||||
|
static unsigned char amiga_psfreq;
|
||||||
|
|
||||||
struct amiga_hw_present amiga_hw_present;
|
struct amiga_hw_present amiga_hw_present;
|
||||||
EXPORT_SYMBOL(amiga_hw_present);
|
EXPORT_SYMBOL(amiga_hw_present);
|
||||||
|
@ -92,8 +91,6 @@ static char *amiga_models[] __initdata = {
|
||||||
static char amiga_model_name[13] = "Amiga ";
|
static char amiga_model_name[13] = "Amiga ";
|
||||||
|
|
||||||
static void amiga_sched_init(irq_handler_t handler);
|
static void amiga_sched_init(irq_handler_t handler);
|
||||||
/* amiga specific irq functions */
|
|
||||||
extern void amiga_init_IRQ(void);
|
|
||||||
static void amiga_get_model(char *model);
|
static void amiga_get_model(char *model);
|
||||||
static int amiga_get_hardware_list(char *buffer);
|
static int amiga_get_hardware_list(char *buffer);
|
||||||
/* amiga specific timer functions */
|
/* amiga specific timer functions */
|
||||||
|
@ -107,8 +104,6 @@ static void amiga_reset(void);
|
||||||
extern void amiga_init_sound(void);
|
extern void amiga_init_sound(void);
|
||||||
static void amiga_mem_console_write(struct console *co, const char *b,
|
static void amiga_mem_console_write(struct console *co, const char *b,
|
||||||
unsigned int count);
|
unsigned int count);
|
||||||
void amiga_serial_console_write(struct console *co, const char *s,
|
|
||||||
unsigned int count);
|
|
||||||
#ifdef CONFIG_HEARTBEAT
|
#ifdef CONFIG_HEARTBEAT
|
||||||
static void amiga_heartbeat(int on);
|
static void amiga_heartbeat(int on);
|
||||||
#endif
|
#endif
|
||||||
|
@ -418,8 +413,7 @@ void __init config_amiga(void)
|
||||||
mach_heartbeat = amiga_heartbeat;
|
mach_heartbeat = amiga_heartbeat;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Fill in the clock values (based on the 700 kHz E-Clock) */
|
/* Fill in the clock value (based on the 700 kHz E-Clock) */
|
||||||
amiga_masterclock = 40*amiga_eclock; /* 28 MHz */
|
|
||||||
amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */
|
amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */
|
||||||
|
|
||||||
/* clear all DMA bits */
|
/* clear all DMA bits */
|
||||||
|
@ -817,8 +811,8 @@ static void amiga_serial_putc(char c)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
void amiga_serial_console_write(struct console *co, const char *s,
|
static void amiga_serial_console_write(struct console *co, const char *s,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*s == '\n')
|
if (*s == '\n')
|
||||||
|
@ -827,7 +821,7 @@ void amiga_serial_console_write(struct console *co, const char *s,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_CONSOLE
|
#if 0
|
||||||
void amiga_serial_puts(const char *s)
|
void amiga_serial_puts(const char *s)
|
||||||
{
|
{
|
||||||
amiga_serial_console_write(NULL, s, strlen(s));
|
amiga_serial_console_write(NULL, s, strlen(s));
|
||||||
|
|
|
@ -20,14 +20,6 @@
|
||||||
#include <asm/atarihw.h>
|
#include <asm/atarihw.h>
|
||||||
#include <asm/atariints.h>
|
#include <asm/atariints.h>
|
||||||
|
|
||||||
/* Flag that Modem1 port is already initialized and used */
|
|
||||||
int atari_MFP_init_done;
|
|
||||||
EXPORT_SYMBOL(atari_MFP_init_done);
|
|
||||||
|
|
||||||
/* Flag that Modem1 port is already initialized and used */
|
|
||||||
int atari_SCC_init_done;
|
|
||||||
EXPORT_SYMBOL(atari_SCC_init_done);
|
|
||||||
|
|
||||||
/* Can be set somewhere, if a SCC master reset has already be done and should
|
/* Can be set somewhere, if a SCC master reset has already be done and should
|
||||||
* not be repeated; used by kgdb */
|
* not be repeated; used by kgdb */
|
||||||
int atari_SCC_reset_done;
|
int atari_SCC_reset_done;
|
||||||
|
@ -47,8 +39,8 @@ static inline void ata_mfp_out(char c)
|
||||||
mfp.usart_dta = c;
|
mfp.usart_dta = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void atari_mfp_console_write(struct console *co, const char *str,
|
static void atari_mfp_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
|
@ -66,8 +58,8 @@ static inline void ata_scc_out(char c)
|
||||||
scc.cha_b_data = c;
|
scc.cha_b_data = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void atari_scc_console_write(struct console *co, const char *str,
|
static void atari_scc_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
|
@ -83,8 +75,8 @@ static inline void ata_midi_out(char c)
|
||||||
acia.mid_data = c;
|
acia.mid_data = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void atari_midi_console_write(struct console *co, const char *str,
|
static void atari_midi_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
|
@ -136,7 +128,7 @@ static void atari_par_console_write(struct console *co, const char *str,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_SERIAL_CONSOLE
|
#if 0
|
||||||
int atari_mfp_console_wait_key(struct console *co)
|
int atari_mfp_console_wait_key(struct console *co)
|
||||||
{
|
{
|
||||||
while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */
|
while (!(mfp.rcv_stat & 0x80)) /* wait for rx buf filled */
|
||||||
|
@ -166,11 +158,7 @@ int atari_midi_console_wait_key(struct console *co)
|
||||||
* SCC serial ports. They're used by the debugging interface, kgdb, and the
|
* SCC serial ports. They're used by the debugging interface, kgdb, and the
|
||||||
* serial console code.
|
* serial console code.
|
||||||
*/
|
*/
|
||||||
#ifndef CONFIG_SERIAL_CONSOLE
|
|
||||||
static void __init atari_init_mfp_port(int cflag)
|
static void __init atari_init_mfp_port(int cflag)
|
||||||
#else
|
|
||||||
void atari_init_mfp_port(int cflag)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
|
* timer values for 1200...115200 bps; > 38400 select 110, 134, or 150
|
||||||
|
@ -193,8 +181,6 @@ void atari_init_mfp_port(int cflag)
|
||||||
mfp.tim_dt_d = baud_table[baud];
|
mfp.tim_dt_d = baud_table[baud];
|
||||||
mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
|
mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
|
||||||
mfp.trn_stat |= 0x01; /* enable TX */
|
mfp.trn_stat |= 0x01; /* enable TX */
|
||||||
|
|
||||||
atari_MFP_init_done = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SCC_WRITE(reg, val) \
|
#define SCC_WRITE(reg, val) \
|
||||||
|
@ -214,11 +200,7 @@ void atari_init_mfp_port(int cflag)
|
||||||
MFPDELAY(); \
|
MFPDELAY(); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifndef CONFIG_SERIAL_CONSOLE
|
|
||||||
static void __init atari_init_scc_port(int cflag)
|
static void __init atari_init_scc_port(int cflag)
|
||||||
#else
|
|
||||||
void atari_init_scc_port(int cflag)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
extern int atari_SCC_reset_done;
|
extern int atari_SCC_reset_done;
|
||||||
static int clksrc_table[9] =
|
static int clksrc_table[9] =
|
||||||
|
@ -277,14 +259,9 @@ void atari_init_scc_port(int cflag)
|
||||||
SCC_WRITE(5, reg5 | 8);
|
SCC_WRITE(5, reg5 | 8);
|
||||||
|
|
||||||
atari_SCC_reset_done = 1;
|
atari_SCC_reset_done = 1;
|
||||||
atari_SCC_init_done = 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef CONFIG_SERIAL_CONSOLE
|
|
||||||
static void __init atari_init_midi_port(int cflag)
|
static void __init atari_init_midi_port(int cflag)
|
||||||
#else
|
|
||||||
void atari_init_midi_port(int cflag)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
int baud = cflag & CBAUD;
|
int baud = cflag & CBAUD;
|
||||||
int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
|
int csize = ((cflag & CSIZE) == CS8) ? 0x10 : 0x00;
|
||||||
|
|
|
@ -10,7 +10,6 @@ obj-y := bindec.o binstr.o decbin.o do_func.o gen_except.o get_op.o \
|
||||||
x_bsun.o x_fline.o x_operr.o x_ovfl.o x_snan.o x_store.o \
|
x_bsun.o x_fline.o x_operr.o x_ovfl.o x_snan.o x_store.o \
|
||||||
x_unfl.o x_unimp.o x_unsupp.o bugfix.o skeleton.o
|
x_unfl.o x_unimp.o x_unsupp.o bugfix.o skeleton.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := -traditional
|
|
||||||
EXTRA_LDFLAGS := -x
|
EXTRA_LDFLAGS := -x
|
||||||
|
|
||||||
$(OS_OBJS): fpsp.h
|
$(OS_OBJS): fpsp.h
|
||||||
|
|
|
@ -6,5 +6,4 @@
|
||||||
|
|
||||||
obj-y := fskeleton.o iskeleton.o os.o
|
obj-y := fskeleton.o iskeleton.o os.o
|
||||||
|
|
||||||
EXTRA_AFLAGS := -traditional
|
|
||||||
EXTRA_LDFLAGS := -x
|
EXTRA_LDFLAGS := -x
|
||||||
|
|
|
@ -16,5 +16,3 @@ devres-y = ../../../kernel/irq/devres.o
|
||||||
|
|
||||||
obj-$(CONFIG_PCI) += bios32.o
|
obj-$(CONFIG_PCI) += bios32.o
|
||||||
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
|
obj-y$(CONFIG_MMU_SUN3) += dma.o # no, it's not a typo
|
||||||
|
|
||||||
EXTRA_AFLAGS := -traditional
|
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#include <asm/bootinfo.h>
|
#include <asm/bootinfo.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/fpu.h>
|
||||||
#include <asm/irq.h>
|
#include <asm/irq.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/machdep.h>
|
#include <asm/machdep.h>
|
||||||
|
@ -40,6 +41,11 @@
|
||||||
#include <asm/dvma.h>
|
#include <asm/dvma.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if !FPSTATESIZE || !NR_IRQS
|
||||||
|
#warning No CPU/platform type selected, your kernel will not work!
|
||||||
|
#warning Are you building an allnoconfig kernel?
|
||||||
|
#endif
|
||||||
|
|
||||||
unsigned long m68k_machtype;
|
unsigned long m68k_machtype;
|
||||||
EXPORT_SYMBOL(m68k_machtype);
|
EXPORT_SYMBOL(m68k_machtype);
|
||||||
unsigned long m68k_cputype;
|
unsigned long m68k_cputype;
|
||||||
|
@ -116,6 +122,7 @@ extern int bvme6000_parse_bootinfo(const struct bi_record *);
|
||||||
extern int mvme16x_parse_bootinfo(const struct bi_record *);
|
extern int mvme16x_parse_bootinfo(const struct bi_record *);
|
||||||
extern int mvme147_parse_bootinfo(const struct bi_record *);
|
extern int mvme147_parse_bootinfo(const struct bi_record *);
|
||||||
extern int hp300_parse_bootinfo(const struct bi_record *);
|
extern int hp300_parse_bootinfo(const struct bi_record *);
|
||||||
|
extern int apollo_parse_bootinfo(const struct bi_record *);
|
||||||
|
|
||||||
extern void config_amiga(void);
|
extern void config_amiga(void);
|
||||||
extern void config_atari(void);
|
extern void config_atari(void);
|
||||||
|
@ -183,6 +190,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
|
||||||
unknown = mvme147_parse_bootinfo(record);
|
unknown = mvme147_parse_bootinfo(record);
|
||||||
else if (MACH_IS_HP300)
|
else if (MACH_IS_HP300)
|
||||||
unknown = hp300_parse_bootinfo(record);
|
unknown = hp300_parse_bootinfo(record);
|
||||||
|
else if (MACH_IS_APOLLO)
|
||||||
|
unknown = apollo_parse_bootinfo(record);
|
||||||
else
|
else
|
||||||
unknown = 1;
|
unknown = 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* ld script to make m68k Linux kernel */
|
/* ld script to make m68k Linux kernel */
|
||||||
|
|
||||||
#include <asm-generic/vmlinux.lds.h>
|
#include <asm-generic/vmlinux.lds.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||||
OUTPUT_ARCH(m68k)
|
OUTPUT_ARCH(m68k)
|
||||||
|
@ -41,7 +42,7 @@ SECTIONS
|
||||||
_edata = .; /* End of data section */
|
_edata = .; /* End of data section */
|
||||||
|
|
||||||
/* will be freed after init */
|
/* will be freed after init */
|
||||||
. = ALIGN(4096); /* Init code and data */
|
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||||
__init_begin = .;
|
__init_begin = .;
|
||||||
.init.text : {
|
.init.text : {
|
||||||
_sinittext = .;
|
_sinittext = .;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
/* ld script to make m68k Linux kernel */
|
/* ld script to make m68k Linux kernel */
|
||||||
|
|
||||||
#include <asm-generic/vmlinux.lds.h>
|
#include <asm-generic/vmlinux.lds.h>
|
||||||
|
#include <asm/page.h>
|
||||||
|
|
||||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||||
OUTPUT_ARCH(m68k)
|
OUTPUT_ARCH(m68k)
|
||||||
|
@ -34,7 +35,7 @@ SECTIONS
|
||||||
_edata = .;
|
_edata = .;
|
||||||
|
|
||||||
/* will be freed after init */
|
/* will be freed after init */
|
||||||
. = ALIGN(8192); /* Init code and data */
|
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||||
__init_begin = .;
|
__init_begin = .;
|
||||||
.init.text : {
|
.init.text : {
|
||||||
_sinittext = .;
|
_sinittext = .;
|
||||||
|
@ -61,12 +62,12 @@ __init_begin = .;
|
||||||
}
|
}
|
||||||
SECURITY_INIT
|
SECURITY_INIT
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
. = ALIGN(8192);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__initramfs_start = .;
|
__initramfs_start = .;
|
||||||
.init.ramfs : { *(.init.ramfs) }
|
.init.ramfs : { *(.init.ramfs) }
|
||||||
__initramfs_end = .;
|
__initramfs_end = .;
|
||||||
#endif
|
#endif
|
||||||
. = ALIGN(8192);
|
. = ALIGN(PAGE_SIZE);
|
||||||
__init_end = .;
|
__init_end = .;
|
||||||
.data.init.task : { *(.data.init_task) }
|
.data.init.task : { *(.data.init_task) }
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,5 @@
|
||||||
# Makefile for m68k-specific library files..
|
# Makefile for m68k-specific library files..
|
||||||
#
|
#
|
||||||
|
|
||||||
EXTRA_AFLAGS := -traditional
|
|
||||||
|
|
||||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||||
checksum.o string.o uaccess.o
|
checksum.o string.o uaccess.o
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
# Makefile for Linux arch/m68k/mac source directory
|
# Makefile for Linux arch/m68k/mac source directory
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := config.o bootparse.o macints.o iop.o via.o oss.o psc.o \
|
obj-y := config.o macints.o iop.o via.o oss.o psc.o \
|
||||||
baboon.o macboing.o debug.o misc.o
|
baboon.o macboing.o debug.o misc.o
|
||||||
|
|
|
@ -23,9 +23,7 @@
|
||||||
/* #define DEBUG_IRQS */
|
/* #define DEBUG_IRQS */
|
||||||
|
|
||||||
int baboon_present;
|
int baboon_present;
|
||||||
volatile struct baboon *baboon;
|
static volatile struct baboon *baboon;
|
||||||
|
|
||||||
irqreturn_t baboon_irq(int, void *);
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
extern int macide_ack_intr(struct ata_channel *);
|
extern int macide_ack_intr(struct ata_channel *);
|
||||||
|
@ -49,21 +47,11 @@ void __init baboon_init(void)
|
||||||
printk("Baboon detected at %p\n", baboon);
|
printk("Baboon detected at %p\n", baboon);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Register the Baboon interrupt dispatcher on nubus slot $C.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void __init baboon_register_interrupts(void)
|
|
||||||
{
|
|
||||||
request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
|
||||||
"baboon", (void *) baboon);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Baboon interrupt handler. This works a lot like a VIA.
|
* Baboon interrupt handler. This works a lot like a VIA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
irqreturn_t baboon_irq(int irq, void *dev_id)
|
static irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
int irq_bit, irq_num;
|
int irq_bit, irq_num;
|
||||||
unsigned char events;
|
unsigned char events;
|
||||||
|
@ -95,6 +83,16 @@ irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Register the Baboon interrupt dispatcher on nubus slot $C.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void __init baboon_register_interrupts(void)
|
||||||
|
{
|
||||||
|
request_irq(IRQ_NUBUS_C, baboon_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
|
||||||
|
"baboon", (void *) baboon);
|
||||||
|
}
|
||||||
|
|
||||||
void baboon_irq_enable(int irq) {
|
void baboon_irq_enable(int irq) {
|
||||||
#ifdef DEBUG_IRQUSE
|
#ifdef DEBUG_IRQUSE
|
||||||
printk("baboon_irq_enable(%d)\n", irq);
|
printk("baboon_irq_enable(%d)\n", irq);
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
#include <linux/string.h>
|
|
||||||
#include <linux/kernel.h>
|
|
||||||
#include <linux/sched.h>
|
|
||||||
#include <asm/irq.h>
|
|
||||||
#include <asm/setup.h>
|
|
||||||
#include <asm/bootinfo.h>
|
|
||||||
#include <asm/macintosh.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Booter vars
|
|
||||||
*/
|
|
||||||
|
|
||||||
int boothowto;
|
|
||||||
int _boothowto;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Called early to parse the environment (passed to us from the booter)
|
|
||||||
* into a bootinfo struct. Will die as soon as we have our own booter
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define atol(x) simple_strtoul(x,NULL,0)
|
|
||||||
|
|
||||||
void parse_booter(char *env)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
#if 0
|
|
||||||
while(0 && *env)
|
|
||||||
#else
|
|
||||||
while(*env)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
name=env;
|
|
||||||
value=name;
|
|
||||||
while(*value!='='&&*value)
|
|
||||||
value++;
|
|
||||||
if(*value=='=')
|
|
||||||
*value++=0;
|
|
||||||
env=value;
|
|
||||||
while(*env)
|
|
||||||
env++;
|
|
||||||
env++;
|
|
||||||
#if 0
|
|
||||||
if(strcmp(name,"VIDEO_ADDR")==0)
|
|
||||||
mac_mch.videoaddr=atol(value);
|
|
||||||
if(strcmp(name,"ROW_BYTES")==0)
|
|
||||||
mac_mch.videorow=atol(value);
|
|
||||||
if(strcmp(name,"SCREEN_DEPTH")==0)
|
|
||||||
mac_mch.videodepth=atol(value);
|
|
||||||
if(strcmp(name,"DIMENSIONS")==0)
|
|
||||||
mac_mch.dimensions=atol(value);
|
|
||||||
#endif
|
|
||||||
if(strcmp(name,"BOOTTIME")==0)
|
|
||||||
mac_bi_data.boottime=atol(value);
|
|
||||||
if(strcmp(name,"GMTBIAS")==0)
|
|
||||||
mac_bi_data.gmtbias=atol(value);
|
|
||||||
if(strcmp(name,"BOOTERVER")==0)
|
|
||||||
mac_bi_data.bootver=atol(value);
|
|
||||||
if(strcmp(name,"MACOS_VIDEO")==0)
|
|
||||||
mac_bi_data.videological=atol(value);
|
|
||||||
if(strcmp(name,"MACOS_SCC")==0)
|
|
||||||
mac_bi_data.sccbase=atol(value);
|
|
||||||
if(strcmp(name,"MACHINEID")==0)
|
|
||||||
mac_bi_data.id=atol(value);
|
|
||||||
if(strcmp(name,"MEMSIZE")==0)
|
|
||||||
mac_bi_data.memsize=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_MODEM_FLAGS")==0)
|
|
||||||
mac_bi_data.serialmf=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_MODEM_HSKICLK")==0)
|
|
||||||
mac_bi_data.serialhsk=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_MODEM_GPICLK")==0)
|
|
||||||
mac_bi_data.serialgpi=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_PRINT_FLAGS")==0)
|
|
||||||
mac_bi_data.printmf=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_PRINT_HSKICLK")==0)
|
|
||||||
mac_bi_data.printhsk=atol(value);
|
|
||||||
if(strcmp(name,"SERIAL_PRINT_GPICLK")==0)
|
|
||||||
mac_bi_data.printgpi=atol(value);
|
|
||||||
if(strcmp(name,"PROCESSOR")==0)
|
|
||||||
mac_bi_data.cpuid=atol(value);
|
|
||||||
if(strcmp(name,"ROMBASE")==0)
|
|
||||||
mac_bi_data.rombase=atol(value);
|
|
||||||
if(strcmp(name,"TIMEDBRA")==0)
|
|
||||||
mac_bi_data.timedbra=atol(value);
|
|
||||||
if(strcmp(name,"ADBDELAY")==0)
|
|
||||||
mac_bi_data.adbdelay=atol(value);
|
|
||||||
}
|
|
||||||
#if 0 /* XXX: TODO with m68k_mach_* */
|
|
||||||
/* Fill in the base stuff */
|
|
||||||
boot_info.machtype=MACH_MAC;
|
|
||||||
/* Read this from the macinfo we got ! */
|
|
||||||
/* boot_info.cputype=CPU_68020|FPUB_68881;*/
|
|
||||||
/* boot_info.memory[0].addr=0;*/
|
|
||||||
/* boot_info.memory[0].size=((mac_bi_data.id>>7)&31)<<20;*/
|
|
||||||
boot_info.num_memory=1; /* On a MacII */
|
|
||||||
boot_info.ramdisk_size=0; /* For now */
|
|
||||||
*boot_info.command_line=0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void print_booter(char *env)
|
|
||||||
{
|
|
||||||
char *name;
|
|
||||||
char *value;
|
|
||||||
while(*env)
|
|
||||||
{
|
|
||||||
name=env;
|
|
||||||
value=name;
|
|
||||||
while(*value!='='&&*value)
|
|
||||||
value++;
|
|
||||||
if(*value=='=')
|
|
||||||
*value++=0;
|
|
||||||
env=value;
|
|
||||||
while(*env)
|
|
||||||
env++;
|
|
||||||
env++;
|
|
||||||
printk("%s=%s\n", name,value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,6 @@
|
||||||
/* Mac bootinfo struct */
|
/* Mac bootinfo struct */
|
||||||
|
|
||||||
struct mac_booter_data mac_bi_data;
|
struct mac_booter_data mac_bi_data;
|
||||||
int mac_bisize = sizeof mac_bi_data;
|
|
||||||
|
|
||||||
/* New m68k bootinfo stuff and videobase */
|
/* New m68k bootinfo stuff and videobase */
|
||||||
|
|
||||||
|
@ -55,10 +54,8 @@ extern struct mem_info m68k_memory[NUM_MEMINFO];
|
||||||
|
|
||||||
extern struct mem_info m68k_ramdisk;
|
extern struct mem_info m68k_ramdisk;
|
||||||
|
|
||||||
void *mac_env; /* Loaded by the boot asm */
|
|
||||||
|
|
||||||
/* The phys. video addr. - might be bogus on some machines */
|
/* The phys. video addr. - might be bogus on some machines */
|
||||||
unsigned long mac_orig_videoaddr;
|
static unsigned long mac_orig_videoaddr;
|
||||||
|
|
||||||
/* Mac specific timer functions */
|
/* Mac specific timer functions */
|
||||||
extern unsigned long mac_gettimeoffset(void);
|
extern unsigned long mac_gettimeoffset(void);
|
||||||
|
@ -79,6 +76,8 @@ extern void mac_mksound(unsigned int, unsigned int);
|
||||||
extern void nubus_sweep_video(void);
|
extern void nubus_sweep_video(void);
|
||||||
|
|
||||||
static void mac_get_model(char *str);
|
static void mac_get_model(char *str);
|
||||||
|
static void mac_identify(void);
|
||||||
|
static void mac_report_hardware(void);
|
||||||
|
|
||||||
static void __init mac_sched_init(irq_handler_t vector)
|
static void __init mac_sched_init(irq_handler_t vector)
|
||||||
{
|
{
|
||||||
|
@ -765,7 +764,7 @@ static struct mac_model mac_data_table[] = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void __init mac_identify(void)
|
static void __init mac_identify(void)
|
||||||
{
|
{
|
||||||
struct mac_model *m;
|
struct mac_model *m;
|
||||||
|
|
||||||
|
@ -821,7 +820,7 @@ void __init mac_identify(void)
|
||||||
baboon_init();
|
baboon_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init mac_report_hardware(void)
|
static void __init mac_report_hardware(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name);
|
printk(KERN_INFO "Apple Macintosh %s\n", macintosh_config->name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,8 @@ extern void mac_serial_print(const char *);
|
||||||
static int peng, line;
|
static int peng, line;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
void mac_debugging_short(int pos, short num)
|
void mac_debugging_short(int pos, short num)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_SCREEN
|
#ifdef DEBUG_SCREEN
|
||||||
|
@ -125,6 +127,8 @@ void mac_debugging_long(int pos, long addr)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* 0 */
|
||||||
|
|
||||||
#ifdef DEBUG_SERIAL
|
#ifdef DEBUG_SERIAL
|
||||||
/*
|
/*
|
||||||
* TODO: serial debug code
|
* TODO: serial debug code
|
||||||
|
@ -142,12 +146,6 @@ struct mac_SCC {
|
||||||
|
|
||||||
# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
|
# define scc (*((volatile struct mac_SCC*)mac_bi_data.sccbase))
|
||||||
|
|
||||||
/* Flag that serial port is already initialized and used */
|
|
||||||
int mac_SCC_init_done;
|
|
||||||
/* Can be set somewhere, if a SCC master reset has already be done and should
|
|
||||||
* not be repeated; used by kgdb */
|
|
||||||
int mac_SCC_reset_done;
|
|
||||||
|
|
||||||
static int scc_port = -1;
|
static int scc_port = -1;
|
||||||
|
|
||||||
static struct console mac_console_driver = {
|
static struct console mac_console_driver = {
|
||||||
|
@ -171,8 +169,8 @@ static struct console mac_console_driver = {
|
||||||
* this driver if Mac.
|
* this driver if Mac.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void mac_debug_console_write(struct console *co, const char *str,
|
static void mac_debug_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
mac_serial_print(str);
|
mac_serial_print(str);
|
||||||
}
|
}
|
||||||
|
@ -209,8 +207,8 @@ static inline void mac_scca_out(char c)
|
||||||
scc.cha_a_data = c;
|
scc.cha_a_data = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac_sccb_console_write(struct console *co, const char *str,
|
static void mac_sccb_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
|
@ -219,8 +217,8 @@ void mac_sccb_console_write(struct console *co, const char *str,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void mac_scca_console_write(struct console *co, const char *str,
|
static void mac_scca_console_write(struct console *co, const char *str,
|
||||||
unsigned int count)
|
unsigned int count)
|
||||||
{
|
{
|
||||||
while (count--) {
|
while (count--) {
|
||||||
if (*str == '\n')
|
if (*str == '\n')
|
||||||
|
@ -265,14 +263,8 @@ void mac_scca_console_write(struct console *co, const char *str,
|
||||||
barrier(); \
|
barrier(); \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
#ifndef CONFIG_SERIAL_CONSOLE
|
|
||||||
static void __init mac_init_scc_port(int cflag, int port)
|
static void __init mac_init_scc_port(int cflag, int port)
|
||||||
#else
|
|
||||||
void mac_init_scc_port(int cflag, int port)
|
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
extern int mac_SCC_reset_done;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k
|
* baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k
|
||||||
*/
|
*/
|
||||||
|
@ -340,22 +332,9 @@ void mac_init_scc_port(int cflag, int port)
|
||||||
SCCA_WRITE(3, reg3 | 1);
|
SCCA_WRITE(3, reg3 | 1);
|
||||||
SCCA_WRITE(5, reg5 | 8);
|
SCCA_WRITE(5, reg5 | 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
mac_SCC_reset_done = 1;
|
|
||||||
mac_SCC_init_done = 1;
|
|
||||||
}
|
}
|
||||||
#endif /* DEBUG_SERIAL */
|
#endif /* DEBUG_SERIAL */
|
||||||
|
|
||||||
void mac_init_scca_port(int cflag)
|
|
||||||
{
|
|
||||||
mac_init_scc_port(cflag, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void mac_init_sccb_port(int cflag)
|
|
||||||
{
|
|
||||||
mac_init_scc_port(cflag, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int __init mac_debug_setup(char *arg)
|
static int __init mac_debug_setup(char *arg)
|
||||||
{
|
{
|
||||||
if (!MACH_IS_MAC)
|
if (!MACH_IS_MAC)
|
||||||
|
|
|
@ -30,8 +30,8 @@
|
||||||
int oss_present;
|
int oss_present;
|
||||||
volatile struct mac_oss *oss;
|
volatile struct mac_oss *oss;
|
||||||
|
|
||||||
irqreturn_t oss_irq(int, void *);
|
static irqreturn_t oss_irq(int, void *);
|
||||||
irqreturn_t oss_nubus_irq(int, void *);
|
static irqreturn_t oss_nubus_irq(int, void *);
|
||||||
|
|
||||||
extern irqreturn_t via1_irq(int, void *);
|
extern irqreturn_t via1_irq(int, void *);
|
||||||
extern irqreturn_t mac_scc_dispatch(int, void *);
|
extern irqreturn_t mac_scc_dispatch(int, void *);
|
||||||
|
@ -92,7 +92,7 @@ void __init oss_nubus_init(void)
|
||||||
* and SCSI; everything else is routed to its own autovector IRQ.
|
* and SCSI; everything else is routed to its own autovector IRQ.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
irqreturn_t oss_irq(int irq, void *dev_id)
|
static irqreturn_t oss_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
int events;
|
int events;
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ irqreturn_t oss_irq(int irq, void *dev_id)
|
||||||
* Unlike the VIA/RBV this is on its own autovector interrupt level.
|
* Unlike the VIA/RBV this is on its own autovector interrupt level.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
irqreturn_t oss_nubus_irq(int irq, void *dev_id)
|
static irqreturn_t oss_nubus_irq(int irq, void *dev_id)
|
||||||
{
|
{
|
||||||
int events, irq_bit, i;
|
int events, irq_bit, i;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ irqreturn_t psc_irq(int, void *);
|
||||||
* Debugging dump, used in various places to see what's going on.
|
* Debugging dump, used in various places to see what's going on.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void psc_debug_dump(void)
|
static void psc_debug_dump(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
@ -55,7 +55,7 @@ void psc_debug_dump(void)
|
||||||
* expanded to cover what I think are the other 7 channels.
|
* expanded to cover what I think are the other 7 channels.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void psc_dma_die_die_die(void)
|
static void psc_dma_die_die_die(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ volatile long *via_memory_bogon=(long *)&via_memory_bogon;
|
||||||
int rbv_present;
|
int rbv_present;
|
||||||
int via_alt_mapping;
|
int via_alt_mapping;
|
||||||
EXPORT_SYMBOL(via_alt_mapping);
|
EXPORT_SYMBOL(via_alt_mapping);
|
||||||
__u8 rbv_clear;
|
static __u8 rbv_clear;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Globals for accessing the VIA chip registers without having to
|
* Globals for accessing the VIA chip registers without having to
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
# Makefile for the linux kernel.
|
# Makefile for the linux kernel.
|
||||||
#
|
#
|
||||||
|
|
||||||
EXTRA_AFLAGS := -traditional
|
|
||||||
|
|
||||||
#EXTRA_AFLAGS += -DFPU_EMU_DEBUG
|
#EXTRA_AFLAGS += -DFPU_EMU_DEBUG
|
||||||
#EXTRA_CFLAGS += -DFPU_EMU_DEBUG
|
#EXTRA_CFLAGS += -DFPU_EMU_DEBUG
|
||||||
|
|
||||||
|
|
|
@ -285,7 +285,6 @@ void __init paging_init(void)
|
||||||
* to a couple of allocated pages
|
* to a couple of allocated pages
|
||||||
*/
|
*/
|
||||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up SFC/DFC registers
|
* Set up SFC/DFC registers
|
||||||
|
|
|
@ -53,7 +53,6 @@ void __init paging_init(void)
|
||||||
wp_works_ok = 0;
|
wp_works_ok = 0;
|
||||||
#endif
|
#endif
|
||||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
|
||||||
|
|
||||||
address = PAGE_OFFSET;
|
address = PAGE_OFFSET;
|
||||||
pg_dir = swapper_pg_dir;
|
pg_dir = swapper_pg_dir;
|
||||||
|
|
|
@ -41,14 +41,12 @@ static void q40_get_model(char *model);
|
||||||
static int q40_get_hardware_list(char *buffer);
|
static int q40_get_hardware_list(char *buffer);
|
||||||
extern void q40_sched_init(irq_handler_t handler);
|
extern void q40_sched_init(irq_handler_t handler);
|
||||||
|
|
||||||
extern unsigned long q40_gettimeoffset(void);
|
static unsigned long q40_gettimeoffset(void);
|
||||||
extern int q40_hwclk(int, struct rtc_time *);
|
static int q40_hwclk(int, struct rtc_time *);
|
||||||
extern unsigned int q40_get_ss(void);
|
static unsigned int q40_get_ss(void);
|
||||||
extern int q40_set_clock_mmss(unsigned long);
|
static int q40_set_clock_mmss(unsigned long);
|
||||||
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
|
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
|
||||||
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
|
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
|
||||||
extern void q40_reset(void);
|
|
||||||
void q40_halt(void);
|
|
||||||
extern void q40_waitbut(void);
|
extern void q40_waitbut(void);
|
||||||
void q40_set_vectors(void);
|
void q40_set_vectors(void);
|
||||||
|
|
||||||
|
@ -127,7 +125,7 @@ static void q40_heartbeat(int on)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void q40_reset(void)
|
static void q40_reset(void)
|
||||||
{
|
{
|
||||||
halted = 1;
|
halted = 1;
|
||||||
printk("\n\n*******************************************\n"
|
printk("\n\n*******************************************\n"
|
||||||
|
@ -137,7 +135,8 @@ void q40_reset(void)
|
||||||
while (1)
|
while (1)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
void q40_halt(void)
|
|
||||||
|
static void q40_halt(void)
|
||||||
{
|
{
|
||||||
halted = 1;
|
halted = 1;
|
||||||
printk("\n\n*******************\n"
|
printk("\n\n*******************\n"
|
||||||
|
@ -165,7 +164,8 @@ static unsigned int serports[] =
|
||||||
{
|
{
|
||||||
0x3f8,0x2f8,0x3e8,0x2e8,0
|
0x3f8,0x2f8,0x3e8,0x2e8,0
|
||||||
};
|
};
|
||||||
void q40_disable_irqs(void)
|
|
||||||
|
static void q40_disable_irqs(void)
|
||||||
{
|
{
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
|
|
||||||
|
@ -227,7 +227,7 @@ static inline unsigned char bin2bcd(unsigned char b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned long q40_gettimeoffset(void)
|
static unsigned long q40_gettimeoffset(void)
|
||||||
{
|
{
|
||||||
return 5000 * (ql_ticks != 0);
|
return 5000 * (ql_ticks != 0);
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ unsigned long q40_gettimeoffset(void)
|
||||||
* };
|
* };
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int q40_hwclk(int op, struct rtc_time *t)
|
static int q40_hwclk(int op, struct rtc_time *t)
|
||||||
{
|
{
|
||||||
if (op) {
|
if (op) {
|
||||||
/* Write.... */
|
/* Write.... */
|
||||||
|
@ -285,7 +285,7 @@ int q40_hwclk(int op, struct rtc_time *t)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int q40_get_ss(void)
|
static unsigned int q40_get_ss(void)
|
||||||
{
|
{
|
||||||
return bcd2bin(Q40_RTC_SECS);
|
return bcd2bin(Q40_RTC_SECS);
|
||||||
}
|
}
|
||||||
|
@ -295,7 +295,7 @@ unsigned int q40_get_ss(void)
|
||||||
* clock is out by > 30 minutes. Logic lifted from atari code.
|
* clock is out by > 30 minutes. Logic lifted from atari code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int q40_set_clock_mmss(unsigned long nowtime)
|
static int q40_set_clock_mmss(unsigned long nowtime)
|
||||||
{
|
{
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
|
short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
# Makefile for Linux arch/m68k/sun3 source directory
|
# Makefile for Linux arch/m68k/sun3 source directory
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-y := sun3ints.o sun3dvma.o sbus.o idprom.o
|
obj-y := sun3ints.o sun3dvma.o idprom.o
|
||||||
|
|
||||||
obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o
|
obj-$(CONFIG_SUN3) += config.o mmu_emu.o leds.o dvma.o intersil.o
|
||||||
|
|
|
@ -36,7 +36,7 @@ extern char _text, _end;
|
||||||
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
|
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
|
||||||
|
|
||||||
extern unsigned long sun3_gettimeoffset(void);
|
extern unsigned long sun3_gettimeoffset(void);
|
||||||
extern void sun3_sched_init(irq_handler_t handler);
|
static void sun3_sched_init(irq_handler_t handler);
|
||||||
extern void sun3_get_model (char* model);
|
extern void sun3_get_model (char* model);
|
||||||
extern void idprom_init (void);
|
extern void idprom_init (void);
|
||||||
extern int sun3_hwclk(int set, struct rtc_time *t);
|
extern int sun3_hwclk(int set, struct rtc_time *t);
|
||||||
|
@ -114,7 +114,8 @@ static void sun3_halt (void)
|
||||||
|
|
||||||
/* sun3 bootmem allocation */
|
/* sun3 bootmem allocation */
|
||||||
|
|
||||||
void __init sun3_bootmem_alloc(unsigned long memory_start, unsigned long memory_end)
|
static void __init sun3_bootmem_alloc(unsigned long memory_start,
|
||||||
|
unsigned long memory_end)
|
||||||
{
|
{
|
||||||
unsigned long start_page;
|
unsigned long start_page;
|
||||||
|
|
||||||
|
@ -164,7 +165,7 @@ void __init config_sun3(void)
|
||||||
sun3_bootmem_alloc(memory_start, memory_end);
|
sun3_bootmem_alloc(memory_start, memory_end);
|
||||||
}
|
}
|
||||||
|
|
||||||
void __init sun3_sched_init(irq_handler_t timer_routine)
|
static void __init sun3_sched_init(irq_handler_t timer_routine)
|
||||||
{
|
{
|
||||||
sun3_disable_interrupts();
|
sun3_disable_interrupts();
|
||||||
intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
|
intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
static unsigned long ptelist[120];
|
static unsigned long ptelist[120];
|
||||||
|
|
||||||
inline unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr)
|
static unsigned long dvma_page(unsigned long kaddr, unsigned long vaddr)
|
||||||
{
|
{
|
||||||
unsigned long pte;
|
unsigned long pte;
|
||||||
unsigned long j;
|
unsigned long j;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: idprom.c,v 1.22 1996/11/13 05:09:25 davem Exp $
|
/*
|
||||||
* idprom.c: Routines to load the idprom into kernel addresses and
|
* idprom.c: Routines to load the idprom into kernel addresses and
|
||||||
* interpret the data contained within.
|
* interpret the data contained within.
|
||||||
*
|
*
|
||||||
|
@ -25,7 +25,7 @@ static struct idprom idprom_buffer;
|
||||||
* of the Sparc CPU and have a meaningful IDPROM machtype value that we
|
* of the Sparc CPU and have a meaningful IDPROM machtype value that we
|
||||||
* know about. See asm-sparc/machines.h for empirical constants.
|
* know about. See asm-sparc/machines.h for empirical constants.
|
||||||
*/
|
*/
|
||||||
struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
|
static struct Sun_Machine_Models Sun_Machines[NUM_SUN_MACHINES] = {
|
||||||
/* First, Sun3's */
|
/* First, Sun3's */
|
||||||
{ .name = "Sun 3/160 Series", .id_machtype = (SM_SUN3 | SM_3_160) },
|
{ .name = "Sun 3/160 Series", .id_machtype = (SM_SUN3 | SM_3_160) },
|
||||||
{ .name = "Sun 3/50", .id_machtype = (SM_SUN3 | SM_3_50) },
|
{ .name = "Sun 3/50", .id_machtype = (SM_SUN3 | SM_3_50) },
|
||||||
|
|
|
@ -55,7 +55,7 @@ unsigned char pmeg_ctx[PMEGS_NUM];
|
||||||
|
|
||||||
/* pointers to the mm structs for each task in each
|
/* pointers to the mm structs for each task in each
|
||||||
context. 0xffffffff is a marker for kernel context */
|
context. 0xffffffff is a marker for kernel context */
|
||||||
struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {
|
static struct mm_struct *ctx_alloc[CONTEXTS_NUM] = {
|
||||||
[0] = (struct mm_struct *)0xffffffff
|
[0] = (struct mm_struct *)0xffffffff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
# $Id: Makefile,v 1.5 1995/11/25 00:59:48 davem Exp $
|
|
||||||
# Makefile for the Sun Boot PROM interface library under
|
# Makefile for the Sun Boot PROM interface library under
|
||||||
# Linux.
|
# Linux.
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: console.c,v 1.10 1996/12/18 06:46:54 tridge Exp $
|
/*
|
||||||
* console.c: Routines that deal with sending and receiving IO
|
* console.c: Routines that deal with sending and receiving IO
|
||||||
* to/from the current console device using the PROM.
|
* to/from the current console device using the PROM.
|
||||||
*
|
*
|
||||||
|
@ -104,8 +104,6 @@ prom_query_input_device()
|
||||||
return PROMDEV_ITTYB;
|
return PROMDEV_ITTYB;
|
||||||
}
|
}
|
||||||
return PROMDEV_I_UNK;
|
return PROMDEV_I_UNK;
|
||||||
case PROM_AP1000:
|
|
||||||
return PROMDEV_I_UNK;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -166,8 +164,6 @@ prom_query_output_device()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PROM_AP1000:
|
|
||||||
return PROMDEV_I_UNK;
|
|
||||||
};
|
};
|
||||||
return PROMDEV_O_UNK;
|
return PROMDEV_O_UNK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: init.c,v 1.9 1996/12/18 06:46:55 tridge Exp $
|
/*
|
||||||
* init.c: Initialize internal variables used by the PROM
|
* init.c: Initialize internal variables used by the PROM
|
||||||
* library functions.
|
* library functions.
|
||||||
*
|
*
|
||||||
|
@ -31,11 +31,6 @@ extern void prom_ranges_init(void);
|
||||||
|
|
||||||
void __init prom_init(struct linux_romvec *rp)
|
void __init prom_init(struct linux_romvec *rp)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_AP1000
|
|
||||||
extern struct linux_romvec *ap_prom_init(void);
|
|
||||||
rp = ap_prom_init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
romvec = rp;
|
romvec = rp;
|
||||||
#ifndef CONFIG_SUN3
|
#ifndef CONFIG_SUN3
|
||||||
switch(romvec->pv_romvers) {
|
switch(romvec->pv_romvers) {
|
||||||
|
@ -53,10 +48,6 @@ void __init prom_init(struct linux_romvec *rp)
|
||||||
prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n");
|
prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n");
|
||||||
prom_halt();
|
prom_halt();
|
||||||
break;
|
break;
|
||||||
case 42: /* why not :-) */
|
|
||||||
prom_vers = PROM_AP1000;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
prom_printf("PROMLIB: Bad PROM version %d\n",
|
prom_printf("PROMLIB: Bad PROM version %d\n",
|
||||||
romvec->pv_romvers);
|
romvec->pv_romvers);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: misc.c,v 1.15 1997/05/14 20:45:00 davem Exp $
|
/*
|
||||||
* misc.c: Miscellaneous prom functions that don't belong
|
* misc.c: Miscellaneous prom functions that don't belong
|
||||||
* anywhere else.
|
* anywhere else.
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: printf.c,v 1.5 1996/04/04 16:31:07 tridge Exp $
|
/*
|
||||||
* printf.c: Internal prom library printf facility.
|
* printf.c: Internal prom library printf facility.
|
||||||
*
|
*
|
||||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||||
|
@ -37,10 +37,6 @@ prom_printf(char *fmt, ...)
|
||||||
|
|
||||||
bptr = ppbuf;
|
bptr = ppbuf;
|
||||||
|
|
||||||
#ifdef CONFIG_AP1000
|
|
||||||
ap_write(1,bptr,strlen(bptr));
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef CONFIG_KGDB
|
#ifdef CONFIG_KGDB
|
||||||
if (kgdb_initialized) {
|
if (kgdb_initialized) {
|
||||||
printk("kgdb_initialized = %d\n", kgdb_initialized);
|
printk("kgdb_initialized = %d\n", kgdb_initialized);
|
||||||
|
@ -53,7 +49,6 @@ prom_printf(char *fmt, ...)
|
||||||
|
|
||||||
prom_putchar(ch);
|
prom_putchar(ch);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/*
|
|
||||||
* SBus helper functions
|
|
||||||
*
|
|
||||||
* Sun3 don't have a sbus, but many of the used devices are also
|
|
||||||
* used on Sparc machines with sbus. To avoid having a lot of
|
|
||||||
* duplicate code, we provide necessary glue stuff to make using
|
|
||||||
* of the sbus driver code possible.
|
|
||||||
*
|
|
||||||
* (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include <linux/compiler.h>
|
|
||||||
#include <linux/init.h>
|
|
||||||
|
|
||||||
int __init sbus_init(void)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *sparc_alloc_io (u32 address, void *virtual, int len, char *name,
|
|
||||||
u32 bus_type, int rdonly)
|
|
||||||
{
|
|
||||||
return (void *)address;
|
|
||||||
}
|
|
||||||
|
|
||||||
subsys_initcall(sbus_init);
|
|
|
@ -29,7 +29,7 @@ static inline void dvma_unmap_iommu(unsigned long a, int b)
|
||||||
extern void sun3_dvma_init(void);
|
extern void sun3_dvma_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
|
static unsigned long iommu_use[IOMMU_TOTAL_ENTRIES];
|
||||||
|
|
||||||
#define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
|
#define dvma_index(baddr) ((baddr - DVMA_START) >> DVMA_PAGE_SHIFT)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ void sun3_enable_interrupts(void)
|
||||||
sun3_enable_irq(0);
|
sun3_enable_irq(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int led_pattern[8] = {
|
static int led_pattern[8] = {
|
||||||
~(0x80), ~(0x01),
|
~(0x80), ~(0x01),
|
||||||
~(0x40), ~(0x02),
|
~(0x40), ~(0x02),
|
||||||
~(0x20), ~(0x04),
|
~(0x20), ~(0x04),
|
||||||
|
|
|
@ -330,6 +330,7 @@ config SGI_IP22
|
||||||
select SGI_HAS_DS1286
|
select SGI_HAS_DS1286
|
||||||
select SGI_HAS_I8042
|
select SGI_HAS_I8042
|
||||||
select SGI_HAS_INDYDOG
|
select SGI_HAS_INDYDOG
|
||||||
|
select SGI_HAS_HAL2
|
||||||
select SGI_HAS_SEEQ
|
select SGI_HAS_SEEQ
|
||||||
select SGI_HAS_WD93
|
select SGI_HAS_WD93
|
||||||
select SGI_HAS_ZILOG
|
select SGI_HAS_ZILOG
|
||||||
|
@ -386,7 +387,6 @@ config SGI_IP28
|
||||||
select SGI_HAS_I8042
|
select SGI_HAS_I8042
|
||||||
select SGI_HAS_INDYDOG
|
select SGI_HAS_INDYDOG
|
||||||
select SGI_HAS_HAL2
|
select SGI_HAS_HAL2
|
||||||
select SGI_HAS_HAL2
|
|
||||||
select SGI_HAS_SEEQ
|
select SGI_HAS_SEEQ
|
||||||
select SGI_HAS_WD93
|
select SGI_HAS_WD93
|
||||||
select SGI_HAS_ZILOG
|
select SGI_HAS_ZILOG
|
||||||
|
@ -558,6 +558,24 @@ config MACH_TX39XX
|
||||||
config MACH_TX49XX
|
config MACH_TX49XX
|
||||||
bool "Toshiba TX49 series based machines"
|
bool "Toshiba TX49 series based machines"
|
||||||
|
|
||||||
|
config MIKROTIK_RB532
|
||||||
|
bool "Mikrotik RB532 boards"
|
||||||
|
select CEVT_R4K
|
||||||
|
select CSRC_R4K
|
||||||
|
select DMA_NONCOHERENT
|
||||||
|
select GENERIC_HARDIRQS_NO__DO_IRQ
|
||||||
|
select HW_HAS_PCI
|
||||||
|
select IRQ_CPU
|
||||||
|
select SYS_HAS_CPU_MIPS32_R1
|
||||||
|
select SYS_SUPPORTS_32BIT_KERNEL
|
||||||
|
select SYS_SUPPORTS_LITTLE_ENDIAN
|
||||||
|
select SWAP_IO_SPACE
|
||||||
|
select BOOT_RAW
|
||||||
|
select GENERIC_GPIO
|
||||||
|
help
|
||||||
|
Support the Mikrotik(tm) RouterBoard 532 series,
|
||||||
|
based on the IDT RC32434 SoC.
|
||||||
|
|
||||||
config WR_PPMC
|
config WR_PPMC
|
||||||
bool "Wind River PPMC board"
|
bool "Wind River PPMC board"
|
||||||
select CEVT_R4K
|
select CEVT_R4K
|
||||||
|
@ -899,7 +917,7 @@ config BOOT_ELF32
|
||||||
|
|
||||||
config MIPS_L1_CACHE_SHIFT
|
config MIPS_L1_CACHE_SHIFT
|
||||||
int
|
int
|
||||||
default "4" if MACH_DECSTATION
|
default "4" if MACH_DECSTATION || MIKROTIK_RB532
|
||||||
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM
|
default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM
|
||||||
default "4" if PMC_MSP4200_EVAL
|
default "4" if PMC_MSP4200_EVAL
|
||||||
default "5"
|
default "5"
|
||||||
|
|
|
@ -559,6 +559,13 @@ load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
|
||||||
#
|
#
|
||||||
core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/
|
core-$(CONFIG_TOSHIBA_JMR3927) += arch/mips/txx9/jmr3927/
|
||||||
|
|
||||||
|
#
|
||||||
|
# Routerboard 532 board
|
||||||
|
#
|
||||||
|
core-$(CONFIG_MIKROTIK_RB532) += arch/mips/rb532/
|
||||||
|
cflags-$(CONFIG_MIKROTIK_RB532) += -Iinclude/asm-mips/mach-rc32434
|
||||||
|
load-$(CONFIG_MIKROTIK_RB532) += 0xffffffff80101000
|
||||||
|
|
||||||
#
|
#
|
||||||
# Toshiba RBTX4927 board or
|
# Toshiba RBTX4927 board or
|
||||||
# Toshiba RBTX4937 board
|
# Toshiba RBTX4937 board
|
||||||
|
|
|
@ -81,8 +81,8 @@ void __init plat_mem_setup(void)
|
||||||
|
|
||||||
set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
|
set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
|
||||||
|
|
||||||
/* I/O port resource must include LCD/buttons */
|
/* I/O port resource */
|
||||||
ioport_resource.end = 0x0fffffff;
|
ioport_resource.end = 0x01ffffff;
|
||||||
|
|
||||||
/* These resources have been reserved by VIA SuperI/O chip. */
|
/* These resources have been reserved by VIA SuperI/O chip. */
|
||||||
for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++)
|
for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -129,23 +129,6 @@ out:
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
asmlinkage int sys_truncate64(const char __user *path, unsigned int high,
|
|
||||||
unsigned int low)
|
|
||||||
{
|
|
||||||
if ((int)high < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
return sys_truncate(path, ((long) high << 32) | low);
|
|
||||||
}
|
|
||||||
|
|
||||||
asmlinkage int sys_ftruncate64(unsigned int fd, unsigned int high,
|
|
||||||
unsigned int low)
|
|
||||||
{
|
|
||||||
if ((int)high < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
return sys_ftruncate(fd, ((long) high << 32) | low);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sys_execve() executes a new program.
|
* sys_execve() executes a new program.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -354,7 +354,7 @@ einval: li v0, -EINVAL
|
||||||
sys sys_mkdir 2
|
sys sys_mkdir 2
|
||||||
sys sys_rmdir 1 /* 4040 */
|
sys sys_rmdir 1 /* 4040 */
|
||||||
sys sys_dup 1
|
sys sys_dup 1
|
||||||
sys sys_pipe 0
|
sys sysm_pipe 0
|
||||||
sys sys_times 1
|
sys sys_times 1
|
||||||
sys sys_ni_syscall 0
|
sys sys_ni_syscall 0
|
||||||
sys sys_brk 1 /* 4045 */
|
sys sys_brk 1 /* 4045 */
|
||||||
|
|
|
@ -219,7 +219,7 @@ sys_call_table:
|
||||||
PTR sys_readv
|
PTR sys_readv
|
||||||
PTR sys_writev
|
PTR sys_writev
|
||||||
PTR sys_access /* 5020 */
|
PTR sys_access /* 5020 */
|
||||||
PTR sys_pipe
|
PTR sysm_pipe
|
||||||
PTR sys_select
|
PTR sys_select
|
||||||
PTR sys_sched_yield
|
PTR sys_sched_yield
|
||||||
PTR sys_mremap
|
PTR sys_mremap
|
||||||
|
|
|
@ -141,7 +141,7 @@ EXPORT(sysn32_call_table)
|
||||||
PTR compat_sys_readv
|
PTR compat_sys_readv
|
||||||
PTR compat_sys_writev
|
PTR compat_sys_writev
|
||||||
PTR sys_access /* 6020 */
|
PTR sys_access /* 6020 */
|
||||||
PTR sys_pipe
|
PTR sysm_pipe
|
||||||
PTR compat_sys_select
|
PTR compat_sys_select
|
||||||
PTR sys_sched_yield
|
PTR sys_sched_yield
|
||||||
PTR sys_mremap
|
PTR sys_mremap
|
||||||
|
|
|
@ -247,7 +247,7 @@ sys_call_table:
|
||||||
PTR sys_mkdir
|
PTR sys_mkdir
|
||||||
PTR sys_rmdir /* 4040 */
|
PTR sys_rmdir /* 4040 */
|
||||||
PTR sys_dup
|
PTR sys_dup
|
||||||
PTR sys_pipe
|
PTR sysm_pipe
|
||||||
PTR compat_sys_times
|
PTR compat_sys_times
|
||||||
PTR sys_ni_syscall
|
PTR sys_ni_syscall
|
||||||
PTR sys_brk /* 4045 */
|
PTR sys_brk /* 4045 */
|
||||||
|
|
|
@ -40,7 +40,14 @@
|
||||||
#include <asm/sysmips.h>
|
#include <asm/sysmips.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
asmlinkage int sys_pipe(nabi_no_regargs volatile struct pt_regs regs)
|
/*
|
||||||
|
* For historic reasons the pipe(2) syscall on MIPS has an unusual calling
|
||||||
|
* convention. It returns results in registers $v0 / $v1 which means there
|
||||||
|
* is no need for it to do verify the validity of a userspace pointer
|
||||||
|
* argument. Historically that used to be expensive in Linux. These days
|
||||||
|
* the performance advantage is negligible.
|
||||||
|
*/
|
||||||
|
asmlinkage int sysm_pipe(nabi_no_regargs volatile struct pt_regs regs)
|
||||||
{
|
{
|
||||||
int fd[2];
|
int fd[2];
|
||||||
int error, res;
|
int error, res;
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <asm/signal.h>
|
#include <asm/signal.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
|
||||||
|
#include <asm/fpu.h>
|
||||||
#include <asm/fpu_emulator.h>
|
#include <asm/fpu_emulator.h>
|
||||||
|
|
||||||
#define SIGNALLING_NAN 0x7ff800007ff80000LL
|
#define SIGNALLING_NAN 0x7ff800007ff80000LL
|
||||||
|
|
|
@ -49,3 +49,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o
|
||||||
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
|
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
|
||||||
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
|
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
|
||||||
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
|
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
|
||||||
|
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2001 MontaVista Software Inc.
|
||||||
|
* Author: MontaVista Software, Inc.
|
||||||
|
* stevel@mvista.com or source@mvista.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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
|
||||||
|
static int __devinitdata irq_map[2][12] = {
|
||||||
|
{0, 0, 2, 3, 2, 3, 0, 0, 0, 0, 0, 1},
|
||||||
|
{0, 0, 1, 3, 0, 2, 1, 3, 0, 2, 1, 3}
|
||||||
|
};
|
||||||
|
|
||||||
|
int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||||
|
{
|
||||||
|
int irq = 0;
|
||||||
|
|
||||||
|
if (dev->bus->number < 2 && PCI_SLOT(dev->devfn) < 12)
|
||||||
|
irq = irq_map[dev->bus->number][PCI_SLOT(dev->devfn)];
|
||||||
|
|
||||||
|
return irq + GROUP4_IRQ_BASE + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rc32434_pci_early_fixup(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) {
|
||||||
|
/* disable prefetched memory range */
|
||||||
|
pci_write_config_word(dev, PCI_PREF_MEMORY_LIMIT, 0);
|
||||||
|
pci_write_config_word(dev, PCI_PREF_MEMORY_BASE, 0x10);
|
||||||
|
|
||||||
|
pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The fixup applies to both the IDT and VIA devices present on the board
|
||||||
|
*/
|
||||||
|
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, rc32434_pci_early_fixup);
|
||||||
|
|
||||||
|
/* Do platform specific device initialization at pci_enable_device() time */
|
||||||
|
int pcibios_plat_dev_init(struct pci_dev *dev)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,207 @@
|
||||||
|
/*
|
||||||
|
* BRIEF MODULE DESCRIPTION
|
||||||
|
* pci_ops for IDT EB434 board
|
||||||
|
*
|
||||||
|
* Copyright 2004 IDT Inc. (rischelp@idt.com)
|
||||||
|
* Copyright 2006 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
#include <asm/cpu.h>
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
#include <asm/mach-rc32434/pci.h>
|
||||||
|
|
||||||
|
#define PCI_ACCESS_READ 0
|
||||||
|
#define PCI_ACCESS_WRITE 1
|
||||||
|
|
||||||
|
|
||||||
|
#define PCI_CFG_SET(bus, slot, func, off) \
|
||||||
|
(rc32434_pci->pcicfga = (0x80000000 | \
|
||||||
|
((bus) << 16) | ((slot)<<11) | \
|
||||||
|
((func)<<8) | (off)))
|
||||||
|
|
||||||
|
static inline int config_access(unsigned char access_type,
|
||||||
|
struct pci_bus *bus, unsigned int devfn,
|
||||||
|
unsigned char where, u32 *data)
|
||||||
|
{
|
||||||
|
unsigned int slot = PCI_SLOT(devfn);
|
||||||
|
u8 func = PCI_FUNC(devfn);
|
||||||
|
|
||||||
|
/* Setup address */
|
||||||
|
PCI_CFG_SET(bus->number, slot, func, where);
|
||||||
|
rc32434_sync();
|
||||||
|
|
||||||
|
if (access_type == PCI_ACCESS_WRITE)
|
||||||
|
rc32434_pci->pcicfgd = *data;
|
||||||
|
else
|
||||||
|
*data = rc32434_pci->pcicfgd;
|
||||||
|
|
||||||
|
rc32434_sync();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We can't address 8 and 16 bit words directly. Instead we have to
|
||||||
|
* read/write a 32bit word and mask/modify the data we actually want.
|
||||||
|
*/
|
||||||
|
static int read_config_byte(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int where, u8 *val)
|
||||||
|
{
|
||||||
|
u32 data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
|
||||||
|
*val = (data >> ((where & 3) << 3)) & 0xff;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_config_word(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int where, u16 *val)
|
||||||
|
{
|
||||||
|
u32 data;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, &data);
|
||||||
|
*val = (data >> ((where & 3) << 3)) & 0xffff;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_config_dword(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int where, u32 *val)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
int delay = 1;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't scan too far, else there will be errors with plugged in
|
||||||
|
* daughterboard (rb564).
|
||||||
|
*/
|
||||||
|
if (bus->number == 0 && PCI_SLOT(devfn) > 21)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
ret = config_access(PCI_ACCESS_READ, bus, devfn, where, val);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Certain devices react delayed at device scan time, this
|
||||||
|
* gives them time to settle
|
||||||
|
*/
|
||||||
|
if (where == PCI_VENDOR_ID) {
|
||||||
|
if (ret == 0xffffffff || ret == 0x00000000 ||
|
||||||
|
ret == 0x0000ffff || ret == 0xffff0000) {
|
||||||
|
if (delay > 4)
|
||||||
|
return 0;
|
||||||
|
delay *= 2;
|
||||||
|
msleep(delay);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_config_byte(struct pci_bus *bus, unsigned int devfn, int where,
|
||||||
|
u8 val)
|
||||||
|
{
|
||||||
|
u32 data = 0;
|
||||||
|
|
||||||
|
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data = (data & ~(0xff << ((where & 3) << 3))) |
|
||||||
|
(val << ((where & 3) << 3));
|
||||||
|
|
||||||
|
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_config_word(struct pci_bus *bus, unsigned int devfn, int where,
|
||||||
|
u16 val)
|
||||||
|
{
|
||||||
|
u32 data = 0;
|
||||||
|
|
||||||
|
if (config_access(PCI_ACCESS_READ, bus, devfn, where, &data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
data = (data & ~(0xffff << ((where & 3) << 3))) |
|
||||||
|
(val << ((where & 3) << 3));
|
||||||
|
|
||||||
|
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &data))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
write_config_dword(struct pci_bus *bus, unsigned int devfn, int where,
|
||||||
|
u32 val)
|
||||||
|
{
|
||||||
|
if (config_access(PCI_ACCESS_WRITE, bus, devfn, where, &val))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int where, int size, u32 *val)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
return read_config_byte(bus, devfn, where, (u8 *) val);
|
||||||
|
case 2:
|
||||||
|
return read_config_word(bus, devfn, where, (u16 *) val);
|
||||||
|
default:
|
||||||
|
return read_config_dword(bus, devfn, where, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pci_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int where, int size, u32 val)
|
||||||
|
{
|
||||||
|
switch (size) {
|
||||||
|
case 1:
|
||||||
|
return write_config_byte(bus, devfn, where, (u8) val);
|
||||||
|
case 2:
|
||||||
|
return write_config_word(bus, devfn, where, (u16) val);
|
||||||
|
default:
|
||||||
|
return write_config_dword(bus, devfn, where, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct pci_ops rc32434_pci_ops = {
|
||||||
|
.read = pci_config_read,
|
||||||
|
.write = pci_config_write,
|
||||||
|
};
|
|
@ -0,0 +1,221 @@
|
||||||
|
/*
|
||||||
|
* BRIEF MODULE DESCRIPTION
|
||||||
|
* PCI initialization for IDT EB434 board
|
||||||
|
*
|
||||||
|
* Copyright 2004 IDT Inc. (rischelp@idt.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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
#include <asm/mach-rc32434/pci.h>
|
||||||
|
|
||||||
|
#define PCI_ACCESS_READ 0
|
||||||
|
#define PCI_ACCESS_WRITE 1
|
||||||
|
|
||||||
|
/* define an unsigned array for the PCI registers */
|
||||||
|
static unsigned int korina_cnfg_regs[25] = {
|
||||||
|
KORINA_CNFG1, KORINA_CNFG2, KORINA_CNFG3, KORINA_CNFG4,
|
||||||
|
KORINA_CNFG5, KORINA_CNFG6, KORINA_CNFG7, KORINA_CNFG8,
|
||||||
|
KORINA_CNFG9, KORINA_CNFG10, KORINA_CNFG11, KORINA_CNFG12,
|
||||||
|
KORINA_CNFG13, KORINA_CNFG14, KORINA_CNFG15, KORINA_CNFG16,
|
||||||
|
KORINA_CNFG17, KORINA_CNFG18, KORINA_CNFG19, KORINA_CNFG20,
|
||||||
|
KORINA_CNFG21, KORINA_CNFG22, KORINA_CNFG23, KORINA_CNFG24
|
||||||
|
};
|
||||||
|
static struct resource rc32434_res_pci_mem1;
|
||||||
|
static struct resource rc32434_res_pci_mem2;
|
||||||
|
|
||||||
|
static struct resource rc32434_res_pci_mem1 = {
|
||||||
|
.name = "PCI MEM1",
|
||||||
|
.start = 0x50000000,
|
||||||
|
.end = 0x5FFFFFFF,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
.parent = &rc32434_res_pci_mem1,
|
||||||
|
.sibling = NULL,
|
||||||
|
.child = &rc32434_res_pci_mem2
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource rc32434_res_pci_mem2 = {
|
||||||
|
.name = "PCI Mem2",
|
||||||
|
.start = 0x60000000,
|
||||||
|
.end = 0x6FFFFFFF,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
.parent = &rc32434_res_pci_mem1,
|
||||||
|
.sibling = NULL,
|
||||||
|
.child = NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource rc32434_res_pci_io1 = {
|
||||||
|
.name = "PCI I/O1",
|
||||||
|
.start = 0x18800000,
|
||||||
|
.end = 0x188FFFFF,
|
||||||
|
.flags = IORESOURCE_IO,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct pci_ops rc32434_pci_ops;
|
||||||
|
|
||||||
|
#define PCI_MEM1_START PCI_ADDR_START
|
||||||
|
#define PCI_MEM1_END (PCI_ADDR_START + CPUTOPCI_MEM_WIN - 1)
|
||||||
|
#define PCI_MEM2_START (PCI_ADDR_START + CPUTOPCI_MEM_WIN)
|
||||||
|
#define PCI_MEM2_END (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) - 1)
|
||||||
|
#define PCI_IO1_START (PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN))
|
||||||
|
#define PCI_IO1_END \
|
||||||
|
(PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN - 1)
|
||||||
|
#define PCI_IO2_START \
|
||||||
|
(PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + CPUTOPCI_IO_WIN)
|
||||||
|
#define PCI_IO2_END \
|
||||||
|
(PCI_ADDR_START + (2 * CPUTOPCI_MEM_WIN) + (2 * CPUTOPCI_IO_WIN) - 1)
|
||||||
|
|
||||||
|
struct pci_controller rc32434_controller2;
|
||||||
|
|
||||||
|
struct pci_controller rc32434_controller = {
|
||||||
|
.pci_ops = &rc32434_pci_ops,
|
||||||
|
.mem_resource = &rc32434_res_pci_mem1,
|
||||||
|
.io_resource = &rc32434_res_pci_io1,
|
||||||
|
.mem_offset = 0,
|
||||||
|
.io_offset = 0,
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __MIPSEB__
|
||||||
|
#define PCI_ENDIAN_FLAG PCILBAC_sb_m
|
||||||
|
#else
|
||||||
|
#define PCI_ENDIAN_FLAG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int __init rc32434_pcibridge_init(void)
|
||||||
|
{
|
||||||
|
unsigned int pcicvalue, pcicdata = 0;
|
||||||
|
unsigned int dummyread, pcicntlval;
|
||||||
|
int loopCount;
|
||||||
|
unsigned int pci_config_addr;
|
||||||
|
|
||||||
|
pcicvalue = rc32434_pci->pcic;
|
||||||
|
pcicvalue = (pcicvalue >> PCIM_SHFT) & PCIM_BIT_LEN;
|
||||||
|
if (!((pcicvalue == PCIM_H_EA) ||
|
||||||
|
(pcicvalue == PCIM_H_IA_FIX) ||
|
||||||
|
(pcicvalue == PCIM_H_IA_RR))) {
|
||||||
|
pr_err(KERN_ERR "PCI init error!!!\n");
|
||||||
|
/* Not in Host Mode, return ERROR */
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
/* Enables the Idle Grant mode, Arbiter Parking */
|
||||||
|
pcicdata |= (PCI_CTL_IGM | PCI_CTL_EAP | PCI_CTL_EN);
|
||||||
|
rc32434_pci->pcic = pcicdata; /* Enable the PCI bus Interface */
|
||||||
|
/* Zero out the PCI status & PCI Status Mask */
|
||||||
|
for (;;) {
|
||||||
|
pcicdata = rc32434_pci->pcis;
|
||||||
|
if (!(pcicdata & PCI_STAT_RIP))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc32434_pci->pcis = 0;
|
||||||
|
rc32434_pci->pcism = 0xFFFFFFFF;
|
||||||
|
/* Zero out the PCI decoupled registers */
|
||||||
|
rc32434_pci->pcidac = 0; /*
|
||||||
|
* disable PCI decoupled accesses at
|
||||||
|
* initialization
|
||||||
|
*/
|
||||||
|
rc32434_pci->pcidas = 0; /* clear the status */
|
||||||
|
rc32434_pci->pcidasm = 0x0000007F; /* Mask all the interrupts */
|
||||||
|
/* Mask PCI Messaging Interrupts */
|
||||||
|
rc32434_pci_msg->pciiic = 0;
|
||||||
|
rc32434_pci_msg->pciiim = 0xFFFFFFFF;
|
||||||
|
rc32434_pci_msg->pciioic = 0;
|
||||||
|
rc32434_pci_msg->pciioim = 0;
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup PCILB0 as Memory Window */
|
||||||
|
rc32434_pci->pcilba[0].address = (unsigned int) (PCI_ADDR_START);
|
||||||
|
|
||||||
|
/* setup the PCI map address as same as the local address */
|
||||||
|
|
||||||
|
rc32434_pci->pcilba[0].mapping = (unsigned int) (PCI_ADDR_START);
|
||||||
|
|
||||||
|
|
||||||
|
/* Setup PCILBA1 as MEM */
|
||||||
|
rc32434_pci->pcilba[0].control =
|
||||||
|
(((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
|
||||||
|
dummyread = rc32434_pci->pcilba[0].control; /* flush the CPU write Buffers */
|
||||||
|
rc32434_pci->pcilba[1].address = 0x60000000;
|
||||||
|
rc32434_pci->pcilba[1].mapping = 0x60000000;
|
||||||
|
|
||||||
|
/* setup PCILBA2 as IO Window */
|
||||||
|
rc32434_pci->pcilba[1].control =
|
||||||
|
(((SIZE_256MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
|
||||||
|
dummyread = rc32434_pci->pcilba[1].control; /* flush the CPU write Buffers */
|
||||||
|
rc32434_pci->pcilba[2].address = 0x18C00000;
|
||||||
|
rc32434_pci->pcilba[2].mapping = 0x18FFFFFF;
|
||||||
|
|
||||||
|
/* setup PCILBA2 as IO Window */
|
||||||
|
rc32434_pci->pcilba[2].control =
|
||||||
|
(((SIZE_4MB & 0x1f) << PCI_LBAC_SIZE_BIT) | PCI_ENDIAN_FLAG);
|
||||||
|
dummyread = rc32434_pci->pcilba[2].control; /* flush the CPU write Buffers */
|
||||||
|
|
||||||
|
/* Setup PCILBA3 as IO Window */
|
||||||
|
rc32434_pci->pcilba[3].address = 0x18800000;
|
||||||
|
rc32434_pci->pcilba[3].mapping = 0x18800000;
|
||||||
|
rc32434_pci->pcilba[3].control =
|
||||||
|
((((SIZE_1MB & 0x1ff) << PCI_LBAC_SIZE_BIT) | PCI_LBAC_MSI) |
|
||||||
|
PCI_ENDIAN_FLAG);
|
||||||
|
dummyread = rc32434_pci->pcilba[3].control; /* flush the CPU write Buffers */
|
||||||
|
|
||||||
|
pci_config_addr = (unsigned int) (0x80000004);
|
||||||
|
for (loopCount = 0; loopCount < 24; loopCount++) {
|
||||||
|
rc32434_pci->pcicfga = pci_config_addr;
|
||||||
|
dummyread = rc32434_pci->pcicfga;
|
||||||
|
rc32434_pci->pcicfgd = korina_cnfg_regs[loopCount];
|
||||||
|
dummyread = rc32434_pci->pcicfgd;
|
||||||
|
pci_config_addr += 4;
|
||||||
|
}
|
||||||
|
rc32434_pci->pcitc =
|
||||||
|
(unsigned int) ((PCITC_RTIMER_VAL & 0xff) << PCI_TC_RTIMER_BIT) |
|
||||||
|
((PCITC_DTIMER_VAL & 0xff) << PCI_TC_DTIMER_BIT);
|
||||||
|
|
||||||
|
pcicntlval = rc32434_pci->pcic;
|
||||||
|
pcicntlval &= ~PCI_CTL_TNR;
|
||||||
|
rc32434_pci->pcic = pcicntlval;
|
||||||
|
pcicntlval = rc32434_pci->pcic;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init rc32434_pci_init(void)
|
||||||
|
{
|
||||||
|
pr_info("PCI: Initializing PCI\n");
|
||||||
|
|
||||||
|
ioport_resource.start = rc32434_res_pci_io1.start;
|
||||||
|
ioport_resource.end = rc32434_res_pci_io1.end;
|
||||||
|
|
||||||
|
rc32434_pcibridge_init();
|
||||||
|
|
||||||
|
register_pci_controller(&rc32434_controller);
|
||||||
|
rc32434_sync();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(rc32434_pci_init);
|
|
@ -204,7 +204,7 @@ static int pcibios_enable_resources(struct pci_dev *dev, int mask)
|
||||||
* If we set up a device for bus mastering, we need to check the latency
|
* If we set up a device for bus mastering, we need to check the latency
|
||||||
* timer as certain crappy BIOSes forget to set it properly.
|
* timer as certain crappy BIOSes forget to set it properly.
|
||||||
*/
|
*/
|
||||||
unsigned int pcibios_max_latency = 255;
|
static unsigned int pcibios_max_latency = 255;
|
||||||
|
|
||||||
void pcibios_set_master(struct pci_dev *dev)
|
void pcibios_set_master(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
#
|
||||||
|
# Makefile for the RB532 board specific parts of the kernel
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-y += irq.o time.o setup.o serial.o prom.o gpio.o devices.o
|
||||||
|
|
||||||
|
EXTRA_CFLAGS += -Werror
|
|
@ -0,0 +1,331 @@
|
||||||
|
/*
|
||||||
|
* RouterBoard 500 Platform devices
|
||||||
|
*
|
||||||
|
* Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
|
||||||
|
* Copyright (C) 2007 Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/ctype.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/mtd/nand.h>
|
||||||
|
#include <linux/mtd/mtd.h>
|
||||||
|
#include <linux/mtd/partitions.h>
|
||||||
|
#include <linux/gpio_keys.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
#include <asm/mach-rc32434/dma.h>
|
||||||
|
#include <asm/mach-rc32434/dma_v.h>
|
||||||
|
#include <asm/mach-rc32434/eth.h>
|
||||||
|
#include <asm/mach-rc32434/rb.h>
|
||||||
|
#include <asm/mach-rc32434/integ.h>
|
||||||
|
#include <asm/mach-rc32434/gpio.h>
|
||||||
|
|
||||||
|
#define ETH0_DMA_RX_IRQ (GROUP1_IRQ_BASE + 0)
|
||||||
|
#define ETH0_DMA_TX_IRQ (GROUP1_IRQ_BASE + 1)
|
||||||
|
#define ETH0_RX_OVR_IRQ (GROUP3_IRQ_BASE + 9)
|
||||||
|
#define ETH0_TX_UND_IRQ (GROUP3_IRQ_BASE + 10)
|
||||||
|
|
||||||
|
#define ETH0_RX_DMA_ADDR (DMA0_BASE_ADDR + 0 * DMA_CHAN_OFFSET)
|
||||||
|
#define ETH0_TX_DMA_ADDR (DMA0_BASE_ADDR + 1 * DMA_CHAN_OFFSET)
|
||||||
|
|
||||||
|
/* NAND definitions */
|
||||||
|
#define GPIO_RDY (1 << 0x08)
|
||||||
|
#define GPIO_WPX (1 << 0x09)
|
||||||
|
#define GPIO_ALE (1 << 0x0a)
|
||||||
|
#define GPIO_CLE (1 << 0x0b)
|
||||||
|
|
||||||
|
extern char *board_type;
|
||||||
|
|
||||||
|
static struct resource korina_dev0_res[] = {
|
||||||
|
{
|
||||||
|
.name = "korina_regs",
|
||||||
|
.start = ETH0_BASE_ADDR,
|
||||||
|
.end = ETH0_BASE_ADDR + sizeof(struct eth_regs),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}, {
|
||||||
|
.name = "korina_rx",
|
||||||
|
.start = ETH0_DMA_RX_IRQ,
|
||||||
|
.end = ETH0_DMA_RX_IRQ,
|
||||||
|
.flags = IORESOURCE_IRQ
|
||||||
|
}, {
|
||||||
|
.name = "korina_tx",
|
||||||
|
.start = ETH0_DMA_TX_IRQ,
|
||||||
|
.end = ETH0_DMA_TX_IRQ,
|
||||||
|
.flags = IORESOURCE_IRQ
|
||||||
|
}, {
|
||||||
|
.name = "korina_ovr",
|
||||||
|
.start = ETH0_RX_OVR_IRQ,
|
||||||
|
.end = ETH0_RX_OVR_IRQ,
|
||||||
|
.flags = IORESOURCE_IRQ
|
||||||
|
}, {
|
||||||
|
.name = "korina_und",
|
||||||
|
.start = ETH0_TX_UND_IRQ,
|
||||||
|
.end = ETH0_TX_UND_IRQ,
|
||||||
|
.flags = IORESOURCE_IRQ
|
||||||
|
}, {
|
||||||
|
.name = "korina_dma_rx",
|
||||||
|
.start = ETH0_RX_DMA_ADDR,
|
||||||
|
.end = ETH0_RX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}, {
|
||||||
|
.name = "korina_dma_tx",
|
||||||
|
.start = ETH0_TX_DMA_ADDR,
|
||||||
|
.end = ETH0_TX_DMA_ADDR + DMA_CHAN_OFFSET - 1,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct korina_device korina_dev0_data = {
|
||||||
|
.name = "korina0",
|
||||||
|
.mac = {0xde, 0xca, 0xff, 0xc0, 0xff, 0xee}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device korina_dev0 = {
|
||||||
|
.id = 0,
|
||||||
|
.name = "korina",
|
||||||
|
.dev.platform_data = &korina_dev0_data,
|
||||||
|
.resource = korina_dev0_res,
|
||||||
|
.num_resources = ARRAY_SIZE(korina_dev0_res),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CF_GPIO_NUM 13
|
||||||
|
|
||||||
|
static struct resource cf_slot0_res[] = {
|
||||||
|
{
|
||||||
|
.name = "cf_membase",
|
||||||
|
.flags = IORESOURCE_MEM
|
||||||
|
}, {
|
||||||
|
.name = "cf_irq",
|
||||||
|
.start = (8 + 4 * 32 + CF_GPIO_NUM), /* 149 */
|
||||||
|
.end = (8 + 4 * 32 + CF_GPIO_NUM),
|
||||||
|
.flags = IORESOURCE_IRQ
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct cf_device cf_slot0_data = {
|
||||||
|
.gpio_pin = 13
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device cf_slot0 = {
|
||||||
|
.id = 0,
|
||||||
|
.name = "pata-rb532-cf",
|
||||||
|
.dev.platform_data = &cf_slot0_data,
|
||||||
|
.resource = cf_slot0_res,
|
||||||
|
.num_resources = ARRAY_SIZE(cf_slot0_res),
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Resources and device for NAND */
|
||||||
|
static int rb532_dev_ready(struct mtd_info *mtd)
|
||||||
|
{
|
||||||
|
return readl(IDT434_REG_BASE + GPIOD) & GPIO_RDY;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rb532_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl)
|
||||||
|
{
|
||||||
|
struct nand_chip *chip = mtd->priv;
|
||||||
|
unsigned char orbits, nandbits;
|
||||||
|
|
||||||
|
if (ctrl & NAND_CTRL_CHANGE) {
|
||||||
|
orbits = (ctrl & NAND_CLE) << 1;
|
||||||
|
orbits |= (ctrl & NAND_ALE) >> 1;
|
||||||
|
|
||||||
|
nandbits = (~ctrl & NAND_CLE) << 1;
|
||||||
|
nandbits |= (~ctrl & NAND_ALE) >> 1;
|
||||||
|
|
||||||
|
set_latch_u5(orbits, nandbits);
|
||||||
|
}
|
||||||
|
if (cmd != NAND_CMD_NONE)
|
||||||
|
writeb(cmd, chip->IO_ADDR_W);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct resource nand_slot0_res[] = {
|
||||||
|
[0] = {
|
||||||
|
.name = "nand_membase",
|
||||||
|
.flags = IORESOURCE_MEM
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_nand_data rb532_nand_data = {
|
||||||
|
.ctrl.dev_ready = rb532_dev_ready,
|
||||||
|
.ctrl.cmd_ctrl = rb532_cmd_ctrl,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device nand_slot0 = {
|
||||||
|
.name = "gen_nand",
|
||||||
|
.id = -1,
|
||||||
|
.resource = nand_slot0_res,
|
||||||
|
.num_resources = ARRAY_SIZE(nand_slot0_res),
|
||||||
|
.dev.platform_data = &rb532_nand_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct mtd_partition rb532_partition_info[] = {
|
||||||
|
{
|
||||||
|
.name = "Routerboard NAND boot",
|
||||||
|
.offset = 0,
|
||||||
|
.size = 4 * 1024 * 1024,
|
||||||
|
}, {
|
||||||
|
.name = "rootfs",
|
||||||
|
.offset = MTDPART_OFS_NXTBLK,
|
||||||
|
.size = MTDPART_SIZ_FULL,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device rb532_led = {
|
||||||
|
.name = "rb532-led",
|
||||||
|
.id = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_keys_button rb532_gpio_btn[] = {
|
||||||
|
{
|
||||||
|
.gpio = 1,
|
||||||
|
.code = BTN_0,
|
||||||
|
.desc = "S1",
|
||||||
|
.active_low = 1,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_keys_platform_data rb532_gpio_btn_data = {
|
||||||
|
.buttons = rb532_gpio_btn,
|
||||||
|
.nbuttons = ARRAY_SIZE(rb532_gpio_btn),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device rb532_button = {
|
||||||
|
.name = "gpio-keys",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &rb532_gpio_btn_data,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource rb532_wdt_res[] = {
|
||||||
|
{
|
||||||
|
.name = "rb532_wdt_res",
|
||||||
|
.start = INTEG0_BASE_ADDR,
|
||||||
|
.end = INTEG0_BASE_ADDR + sizeof(struct integ),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device rb532_wdt = {
|
||||||
|
.name = "rc32434_wdt",
|
||||||
|
.id = -1,
|
||||||
|
.resource = rb532_wdt_res,
|
||||||
|
.num_resources = ARRAY_SIZE(rb532_wdt_res),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device *rb532_devs[] = {
|
||||||
|
&korina_dev0,
|
||||||
|
&nand_slot0,
|
||||||
|
&cf_slot0,
|
||||||
|
&rb532_led,
|
||||||
|
&rb532_button,
|
||||||
|
&rb532_wdt
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init parse_mac_addr(char *macstr)
|
||||||
|
{
|
||||||
|
int i, j;
|
||||||
|
unsigned char result, value;
|
||||||
|
|
||||||
|
for (i = 0; i < 6; i++) {
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
if (i != 5 && *(macstr + 2) != ':')
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (j = 0; j < 2; j++) {
|
||||||
|
if (isxdigit(*macstr)
|
||||||
|
&& (value =
|
||||||
|
isdigit(*macstr) ? *macstr -
|
||||||
|
'0' : toupper(*macstr) - 'A' + 10) < 16) {
|
||||||
|
result = result * 16 + value;
|
||||||
|
macstr++;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
macstr++;
|
||||||
|
korina_dev0_data.mac[i] = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* DEVICE CONTROLLER 1 */
|
||||||
|
#define CFG_DC_DEV1 ((void *)0xb8010010)
|
||||||
|
#define CFG_DC_DEV2 ((void *)0xb8010020)
|
||||||
|
#define CFG_DC_DEVBASE 0x0
|
||||||
|
#define CFG_DC_DEVMASK 0x4
|
||||||
|
#define CFG_DC_DEVC 0x8
|
||||||
|
#define CFG_DC_DEVTC 0xC
|
||||||
|
|
||||||
|
/* NAND definitions */
|
||||||
|
#define NAND_CHIP_DELAY 25
|
||||||
|
|
||||||
|
static void __init rb532_nand_setup(void)
|
||||||
|
{
|
||||||
|
switch (mips_machtype) {
|
||||||
|
case MACH_MIKROTIK_RB532A:
|
||||||
|
set_latch_u5(LO_FOFF | LO_CEX,
|
||||||
|
LO_ULED | LO_ALE | LO_CLE | LO_WPX);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
set_latch_u5(LO_WPX | LO_FOFF | LO_CEX,
|
||||||
|
LO_ULED | LO_ALE | LO_CLE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setup NAND specific settings */
|
||||||
|
rb532_nand_data.chip.nr_chips = 1;
|
||||||
|
rb532_nand_data.chip.nr_partitions = ARRAY_SIZE(rb532_partition_info);
|
||||||
|
rb532_nand_data.chip.partitions = rb532_partition_info;
|
||||||
|
rb532_nand_data.chip.chip_delay = NAND_CHIP_DELAY;
|
||||||
|
rb532_nand_data.chip.options = NAND_NO_AUTOINCR;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int __init plat_setup_devices(void)
|
||||||
|
{
|
||||||
|
/* Look for the CF card reader */
|
||||||
|
if (!readl(CFG_DC_DEV1 + CFG_DC_DEVMASK))
|
||||||
|
rb532_devs[1] = NULL;
|
||||||
|
else {
|
||||||
|
cf_slot0_res[0].start =
|
||||||
|
readl(CFG_DC_DEV1 + CFG_DC_DEVBASE);
|
||||||
|
cf_slot0_res[0].end = cf_slot0_res[0].start + 0x1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read the NAND resources from the device controller */
|
||||||
|
nand_slot0_res[0].start = readl(CFG_DC_DEV2 + CFG_DC_DEVBASE);
|
||||||
|
nand_slot0_res[0].end = nand_slot0_res[0].start + 0x1000;
|
||||||
|
|
||||||
|
/* Initialise the NAND device */
|
||||||
|
rb532_nand_setup();
|
||||||
|
|
||||||
|
return platform_add_devices(rb532_devs, ARRAY_SIZE(rb532_devs));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init setup_kmac(char *s)
|
||||||
|
{
|
||||||
|
printk(KERN_INFO "korina mac = %s\n", s);
|
||||||
|
parse_mac_addr(s);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
__setup("kmac=", setup_kmac);
|
||||||
|
|
||||||
|
arch_initcall(plat_setup_devices);
|
|
@ -0,0 +1,220 @@
|
||||||
|
/*
|
||||||
|
* Miscellaneous functions for IDT EB434 board
|
||||||
|
*
|
||||||
|
* Copyright 2004 IDT Inc. (rischelp@idt.com)
|
||||||
|
* Copyright 2006 Phil Sutter <n0-1@freewrt.org>
|
||||||
|
* Copyright 2007 Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
|
||||||
|
#include <asm/addrspace.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rb.h>
|
||||||
|
|
||||||
|
struct rb532_gpio_reg __iomem *rb532_gpio_reg0;
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_reg0);
|
||||||
|
|
||||||
|
struct mpmc_device dev3;
|
||||||
|
|
||||||
|
static struct resource rb532_gpio_reg0_res[] = {
|
||||||
|
{
|
||||||
|
.name = "gpio_reg0",
|
||||||
|
.start = (u32)(IDT434_REG_BASE + GPIOBASE),
|
||||||
|
.end = (u32)(IDT434_REG_BASE + GPIOBASE + sizeof(struct rb532_gpio_reg)),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct resource rb532_dev3_ctl_res[] = {
|
||||||
|
{
|
||||||
|
.name = "dev3_ctl",
|
||||||
|
.start = (u32)(IDT434_REG_BASE + DEV3BASE),
|
||||||
|
.end = (u32)(IDT434_REG_BASE + DEV3BASE + sizeof(struct dev_reg)),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void set_434_reg(unsigned reg_offs, unsigned bit, unsigned len, unsigned val)
|
||||||
|
{
|
||||||
|
unsigned flags, data;
|
||||||
|
unsigned i = 0;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev3.lock, flags);
|
||||||
|
|
||||||
|
data = *(volatile unsigned *) (IDT434_REG_BASE + reg_offs);
|
||||||
|
for (i = 0; i != len; ++i) {
|
||||||
|
if (val & (1 << i))
|
||||||
|
data |= (1 << (i + bit));
|
||||||
|
else
|
||||||
|
data &= ~(1 << (i + bit));
|
||||||
|
}
|
||||||
|
writel(data, (IDT434_REG_BASE + reg_offs));
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev3.lock, flags);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(set_434_reg);
|
||||||
|
|
||||||
|
unsigned get_434_reg(unsigned reg_offs)
|
||||||
|
{
|
||||||
|
return readl(IDT434_REG_BASE + reg_offs);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(get_434_reg);
|
||||||
|
|
||||||
|
void set_latch_u5(unsigned char or_mask, unsigned char nand_mask)
|
||||||
|
{
|
||||||
|
unsigned flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dev3.lock, flags);
|
||||||
|
|
||||||
|
dev3.state = (dev3.state | or_mask) & ~nand_mask;
|
||||||
|
writel(dev3.state, &dev3.base);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&dev3.lock, flags);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(set_latch_u5);
|
||||||
|
|
||||||
|
unsigned char get_latch_u5(void)
|
||||||
|
{
|
||||||
|
return dev3.state;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(get_latch_u5);
|
||||||
|
|
||||||
|
int rb532_gpio_get_value(unsigned gpio)
|
||||||
|
{
|
||||||
|
return readl(&rb532_gpio_reg0->gpiod) & (1 << gpio);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_get_value);
|
||||||
|
|
||||||
|
void rb532_gpio_set_value(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
unsigned tmp;
|
||||||
|
|
||||||
|
tmp = readl(&rb532_gpio_reg0->gpiod) & ~(1 << gpio);
|
||||||
|
if (value)
|
||||||
|
tmp |= 1 << gpio;
|
||||||
|
|
||||||
|
writel(tmp, (void *)&rb532_gpio_reg0->gpiod);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_set_value);
|
||||||
|
|
||||||
|
int rb532_gpio_direction_input(unsigned gpio)
|
||||||
|
{
|
||||||
|
writel(readl(&rb532_gpio_reg0->gpiocfg) & ~(1 << gpio),
|
||||||
|
(void *)&rb532_gpio_reg0->gpiocfg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_direction_input);
|
||||||
|
|
||||||
|
int rb532_gpio_direction_output(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
gpio_set_value(gpio, value);
|
||||||
|
writel(readl(&rb532_gpio_reg0->gpiocfg) | (1 << gpio),
|
||||||
|
(void *)&rb532_gpio_reg0->gpiocfg);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_direction_output);
|
||||||
|
|
||||||
|
void rb532_gpio_set_int_level(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
unsigned tmp;
|
||||||
|
|
||||||
|
tmp = readl(&rb532_gpio_reg0->gpioilevel) & ~(1 << gpio);
|
||||||
|
if (value)
|
||||||
|
tmp |= 1 << gpio;
|
||||||
|
writel(tmp, (void *)&rb532_gpio_reg0->gpioilevel);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_set_int_level);
|
||||||
|
|
||||||
|
int rb532_gpio_get_int_level(unsigned gpio)
|
||||||
|
{
|
||||||
|
return readl(&rb532_gpio_reg0->gpioilevel) & (1 << gpio);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_get_int_level);
|
||||||
|
|
||||||
|
void rb532_gpio_set_int_status(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
unsigned tmp;
|
||||||
|
|
||||||
|
tmp = readl(&rb532_gpio_reg0->gpioistat);
|
||||||
|
if (value)
|
||||||
|
tmp |= 1 << gpio;
|
||||||
|
writel(tmp, (void *)&rb532_gpio_reg0->gpioistat);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_set_int_status);
|
||||||
|
|
||||||
|
int rb532_gpio_get_int_status(unsigned gpio)
|
||||||
|
{
|
||||||
|
return readl(&rb532_gpio_reg0->gpioistat) & (1 << gpio);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_get_int_status);
|
||||||
|
|
||||||
|
void rb532_gpio_set_func(unsigned gpio, int value)
|
||||||
|
{
|
||||||
|
unsigned tmp;
|
||||||
|
|
||||||
|
tmp = readl(&rb532_gpio_reg0->gpiofunc);
|
||||||
|
if (value)
|
||||||
|
tmp |= 1 << gpio;
|
||||||
|
writel(tmp, (void *)&rb532_gpio_reg0->gpiofunc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_set_func);
|
||||||
|
|
||||||
|
int rb532_gpio_get_func(unsigned gpio)
|
||||||
|
{
|
||||||
|
return readl(&rb532_gpio_reg0->gpiofunc) & (1 << gpio);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rb532_gpio_get_func);
|
||||||
|
|
||||||
|
int __init rb532_gpio_init(void)
|
||||||
|
{
|
||||||
|
rb532_gpio_reg0 = ioremap_nocache(rb532_gpio_reg0_res[0].start,
|
||||||
|
rb532_gpio_reg0_res[0].end -
|
||||||
|
rb532_gpio_reg0_res[0].start);
|
||||||
|
|
||||||
|
if (!rb532_gpio_reg0) {
|
||||||
|
printk(KERN_ERR "rb532: cannot remap GPIO register 0\n");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
dev3.base = ioremap_nocache(rb532_dev3_ctl_res[0].start,
|
||||||
|
rb532_dev3_ctl_res[0].end -
|
||||||
|
rb532_dev3_ctl_res[0].start);
|
||||||
|
|
||||||
|
if (!dev3.base) {
|
||||||
|
printk(KERN_ERR "rb532: cannot remap device controller 3\n");
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
arch_initcall(rb532_gpio_init);
|
|
@ -0,0 +1,209 @@
|
||||||
|
/*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation; either version 2 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
* Copyright 2002 MontaVista Software Inc.
|
||||||
|
* Author: MontaVista Software, Inc.
|
||||||
|
* stevel@mvista.com or source@mvista.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/bitops.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/io.h>
|
||||||
|
#include <linux/kernel_stat.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/signal.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/interrupt.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/random.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
|
||||||
|
struct intr_group {
|
||||||
|
u32 mask; /* mask of valid bits in pending/mask registers */
|
||||||
|
volatile u32 *base_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define RC32434_NR_IRQS (GROUP4_IRQ_BASE + 32)
|
||||||
|
|
||||||
|
#if (NR_IRQS < RC32434_NR_IRQS)
|
||||||
|
#error Too little irqs defined. Did you override <asm/irq.h> ?
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static const struct intr_group intr_group[NUM_INTR_GROUPS] = {
|
||||||
|
{
|
||||||
|
.mask = 0x0000efff,
|
||||||
|
.base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 0 * IC_GROUP_OFFSET)},
|
||||||
|
{
|
||||||
|
.mask = 0x00001fff,
|
||||||
|
.base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 1 * IC_GROUP_OFFSET)},
|
||||||
|
{
|
||||||
|
.mask = 0x00000007,
|
||||||
|
.base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 2 * IC_GROUP_OFFSET)},
|
||||||
|
{
|
||||||
|
.mask = 0x0003ffff,
|
||||||
|
.base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 3 * IC_GROUP_OFFSET)},
|
||||||
|
{
|
||||||
|
.mask = 0xffffffff,
|
||||||
|
.base_addr = (u32 *) KSEG1ADDR(IC_GROUP0_PEND + 4 * IC_GROUP_OFFSET)}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define READ_PEND(base) (*(base))
|
||||||
|
#define READ_MASK(base) (*(base + 2))
|
||||||
|
#define WRITE_MASK(base, val) (*(base + 2) = (val))
|
||||||
|
|
||||||
|
static inline int irq_to_group(unsigned int irq_nr)
|
||||||
|
{
|
||||||
|
return (irq_nr - GROUP0_IRQ_BASE) >> 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int group_to_ip(unsigned int group)
|
||||||
|
{
|
||||||
|
return group + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void enable_local_irq(unsigned int ip)
|
||||||
|
{
|
||||||
|
int ipnum = 0x100 << ip;
|
||||||
|
|
||||||
|
set_c0_status(ipnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void disable_local_irq(unsigned int ip)
|
||||||
|
{
|
||||||
|
int ipnum = 0x100 << ip;
|
||||||
|
|
||||||
|
clear_c0_status(ipnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void ack_local_irq(unsigned int ip)
|
||||||
|
{
|
||||||
|
int ipnum = 0x100 << ip;
|
||||||
|
|
||||||
|
clear_c0_cause(ipnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rb532_enable_irq(unsigned int irq_nr)
|
||||||
|
{
|
||||||
|
int ip = irq_nr - GROUP0_IRQ_BASE;
|
||||||
|
unsigned int group, intr_bit;
|
||||||
|
volatile unsigned int *addr;
|
||||||
|
|
||||||
|
if (ip < 0)
|
||||||
|
enable_local_irq(irq_nr);
|
||||||
|
else {
|
||||||
|
group = ip >> 5;
|
||||||
|
|
||||||
|
ip &= (1 << 5) - 1;
|
||||||
|
intr_bit = 1 << ip;
|
||||||
|
|
||||||
|
enable_local_irq(group_to_ip(group));
|
||||||
|
|
||||||
|
addr = intr_group[group].base_addr;
|
||||||
|
WRITE_MASK(addr, READ_MASK(addr) & ~intr_bit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rb532_disable_irq(unsigned int irq_nr)
|
||||||
|
{
|
||||||
|
int ip = irq_nr - GROUP0_IRQ_BASE;
|
||||||
|
unsigned int group, intr_bit, mask;
|
||||||
|
volatile unsigned int *addr;
|
||||||
|
|
||||||
|
if (ip < 0) {
|
||||||
|
disable_local_irq(irq_nr);
|
||||||
|
} else {
|
||||||
|
group = ip >> 5;
|
||||||
|
|
||||||
|
ip &= (1 << 5) - 1;
|
||||||
|
intr_bit = 1 << ip;
|
||||||
|
addr = intr_group[group].base_addr;
|
||||||
|
mask = READ_MASK(addr);
|
||||||
|
mask |= intr_bit;
|
||||||
|
WRITE_MASK(addr, mask);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* if there are no more interrupts enabled in this
|
||||||
|
* group, disable corresponding IP
|
||||||
|
*/
|
||||||
|
if (mask == intr_group[group].mask)
|
||||||
|
disable_local_irq(group_to_ip(group));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rb532_mask_and_ack_irq(unsigned int irq_nr)
|
||||||
|
{
|
||||||
|
rb532_disable_irq(irq_nr);
|
||||||
|
ack_local_irq(group_to_ip(irq_to_group(irq_nr)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct irq_chip rc32434_irq_type = {
|
||||||
|
.name = "RB532",
|
||||||
|
.ack = rb532_disable_irq,
|
||||||
|
.mask = rb532_disable_irq,
|
||||||
|
.mask_ack = rb532_mask_and_ack_irq,
|
||||||
|
.unmask = rb532_enable_irq,
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init arch_init_irq(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pr_info("Initializing IRQ's: %d out of %d\n", RC32434_NR_IRQS, NR_IRQS);
|
||||||
|
|
||||||
|
for (i = 0; i < RC32434_NR_IRQS; i++)
|
||||||
|
set_irq_chip_and_handler(i, &rc32434_irq_type,
|
||||||
|
handle_level_irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main Interrupt dispatcher */
|
||||||
|
asmlinkage void plat_irq_dispatch(void)
|
||||||
|
{
|
||||||
|
unsigned int ip, pend, group;
|
||||||
|
volatile unsigned int *addr;
|
||||||
|
unsigned int cp0_cause = read_c0_cause() & read_c0_status();
|
||||||
|
|
||||||
|
if (cp0_cause & CAUSEF_IP7) {
|
||||||
|
do_IRQ(7);
|
||||||
|
} else {
|
||||||
|
ip = (cp0_cause & 0x7c00);
|
||||||
|
if (ip) {
|
||||||
|
group = 21 + (fls(ip) - 32);
|
||||||
|
|
||||||
|
addr = intr_group[group].base_addr;
|
||||||
|
|
||||||
|
pend = READ_PEND(addr);
|
||||||
|
pend &= ~READ_MASK(addr); /* only unmasked interrupts */
|
||||||
|
pend = 39 + (fls(pend) - 32);
|
||||||
|
do_IRQ((group << 5) + pend);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,158 @@
|
||||||
|
/*
|
||||||
|
* RouterBoard 500 specific prom routines
|
||||||
|
*
|
||||||
|
* Copyright (C) 2003, Peter Sadik <peter.sadik@idt.com>
|
||||||
|
* Copyright (C) 2005-2006, P.Christeas <p_christ@hol.gr>
|
||||||
|
* Copyright (C) 2007, Gabor Juhos <juhosg@openwrt.org>
|
||||||
|
* Felix Fietkau <nbd@openwrt.org>
|
||||||
|
* Florian Fainelli <florian@openwrt.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/mm.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/string.h>
|
||||||
|
#include <linux/console.h>
|
||||||
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
#include <linux/blkdev.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/mach-rc32434/ddr.h>
|
||||||
|
#include <asm/mach-rc32434/prom.h>
|
||||||
|
|
||||||
|
extern void __init setup_serial_port(void);
|
||||||
|
|
||||||
|
unsigned int idt_cpu_freq = 132000000;
|
||||||
|
EXPORT_SYMBOL(idt_cpu_freq);
|
||||||
|
unsigned int gpio_bootup_state;
|
||||||
|
EXPORT_SYMBOL(gpio_bootup_state);
|
||||||
|
|
||||||
|
static struct resource ddr_reg[] = {
|
||||||
|
{
|
||||||
|
.name = "ddr-reg",
|
||||||
|
.start = DDR0_PHYS_ADDR,
|
||||||
|
.end = DDR0_PHYS_ADDR + sizeof(struct ddr_ram),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void __init prom_free_prom_memory(void)
|
||||||
|
{
|
||||||
|
/* No prom memory to free */
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int match_tag(char *arg, const char *tag)
|
||||||
|
{
|
||||||
|
return strncmp(arg, tag, strlen(tag)) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned long tag2ul(char *arg, const char *tag)
|
||||||
|
{
|
||||||
|
char *num;
|
||||||
|
|
||||||
|
num = arg + strlen(tag);
|
||||||
|
return simple_strtoul(num, 0, 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init prom_setup_cmdline(void)
|
||||||
|
{
|
||||||
|
char cmd_line[CL_SIZE];
|
||||||
|
char *cp, *board;
|
||||||
|
int prom_argc;
|
||||||
|
char **prom_argv, **prom_envp;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
prom_argc = fw_arg0;
|
||||||
|
prom_argv = (char **) fw_arg1;
|
||||||
|
prom_envp = (char **) fw_arg2;
|
||||||
|
|
||||||
|
cp = cmd_line;
|
||||||
|
/* Note: it is common that parameters start
|
||||||
|
* at argv[1] and not argv[0],
|
||||||
|
* however, our elf loader starts at [0] */
|
||||||
|
for (i = 0; i < prom_argc; i++) {
|
||||||
|
if (match_tag(prom_argv[i], FREQ_TAG)) {
|
||||||
|
idt_cpu_freq = tag2ul(prom_argv[i], FREQ_TAG);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef IGNORE_CMDLINE_MEM
|
||||||
|
/* parses out the "mem=xx" arg */
|
||||||
|
if (match_tag(prom_argv[i], MEM_TAG))
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
if (i > 0)
|
||||||
|
*(cp++) = ' ';
|
||||||
|
if (match_tag(prom_argv[i], BOARD_TAG)) {
|
||||||
|
board = prom_argv[i] + strlen(BOARD_TAG);
|
||||||
|
|
||||||
|
if (match_tag(board, BOARD_RB532A))
|
||||||
|
mips_machtype = MACH_MIKROTIK_RB532A;
|
||||||
|
else
|
||||||
|
mips_machtype = MACH_MIKROTIK_RB532;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_tag(prom_argv[i], GPIO_TAG))
|
||||||
|
gpio_bootup_state = tag2ul(prom_argv[i], GPIO_TAG);
|
||||||
|
|
||||||
|
strcpy(cp, prom_argv[i]);
|
||||||
|
cp += strlen(prom_argv[i]);
|
||||||
|
}
|
||||||
|
*(cp++) = ' ';
|
||||||
|
|
||||||
|
i = strlen(arcs_cmdline);
|
||||||
|
if (i > 0) {
|
||||||
|
*(cp++) = ' ';
|
||||||
|
strcpy(cp, arcs_cmdline);
|
||||||
|
cp += strlen(arcs_cmdline);
|
||||||
|
}
|
||||||
|
if (gpio_bootup_state & 0x02)
|
||||||
|
strcpy(cp, GPIO_INIT_NOBUTTON);
|
||||||
|
else
|
||||||
|
strcpy(cp, GPIO_INIT_BUTTON);
|
||||||
|
|
||||||
|
cmd_line[CL_SIZE-1] = '\0';
|
||||||
|
|
||||||
|
strcpy(arcs_cmdline, cmd_line);
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init prom_init(void)
|
||||||
|
{
|
||||||
|
struct ddr_ram __iomem *ddr;
|
||||||
|
phys_t memsize;
|
||||||
|
phys_t ddrbase;
|
||||||
|
|
||||||
|
ddr = ioremap_nocache(ddr_reg[0].start,
|
||||||
|
ddr_reg[0].end - ddr_reg[0].start);
|
||||||
|
|
||||||
|
if (!ddr) {
|
||||||
|
printk(KERN_ERR "Unable to remap DDR register\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ddrbase = (phys_t)&ddr->ddrbase;
|
||||||
|
memsize = (phys_t)&ddr->ddrmask;
|
||||||
|
memsize = 0 - memsize;
|
||||||
|
|
||||||
|
prom_setup_cmdline();
|
||||||
|
|
||||||
|
/* give all RAM to boot allocator,
|
||||||
|
* except for the first 0x400 and the last 0x200 bytes */
|
||||||
|
add_memory_region(ddrbase + 0x400, memsize - 0x600, BOOT_MEM_RAM);
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* BRIEF MODULE DESCRIPTION
|
||||||
|
* Serial port initialisation.
|
||||||
|
*
|
||||||
|
* Copyright 2004 IDT Inc. (rischelp@idt.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.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
|
||||||
|
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
|
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
|
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/tty.h>
|
||||||
|
#include <linux/serial_core.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
|
||||||
|
#include <asm/serial.h>
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
|
||||||
|
extern unsigned int idt_cpu_freq;
|
||||||
|
|
||||||
|
static struct uart_port rb532_uart = {
|
||||||
|
.type = PORT_16550A,
|
||||||
|
.line = 0,
|
||||||
|
.irq = RC32434_UART0_IRQ,
|
||||||
|
.iotype = UPIO_MEM,
|
||||||
|
.membase = (char *)KSEG1ADDR(RC32434_UART0_BASE),
|
||||||
|
.regshift = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
int __init setup_serial_port(void)
|
||||||
|
{
|
||||||
|
rb532_uart.uartclk = idt_cpu_freq;
|
||||||
|
|
||||||
|
return early_serial_setup(&rb532_uart);
|
||||||
|
}
|
||||||
|
arch_initcall(setup_serial_port);
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* setup.c - boot time setup code
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
|
||||||
|
#include <asm/bootinfo.h>
|
||||||
|
#include <asm/reboot.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <linux/ioport.h>
|
||||||
|
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
#include <asm/mach-rc32434/pci.h>
|
||||||
|
|
||||||
|
struct pci_reg __iomem *pci_reg;
|
||||||
|
EXPORT_SYMBOL(pci_reg);
|
||||||
|
|
||||||
|
static struct resource pci0_res[] = {
|
||||||
|
{
|
||||||
|
.name = "pci_reg0",
|
||||||
|
.start = PCI0_BASE_ADDR,
|
||||||
|
.end = PCI0_BASE_ADDR + sizeof(struct pci_reg),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void rb_machine_restart(char *command)
|
||||||
|
{
|
||||||
|
/* just jump to the reset vector */
|
||||||
|
writel(0x80000001, (void *)KSEG1ADDR(RC32434_REG_BASE + RC32434_RST));
|
||||||
|
((void (*)(void)) KSEG1ADDR(0x1FC00000u))();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rb_machine_halt(void)
|
||||||
|
{
|
||||||
|
for (;;)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init plat_mem_setup(void)
|
||||||
|
{
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
_machine_restart = rb_machine_restart;
|
||||||
|
_machine_halt = rb_machine_halt;
|
||||||
|
pm_power_off = rb_machine_halt;
|
||||||
|
|
||||||
|
set_io_port_base(KSEG1);
|
||||||
|
|
||||||
|
pci_reg = ioremap_nocache(pci0_res[0].start,
|
||||||
|
pci0_res[0].end - pci0_res[0].start);
|
||||||
|
if (!pci_reg) {
|
||||||
|
printk(KERN_ERR "Could not remap PCI registers\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
val = __raw_readl(&pci_reg->pcic);
|
||||||
|
val &= 0xFFFFFF7;
|
||||||
|
__raw_writel(val, (void *)&pci_reg->pcic);
|
||||||
|
|
||||||
|
#ifdef CONFIG_PCI
|
||||||
|
/* Enable PCI interrupts in EPLD Mask register */
|
||||||
|
*epld_mask = 0x0;
|
||||||
|
*(epld_mask + 1) = 0x0;
|
||||||
|
#endif
|
||||||
|
write_c0_wired(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *get_system_type(void)
|
||||||
|
{
|
||||||
|
switch (mips_machtype) {
|
||||||
|
case MACH_MIKROTIK_RB532A:
|
||||||
|
return "Mikrotik RB532A";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return "Mikrotik RB532";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Carsten Langgaard, carstenl@mips.com
|
||||||
|
* Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* This program is free software; you can distribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License (Version 2) as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
|
||||||
|
*
|
||||||
|
* Setting up the clock on the MIPS boards.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/kernel_stat.h>
|
||||||
|
#include <linux/ptrace.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
#include <linux/spinlock.h>
|
||||||
|
#include <linux/mc146818rtc.h>
|
||||||
|
#include <linux/irq.h>
|
||||||
|
#include <linux/timex.h>
|
||||||
|
|
||||||
|
#include <asm/mipsregs.h>
|
||||||
|
#include <asm/debug.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
#include <asm/mach-rc32434/rc32434.h>
|
||||||
|
|
||||||
|
extern unsigned int idt_cpu_freq;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Figure out the r4k offset, the amount to increment the compare
|
||||||
|
* register for each time tick. There is no RTC available.
|
||||||
|
*
|
||||||
|
* The RC32434 counts at half the CPU *core* speed.
|
||||||
|
*/
|
||||||
|
static unsigned long __init cal_r4koff(void)
|
||||||
|
{
|
||||||
|
mips_hpt_frequency = idt_cpu_freq * IDT_CLOCK_MULT / 2;
|
||||||
|
|
||||||
|
return mips_hpt_frequency / HZ;
|
||||||
|
}
|
||||||
|
|
||||||
|
void __init plat_time_init(void)
|
||||||
|
{
|
||||||
|
unsigned int est_freq, flags;
|
||||||
|
unsigned long r4k_offset;
|
||||||
|
|
||||||
|
local_irq_save(flags);
|
||||||
|
|
||||||
|
printk(KERN_INFO "calculating r4koff... ");
|
||||||
|
r4k_offset = cal_r4koff();
|
||||||
|
printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);
|
||||||
|
|
||||||
|
est_freq = 2 * r4k_offset * HZ;
|
||||||
|
est_freq += 5000; /* round */
|
||||||
|
est_freq -= est_freq % 10000;
|
||||||
|
printk(KERN_INFO "CPU frequency %d.%02d MHz\n", est_freq / 1000000,
|
||||||
|
(est_freq % 1000000) * 100 / 1000000);
|
||||||
|
local_irq_restore(flags);
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue