mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
Merge branch 'linus' into cpus4096-for-linus
Conflicts: net/sunrpc/svc.c Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
commit
eb6a12c242
@ -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
|
||||
When: January 2009
|
||||
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
|
||||
removal fixed lm-sensors (2.x or 3.x) should be readily available.
|
||||
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.
|
||||
|
||||
struct configfs_group_operations {
|
||||
int (*make_item)(struct config_group *group,
|
||||
const char *name,
|
||||
struct config_item **new_item);
|
||||
int (*make_group)(struct config_group *group,
|
||||
const char *name,
|
||||
struct config_group **new_group);
|
||||
struct config_item *(*make_item)(struct config_group *group,
|
||||
const char *name);
|
||||
struct config_group *(*make_group)(struct config_group *group,
|
||||
const char *name);
|
||||
int (*commit_item)(struct config_item *item);
|
||||
void (*disconnect_notify)(struct config_group *group,
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
simple_child = kzalloc(sizeof(struct simple_child), GFP_KERNEL);
|
||||
if (!simple_child)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
*new_item = &simple_child->item;
|
||||
return 0;
|
||||
return &simple_child->item;
|
||||
}
|
||||
|
||||
static struct configfs_attribute simple_children_attr_description = {
|
||||
@ -360,21 +359,20 @@ static struct configfs_subsystem simple_children_subsys = {
|
||||
* 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;
|
||||
|
||||
simple_children = kzalloc(sizeof(struct simple_children),
|
||||
GFP_KERNEL);
|
||||
if (!simple_children)
|
||||
return -ENOMEM;
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
||||
config_group_init_type_name(&simple_children->group, name,
|
||||
&simple_children_type);
|
||||
|
||||
*new_group = &simple_children->group;
|
||||
return 0;
|
||||
return &simple_children->group;
|
||||
}
|
||||
|
||||
static struct configfs_attribute group_children_attr_description = {
|
||||
|
@ -5,7 +5,7 @@
|
||||
################################################################################
|
||||
|
||||
Author: NetApp and Open Grid Computing
|
||||
Date: April 15, 2008
|
||||
Date: May 29, 2008
|
||||
|
||||
Table of Contents
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@ -60,16 +60,18 @@ Installation
|
||||
The procedures described in this document have been tested with
|
||||
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
|
||||
command in nfs-utils-1.1.1 or greater. To see which version of mount.nfs
|
||||
you are using, type:
|
||||
An NFS/RDMA mount point can be obtained by using the mount.nfs command in
|
||||
nfs-utils-1.1.2 or greater (nfs-utils-1.1.1 was the first nfs-utils
|
||||
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,
|
||||
then you will need to install the latest version of nfs-utils.
|
||||
If the version is less than 1.1.2 or the command does not exist,
|
||||
you should install the latest version of nfs-utils.
|
||||
|
||||
Download the latest package from:
|
||||
|
||||
@ -77,22 +79,33 @@ Installation
|
||||
|
||||
Uncompress the package and follow the installation instructions.
|
||||
|
||||
If you will not be using GSS and NFSv4, the installation process
|
||||
can be simplified by disabling these features when running configure:
|
||||
If you will not need the idmapper and gssd executables (you do not need
|
||||
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
|
||||
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.
|
||||
The standard technique is to create a symlink called mount.nfs4 to mount.nfs.
|
||||
or v4 mounts. To initiate a v4 mount, the binary must be called
|
||||
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
|
||||
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
|
||||
|
||||
@ -156,8 +169,8 @@ Check RDMA and NFS Setup
|
||||
this time. For example, if you are using a Mellanox Tavor/Sinai/Arbel
|
||||
card:
|
||||
|
||||
> modprobe ib_mthca
|
||||
> modprobe ib_ipoib
|
||||
$ modprobe ib_mthca
|
||||
$ modprobe ib_ipoib
|
||||
|
||||
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
|
||||
@ -166,7 +179,7 @@ Check RDMA and NFS Setup
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
assumes you have two IB hosts named host1 and host2):
|
||||
|
||||
host1> ifconfig ib0 a.b.c.x
|
||||
host2> ifconfig ib0 a.b.c.y
|
||||
host1> ping a.b.c.y
|
||||
host2> ping a.b.c.x
|
||||
host1$ ifconfig ib0 a.b.c.x
|
||||
host2$ ifconfig ib0 a.b.c.y
|
||||
host1$ ping a.b.c.y
|
||||
host2$ ping a.b.c.x
|
||||
|
||||
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.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
|
||||
cleint's iWARP address(es) for an RNIC.
|
||||
The IP address(es) is(are) the client's IPoIB address for an InfiniBand
|
||||
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
|
||||
use a reserved port.
|
||||
NOTE: The "insecure" option must be used because the NFS/RDMA client does
|
||||
not use a reserved port.
|
||||
|
||||
Each time a machine boots:
|
||||
|
||||
@ -214,43 +227,45 @@ NFS/RDMA Setup
|
||||
|
||||
For InfiniBand using a Mellanox adapter:
|
||||
|
||||
> modprobe ib_mthca
|
||||
> modprobe ib_ipoib
|
||||
> ifconfig ib0 a.b.c.d
|
||||
$ modprobe ib_mthca
|
||||
$ modprobe ib_ipoib
|
||||
$ ifconfig ib0 a.b.c.d
|
||||
|
||||
NOTE: use unique addresses for the client and server
|
||||
|
||||
- Start the NFS server
|
||||
|
||||
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
||||
load the RDMA transport module:
|
||||
If the NFS/RDMA server was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||
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
|
||||
|
||||
> service nfs start
|
||||
$ service nfs start
|
||||
|
||||
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
|
||||
|
||||
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in kernel config),
|
||||
load the RDMA client module:
|
||||
If the NFS/RDMA client was built as a module (CONFIG_SUNRPC_XPRT_RDMA=m in
|
||||
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
|
||||
"proto" field for the given mount.
|
||||
To verify that the mount is using RDMA, run "cat /proc/mounts" and check
|
||||
the "proto" field for the given mount.
|
||||
|
||||
Congratulations! You're using NFS/RDMA!
|
||||
|
@ -289,35 +289,73 @@ downdelay
|
||||
fail_over_mac
|
||||
|
||||
Specifies whether active-backup mode should set all slaves to
|
||||
the same MAC address (the traditional behavior), or, when
|
||||
enabled, change the bond's MAC address when changing the
|
||||
active interface (i.e., fail over the MAC address itself).
|
||||
the same MAC address at enslavement (the traditional
|
||||
behavior), or, when enabled, perform special handling of the
|
||||
bond's MAC address in accordance with the selected policy.
|
||||
|
||||
Fail over MAC 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).
|
||||
Possible values are:
|
||||
|
||||
The down side of fail over MAC 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.
|
||||
none or 0
|
||||
|
||||
When fail over MAC 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.
|
||||
This setting disables fail_over_mac, and causes
|
||||
bonding to set all slaves of an active-backup bond to
|
||||
the same MAC address at enslavement time. This is the
|
||||
default.
|
||||
|
||||
A value of 0 disables fail over MAC, and is the default. A
|
||||
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.
|
||||
active or 1
|
||||
|
||||
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
|
||||
|
||||
@ -338,7 +376,8 @@ max_bonds
|
||||
Specifies the number of bonding devices to create for this
|
||||
instance of the bonding driver. E.g., if max_bonds is 3, and
|
||||
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
|
||||
|
||||
@ -501,6 +540,17 @@ mode
|
||||
swapped with the new curr_active_slave that was
|
||||
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
|
||||
|
||||
A string (eth0, eth2, etc) specifying which slave is the
|
||||
|
167
Documentation/networking/dm9000.txt
Normal file
167
Documentation/networking/dm9000.txt
Normal file
@ -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
|
||||
Limit the maximal rates for sending ICMP packets whose type matches
|
||||
icmp_ratemask (see below) to specific targets.
|
||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
||||
Default: 100
|
||||
0 to disable any limiting,
|
||||
otherwise the minimal space between responses in milliseconds.
|
||||
Default: 1000
|
||||
|
||||
icmp_ratemask - INTEGER
|
||||
Mask made of ICMP types for which rates are being limited.
|
||||
@ -1023,11 +1024,23 @@ max_addresses - INTEGER
|
||||
autoconfigured addresses.
|
||||
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/*:
|
||||
ratelimit - INTEGER
|
||||
Limit the maximal rates for sending ICMPv6 packets.
|
||||
0 to disable any limiting, otherwise the maximal rate in jiffies(1)
|
||||
Default: 100
|
||||
0 to disable any limiting,
|
||||
otherwise the minimal space between responses in milliseconds.
|
||||
Default: 1000
|
||||
|
||||
|
||||
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
|
||||
@ -9,94 +9,151 @@ Contents
|
||||
|
||||
- In This Release
|
||||
- Identifying Your Adapter
|
||||
- Building and Installation
|
||||
- Command Line Parameters
|
||||
- Improving Performance
|
||||
- Additional Configurations
|
||||
- Known Issues/Troubleshooting
|
||||
- Support
|
||||
|
||||
|
||||
|
||||
In This Release
|
||||
===============
|
||||
|
||||
This file describes the Linux* Base Driver for the Intel(R) PRO/10GbE Family
|
||||
of Adapters, version 1.0.x.
|
||||
This file describes the ixgb Linux Base Driver for the 10 Gigabit Intel(R)
|
||||
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
|
||||
========================
|
||||
|
||||
To verify your Intel adapter is supported, find the board ID number on the
|
||||
adapter. Look for a label that has a barcode and a number in the format
|
||||
A12345-001.
|
||||
The following Intel network adapters are compatible with the drivers in this
|
||||
release:
|
||||
|
||||
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
|
||||
=======================
|
||||
|
||||
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
|
||||
using this syntax:
|
||||
If the driver is built as a module, the following optional parameters are
|
||||
used by entering them on the command line with the modprobe command using
|
||||
this syntax:
|
||||
|
||||
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.
|
||||
|
||||
The default value for each parameter is generally the recommended setting,
|
||||
unless otherwise noted. Also, if the driver is statically built into the
|
||||
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.
|
||||
unless otherwise noted.
|
||||
|
||||
FlowControl
|
||||
Valid Range: 0-3 (0=none, 1=Rx only, 2=Tx only, 3=Rx&Tx)
|
||||
Default: Read from the EEPROM
|
||||
If EEPROM is not detected, default is 3
|
||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||
Ethernet PAUSE frames.
|
||||
If EEPROM is not detected, default is 1
|
||||
This parameter controls the automatic generation(Tx) and response(Rx) to
|
||||
Ethernet PAUSE frames. There are hardware bugs associated with enabling
|
||||
Tx flow control so beware.
|
||||
|
||||
RxDescriptors
|
||||
Valid Range: 64-512
|
||||
Default Value: 512
|
||||
This value is the number of receive descriptors allocated by the driver.
|
||||
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 and can be either 2048, 4056, 8192, or 16384 bytes,
|
||||
depending on the MTU setting. When the MTU size is 1500 or less, the
|
||||
This value is the number of receive descriptors allocated by the driver.
|
||||
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 and can be either 2048, 4056, 8192, or 16384 bytes,
|
||||
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 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.
|
||||
|
||||
RxIntDelay
|
||||
Valid Range: 0-65535 (0=off)
|
||||
Default Value: 6
|
||||
This value delays the generation of receive interrupts in units of
|
||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||
efficiency if properly tuned for specific network traffic. Increasing
|
||||
this value adds extra latency to frame reception and can end up
|
||||
decreasing the throughput of TCP traffic. If the system is reporting
|
||||
dropped receives, this value may be set too high, causing the driver to
|
||||
Default Value: 72
|
||||
This value delays the generation of receive interrupts in units of
|
||||
0.8192 microseconds. Receive interrupt reduction can improve CPU
|
||||
efficiency if properly tuned for specific network traffic. Increasing
|
||||
this value adds extra latency to frame reception and can end up
|
||||
decreasing the throughput of TCP traffic. If the system is reporting
|
||||
dropped receives, this value may be set too high, causing the driver to
|
||||
run out of available receive descriptors.
|
||||
|
||||
TxDescriptors
|
||||
Valid Range: 64-4096
|
||||
Default Value: 256
|
||||
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.
|
||||
|
||||
XsumRX
|
||||
@ -105,51 +162,49 @@ Default Value: 1
|
||||
A value of '1' indicates that the driver should enable IP checksum
|
||||
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
|
||||
=====================
|
||||
|
||||
With the Intel PRO/10 GbE adapter, the default Linux configuration will very
|
||||
likely limit the total available throughput artificially. There is a set of
|
||||
things that when applied together increase the ability of Linux to transmit
|
||||
and receive data. The following enhancements were originally acquired from
|
||||
settings published at http://www.spec.org/web99 for various submitted results
|
||||
using Linux.
|
||||
With the 10 Gigabit server adapters, the default Linux configuration will
|
||||
very likely limit the total available throughput artificially. There is a set
|
||||
of configuration changes that, when applied together, will increase the ability
|
||||
of Linux to transmit and receive data. The following enhancements were
|
||||
originally acquired from settings published at http://www.spec.org/web99/ for
|
||||
various submitted results using Linux.
|
||||
|
||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||
tuning your network performance.
|
||||
NOTE: These changes are only suggestions, and serve as a starting point for
|
||||
tuning your network performance.
|
||||
|
||||
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.
|
||||
- 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.
|
||||
|
||||
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
|
||||
behavior after modifying this register may be undefined (possibly errors of some
|
||||
kind). A power-cycle, hard reset or explicitly setting the e6 register back to
|
||||
22 (setpci -d 8086:1048 e6.b=22) may be required to get back to a stable
|
||||
configuration.
|
||||
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
|
||||
behavior after modifying this register may be undefined (possibly errors of
|
||||
some kind). A power-cycle, hard reset or explicitly setting the e6 register
|
||||
back to 22 (setpci -d 8086:1a48 e6.b=22) may be required to get back to a
|
||||
stable configuration.
|
||||
|
||||
- COPY these lines and paste them into ixgb_perf.sh:
|
||||
#!/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
|
||||
setpci -d 8086:1048 e6.b=2e
|
||||
# set the MTU (max transmission unit) - it requires your switch and clients to change too!
|
||||
# replace 1a48 with appropriate 10GbE device's ID installed on the system,
|
||||
# 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
|
||||
# your ixgb adapter should be loaded as eth1 for this to work, change if needed
|
||||
ifconfig eth1 mtu 9000 txqueuelen 1000 up
|
||||
# call the sysctl utility to modify /proc/sys entries
|
||||
sysctl -p ./sysctl_ixgb.conf
|
||||
# call the sysctl utility to modify /proc/sys entries
|
||||
sysctl -p ./sysctl_ixgb.conf
|
||||
- END ixgb_perf.sh
|
||||
|
||||
- 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
|
||||
|
||||
### IPV4 specific settings
|
||||
net.ipv4.tcp_timestamps = 0 # turns TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_sack = 0 # turn SACK support off, default on
|
||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||
net.ipv4.tcp_rmem = 10000000 10000000 10000000 # sets min/default/max TCP read buffer, default 4096 87380 174760
|
||||
net.ipv4.tcp_wmem = 10000000 10000000 10000000 # sets min/pressure/max TCP write buffer, default 4096 16384 131072
|
||||
net.ipv4.tcp_mem = 10000000 10000000 10000000 # sets min/pressure/max TCP buffer space, default 31744 32256 32768
|
||||
# turn TCP timestamp support off, default 1, reduces CPU use
|
||||
net.ipv4.tcp_timestamps = 0
|
||||
# turn SACK support off, default on
|
||||
# on systems with a VERY fast bus -> memory interface this is the big gainer
|
||||
net.ipv4.tcp_sack = 0
|
||||
# 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)
|
||||
net.core.rmem_max = 524287 # maximum receive socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287 # maximum send socket buffer size, default 131071
|
||||
net.core.rmem_default = 524287 # default receive socket buffer size, default 65535
|
||||
net.core.wmem_default = 524287 # default send socket buffer size, default 65535
|
||||
net.core.optmem_max = 524287 # maximum amount of option memory buffers, default 10240
|
||||
net.core.netdev_max_backlog = 300000 # number of unprocessed input packets before kernel starts dropping them, default 300
|
||||
# set maximum receive socket buffer size, default 131071
|
||||
net.core.rmem_max = 524287
|
||||
# set maximum send socket buffer size, default 131071
|
||||
net.core.wmem_max = 524287
|
||||
# set default receive socket buffer size, default 65535
|
||||
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
|
||||
|
||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||
your ixgb driver is using.
|
||||
Edit the ixgb_perf.sh script if necessary to change eth1 to whatever interface
|
||||
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
|
||||
only last only until the next system reboot.
|
||||
NOTE: Unless these scripts are added to the boot process, these changes will
|
||||
only last only until the next system reboot.
|
||||
|
||||
|
||||
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
|
||||
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:
|
||||
For instance, use the commands:
|
||||
sysctl -w net.core.rmem_max=262143
|
||||
and
|
||||
sysctl -w net.core.rmem_default=262143
|
||||
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
|
||||
will increase the amount of memory used by the network stack for receives, and
|
||||
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
|
||||
will increase the amount of memory used by the network stack for receives, and
|
||||
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
|
||||
=======
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
kernel with a supported adapter, email the specific information related to
|
||||
the issue to linux.nics@intel.com.
|
||||
kernel with a supported adapter, email the specific information related
|
||||
to the issue to e1000-devel@lists.sf.net
|
||||
|
67
Documentation/networking/mac80211_hwsim/README
Normal file
67
Documentation/networking/mac80211_hwsim/README
Normal file
@ -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
|
11
Documentation/networking/mac80211_hwsim/hostapd.conf
Normal file
11
Documentation/networking/mac80211_hwsim/hostapd.conf
Normal file
@ -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
|
10
Documentation/networking/mac80211_hwsim/wpa_supplicant.conf
Normal file
10
Documentation/networking/mac80211_hwsim/wpa_supplicant.conf
Normal file
@ -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 2: Qdisc support for multiqueue devices
|
||||
Section 3: Brief howto using PRIO or RR for multiqueue devices
|
||||
|
||||
|
||||
Intro: Kernel support for multiqueue devices
|
||||
---------------------------------------------------------
|
||||
|
||||
Kernel support for multiqueue devices is only an API that is presented to the
|
||||
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.
|
||||
|
||||
Kernel support for multiqueue devices is always present.
|
||||
|
||||
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
|
||||
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>
|
||||
|
@ -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%
|
||||
on certain platforms).
|
||||
|
||||
e. NAPI. Compile-time option(CONFIG_S2IO_NAPI) for better Rx interrupt
|
||||
moderation.
|
||||
|
||||
f. Statistics. Comprehensive MAC-level and software statistics displayed
|
||||
e. Statistics. Comprehensive MAC-level and software statistics displayed
|
||||
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.
|
||||
|
||||
4. Command line parameters
|
||||
|
@ -41,12 +41,24 @@ Table of Contents
|
||||
VI - System-on-a-chip devices and nodes
|
||||
1) Defining child nodes of an SOC
|
||||
2) Representing devices without a current OF specification
|
||||
a) PHY nodes
|
||||
b) Interrupt controllers
|
||||
c) CFI or JEDEC memory-mapped NOR flash
|
||||
d) 4xx/Axon EMAC ethernet nodes
|
||||
e) Xilinx IP cores
|
||||
f) USB EHCI controllers
|
||||
a) MDIO IO device
|
||||
b) Gianfar-compatible ethernet nodes
|
||||
c) PHY nodes
|
||||
d) Interrupt controllers
|
||||
e) I2C
|
||||
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
|
||||
1) The /system-controller node
|
||||
@ -1815,6 +1827,60 @@ platforms are moved over to use the flattened-device-tree model.
|
||||
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
|
||||
===========================================================
|
||||
|
||||
|
@ -1,89 +1,528 @@
|
||||
rfkill - RF switch subsystem support
|
||||
====================================
|
||||
|
||||
1 Implementation details
|
||||
2 Driver support
|
||||
3 Userspace support
|
||||
1 Introduction
|
||||
2 Implementation details
|
||||
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
|
||||
to enable wireless devices like WiFi and Bluetooth.
|
||||
The rfkill subsystem is composed of various components: the rfkill class, the
|
||||
rfkill-input module (an input layer handler), and some specific input layer
|
||||
events.
|
||||
|
||||
This is done by providing the user 3 possibilities:
|
||||
1 - The rfkill system handles all events; userspace is not aware of events.
|
||||
2 - The rfkill system handles all events; userspace is informed about the events.
|
||||
3 - The rfkill system does not handle events; userspace handles all events.
|
||||
The rfkill class provides kernel drivers with an interface that allows them to
|
||||
know when they should enable or disable a wireless network device transmitter.
|
||||
This is enabled by the CONFIG_RFKILL Kconfig option.
|
||||
|
||||
The buttons to enable and disable the wireless radios are important in
|
||||
situations where the user is for example using his laptop on a location where
|
||||
wireless radios _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 still provides userspace the possibility
|
||||
to take over the task to handle the key events.
|
||||
The rfkill class support makes sure userspace will be notified of all state
|
||||
changes on rfkill devices through uevents. It provides a notification chain
|
||||
for interested parties in the kernel to also get notified of rfkill state
|
||||
changes in other drivers. It creates several sysfs entries which can be used
|
||||
by userspace. See section "Userspace support".
|
||||
|
||||
The system inside the kernel has been split into 2 separate sections:
|
||||
1 - RFKILL
|
||||
2 - RFKILL_INPUT
|
||||
The rfkill-input module provides the kernel with the ability to implement a
|
||||
basic response when the user presses a key or button (or toggles a switch)
|
||||
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
|
||||
be notified of any events through the input device. It also creates several
|
||||
sysfs entries which can be used by userspace. See section "Userspace support".
|
||||
rfkill-input is a rfkill-related events input layer handler. This handler will
|
||||
listen to all rfkill key events and will change the rfkill state of the
|
||||
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
|
||||
listen to all rfkill key events and will toggle the radio accordingly.
|
||||
With this option enabled userspace could either do nothing or simply
|
||||
perform monitoring tasks.
|
||||
The rfkill-input module also provides EPO (emergency power-off) functionality
|
||||
for all wireless transmitters. This function cannot be overridden, and it is
|
||||
always active. rfkill EPO is related to *_RFKILL_ALL input layer events.
|
||||
|
||||
|
||||
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
|
||||
depend on the Kconfig symbol RFKILL; it should _not_ depend on
|
||||
RKFILL_INPUT.
|
||||
1. If the device is an input device that, because of hardware or firmware,
|
||||
causes wireless transmitters to be blocked regardless of the kernel's will, it
|
||||
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
|
||||
will be required to determine the key state changes. For this the input
|
||||
layer providers the input-polldev handler.
|
||||
2. If the wireless transmitter switch control is read-only, it is an input
|
||||
device and not to be registered with the rfkill class (and maybe not to be made
|
||||
an input layer event source either, see below).
|
||||
|
||||
A driver should implement a few steps to correctly make use of the
|
||||
rfkill subsystem. First for non-polling drivers:
|
||||
3. If there is some other device driver *closer* to the actual hardware the
|
||||
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()
|
||||
- input_allocate_device()
|
||||
- rfkill_register()
|
||||
- input_register_device()
|
||||
E.g:
|
||||
[RFKILL slider switch] -- [GPIO hardware] -- [WLAN card rf-kill input]
|
||||
(platform driver) (wireless card driver)
|
||||
|
||||
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()
|
||||
- input_allocate_polled_device()
|
||||
- rfkill_register()
|
||||
- input_register_polled_device()
|
||||
On the other hand, some embedded devices do this:
|
||||
|
||||
When a key event has been detected, the correct event should be
|
||||
sent over the input device which has been registered by the driver.
|
||||
[RFKILL slider switch] -- [WLAN card rf-kill input]
|
||||
(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
|
||||
key event when the rfkill key has been pressed.
|
||||
1. NEVER confuse input device keys and buttons with input device switches.
|
||||
|
||||
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:
|
||||
|
||||
name: Name assigned by driver to this key (interface or driver name).
|
||||
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
|
||||
|
||||
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
|
||||
state, will be will be toggled accordingly.
|
||||
this means that when 1 or 0 is written, the device rfkill state (if not yet in
|
||||
the requested state), will be will be toggled accordingly.
|
||||
|
||||
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
|
||||
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
|
||||
tasks when the rkfill key is pressed.
|
||||
check the sysfs "state" entry regularly to correctly perform the required tasks
|
||||
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.
|
||||
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)
|
||||
Change the port parameters, including word length, parity, stop
|
||||
bits. Update read_status_mask and ignore_status_mask to indicate
|
||||
|
@ -8,3 +8,4 @@
|
||||
7 -> Hauppauge WinTV-HVR1200 [0070:71d1,0070:71d3]
|
||||
8 -> Hauppauge WinTV-HVR1700 [0070:8101]
|
||||
9 -> Hauppauge WinTV-HVR1400 [0070:8010]
|
||||
10 -> DViCO FusionHDTV7 Dual Express [18ac:d618]
|
||||
|
@ -8,10 +8,13 @@
|
||||
7 -> Leadtek Winfast USB II (em2800)
|
||||
8 -> Kworld USB2800 (em2800)
|
||||
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]
|
||||
12 -> Kworld PVR TV 2800 RF (em2820/em2840)
|
||||
13 -> Terratec Prodigy XS (em2880) [0ccd:0047]
|
||||
14 -> Pixelview Prolink PlayTV USB 2.0 (em2820/em2840)
|
||||
15 -> V-Gear PocketTV (em2800)
|
||||
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]
|
||||
37 -> Items MuchTV Plus / IT-005
|
||||
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]
|
||||
41 -> Compro VideoMate TV Gold+ [185b:c100]
|
||||
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]
|
||||
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]
|
||||
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]
|
||||
132 -> Genius TVGO AM11MCE
|
||||
133 -> NXP Snake DVB-S reference design
|
||||
@ -141,3 +141,7 @@
|
||||
140 -> Avermedia DVB-S Pro A700 [1461:a7a1]
|
||||
141 -> Avermedia DVB-S Hybrid+FM A700 [1461:a7a2]
|
||||
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
|
||||
encoder chip:
|
||||
|
||||
1) The only hardware currently supported is the Hauppauge HVR-1600
|
||||
card and the Compro VideoMate H900 (note that this card only
|
||||
supports analog input, it has no digital tuner!).
|
||||
1) Currently supported are:
|
||||
|
||||
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
|
||||
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
|
||||
incorrect audio register information in the datasheet. We are
|
||||
waiting for updated information from Conexant.
|
||||
3) VBI (raw or sliced) has not yet been implemented.
|
||||
|
||||
4) VBI (raw or sliced) has not yet been implemented.
|
||||
4) MPEG indexing is not yet implemented.
|
||||
|
||||
5) MPEG indexing is not yet implemented.
|
||||
|
||||
6) The driver is still a bit rough around the edges, this should
|
||||
5) The driver is still a bit rough around the edges, this should
|
||||
improve over time.
|
||||
|
||||
|
||||
Firmware:
|
||||
|
||||
The firmware needs to be extracted from the Windows Hauppauge HVR-1600
|
||||
driver, available here:
|
||||
You can obtain the firmware files 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
|
||||
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
|
||||
Untar and copy the .fw files to your firmware directory.
|
||||
|
243
Documentation/video4linux/gspca.txt
Normal file
243
Documentation/video4linux/gspca.txt
Normal file
@ -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
|
||||
P: Bruce Allan
|
||||
M: bruce.w.allan@intel.com
|
||||
P: PJ Waskiewicz
|
||||
M: peter.p.waskiewicz.jr@intel.com
|
||||
P: John Ronciak
|
||||
M: john.ronciak@intel.com
|
||||
L: e1000-devel@lists.sourceforge.net
|
||||
@ -2725,12 +2727,10 @@ L: libertas-dev@lists.infradead.org
|
||||
S: Maintained
|
||||
|
||||
MARVELL MV643XX ETHERNET DRIVER
|
||||
P: Dale Farnsworth
|
||||
M: dale@farnsworth.org
|
||||
P: Manish Lachwani
|
||||
M: mlachwani@mvista.com
|
||||
P: Lennert Buytenhek
|
||||
M: buytenh@marvell.com
|
||||
L: netdev@vger.kernel.org
|
||||
S: Odd Fixes for 2.4; Maintained for 2.6.
|
||||
S: Supported
|
||||
|
||||
MATROX FRAMEBUFFER DRIVER
|
||||
P: Petr Vandrovec
|
||||
@ -3274,14 +3274,6 @@ L: linux-kernel@vger.kernel.org
|
||||
T: git git.infradead.org/battery-2.6.git
|
||||
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
|
||||
P: Adam Belay
|
||||
M: ambx1@neo.rr.com
|
||||
|
@ -323,10 +323,15 @@ static struct platform_device smc91x_device = {
|
||||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x203FB800,
|
||||
.end = 0x203FB800 + 8,
|
||||
.end = 0x203FB800 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x203FB800 + 4,
|
||||
.end = 0x203FB800 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF9,
|
||||
.end = IRQ_PF9,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
@ -65,10 +65,15 @@ static struct platform_device rtc_device = {
|
||||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x20300000,
|
||||
.end = 0x20300000 + 8,
|
||||
.end = 0x20300000 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x20300000 + 4,
|
||||
.end = 0x20300000 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF10,
|
||||
.end = IRQ_PF10,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
@ -166,10 +166,15 @@ static struct platform_device smc91x_device = {
|
||||
static struct resource dm9000_resources[] = {
|
||||
[0] = {
|
||||
.start = 0x203FB800,
|
||||
.end = 0x203FB800 + 8,
|
||||
.end = 0x203FB800 + 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = 0x203FB800 + 4,
|
||||
.end = 0x203FB800 + 5,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
.start = IRQ_PF9,
|
||||
.end = IRQ_PF9,
|
||||
.flags = (IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE),
|
||||
|
@ -2,7 +2,6 @@
|
||||
# arch/cris/arch-v10/boot/Makefile
|
||||
#
|
||||
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
subdir- := compressed rescue
|
||||
|
@ -2,12 +2,10 @@
|
||||
# arch/cris/arch-v10/boot/compressed/Makefile
|
||||
#
|
||||
|
||||
CC = gcc-cris -melf $(LINUXINCLUDE)
|
||||
ccflags-y += -O2
|
||||
LD = ld-cris
|
||||
ldflags-y += -T $(obj)/decompress.ld
|
||||
asflags-y += $(LINUXINCLUDE)
|
||||
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
@ -21,12 +19,6 @@ $(obj)/decompress.o: $(OBJECTS) FORCE
|
||||
$(obj)/decompress.bin: $(obj)/decompress.o FORCE
|
||||
$(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
|
||||
$(call if_changed,image)
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
OUTPUT_FORMAT(elf32-us-cris)
|
||||
/* OUTPUT_FORMAT(elf32-us-cris) */
|
||||
OUTPUT_FORMAT(elf32-cris)
|
||||
|
||||
MEMORY
|
||||
{
|
||||
|
@ -15,77 +15,77 @@
|
||||
#define COMMAND_LINE_MAGIC 0x87109563
|
||||
|
||||
;; Exported symbols
|
||||
|
||||
.globl _input_data
|
||||
|
||||
|
||||
.globl input_data
|
||||
|
||||
|
||||
.text
|
||||
|
||||
nop
|
||||
di
|
||||
|
||||
;; 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
|
||||
nop
|
||||
|
||||
|
||||
#include "../../lib/dram_init.S"
|
||||
|
||||
dram_init_finished:
|
||||
|
||||
|
||||
dram_init_finished:
|
||||
|
||||
;; Initiate the PA and PB ports
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, r0
|
||||
move.b r0, [R_PORT_PA_DATA]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DATA, $r0
|
||||
move.b $r0, [R_PORT_PA_DATA]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, r0
|
||||
move.b r0, [R_PORT_PA_DIR]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PA_DIR, $r0
|
||||
move.b $r0, [R_PORT_PA_DIR]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, r0
|
||||
move.b r0, [R_PORT_PB_DATA]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DATA, $r0
|
||||
move.b $r0, [R_PORT_PB_DATA]
|
||||
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, r0
|
||||
move.b r0, [R_PORT_PB_DIR]
|
||||
move.b CONFIG_ETRAX_DEF_R_PORT_PB_DIR, $r0
|
||||
move.b $r0, [R_PORT_PB_DIR]
|
||||
|
||||
;; Setup the stack to a suitably high address.
|
||||
;; We assume 8 MB is the minimum DRAM in an eLinux
|
||||
;; 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
|
||||
;; in the flash (since we wont try to copy it to DRAM
|
||||
;; before unpacking). It is at _edata, but in flash.
|
||||
;; Use (_edata - basse) as offset to the current PC.
|
||||
|
||||
basse: move.d pc, r5
|
||||
and.d 0x7fffffff, r5 ; strip any non-cache bit
|
||||
subq 2, r5 ; compensate for the move.d pc instr
|
||||
move.d r5, r0 ; save for later - flash address of 'basse'
|
||||
add.d _edata, r5
|
||||
sub.d basse, r5 ; r5 = flash address of '_edata'
|
||||
|
||||
|
||||
basse: move.d $pc, $r5
|
||||
and.d 0x7fffffff, $r5 ; strip any non-cache bit
|
||||
subq 2, $r5 ; compensate for the move.d $pc instr
|
||||
move.d $r5, $r0 ; save for later - flash address of 'basse'
|
||||
add.d _edata, $r5
|
||||
sub.d basse, $r5 ; $r5 = flash address of '_edata'
|
||||
|
||||
;; Copy text+data to DRAM
|
||||
|
||||
move.d basse, r1 ; destination
|
||||
move.d _edata, r2 ; end destination
|
||||
1: move.w [r0+], r3
|
||||
move.w r3, [r1+]
|
||||
cmp.d r2, r1
|
||||
|
||||
move.d basse, $r1 ; destination
|
||||
move.d _edata, $r2 ; end destination
|
||||
1: move.w [$r0+], $r3
|
||||
move.w $r3, [$r1+]
|
||||
cmp.d $r2, $r1
|
||||
bcs 1b
|
||||
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)
|
||||
|
||||
moveq 0, r0
|
||||
move.d _edata, r1
|
||||
move.d _end, r2
|
||||
1: move.w r0, [r1+]
|
||||
cmp.d r2, r1
|
||||
|
||||
moveq 0, $r0
|
||||
move.d _edata, $r1
|
||||
move.d _end, $r2
|
||||
1: move.w $r0, [$r1+]
|
||||
cmp.d $r2, $r1
|
||||
bcs 1b
|
||||
nop
|
||||
|
||||
@ -94,16 +94,16 @@ basse: move.d pc, r5
|
||||
move.d $r10, [$r12]
|
||||
move.d _cmd_line_addr, $r12
|
||||
move.d $r11, [$r12]
|
||||
|
||||
;; Do the decompression and save compressed size in _inptr
|
||||
|
||||
jsr _decompress_kernel
|
||||
|
||||
;; Put start address of root partition in r9 so the kernel can use it
|
||||
;; Do the decompression and save compressed size in inptr
|
||||
|
||||
jsr decompress_kernel
|
||||
|
||||
;; Put start address of root partition in $r9 so the kernel can use it
|
||||
;; when mounting from flash
|
||||
|
||||
move.d [_input_data], r9 ; flash address of compressed kernel
|
||||
add.d [_inptr], r9 ; size of compressed kernel
|
||||
move.d [input_data], $r9 ; flash address of compressed kernel
|
||||
add.d [inptr], $r9 ; size of compressed kernel
|
||||
|
||||
;; Restore command line magic and address.
|
||||
move.d _cmd_line_magic, $r10
|
||||
@ -112,12 +112,12 @@ basse: move.d pc, r5
|
||||
move.d [$r11], $r11
|
||||
|
||||
;; 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
|
||||
|
||||
|
||||
.data
|
||||
|
||||
_input_data:
|
||||
input_data:
|
||||
.dword 0 ; used by the decompressor
|
||||
_cmd_line_magic:
|
||||
.dword 0
|
||||
|
@ -29,12 +29,10 @@
|
||||
#define OF(args) args
|
||||
#define STATIC static
|
||||
|
||||
void* memset(void* s, int c, size_t n);
|
||||
void* memcpy(void* __dest, __const void* __src,
|
||||
size_t __n);
|
||||
|
||||
#define memzero(s, n) memset ((s), 0, (n))
|
||||
void *memset(void *s, int c, size_t n);
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n);
|
||||
|
||||
#define memzero(s, n) memset((s), 0, (n))
|
||||
|
||||
typedef unsigned char uch;
|
||||
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 RESERVED 0xC0 /* bit 6,7: reserved */
|
||||
|
||||
#define get_byte() inbuf[inptr++]
|
||||
|
||||
#define get_byte() (inbuf[inptr++])
|
||||
|
||||
/* Diagnostic functions */
|
||||
#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 Tracev(x) {if (verbose) fprintf x ;}
|
||||
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||||
# define Tracec(c,x) {if (verbose && (c)) fprintf x ;}
|
||||
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||||
# define Tracev(x) do { \
|
||||
if (verbose) \
|
||||
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
|
||||
# define Assert(cond,msg)
|
||||
# define Assert(cond, msg)
|
||||
# define Trace(x)
|
||||
# define Tracev(x)
|
||||
# define Tracevv(x)
|
||||
# define Tracec(c,x)
|
||||
# define Tracecv(c,x)
|
||||
# define Tracec(c, x)
|
||||
# define Tracecv(c, x)
|
||||
#endif
|
||||
|
||||
static int fill_inbuf(void);
|
||||
static void flush_window(void);
|
||||
static void error(char *m);
|
||||
static void gzip_mark(void **);
|
||||
static void gzip_release(void **);
|
||||
|
||||
extern char *input_data; /* lives in head.S */
|
||||
|
||||
static long bytes_out = 0;
|
||||
static uch *output_data;
|
||||
static unsigned long output_ptr = 0;
|
||||
|
||||
|
||||
static void *malloc(int size);
|
||||
static void free(void *where);
|
||||
static void error(char *m);
|
||||
static void gzip_mark(void **);
|
||||
static void gzip_release(void **);
|
||||
|
||||
|
||||
static void puts(const char *);
|
||||
|
||||
/* the "heap" is put directly after the BSS ends, at end */
|
||||
|
||||
extern int end;
|
||||
static long free_mem_ptr = (long)&end;
|
||||
|
||||
|
||||
extern int _end;
|
||||
static long free_mem_ptr = (long)&_end;
|
||||
|
||||
#include "../../../../../lib/inflate.c"
|
||||
|
||||
static void *malloc(int size)
|
||||
{
|
||||
void *p;
|
||||
|
||||
if (size <0) error("Malloc error");
|
||||
if (size < 0)
|
||||
error("Malloc error");
|
||||
|
||||
free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */
|
||||
|
||||
@ -142,44 +152,47 @@ static void
|
||||
puts(const char *s)
|
||||
{
|
||||
#ifndef CONFIG_ETRAX_DEBUG_PORT_NULL
|
||||
while(*s) {
|
||||
while (*s) {
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT0
|
||||
while(!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL0_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL0_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT1
|
||||
while(!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL1_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL1_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT2
|
||||
while(!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL2_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL2_TR_DATA = *s++;
|
||||
#endif
|
||||
#ifdef CONFIG_ETRAX_DEBUG_PORT3
|
||||
while(!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
||||
while (!(*R_SERIAL3_STATUS & (1 << 5))) ;
|
||||
*R_SERIAL3_TR_DATA = *s++;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void*
|
||||
memset(void* s, int c, size_t n)
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
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*
|
||||
memcpy(void* __dest, __const void* __src,
|
||||
size_t __n)
|
||||
void *memcpy(void *__dest, __const void *__src, size_t __n)
|
||||
{
|
||||
int i;
|
||||
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.)
|
||||
*/
|
||||
|
||||
static void
|
||||
flush_window()
|
||||
static void flush_window(void)
|
||||
{
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out++ = *in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
ulg c = crc; /* temporary variable */
|
||||
unsigned n;
|
||||
uch *in, *out, ch;
|
||||
|
||||
in = window;
|
||||
out = &output_data[output_ptr];
|
||||
for (n = 0; n < outcnt; n++) {
|
||||
ch = *out = *in;
|
||||
out++;
|
||||
in++;
|
||||
c = crc_32_tab[((int)c ^ ch) & 0xff] ^ (c >> 8);
|
||||
}
|
||||
crc = c;
|
||||
bytes_out += (ulg)outcnt;
|
||||
output_ptr += (ulg)outcnt;
|
||||
outcnt = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
error(char *x)
|
||||
static void error(char *x)
|
||||
{
|
||||
puts("\n\n");
|
||||
puts(x);
|
||||
puts("\n\n -- System halted\n");
|
||||
|
||||
while(1); /* Halt */
|
||||
while (1); /* Halt */
|
||||
}
|
||||
|
||||
void
|
||||
setup_normal_output_buffer()
|
||||
void setup_normal_output_buffer(void)
|
||||
{
|
||||
output_data = (char *)KERNEL_LOAD_ADR;
|
||||
}
|
||||
|
||||
void
|
||||
decompress_kernel()
|
||||
void decompress_kernel(void)
|
||||
{
|
||||
char revision;
|
||||
|
||||
|
||||
/* input_data is set in head.S */
|
||||
inbuf = input_data;
|
||||
|
||||
@ -257,11 +268,10 @@ decompress_kernel()
|
||||
|
||||
makecrc();
|
||||
|
||||
__asm__ volatile ("move vr,%0" : "=rm" (revision));
|
||||
if (revision < 10)
|
||||
{
|
||||
__asm__ volatile ("move $vr,%0" : "=rm" (revision));
|
||||
if (revision < 10) {
|
||||
puts("You need an ETRAX 100LX to run linux 2.6\n");
|
||||
while(1);
|
||||
while (1);
|
||||
}
|
||||
|
||||
puts("Uncompressing Linux...\n");
|
||||
|
@ -2,12 +2,9 @@
|
||||
# Makefile for rescue (bootstrap) code
|
||||
#
|
||||
|
||||
CC = gcc-cris -mlinux $(LINUXINCLUDE)
|
||||
ccflags-y += -O2
|
||||
asflags-y += -traditional
|
||||
LD = gcc-cris -mlinux -nostdlib
|
||||
ldflags-y += -T $(obj)/rescue.ld
|
||||
OBJCOPY = objcopy-cris
|
||||
ccflags-y += -O2 $(LINUXINCLUDE)
|
||||
asflags-y += $(LINUXINCLUDE)
|
||||
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = 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,
|
||||
sizeof tm)) {
|
||||
spin_unlock(&rtc_lock);
|
||||
mutex_unlock(&rtc_lock);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
|
@ -426,12 +426,18 @@ static int dummy_write(struct tty_struct * tty,
|
||||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
dummy_write_room(struct tty_struct *tty)
|
||||
static int dummy_write_room(struct tty_struct *tty)
|
||||
{
|
||||
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
|
||||
init_dummy_console(void)
|
||||
{
|
||||
@ -444,14 +450,14 @@ init_dummy_console(void)
|
||||
dummy_driver.type = TTY_DRIVER_TYPE_SERIAL;
|
||||
dummy_driver.subtype = SERIAL_TYPE_NORMAL;
|
||||
dummy_driver.init_termios = tty_std_termios;
|
||||
/* Normally B9600 default... */
|
||||
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.init_termios.c_ispeed = 115200;
|
||||
dummy_driver.init_termios.c_ospeed = 115200;
|
||||
|
||||
dummy_driver.open = dummy_open;
|
||||
dummy_driver.close = dummy_close;
|
||||
dummy_driver.write = dummy_write;
|
||||
dummy_driver.write_room = dummy_write_room;
|
||||
dummy_driver.ops = &dummy_ops;
|
||||
if (tty_register_driver(&dummy_driver))
|
||||
panic("Couldn't register dummy serial driver\n");
|
||||
}
|
||||
|
@ -2,7 +2,6 @@
|
||||
# arch/cris/arch-v32/boot/Makefile
|
||||
#
|
||||
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary -R .note -R .comment
|
||||
|
||||
subdir- := compressed rescue
|
||||
|
@ -2,14 +2,10 @@
|
||||
# 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
|
||||
ccflags-y += -O2 -I $(srctree)/include/asm/mach/ -I $(srctree)/include/asm/arch
|
||||
LD = gcc-cris -mlinux -march=v32 -nostdlib
|
||||
ldflags-y += -T $(obj)/decompress.ld
|
||||
obj-y = head.o misc.o
|
||||
ldflags-y += -T $(srctree)/$(obj)/decompress.ld
|
||||
OBJECTS = $(obj)/head.o $(obj)/misc.o
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
|
||||
quiet_cmd_image = BUILD $@
|
||||
|
@ -7,9 +7,8 @@ ccflags-y += -O2 -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
|
||||
ldflags-y += -T $(obj)/rescue.ld
|
||||
ldflags-y += -T $(srctree)/$(obj)/rescue.ld
|
||||
LDPOSTFLAGS = -lgcc
|
||||
OBJCOPY = objcopy-cris
|
||||
OBJCOPYFLAGS = -O binary --remove-section=.bss
|
||||
obj-$(CONFIG_ETRAX_AXISFLASHMAP) = 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,
|
||||
sizeof tm)) {
|
||||
spin_unlock(&rtc_lock);
|
||||
mutex_unlock(&rtc_lock);
|
||||
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_)
|
||||
{
|
||||
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;
|
||||
local_irq_restore(flags);
|
||||
|
||||
wake_up_interruptible(&tty->write_wait);
|
||||
|
||||
if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
|
||||
tty->ldisc.write_wakeup)
|
||||
(tty->ldisc.write_wakeup)(tty);
|
||||
tty_wakeup(tty);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -404,12 +388,6 @@ static void rs_unthrottle(struct tty_struct * tty)
|
||||
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,
|
||||
unsigned int cmd, unsigned long arg)
|
||||
@ -422,14 +400,6 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file,
|
||||
}
|
||||
|
||||
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:
|
||||
printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
|
||||
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)
|
||||
{
|
||||
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 */
|
||||
if ((old_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.
|
||||
*/
|
||||
shutdown(info);
|
||||
if (tty->ops->flush_buffer)
|
||||
tty->ops->flush_buffer(tty);
|
||||
if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
|
||||
rs_flush_buffer(tty);
|
||||
tty_ldisc_flush(tty);
|
||||
info->event = 0;
|
||||
info->tty = NULL;
|
||||
if (info->blocked_open) {
|
||||
@ -955,7 +916,6 @@ static const struct tty_operations hp_ops = {
|
||||
.stop = rs_stop,
|
||||
.start = rs_start,
|
||||
.hangup = rs_hangup,
|
||||
.break_ctl = rs_break,
|
||||
.wait_until_sent = rs_wait_until_sent,
|
||||
.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_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
|
||||
obj-$(CONFIG_KVM) += kvm.o
|
||||
|
@ -187,6 +187,9 @@ int kvm_dev_ioctl_check_extension(long ext)
|
||||
|
||||
r = 1;
|
||||
break;
|
||||
case KVM_CAP_COALESCED_MMIO:
|
||||
r = KVM_COALESCED_MMIO_PAGE_OFFSET;
|
||||
break;
|
||||
default:
|
||||
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,
|
||||
gpa_t addr)
|
||||
gpa_t addr, int len, int is_write)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -231,7 +234,7 @@ static int handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
|
||||
kvm_run->exit_reason = KVM_EXIT_MMIO;
|
||||
return 0;
|
||||
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 (!p->dir)
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -1460,6 +1455,9 @@ int kvm_arch_set_memory_region(struct kvm *kvm,
|
||||
return 0;
|
||||
}
|
||||
|
||||
void kvm_arch_flush_shadow(struct kvm *kvm)
|
||||
{
|
||||
}
|
||||
|
||||
long kvm_arch_dev_ioctl(struct file *filp,
|
||||
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
|
||||
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
|
||||
tristate "Atari MIDI serial support"
|
||||
depends on ATARI
|
||||
@ -578,18 +556,6 @@ config MAC_HID
|
||||
depends on INPUT_ADBHID
|
||||
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
|
||||
tristate "HP DCA serial support"
|
||||
depends on DIO && SERIAL_8250
|
||||
@ -640,7 +606,7 @@ config DN_SERIAL
|
||||
|
||||
config SERIAL_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---
|
||||
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
|
||||
|
@ -13,7 +13,7 @@
|
||||
# Copyright (C) 1994 by Hamish Macdonald
|
||||
#
|
||||
|
||||
KBUILD_DEFCONFIG := amiga_defconfig
|
||||
KBUILD_DEFCONFIG := multi_defconfig
|
||||
|
||||
# override top level makefile
|
||||
AS += -m68020
|
||||
|
@ -36,14 +36,11 @@
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
unsigned long amiga_model;
|
||||
EXPORT_SYMBOL(amiga_model);
|
||||
static unsigned long amiga_model;
|
||||
|
||||
unsigned long amiga_eclock;
|
||||
EXPORT_SYMBOL(amiga_eclock);
|
||||
|
||||
unsigned long amiga_masterclock;
|
||||
|
||||
unsigned long amiga_colorclock;
|
||||
EXPORT_SYMBOL(amiga_colorclock);
|
||||
|
||||
@ -51,7 +48,9 @@ unsigned long amiga_chipset;
|
||||
EXPORT_SYMBOL(amiga_chipset);
|
||||
|
||||
unsigned char amiga_vblank;
|
||||
unsigned char amiga_psfreq;
|
||||
EXPORT_SYMBOL(amiga_vblank);
|
||||
|
||||
static unsigned char amiga_psfreq;
|
||||
|
||||
struct amiga_hw_present 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 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 int amiga_get_hardware_list(char *buffer);
|
||||
/* amiga specific timer functions */
|
||||
@ -107,8 +104,6 @@ static void amiga_reset(void);
|
||||
extern void amiga_init_sound(void);
|
||||
static void amiga_mem_console_write(struct console *co, const char *b,
|
||||
unsigned int count);
|
||||
void amiga_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count);
|
||||
#ifdef CONFIG_HEARTBEAT
|
||||
static void amiga_heartbeat(int on);
|
||||
#endif
|
||||
@ -418,8 +413,7 @@ void __init config_amiga(void)
|
||||
mach_heartbeat = amiga_heartbeat;
|
||||
#endif
|
||||
|
||||
/* Fill in the clock values (based on the 700 kHz E-Clock) */
|
||||
amiga_masterclock = 40*amiga_eclock; /* 28 MHz */
|
||||
/* Fill in the clock value (based on the 700 kHz E-Clock) */
|
||||
amiga_colorclock = 5*amiga_eclock; /* 3.5 MHz */
|
||||
|
||||
/* 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,
|
||||
unsigned int count)
|
||||
static void amiga_serial_console_write(struct console *co, const char *s,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
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)
|
||||
{
|
||||
amiga_serial_console_write(NULL, s, strlen(s));
|
||||
|
@ -20,14 +20,6 @@
|
||||
#include <asm/atarihw.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
|
||||
* not be repeated; used by kgdb */
|
||||
int atari_SCC_reset_done;
|
||||
@ -47,8 +39,8 @@ static inline void ata_mfp_out(char c)
|
||||
mfp.usart_dta = c;
|
||||
}
|
||||
|
||||
void atari_mfp_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_mfp_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
@ -66,8 +58,8 @@ static inline void ata_scc_out(char c)
|
||||
scc.cha_b_data = c;
|
||||
}
|
||||
|
||||
void atari_scc_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_scc_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
@ -83,8 +75,8 @@ static inline void ata_midi_out(char c)
|
||||
acia.mid_data = c;
|
||||
}
|
||||
|
||||
void atari_midi_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void atari_midi_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
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)
|
||||
{
|
||||
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
|
||||
* serial console code.
|
||||
*/
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
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
|
||||
@ -193,8 +181,6 @@ void atari_init_mfp_port(int cflag)
|
||||
mfp.tim_dt_d = baud_table[baud];
|
||||
mfp.tim_ct_cd |= 0x01; /* start timer D, 1:4 */
|
||||
mfp.trn_stat |= 0x01; /* enable TX */
|
||||
|
||||
atari_MFP_init_done = 1;
|
||||
}
|
||||
|
||||
#define SCC_WRITE(reg, val) \
|
||||
@ -214,11 +200,7 @@ void atari_init_mfp_port(int cflag)
|
||||
MFPDELAY(); \
|
||||
} while (0)
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init atari_init_scc_port(int cflag)
|
||||
#else
|
||||
void atari_init_scc_port(int cflag)
|
||||
#endif
|
||||
{
|
||||
extern int atari_SCC_reset_done;
|
||||
static int clksrc_table[9] =
|
||||
@ -277,14 +259,9 @@ void atari_init_scc_port(int cflag)
|
||||
SCC_WRITE(5, reg5 | 8);
|
||||
|
||||
atari_SCC_reset_done = 1;
|
||||
atari_SCC_init_done = 1;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
static void __init atari_init_midi_port(int cflag)
|
||||
#else
|
||||
void atari_init_midi_port(int cflag)
|
||||
#endif
|
||||
{
|
||||
int baud = cflag & CBAUD;
|
||||
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_unfl.o x_unimp.o x_unsupp.o bugfix.o skeleton.o
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
EXTRA_LDFLAGS := -x
|
||||
|
||||
$(OS_OBJS): fpsp.h
|
||||
|
@ -6,5 +6,4 @@
|
||||
|
||||
obj-y := fskeleton.o iskeleton.o os.o
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
EXTRA_LDFLAGS := -x
|
||||
|
@ -16,5 +16,3 @@ devres-y = ../../../kernel/irq/devres.o
|
||||
|
||||
obj-$(CONFIG_PCI) += bios32.o
|
||||
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/setup.h>
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/irq.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/machdep.h>
|
||||
@ -40,6 +41,11 @@
|
||||
#include <asm/dvma.h>
|
||||
#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;
|
||||
EXPORT_SYMBOL(m68k_machtype);
|
||||
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 mvme147_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_atari(void);
|
||||
@ -183,6 +190,8 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
|
||||
unknown = mvme147_parse_bootinfo(record);
|
||||
else if (MACH_IS_HP300)
|
||||
unknown = hp300_parse_bootinfo(record);
|
||||
else if (MACH_IS_APOLLO)
|
||||
unknown = apollo_parse_bootinfo(record);
|
||||
else
|
||||
unknown = 1;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* ld script to make m68k Linux kernel */
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||
OUTPUT_ARCH(m68k)
|
||||
@ -41,7 +42,7 @@ SECTIONS
|
||||
_edata = .; /* End of data section */
|
||||
|
||||
/* will be freed after init */
|
||||
. = ALIGN(4096); /* Init code and data */
|
||||
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||
__init_begin = .;
|
||||
.init.text : {
|
||||
_sinittext = .;
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* ld script to make m68k Linux kernel */
|
||||
|
||||
#include <asm-generic/vmlinux.lds.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
|
||||
OUTPUT_ARCH(m68k)
|
||||
@ -34,7 +35,7 @@ SECTIONS
|
||||
_edata = .;
|
||||
|
||||
/* will be freed after init */
|
||||
. = ALIGN(8192); /* Init code and data */
|
||||
. = ALIGN(PAGE_SIZE); /* Init code and data */
|
||||
__init_begin = .;
|
||||
.init.text : {
|
||||
_sinittext = .;
|
||||
@ -61,12 +62,12 @@ __init_begin = .;
|
||||
}
|
||||
SECURITY_INIT
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
. = ALIGN(8192);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__initramfs_start = .;
|
||||
.init.ramfs : { *(.init.ramfs) }
|
||||
__initramfs_end = .;
|
||||
#endif
|
||||
. = ALIGN(8192);
|
||||
. = ALIGN(PAGE_SIZE);
|
||||
__init_end = .;
|
||||
.data.init.task : { *(.data.init_task) }
|
||||
|
||||
|
@ -2,7 +2,5 @@
|
||||
# Makefile for m68k-specific library files..
|
||||
#
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
||||
lib-y := ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \
|
||||
checksum.o string.o uaccess.o
|
||||
|
@ -2,5 +2,5 @@
|
||||
# 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
|
||||
|
@ -23,9 +23,7 @@
|
||||
/* #define DEBUG_IRQS */
|
||||
|
||||
int baboon_present;
|
||||
volatile struct baboon *baboon;
|
||||
|
||||
irqreturn_t baboon_irq(int, void *);
|
||||
static volatile struct baboon *baboon;
|
||||
|
||||
#if 0
|
||||
extern int macide_ack_intr(struct ata_channel *);
|
||||
@ -49,21 +47,11 @@ void __init baboon_init(void)
|
||||
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.
|
||||
*/
|
||||
|
||||
irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||
static irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||
{
|
||||
int irq_bit, irq_num;
|
||||
unsigned char events;
|
||||
@ -95,6 +83,16 @@ irqreturn_t baboon_irq(int irq, void *dev_id)
|
||||
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) {
|
||||
#ifdef DEBUG_IRQUSE
|
||||
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 */
|
||||
|
||||
struct mac_booter_data mac_bi_data;
|
||||
int mac_bisize = sizeof mac_bi_data;
|
||||
|
||||
/* New m68k bootinfo stuff and videobase */
|
||||
|
||||
@ -55,10 +54,8 @@ extern struct mem_info m68k_memory[NUM_MEMINFO];
|
||||
|
||||
extern struct mem_info m68k_ramdisk;
|
||||
|
||||
void *mac_env; /* Loaded by the boot asm */
|
||||
|
||||
/* 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 */
|
||||
extern unsigned long mac_gettimeoffset(void);
|
||||
@ -79,6 +76,8 @@ extern void mac_mksound(unsigned int, unsigned int);
|
||||
extern void nubus_sweep_video(void);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -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;
|
||||
|
||||
@ -821,7 +820,7 @@ void __init mac_identify(void)
|
||||
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);
|
||||
}
|
||||
|
@ -51,6 +51,8 @@ extern void mac_serial_print(const char *);
|
||||
static int peng, line;
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
|
||||
void mac_debugging_short(int pos, short num)
|
||||
{
|
||||
#ifdef DEBUG_SCREEN
|
||||
@ -125,6 +127,8 @@ void mac_debugging_long(int pos, long addr)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* 0 */
|
||||
|
||||
#ifdef DEBUG_SERIAL
|
||||
/*
|
||||
* TODO: serial debug code
|
||||
@ -142,12 +146,6 @@ struct mac_SCC {
|
||||
|
||||
# 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 struct console mac_console_driver = {
|
||||
@ -171,8 +169,8 @@ static struct console mac_console_driver = {
|
||||
* this driver if Mac.
|
||||
*/
|
||||
|
||||
void mac_debug_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void mac_debug_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
mac_serial_print(str);
|
||||
}
|
||||
@ -209,8 +207,8 @@ static inline void mac_scca_out(char c)
|
||||
scc.cha_a_data = c;
|
||||
}
|
||||
|
||||
void mac_sccb_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
static void mac_sccb_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
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,
|
||||
unsigned int count)
|
||||
static void mac_scca_console_write(struct console *co, const char *str,
|
||||
unsigned int count)
|
||||
{
|
||||
while (count--) {
|
||||
if (*str == '\n')
|
||||
@ -265,14 +263,8 @@ void mac_scca_console_write(struct console *co, const char *str,
|
||||
barrier(); \
|
||||
} while(0)
|
||||
|
||||
#ifndef CONFIG_SERIAL_CONSOLE
|
||||
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
|
||||
*/
|
||||
@ -340,22 +332,9 @@ void mac_init_scc_port(int cflag, int port)
|
||||
SCCA_WRITE(3, reg3 | 1);
|
||||
SCCA_WRITE(5, reg5 | 8);
|
||||
}
|
||||
|
||||
mac_SCC_reset_done = 1;
|
||||
mac_SCC_init_done = 1;
|
||||
}
|
||||
#endif /* DEBUG_SERIAL */
|
||||
|
||||
void mac_init_scca_port(int cflag)
|
||||
{
|
||||
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)
|
||||
{
|
||||
if (!MACH_IS_MAC)
|
||||
|
@ -30,8 +30,8 @@
|
||||
int oss_present;
|
||||
volatile struct mac_oss *oss;
|
||||
|
||||
irqreturn_t oss_irq(int, void *);
|
||||
irqreturn_t oss_nubus_irq(int, void *);
|
||||
static irqreturn_t oss_irq(int, void *);
|
||||
static irqreturn_t oss_nubus_irq(int, void *);
|
||||
|
||||
extern irqreturn_t via1_irq(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.
|
||||
*/
|
||||
|
||||
irqreturn_t oss_irq(int irq, void *dev_id)
|
||||
static irqreturn_t oss_irq(int irq, void *dev_id)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
|
@ -36,7 +36,7 @@ irqreturn_t psc_irq(int, void *);
|
||||
* 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;
|
||||
|
||||
@ -55,7 +55,7 @@ void psc_debug_dump(void)
|
||||
* 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;
|
||||
|
||||
|
@ -45,7 +45,7 @@ volatile long *via_memory_bogon=(long *)&via_memory_bogon;
|
||||
int rbv_present;
|
||||
int 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
|
||||
|
@ -2,8 +2,6 @@
|
||||
# Makefile for the linux kernel.
|
||||
#
|
||||
|
||||
EXTRA_AFLAGS := -traditional
|
||||
|
||||
#EXTRA_AFLAGS += -DFPU_EMU_DEBUG
|
||||
#EXTRA_CFLAGS += -DFPU_EMU_DEBUG
|
||||
|
||||
|
@ -285,7 +285,6 @@ void __init paging_init(void)
|
||||
* to a couple of allocated pages
|
||||
*/
|
||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* Set up SFC/DFC registers
|
||||
|
@ -53,7 +53,6 @@ void __init paging_init(void)
|
||||
wp_works_ok = 0;
|
||||
#endif
|
||||
empty_zero_page = alloc_bootmem_pages(PAGE_SIZE);
|
||||
memset(empty_zero_page, 0, PAGE_SIZE);
|
||||
|
||||
address = PAGE_OFFSET;
|
||||
pg_dir = swapper_pg_dir;
|
||||
|
@ -41,14 +41,12 @@ static void q40_get_model(char *model);
|
||||
static int q40_get_hardware_list(char *buffer);
|
||||
extern void q40_sched_init(irq_handler_t handler);
|
||||
|
||||
extern unsigned long q40_gettimeoffset(void);
|
||||
extern int q40_hwclk(int, struct rtc_time *);
|
||||
extern unsigned int q40_get_ss(void);
|
||||
extern int q40_set_clock_mmss(unsigned long);
|
||||
static unsigned long q40_gettimeoffset(void);
|
||||
static int q40_hwclk(int, struct rtc_time *);
|
||||
static unsigned int q40_get_ss(void);
|
||||
static int q40_set_clock_mmss(unsigned long);
|
||||
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
|
||||
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
|
||||
extern void q40_reset(void);
|
||||
void q40_halt(void);
|
||||
extern void q40_waitbut(void);
|
||||
void q40_set_vectors(void);
|
||||
|
||||
@ -127,7 +125,7 @@ static void q40_heartbeat(int on)
|
||||
}
|
||||
#endif
|
||||
|
||||
void q40_reset(void)
|
||||
static void q40_reset(void)
|
||||
{
|
||||
halted = 1;
|
||||
printk("\n\n*******************************************\n"
|
||||
@ -137,7 +135,8 @@ void q40_reset(void)
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
void q40_halt(void)
|
||||
|
||||
static void q40_halt(void)
|
||||
{
|
||||
halted = 1;
|
||||
printk("\n\n*******************\n"
|
||||
@ -165,7 +164,8 @@ static unsigned int serports[] =
|
||||
{
|
||||
0x3f8,0x2f8,0x3e8,0x2e8,0
|
||||
};
|
||||
void q40_disable_irqs(void)
|
||||
|
||||
static void q40_disable_irqs(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
@ -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) {
|
||||
/* Write.... */
|
||||
@ -285,7 +285,7 @@ int q40_hwclk(int op, struct rtc_time *t)
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int q40_get_ss(void)
|
||||
static unsigned int q40_get_ss(void)
|
||||
{
|
||||
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.
|
||||
*/
|
||||
|
||||
int q40_set_clock_mmss(unsigned long nowtime)
|
||||
static int q40_set_clock_mmss(unsigned long nowtime)
|
||||
{
|
||||
int retval = 0;
|
||||
short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60;
|
||||
|
@ -2,6 +2,6 @@
|
||||
# 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
|
||||
|
@ -36,7 +36,7 @@ extern char _text, _end;
|
||||
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
|
||||
|
||||
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 idprom_init (void);
|
||||
extern int sun3_hwclk(int set, struct rtc_time *t);
|
||||
@ -114,7 +114,8 @@ static void sun3_halt (void)
|
||||
|
||||
/* 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;
|
||||
|
||||
@ -164,7 +165,7 @@ void __init config_sun3(void)
|
||||
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();
|
||||
intersil_clock->cmd_reg=(INTERSIL_RUN|INTERSIL_INT_DISABLE|INTERSIL_24H_MODE);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
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 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
|
||||
* 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
|
||||
* 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 */
|
||||
{ .name = "Sun 3/160 Series", .id_machtype = (SM_SUN3 | SM_3_160) },
|
||||
{ .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
|
||||
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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
# 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
|
||||
* to/from the current console device using the PROM.
|
||||
*
|
||||
@ -104,8 +104,6 @@ prom_query_input_device()
|
||||
return PROMDEV_ITTYB;
|
||||
}
|
||||
return PROMDEV_I_UNK;
|
||||
case PROM_AP1000:
|
||||
return PROMDEV_I_UNK;
|
||||
};
|
||||
}
|
||||
#endif
|
||||
@ -166,8 +164,6 @@ prom_query_output_device()
|
||||
};
|
||||
}
|
||||
break;
|
||||
case PROM_AP1000:
|
||||
return PROMDEV_I_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
|
||||
* library functions.
|
||||
*
|
||||
@ -31,11 +31,6 @@ extern void prom_ranges_init(void);
|
||||
|
||||
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;
|
||||
#ifndef CONFIG_SUN3
|
||||
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_halt();
|
||||
break;
|
||||
case 42: /* why not :-) */
|
||||
prom_vers = PROM_AP1000;
|
||||
break;
|
||||
|
||||
default:
|
||||
prom_printf("PROMLIB: Bad PROM version %d\n",
|
||||
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
|
||||
* 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.
|
||||
*
|
||||
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
|
||||
@ -37,10 +37,6 @@ prom_printf(char *fmt, ...)
|
||||
|
||||
bptr = ppbuf;
|
||||
|
||||
#ifdef CONFIG_AP1000
|
||||
ap_write(1,bptr,strlen(bptr));
|
||||
#else
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
if (kgdb_initialized) {
|
||||
printk("kgdb_initialized = %d\n", kgdb_initialized);
|
||||
@ -53,7 +49,6 @@ prom_printf(char *fmt, ...)
|
||||
|
||||
prom_putchar(ch);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
va_end(args);
|
||||
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);
|
||||
#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)
|
||||
|
||||
|
@ -30,7 +30,7 @@ void sun3_enable_interrupts(void)
|
||||
sun3_enable_irq(0);
|
||||
}
|
||||
|
||||
int led_pattern[8] = {
|
||||
static int led_pattern[8] = {
|
||||
~(0x80), ~(0x01),
|
||||
~(0x40), ~(0x02),
|
||||
~(0x20), ~(0x04),
|
||||
|
@ -330,6 +330,7 @@ config SGI_IP22
|
||||
select SGI_HAS_DS1286
|
||||
select SGI_HAS_I8042
|
||||
select SGI_HAS_INDYDOG
|
||||
select SGI_HAS_HAL2
|
||||
select SGI_HAS_SEEQ
|
||||
select SGI_HAS_WD93
|
||||
select SGI_HAS_ZILOG
|
||||
@ -386,7 +387,6 @@ config SGI_IP28
|
||||
select SGI_HAS_I8042
|
||||
select SGI_HAS_INDYDOG
|
||||
select SGI_HAS_HAL2
|
||||
select SGI_HAS_HAL2
|
||||
select SGI_HAS_SEEQ
|
||||
select SGI_HAS_WD93
|
||||
select SGI_HAS_ZILOG
|
||||
@ -558,6 +558,24 @@ config MACH_TX39XX
|
||||
config MACH_TX49XX
|
||||
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
|
||||
bool "Wind River PPMC board"
|
||||
select CEVT_R4K
|
||||
@ -899,7 +917,7 @@ config BOOT_ELF32
|
||||
|
||||
config MIPS_L1_CACHE_SHIFT
|
||||
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 "4" if PMC_MSP4200_EVAL
|
||||
default "5"
|
||||
|
@ -559,6 +559,13 @@ load-$(CONFIG_MACH_TX49XX) += 0xffffffff80100000
|
||||
#
|
||||
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 RBTX4937 board
|
||||
|
@ -81,8 +81,8 @@ void __init plat_mem_setup(void)
|
||||
|
||||
set_io_port_base(CKSEG1ADDR(GT_DEF_PCI0_IO_BASE));
|
||||
|
||||
/* I/O port resource must include LCD/buttons */
|
||||
ioport_resource.end = 0x0fffffff;
|
||||
/* I/O port resource */
|
||||
ioport_resource.end = 0x01ffffff;
|
||||
|
||||
/* These resources have been reserved by VIA SuperI/O chip. */
|
||||
for (i = 0; i < ARRAY_SIZE(cobalt_reserved_resources); i++)
|
||||
|
1314
arch/mips/configs/rb532_defconfig
Normal file
1314
arch/mips/configs/rb532_defconfig
Normal file
File diff suppressed because it is too large
Load Diff
@ -129,23 +129,6 @@ out:
|
||||
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.
|
||||
*/
|
||||
|
@ -354,7 +354,7 @@ einval: li v0, -EINVAL
|
||||
sys sys_mkdir 2
|
||||
sys sys_rmdir 1 /* 4040 */
|
||||
sys sys_dup 1
|
||||
sys sys_pipe 0
|
||||
sys sysm_pipe 0
|
||||
sys sys_times 1
|
||||
sys sys_ni_syscall 0
|
||||
sys sys_brk 1 /* 4045 */
|
||||
|
@ -219,7 +219,7 @@ sys_call_table:
|
||||
PTR sys_readv
|
||||
PTR sys_writev
|
||||
PTR sys_access /* 5020 */
|
||||
PTR sys_pipe
|
||||
PTR sysm_pipe
|
||||
PTR sys_select
|
||||
PTR sys_sched_yield
|
||||
PTR sys_mremap
|
||||
|
@ -141,7 +141,7 @@ EXPORT(sysn32_call_table)
|
||||
PTR compat_sys_readv
|
||||
PTR compat_sys_writev
|
||||
PTR sys_access /* 6020 */
|
||||
PTR sys_pipe
|
||||
PTR sysm_pipe
|
||||
PTR compat_sys_select
|
||||
PTR sys_sched_yield
|
||||
PTR sys_mremap
|
||||
|
@ -247,7 +247,7 @@ sys_call_table:
|
||||
PTR sys_mkdir
|
||||
PTR sys_rmdir /* 4040 */
|
||||
PTR sys_dup
|
||||
PTR sys_pipe
|
||||
PTR sysm_pipe
|
||||
PTR compat_sys_times
|
||||
PTR sys_ni_syscall
|
||||
PTR sys_brk /* 4045 */
|
||||
|
@ -40,7 +40,14 @@
|
||||
#include <asm/sysmips.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 error, res;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <asm/signal.h>
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
#include <asm/fpu.h>
|
||||
#include <asm/fpu_emulator.h>
|
||||
|
||||
#define SIGNALLING_NAN 0x7ff800007ff80000LL
|
||||
|
@ -49,3 +49,4 @@ obj-$(CONFIG_TOSHIBA_RBTX4938) += fixup-rbtx4938.o
|
||||
obj-$(CONFIG_VICTOR_MPC30X) += fixup-mpc30x.o
|
||||
obj-$(CONFIG_ZAO_CAPCELLA) += fixup-capcella.o
|
||||
obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
|
||||
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
|
||||
|
69
arch/mips/pci/fixup-rc32434.c
Normal file
69
arch/mips/pci/fixup-rc32434.c
Normal file
@ -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;
|
||||
}
|
207
arch/mips/pci/ops-rc32434.c
Normal file
207
arch/mips/pci/ops-rc32434.c
Normal file
@ -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,
|
||||
};
|
221
arch/mips/pci/pci-rc32434.c
Normal file
221
arch/mips/pci/pci-rc32434.c
Normal file
@ -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
|
||||
* 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)
|
||||
{
|
||||
|
7
arch/mips/rb532/Makefile
Normal file
7
arch/mips/rb532/Makefile
Normal file
@ -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
|
331
arch/mips/rb532/devices.c
Normal file
331
arch/mips/rb532/devices.c
Normal file
@ -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);
|
220
arch/mips/rb532/gpio.c
Normal file
220
arch/mips/rb532/gpio.c
Normal file
@ -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);
|
209
arch/mips/rb532/irq.c
Normal file
209
arch/mips/rb532/irq.c
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
158
arch/mips/rb532/prom.c
Normal file
158
arch/mips/rb532/prom.c
Normal file
@ -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);
|
||||
}
|
53
arch/mips/rb532/serial.c
Normal file
53
arch/mips/rb532/serial.c
Normal file
@ -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);
|
79
arch/mips/rb532/setup.c
Normal file
79
arch/mips/rb532/setup.c
Normal file
@ -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;
|
||||
}
|
||||
}
|
67
arch/mips/rb532/time.c
Normal file
67
arch/mips/rb532/time.c
Normal file
@ -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
Block a user