Commit 493455cc authored by Linus Torvalds's avatar Linus Torvalds

Import 2.4.0-test7

parent 1afb7b29
......@@ -1463,6 +1463,12 @@ E: lam836@cs.cuhk.hk
D: Author of the dialog utility, foundation
D: for Menuconfig's lxdialog.
N: Christoph Lameter
E: christoph@lameter.com
D: Digiboard PC/Xe and PC/Xi, Digiboard EPCA
D: Early protocol filter for bridging code
D: Bug fixes
N: Paul Laufer
E: pelaufer@csupomona.edu
D: Soundblaster driver fixes, ISAPnP quirk
......
......@@ -7219,7 +7219,29 @@ CONFIG_EQUALIZER
module, say M here and read Documentation/modules.txt. If unsure,
say N.
Ethertap network tap (EXPERIMENTAL)
Universal TUN/TAP device driver.
CONFIG_TUN
TUN/TAP provides packet reception and transmission for user space programs.
It can be viewed as a simple Point-to-Point or Ethernet device, which
instead of receiving packets from a physical media, receives them from
user space program and instead of sending packets via physical media
writes them to the user space program.
When a program opens /dev/net/tun, driver creates and registers
corresponding net device tunX or tapX. After a program closed above
devices, driver will automatically delete tunXX or tapXX device and all
routes corresponding to it.
Please read Documentation/networking/tuntap.txt for more information.
This driver is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called tun.o. If you want to compile it as a
module, say M here and read Documentation/modules.txt.
If you don't know what to use this for, you don't need it.
Ethertap network tap (OBSOLETE)
CONFIG_ETHERTAP
If you say Y here (and have said Y to "Kernel/User network link
driver", above) and create a character special file /dev/tap0 with
......
......@@ -20,7 +20,7 @@ linux-2.1.x and may not be usable on other architectures than intel now.
It is available from ftp.digi.com/ftp.digiboard.com. You can write me if
you need an patch for this driver.
Bernhard Kaindl (bkaindl@netway.at) 6. April 1997.
Bernhard Kaindl (bkaindl@netway.at) 6. April 1997.
Configuring the Driver
----------------------
......@@ -153,20 +153,18 @@ ports.
Sources of Information
----------------------
Web page: http://private.fuller.edu/clameter/digi.html
Please contact digi directly digilnux@dgii.com. Forward any information of
general interest to me.
Mailing list: digiboard@list.fuller.edu
Web page (mainly of historical interest): http://lameter.com/digi
(Write e-mail to that address to subscribe. Common ListServ commands work.
Archive of messages available)
Christoph Lameter (clameter@fuller.edu) 16. April 1996.
Christoph Lameter (christoph@lameter.com) Aug 14, 2000.
Supporting Tools
----------------
Some tools and more detailed information can be found at
ftp://ftp.fuller.edu/Linux/digi
Some (old) tools and more detailed information can be found at
ftp://lameter.com/digi
The "ditty" tool described in the Digiboard Manuals for other Unixes
is also available.
......
......@@ -81,16 +81,12 @@ Digi Intl. products:
-> FTP: ftp://dgii.com
-> Webpage: http://www.dgii.com
-> Webpage: http://private.fuller.edu/clameter/digi.html
-> Mailing List: digiboard@list.fuller.edu Note write e-mail to subscribe
common ListServ commands will not work.
-> Webpage: http://lameter.com/digi
Acknowledgments:
----------------
Much of this work (And even text) was derived from a similar document
supporting the original public domain DigiBoard driver Copyright (C)
1994,1995 Troy De Jongh. Many thanks to Christoph Lameter
(clameter@fuller.edu) and Mike McLagan (mike.mclagan@linux.org) who authored
(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored
and contributed to the original document.
......@@ -278,7 +278,7 @@
Author: Stephen C. Tweedie.
URL:
ftp://ftp.uk.linux.org:/pub/linux/sct/fs/jfs/journal-design.ps.gz
Keywords: ext3, journalist.
Keywords: ext3, journaling.
Description: Excellent 8-pages paper explaining the journaling
capabilities added to ext2 by the author, showing different
problems faced and the alternatives chosen.
......@@ -476,6 +476,14 @@
URL: http://www.linux-mag.com/2000-03/gear_01.html
Keywords: PCI, bus, bus-mastering.
Description: The title says it all.
* Title: "Linux 2.4 Kernel Internals"
Author: Tigran Aivazian.
URL: http://www.moses.uklinux.net/patches/lki.html
Keywords: Linux, kernel, VFS, SMP boot
Description: A little book used for a short training course
I gave on this subject at VERITAS. Covers building the kernel
image, booting (including SMP), process management, VFS and more.
BOOKS: (Not on-line)
......
......@@ -3063,7 +3063,7 @@ Some Examples:
** Tiara **
(model unknown)
-------------------------
- from Christoph Lameter <clameter@netcom.com>
- from Christoph Lameter <christoph@lameter.com>
Here is information about my card as far as I could figure it out:
......
NOTE: Ethertap is now an obsolete facility, and is scheduled
to be removed in the 2.5.x kernel series. Those writing
applications using ethertap should convert their code to
use the TUN/TAP driver instead, see 'tuntap.txt' in this
directory for more details. -DaveM
Ethertap programming mini-HOWTO
-------------------------------
......
Universal TUN/TAP device driver.
Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
Linux, Solaris drivers
Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.com>
FreeBSD TAP driver
Copyright (c) 1999-2000 Maksim Yevmenkin <m_evmenkin@yahoo.com>
1. Description
TUN/TAP provides packet reception and transmission for user space programs.
It can be viewed as a simple Point-to-Point or Ethernet device, which
instead of receiving packets from a physical media, receives them from
user space program and instead of sending packets via physical media
writes them to the user space program.
When a program opens /dev/net/tun, driver creates and registers corresponding
net device tunX or tapX. After a program closed above devices, driver will
automatically delete tunXX or tapXX device and all routes corresponding to it.
This package(http://vtun.sourceforge.net/tun) contains two simple example
programs how to use tun and tap devices. Both programs works like
bridge between two network interfaces.
br_select.c - bridge based on select system call.
br_sigio.c - bridge based on async io and SIGIO signal.
However the best example is VTun http://vtun.sourceforge.net :))
2. Installation
Run './configure' to configure the driver.
Run 'make install' to compile and install driver module and to create
/dev/net/tun device node.
3. Loading driver module
Linux
To load TUN/TAP driver module run:
modprobe tun
To configure automatic loading of the 'tun' module you have to add:
alias char-major-195 tun
to the /etc/conf.modules, and run:
modprobe -a
TUN/TAP driver will be automatically loaded when application access
/dev/net/tun.
If "Kernel module loader" - module auto-loading support is not enabled
in your kernel then you can add
modprobe tun
to one of the startup rc files.
4. Program interface
4.1 Network device allocation:
int tun_alloc(char *dev)
{
struct ifreq ifr;
int fd, err;
if( (fd = open("/dev/net/tun", O_RDWR)) < 0 )
return tun_alloc_old(dev);
memset(&ifr, 0, sizeof(ifr));
/* Flags: IFF_TUN - TUN device (no Ethernet headers)
* IFF_TAP - TAP device
*
* IFF_NO_PI - Do not provide packet information
*/
ifr.ifr_flags = IFF_TUN;
if( *dev )
strncpy(ifr.ifr_name, dev, IFNAMSIZ);
if( (err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0 ){
close(fd);
return err;
}
strcpy(dev, ifr.ifr_name);
return fd;
}
4.2 Frame format:
If flag IFF_NO_PI is not set each frame format is:
Flags [2 bytes]
Proto [2 bytes]
Raw protocol(IP, IPv6, etc) frame.
Universal TUN/TAP device driver Frequently Asked Question.
1. What is the TUN ?
The TUN is Virtual Point-to-Point network device.
TUN driver was designed as low level kernel support for
IP tunneling. It provides to userland application
two interfaces:
- /dev/tunX - character device;
- tunX - virtual Point-to-Point interface.
Userland application can write IP frame to /dev/tunX
and kernel will receive this frame from tunX interface.
In the same time every frame that kernel writes to tunX
interface can be read by userland application from /dev/tunX
device.
2. What is the TAP ?
The TAP is a Virtual Ethernet network device.
TAP driver was designed as low level kernel support for
Ethernet tunneling. It provides to userland application
two interfaces:
- /dev/tapX - character device;
- tapX - virtual Ethernet interface.
Userland application can write Ethernet frame to /dev/tapX
and kernel will receive this frame from tapX interface.
In the same time every frame that kernel writes to tapX
interface can be read by userland application from /dev/tapX
device.
3. What platforms are supported by TUN/TAP driver ?
Currently driver has been written for 3 Unices:
Linux kernels 2.2.x, 2.4.x
FreeBSD 3.x, 4.x, 5.x
Solaris 2.6, 7.0, 8.0
4. What is TUN/TAP driver used for?
As mentioned above, main purpose of TUN/TAP driver is tunneling.
It used by VTun (http://vtun.netpedia.net).
5. How does Virtual network device actually work ?
Virtual network device can be viewed as a simple Point-to-Point or
Ethernet device, which instead of receiving packets from a physical
media, receives them from user space program and instead of sending
packets via physical media sends them to the user space program.
Let's say that you configured IPX on the tap0, then whenever
kernel sends any IPX packet to tap0, it is passed to the application
(VTun for example). Application encrypts, compresses and sends it to
the other side over TCP or UDP. Application on other side decompress
and decrypts them and write packet to the TAP device, kernel handles
the packet like it came from real physical device.
6. What is the difference between TUN driver and TAP driver?
TUN works with IP frames. TAP works with Ethernet frames.
7. What is the difference between BPF and TUN/TAP driver?
BFP is a advanced packet filter. It can be attached to existing
network interface. It does not provide virtual network interface.
TUN/TAP driver does provide virtual network interface and it is possible
to attach BPF to this interface.
8. Does TAP driver support kernel Ethernet bridging?
Yes. Linux and FreeBSD drivers support Ethernet bridging.
......@@ -325,6 +325,13 @@ L: linux-net@vger.kernel.org
W: http://www.dgii.com/linux/
S: Maintained
DIGIBOARD PC/XE AND PC/XI DRIVER
P: Christoph Lameter
M: christoph@lameter.com
W: http://www.dgii.com/linux,http://lameter.com/digi
L: digilnux@dgii.com
S: Maintained
DISK GEOMETRY AND PARTITION HANDLING
P: Andries Brouwer
M: aeb@veritas.com
......
......@@ -331,6 +331,7 @@ CONFIG_NETDEVICES=y
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_EQUALIZER is not set
# CONFIG_TUN is not set
# CONFIG_NET_SB1000 is not set
#
......
......@@ -15,7 +15,7 @@
*
* Chris Beauregard August 9th, 1996
* - Rewrote /proc/mca
*
*
* Chris Beauregard January 7th, 1997
* - Added basic NMI-processing
* - Added more information to mca_info structure
......@@ -30,8 +30,11 @@
* - Fixed the output of 'Driver Installed' in /proc/mca/pos
* - Made the Integrated Video & SCSI show up even if they have id 0000
*
* AV November 9th, 1999
* - switched to regular procfs methods.
* Alexander Viro November 9th, 1999
* - Switched to regular procfs methods
*
* Alfred Arnold & David Weinehall August 23rd, 2000
* - Added support for Planar POS-registers
*/
#include <linux/module.h>
......@@ -50,9 +53,10 @@
#include <asm/uaccess.h>
#include <linux/init.h>
/* This structure holds MCA information. Each (plug-in) adapter has
/* This structure holds MCA information. Each (plug-in) adapter has
* eight POS registers. Then the machine may have integrated video and
* SCSI subsystems, which also have eight POS registers.
* Finally, the motherboard (planar) has got POS-registers.
* Other miscellaneous information follows.
*/
......@@ -92,7 +96,7 @@ struct MCA_info {
/* The mca_info structure pointer. If MCA bus is present, the function
* mca_probe() is invoked. The function puts motherboard, then all
* adapters into setup mode, allocates and fills an MCA_info structure,
* and points this pointer to the structure. Otherwise the pointer
* and points this pointer to the structure. Otherwise the pointer
* is set to zero.
*/
......@@ -194,7 +198,7 @@ void __init mca_init(void)
*/
/* Make sure the MCA bus is present */
if(!MCA_bus)
return;
printk("Micro Channel bus detected.\n");
......@@ -216,7 +220,16 @@ void __init mca_init(void)
outb_p(0, MCA_ADAPTER_SETUP_REG);
/* Put motherboard into video setup mode, read integrated video
/* Read motherboard POS registers */
outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG);
mca_info->slot[MCA_MOTHERBOARD].name[0] = 0;
for(j=0; j<8; j++) {
mca_info->slot[MCA_MOTHERBOARD].pos[j] = inb_p(MCA_POS_REG(j));
}
mca_configure_adapter_status(MCA_MOTHERBOARD);
/* Put motherboard into video setup mode, read integrated video
* POS registers, and turn motherboard setup off.
*/
......@@ -242,7 +255,7 @@ void __init mca_init(void)
outb_p(0xf7, MCA_MOTHERBOARD_SETUP_REG);
mca_info->slot[MCA_INTEGSCSI].name[0] = 0;
for(j=0; j<8; j++) {
if((mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff)
if((mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j))) != 0xff)
{
/* 0xff all across means no device. 0x00 means
* something's broken, but a device is probably there.
......@@ -256,17 +269,17 @@ void __init mca_init(void)
mca_info->which_scsi = 0xf7;
}
}
if(!mca_info->which_scsi) {
if(!mca_info->which_scsi) {
/* Didn't find it at 0xf7, try somewhere else... */
mca_info->which_scsi = 0xfd;
outb_p(0xfd, MCA_MOTHERBOARD_SETUP_REG);
for(j=0; j<8; j++)
for(j=0; j<8; j++)
mca_info->slot[MCA_INTEGSCSI].pos[j] = inb_p(MCA_POS_REG(j));
}
mca_configure_adapter_status(MCA_INTEGSCSI);
/* Turn off motherboard setup */
outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
......@@ -311,6 +324,9 @@ static void mca_handle_nmi_slot(int slot, int check_flag)
} else if(slot == MCA_INTEGVIDEO) {
printk("NMI: caused by MCA integrated video adapter (%s)\n",
mca_info->slot[slot].name);
} else if(slot == MCA_MOTHERBOARD) {
printk("NMI: caused by motherboard (%s)\n",
mca_info->slot[slot].name);
}
/* More info available in POS 6 and 7? */
......@@ -375,7 +391,7 @@ void mca_handle_nmi(void)
*
* Disabled adapters are not reported.
*/
int mca_find_adapter(int id, int start)
{
if(mca_info == NULL || id == 0xffff) {
......@@ -423,7 +439,7 @@ EXPORT_SYMBOL(mca_find_adapter);
* to scan for further cards when some may already be driven.
*/
int mca_find_unused_adapter(int id, int start)
int mca_find_unused_adapter(int id, int start)
{
if(mca_info == NULL || id == 0xffff) {
return MCA_NOTFOUND;
......@@ -450,7 +466,7 @@ int mca_find_unused_adapter(int id, int start)
}
return MCA_NOTFOUND;
} /* mca_find_unused_adapter() */
} /* mca_find_unused_adapter() */
EXPORT_SYMBOL(mca_find_unused_adapter);
......@@ -465,8 +481,8 @@ EXPORT_SYMBOL(mca_find_unused_adapter);
* when it scanned the MCA space. The register value is returned.
* Missing or invalid registers report 0.
*/
unsigned char mca_read_stored_pos(int slot, int reg)
unsigned char mca_read_stored_pos(int slot, int reg)
{
if(slot < 0 || slot >= MCA_NUMADAPTERS || mca_info == NULL) return 0;
if(reg < 0 || reg >= 8) return 0;
......@@ -487,9 +503,8 @@ EXPORT_SYMBOL(mca_read_stored_pos);
* may not be invoked from interrupt context. It handles the
* deep magic required for onboard devices transparently.
*/
unsigned char mca_read_pos(int slot, int reg)
unsigned char mca_read_pos(int slot, int reg)
{
unsigned int byte = 0;
unsigned long flags;
......@@ -524,6 +539,14 @@ unsigned char mca_read_pos(int slot, int reg)
byte = inb_p(MCA_POS_REG(reg));
outb_p(0xff, MCA_MOTHERBOARD_SETUP_REG);
} else if(slot == MCA_MOTHERBOARD) {
/* Disable adapter setup, enable motherboard setup */
outb_p(0, MCA_ADAPTER_SETUP_REG);
outb_p(0x7f, MCA_MOTHERBOARD_SETUP_REG);
byte = inb_p(MCA_POS_REG(reg));
outp_b(0xff, MCA_MOTHERBOARD_SETUP_REG);
} else if(slot < MCA_MAX_SLOT_NR) {
/* Make sure motherboard setup is off */
......@@ -556,7 +579,7 @@ EXPORT_SYMBOL(mca_read_pos);
* @reg: register to read from
* @byte: byte to write to the POS registers
*
* Store a POS value directly from the hardware. You should not
* Store a POS value directly from the hardware. You should not
* normally need to use this function and should have a very good
* knowledge of MCA bus before you do so. Doing this wrongly can
* damage the hardware.
......@@ -574,7 +597,7 @@ EXPORT_SYMBOL(mca_read_pos);
* screws up.
*/
void mca_write_pos(int slot, int reg, unsigned char byte)
void mca_write_pos(int slot, int reg, unsigned char byte)
{
unsigned long flags;
......@@ -615,11 +638,11 @@ EXPORT_SYMBOL(mca_write_pos);
* @name: text string for the namen
*
* This function sets the name reported via /proc for this
* adapter slot. This is for user information only. Setting a
* adapter slot. This is for user information only. Setting a
* name deletes any previous name.
*/
void mca_set_adapter_name(int slot, char* name)
void mca_set_adapter_name(int slot, char* name)
{
if(mca_info == NULL) return;
......@@ -640,7 +663,7 @@ EXPORT_SYMBOL(mca_set_adapter_name);
/**
* mca_set_adapter_procfn - Set the /proc callback
* @slot: slot to configure
* @procfn: callback function to call for /proc
* @procfn: callback function to call for /proc
* @dev: device information passed to the callback
*
* This sets up an information callback for /proc/mca/slot?. The
......@@ -648,7 +671,7 @@ EXPORT_SYMBOL(mca_set_adapter_name);
* some equally informative context information, or nothing, if you
* prefer), and is expected to put useful information into the
* buffer. The adapter name, ID, and POS registers get printed
* before this is called though, so don't do it again.
* before this is called though, so don't do it again.
*
* This should be called with a %NULL @procfn when a module
* unregisters, thus preventing kernel crashes and other such
......@@ -722,8 +745,8 @@ EXPORT_SYMBOL(mca_mark_as_unused);
* Return the adapter description if set. If it has not been
* set or the slot is out range then return NULL.
*/
char *mca_get_adapter_name(int slot)
char *mca_get_adapter_name(int slot)
{
if(mca_info == NULL) return 0;
......@@ -789,14 +812,12 @@ int get_mca_info(char *page, char **start, off_t off,
{
int i, j, len = 0;
if(MCA_bus && mca_info != NULL)
{
if(MCA_bus && mca_info != NULL) {
/* Format POS registers of eight MCA slots */
for(i=0; i<MCA_MAX_SLOT_NR; i++)
{
for(i=0; i<MCA_MAX_SLOT_NR; i++) {
len += sprintf(page+len, "Slot %d: ", i+1);
for(j=0; j<8; j++)
for(j=0; j<8; j++)
len += sprintf(page+len, "%02x ", mca_info->slot[i].pos[j]);
len += sprintf(page+len, " %s\n", mca_info->slot[i].name);
}
......@@ -804,19 +825,26 @@ int get_mca_info(char *page, char **start, off_t off,
/* Format POS registers of integrated video subsystem */
len += sprintf(page+len, "Video : ");
for(j=0; j<8; j++)
for(j=0; j<8; j++)
len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGVIDEO].pos[j]);
len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGVIDEO].name);
/* Format POS registers of integrated SCSI subsystem */
len += sprintf(page+len, "SCSI : ");
for(j=0; j<8; j++)
len += sprintf(page+len, "%02x ", mca_info->slot[MCA_INTEGSCSI].pos[j]);
len += sprintf(page+len, " %s\n", mca_info->slot[MCA_INTEGSCSI].name);
/* Format POS registers of motherboard */
len += sprintf(page+len, "Planar: ");
for(j=0; j<8; j++)
len += sprintf(page+len, "%02x ", mca_info->slot[MCA_MOTHERBOARD].pos[j]);
len += sprintf(page+len, " %s\n", mca_info->slot[MCA_MOTHERBOARD].name);
} else {
/* Leave it empty if MCA not detected - this should *never*
* happen!
* happen!
*/
}
......@@ -843,6 +871,8 @@ static int mca_default_procfn(char* buf, struct MCA_adapter *p)
len += sprintf(buf+len, "Integrated SCSI Adapter\n");
} else if(slot == MCA_INTEGVIDEO) {
len += sprintf(buf+len, "Integrated Video Adapter\n");
} else if(slot == MCA_MOTHERBOARD) {
len += sprintf(buf+len, "Motherboard\n");
}
if(p->name[0]) {
......@@ -932,6 +962,7 @@ void __init mca_do_proc_init(void)
if(i < MCA_MAX_SLOT_NR) sprintf(p->procname,"slot%d", i+1);
else if(i == MCA_INTEGVIDEO) sprintf(p->procname,"video");
else if(i == MCA_INTEGSCSI) sprintf(p->procname,"scsi");
else if(i == MCA_MOTHERBOARD) sprintf(p->procname,"planar");
if(!mca_isadapter(i)) continue;
......
......@@ -16,7 +16,7 @@
* Intel Mobile Pentium II detection fix. Sean Gilley, June 1999.
*
* IDT Winchip tweaks, misc clean ups.
* Dave Jones <dave@powertweak.com>, August 1999
* Dave Jones <davej@suse.de>, August 1999
*
* Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999
*
......@@ -27,7 +27,7 @@
* David Parsons <orc@pell.chi.il.us>, July-August 1999
*
* Cleaned up cache-detection code
* Dave Jones <dave@powertweak.com>, October 1999
* Dave Jones <davej@suse.de>, October 1999
*
* Added proper L2 cache detection for Coppermine
* Dragan Stancevic <visitor@valinux.com>, October 1999
......@@ -38,7 +38,7 @@
*
* Detection for Celeron coppermine, identify_cpu() overhauled,
* and a few other clean ups.
* Dave Jones <dave@powertweak.com>, April 2000
* Dave Jones <davej@suse.de>, April 2000
*
* Pentium III FXSR, SSE support
* General FPU state handling cleanups
......@@ -48,6 +48,9 @@
* and 8-way type cache happy bunch from Intel:^)
* Dragan Stancevic <visitor@valinux.com>, May 2000
*
* Forward port AMD Duron errata T13 from 2.2.17pre
* Dave Jones <davej@suse.de>, August 2000
*
*/
/*
......@@ -934,7 +937,7 @@ static int __init amd_model(struct cpuinfo_x86 *c)
break;
}
break;
case 6: /* An Athlon. We can trust the BIOS probably */
case 6: /* An Athlon/Duron. We can trust the BIOS probably */
break;
}
......@@ -945,10 +948,19 @@ static int __init amd_model(struct cpuinfo_x86 *c)
edx>>24, ecx>>24, edx&0xFF);
c->x86_cache_size=(ecx>>24)+(edx>>24);
}
if (n >= 0x80000006) {
cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
printk("CPU: L2 Cache: %dK\n", ecx>>16);
c->x86_cache_size=(ecx>>16);
/* AMD errata T13 (order #21922) */
if (boot_cpu_data.x86 == 6 && boot_cpu_data.x86_model == 3 &&
boot_cpu_data.x86_mask == 0)
{
c->x86_cache_size = 64;
printk("CPU: L2 Cache: 64K\n");
} else {
if (n >= 0x80000006) {
cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
printk("CPU: L2 Cache: %dK\n", ecx>>16);
c->x86_cache_size=(ecx>>16);
}
}
return r;
......@@ -1547,7 +1559,7 @@ void __init identify_cpu(struct cpuinfo_x86 *c)
if(c->x86_vendor == X86_VENDOR_NEXGEN)
c->x86_cache_size = 256; /* A few had 1Mb.. */
for (i = 0; i < sizeof(cpu_models)/sizeof(struct cpu_model_info); i++) {
if (cpu_models[i].vendor == c->x86_vendor &&
cpu_models[i].x86 == c->x86) {
......@@ -1579,8 +1591,8 @@ void __init dodgy_tsc(void)
cyrix_model(&boot_cpu_data);
}
static char *cpu_vendor_names[] __initdata = {
"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
......
# $Id: config.in,v 1.101 2000/08/09 18:25:31 anton Exp $
# $Id: config.in,v 1.102 2000/08/23 05:59:28 davem Exp $
# For a description of the syntax of this configuration file,
# see Documentation/kbuild/config-language.txt.
#
......@@ -202,9 +202,10 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then
tristate ' Dummy net driver support' CONFIG_DUMMY
tristate ' Bonding driver support' CONFIG_BONDING
tristate ' Universal TUN/TAP device driver support' CONFIG_TUN
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_NETLINK" = "y" ]; then
tristate ' Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP
tristate ' Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
fi
fi
tristate ' PPP (point-to-point) support' CONFIG_PPP
......
#!/bin/sh
case $1 in
-printf)
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
/g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/printf ("#define AOFF_'$2'_\0 0x%08x\\n", check_asm_data[i++]); printf("#define ASIZ_'$2'_\0 0x%08x\\n", check_asm_data[i++]);/' >> $4
echo "printf (\"#define ASIZ_$2\\t0x%08x\\n\", check_asm_data[i++]);" >> $4
;;
-data)
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
/g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/ ((char *)\&((struct '$2'_struct *)0)->\0) - ((char *)((struct '$2'_struct *)0)), sizeof(((struct '$2'_struct *)0)->\0),/' >> $4
echo " sizeof(struct $2_struct)," >> $4
;;
......
# $Id: config.in,v 1.120 2000/08/09 08:45:39 anton Exp $
# $Id: config.in,v 1.121 2000/08/23 05:59:28 davem Exp $
# For a description of the syntax of this configuration file,
# see the Configure script.
#
......@@ -236,9 +236,10 @@ if [ "$CONFIG_NET" = "y" ]; then
if [ "$CONFIG_NETDEVICES" = "y" ]; then
tristate ' Dummy net driver support' CONFIG_DUMMY
tristate ' Bonding driver support' CONFIG_BONDING
tristate ' Universal TUN/TAP device driver support' CONFIG_TUN
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_NETLINK" = "y" ]; then
tristate ' Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP
tristate ' Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
fi
fi
tristate ' PPP (point-to-point) support' CONFIG_PPP
......
......@@ -454,6 +454,7 @@ CONFIG_SUNRPC=y
CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_SMB_FS=m
CONFIG_SMB_NLS_REMOTE=""
# CONFIG_NCP_FS is not set
# CONFIG_NCPFS_PACKET_SIGNING is not set
# CONFIG_NCPFS_IOCTL_LOCKING is not set
......
#!/bin/sh
case $1 in
-printf)
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
/g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/printf ("#define AOFF_'$2'_\0 0x%08x\\n", check_asm_data[i++]); printf("#define ASIZ_'$2'_\0 0x%08x\\n", check_asm_data[i++]);/' >> $4
echo "printf (\"#define ASIZ_$2\\t0x%08x\\n\", check_asm_data[i++]);" >> $4
;;
-data)
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
sed -n -e '/struct[ ]*'$2'_struct[ ]*{/,/};/p' < $3 | sed '/struct[ ]*'$2'_struct[ ]*{/d;/:[0-9]*[ ]*;/d;/^[ ]*$/d;/};/d;s/^[ ]*//;s/volatile[ ]*//;s/\(unsigned\|signed\|struct\)[ ]*//;s/\(\[\|__attribute__\).*;[ ]*$//;s/(\*//;s/)(.*)//;s/;[ ]*$//;s/^[^ ]*[ ]*//;s/,/\
/g' | sed 's/^[ *]*//;s/[ ]*$//;s/^.*$/ ((char *)\&((struct '$2'_struct *)0)->\0) - ((char *)((struct '$2'_struct *)0)), sizeof(((struct '$2'_struct *)0)->\0),/' >> $4
echo " sizeof(struct $2_struct)," >> $4
;;
......
/* $Id: sys_sparc32.c,v 1.162 2000/08/16 15:33:30 davem Exp $
/* $Id: sys_sparc32.c,v 1.163 2000/08/22 10:09:10 jj Exp $
* sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
*
* Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
......@@ -48,6 +48,7 @@
#include <linux/ipv6.h>
#include <linux/in.h>
#include <linux/icmpv6.h>
#include <linux/sysctl.h>
#include <asm/types.h>
#include <asm/ipc.h>
......@@ -4161,3 +4162,51 @@ asmlinkage int sys_setpriority32(u32 which, u32 who, u32 niceval)
(int) who,
(int) niceval);
}
struct __sysctl_args32 {
u32 name;
int nlen;
u32 oldval;
u32 oldlenp;
u32 newval;
u32 newlen;
u32 __unused[4];
};
extern asmlinkage long sys32_sysctl(struct __sysctl_args32 *args)
{
struct __sysctl_args32 tmp;
int error;
size_t oldlen, *oldlenp = NULL;
unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7;
if (copy_from_user(&tmp, args, sizeof(tmp)))
return -EFAULT;
if (tmp.oldval && tmp.oldlenp) {
/* Duh, this is ugly and might not work if sysctl_args
is in read-only memory, but do_sysctl does indirectly
a lot of uaccess in both directions and we'd have to
basically copy the whole sysctl.c here, and
glibc's __sysctl uses rw memory for the structure
anyway. */
if (get_user(oldlen, (u32 *)A(tmp.oldlenp)) ||
put_user(oldlen, (size_t *)addr))
return -EFAULT;
oldlenp = (size_t *)addr;
}
lock_kernel();
error = do_sysctl((int *)A(tmp.name), tmp.nlen, (void *)A(tmp.oldval),
oldlenp, (void *)A(tmp.newval), tmp.newlen);
unlock_kernel();
if (oldlenp) {
if (!error) {
if (get_user(oldlen, (size_t *)addr) ||
put_user(oldlen, (u32 *)A(tmp.oldlenp)))
error = -EFAULT;
}
copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused));
}
return error;
}
/* $Id: systbls.S,v 1.76 2000/08/12 20:49:49 jj Exp $
/* $Id: systbls.S,v 1.77 2000/08/22 10:09:10 jj Exp $
* systbls.S: System call entry point tables for OS compatibility.
* The native Linux system call table lives here also.
*
......@@ -69,7 +69,7 @@ sys_call_table32:
.word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, sys32_nanosleep
/*250*/ .word sys32_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
.word sys_aplib
/* Now the 64-bit native Linux syscall table. */
......
......@@ -14,6 +14,10 @@
* an existing request
* - elevator_dequeue_fn, called when a request is taken off the active list
*
* 20082000 Dave Jones <davej@suse.de> :
* Removed tests for max-bomb-segments, which was breaking elvtune
* when run without -bN
*
*/
#include <linux/fs.h>
......@@ -147,7 +151,7 @@ int blkelvget_ioctl(elevator_t * elevator, blkelv_ioctl_arg_t * arg)
output.queue_ID = elevator->queue_ID;
output.read_latency = elevator->read_latency;
output.write_latency = elevator->write_latency;
output.max_bomb_segments = elevator->max_bomb_segments;
output.max_bomb_segments = 0;
if (copy_to_user(arg, &output, sizeof(blkelv_ioctl_arg_t)))
return -EFAULT;
......@@ -166,13 +170,9 @@ int blkelvset_ioctl(elevator_t * elevator, const blkelv_ioctl_arg_t * arg)
return -EINVAL;
if (input.write_latency < 0)
return -EINVAL;
if (input.max_bomb_segments <= 0)
return -EINVAL;
elevator->read_latency = input.read_latency;
elevator->write_latency = input.write_latency;
elevator->max_bomb_segments = input.max_bomb_segments;
return 0;
}
......
/*
* linux/drivers/char/pcxe.c
* linux/drivers/char/pcxx.c
*
* Written by Troy De Jongh, November, 1994
*
......@@ -12,13 +12,11 @@
* This driver does NOT support DigiBoard's fastcook FEP option and
* does not support the transparent print (i.e. digiprint) option.
*
* This Driver is currently maintained by Christoph Lameter (clameter@fuller.edu)
* Please contact the mailing list for problems first.
* This Driver is currently maintained by Christoph Lameter (christoph@lameter.com)
*
* Sources of Information:
* 1. The Linux Digiboard Page at http://private.fuller.edu/clameter/digi.html
* 2. The Linux Digiboard Mailing list at digiboard@list.fuller.edu
* (Simply write a message to introduce yourself to subscribe)
* Please contact digi for support issues at digilnux@dgii.com. Some
* information (mostly of historical interest) can be found at
* http://lameter.com/digi.
*
* 1.5.2 Fall 1995 Bug fixes by David Nugent
* 1.5.3 March 9, 1996 Christoph Lameter: Fixed 115.2K Support. Memory
......@@ -39,6 +37,8 @@
* verbose messages to assist user during card configuration.
* Currently only tested on a PC/Xi card, but should work on Xe
* and Xeve also.
* 1.6.2 August, 7, 2000: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* get rid of panics, release previously allocated resources
*
*/
......@@ -81,7 +81,7 @@
#include <asm/bitops.h>
#include <asm/semaphore.h>
#define VERSION "1.6.1"
#define VERSION "1.6.2"
#include "digi.h"
#include "fep.h"
......@@ -193,6 +193,30 @@ static inline void assertmemoff(struct channel *ch);
#define TZ_BUFSZ 4096
/* function definitions */
/*****************************************************************************/
static void cleanup_board_resources(void)
{
int crd, i;
struct board_info *bd;
struct channel *ch;
for(crd = 0; crd < numcards; crd++) {
bd = &boards[crd];
ch = digi_channels + bd->first_minor;
if (bd->region)
release_region(bd->port, 4);
for(i = 0; i < bd->numports; i++, ch++)
if (ch->tmp_buf)
kfree(ch->tmp_buf);
}
}
/*****************************************************************************/
#ifdef MODULE
/*
......@@ -209,10 +233,7 @@ void cleanup_module()
{
unsigned long flags;
int crd, i;
int e1, e2;
struct board_info *bd;
struct channel *ch;
printk(KERN_NOTICE "Unloading PC/Xx version %s\n", VERSION);
......@@ -226,14 +247,7 @@ void cleanup_module()
if ((e2 = tty_unregister_driver(&pcxe_callout)))
printk("SERIAL: failed to unregister callout driver (%d)\n",e2);
for(crd=0; crd < numcards; crd++) {
bd = &boards[crd];
ch = digi_channels+bd->first_minor;
for(i=0; i < bd->numports; i++, ch++) {
kfree(ch->tmp_buf);
}
release_region(bd->port, 4);
}
cleanup_board_resources();
kfree(digi_channels);
kfree(pcxe_termios_locked);
kfree(pcxe_termios);
......@@ -620,7 +634,7 @@ static void pcxe_close(struct tty_struct * tty, struct file * filp)
** worth noting that while I'm not sure what this hunk of code is supposed
** to do, it is not present in the serial.c driver. Hmmm. If you know,
** please send me a note. brian@ilinx.com
** Don't know either what this is supposed to do clameter@waterf.org.
** Don't know either what this is supposed to do christoph@lameter.com.
*/
if(tty->ldisc.num != ldiscs[N_TTY].num) {
if(tty->ldisc.close)
......@@ -1090,6 +1104,7 @@ int __init pcxe_init(void)
{
ulong memory_seg=0, memory_size=0;
int lowwater, enabled_cards=0, i, crd, shrinkmem=0, topwin = 0xff00L, botwin=0x100L;
int ret = -ENOMEM;
unchar *fepos, *memaddr, *bios, v;
volatile struct global_data *gd;
volatile struct board_chan *bc;
......@@ -1099,7 +1114,7 @@ int __init pcxe_init(void)
printk(KERN_NOTICE "Digiboard PC/X{i,e,eve} driver v%s\n", VERSION);
#ifdef MODULE
for (i = 0; i < 4; i++) {
for (i = 0; i < MAX_DIGI_BOARDS; i++) {
if (io[i]) {
numcards = 0;
break;
......@@ -1108,7 +1123,7 @@ int __init pcxe_init(void)
if (numcards == 0) {
int first_minor = 0;
for (i = 0; i < 4; i++) {
for (i = 0; i < MAX_DIGI_BOARDS; i++) {
if (io[i] == 0) {
boards[i].port = 0;
boards[i].status = DISABLED;
......@@ -1139,6 +1154,7 @@ int __init pcxe_init(void)
else
boards[i].numports = 16;
boards[i].region = NULL;
first_minor += boards[i].numports;
}
}
......@@ -1178,23 +1194,31 @@ int __init pcxe_init(void)
* unused spaces.
*/
digi_channels = kmalloc(sizeof(struct channel) * nbdevs, GFP_KERNEL);
if (!digi_channels)
panic("Unable to allocate digi_channel struct");
if (!digi_channels) {
printk(KERN_ERR "Unable to allocate digi_channel struct\n");
return -ENOMEM;
}
memset(digi_channels, 0, sizeof(struct channel) * nbdevs);
pcxe_table = kmalloc(sizeof(struct tty_struct *) * nbdevs, GFP_KERNEL);
if (!pcxe_table)
panic("Unable to allocate pcxe_table struct");
if (!pcxe_table) {
printk(KERN_ERR "Unable to allocate pcxe_table struct\n");
goto cleanup_digi_channels;
}
memset(pcxe_table, 0, sizeof(struct tty_struct *) * nbdevs);
pcxe_termios = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
if (!pcxe_termios)
panic("Unable to allocate pcxe_termios struct");
if (!pcxe_termios) {
printk(KERN_ERR "Unable to allocate pcxe_termios struct\n");
goto cleanup_pcxe_table;
}
memset(pcxe_termios,0,sizeof(struct termios *)*nbdevs);
pcxe_termios_locked = kmalloc(sizeof(struct termios *) * nbdevs, GFP_KERNEL);
if (!pcxe_termios_locked)
panic("Unable to allocate pcxe_termios_locked struct");
if (!pcxe_termios_locked) {
printk(KERN_ERR "Unable to allocate pcxe_termios_locked struct\n");
goto cleanup_pcxe_termios;
}
memset(pcxe_termios_locked,0,sizeof(struct termios *)*nbdevs);
init_bh(DIGI_BH,do_pcxe_bh);
......@@ -1512,7 +1536,13 @@ int __init pcxe_init(void)
if((bd->type == PCXEVE) && (*(ushort *)((ulong)memaddr+NPORT) < 3))
shrinkmem = 1;
request_region(bd->port, 4, "PC/Xx");
bd->region = request_region(bd->port, 4, "PC/Xx");
if (!bd->region) {
printk(KERN_ERR "I/O port 0x%x is already used\n", bd->port);
ret = -EBUSY;
goto cleanup_boards;
}
for(i=0; i < bd->numports; i++, ch++, bc++) {
if(((ushort *)((ulong)memaddr + PORTBASE))[i] == 0) {
......@@ -1562,6 +1592,12 @@ int __init pcxe_init(void)
ch->txbufsize = bc->tmax + 1;
ch->rxbufsize = bc->rmax + 1;
ch->tmp_buf = kmalloc(ch->txbufsize,GFP_KERNEL);
if (!ch->tmp_buf) {
printk(KERN_ERR "Unable to allocate memory for temp buffers\n");
goto cleanup_boards;
}
lowwater = ch->txbufsize >= 2000 ? 1024 : ch->txbufsize/2;
fepcmd(ch, STXLWATER, lowwater, 0, 10, 0);
fepcmd(ch, SRXLWATER, ch->rxbufsize/4, 0, 10, 0);
......@@ -1608,14 +1644,21 @@ int __init pcxe_init(void)
if (enabled_cards <= 0) {
printk(KERN_NOTICE "PC/Xx: No cards enabled, no driver.\n");
return -EIO;
ret = -EIO;
goto cleanup_boards;
}
if(tty_register_driver(&pcxe_driver))
panic("Couldn't register PC/Xe driver");
ret = tty_register_driver(&pcxe_driver);
if(ret) {
printk(KERN_ERR "Couldn't register PC/Xe driver\n");
goto cleanup_boards;
}
if(tty_register_driver(&pcxe_callout))
panic("Couldn't register PC/Xe callout");
ret = tty_register_driver(&pcxe_callout);
if(ret) {
printk(KERN_ERR "Couldn't register PC/Xe callout\n");
goto cleanup_pcxe_driver;
}
/*
* Start up the poller to check for events on all enabled boards
......@@ -1626,6 +1669,13 @@ int __init pcxe_init(void)
printk(KERN_NOTICE "PC/Xx: Driver with %d card(s) ready.\n", enabled_cards);
return 0;
cleanup_pcxe_driver: tty_unregister_driver(&pcxe_driver);
cleanup_boards: cleanup_board_resources();
kfree(pcxe_termios_locked);
cleanup_pcxe_termios: kfree(pcxe_termios);
cleanup_pcxe_table: kfree(pcxe_table);
cleanup_digi_channels: kfree(digi_channels);
return ret;
}
......
......@@ -51,6 +51,7 @@ struct board_info {
ulong membase;
ulong memsize;
ushort first_minor;
void *region;
};
......
......@@ -4,8 +4,10 @@
mainmenu_option next_comment
comment 'Multimedia devices'
# wow, you just got to love this :)
source drivers/media/video/Config.in
source drivers/media/radio/Config.in
tristate 'Video For Linux' CONFIG_VIDEO_DEV
if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
source drivers/media/video/Config.in
source drivers/media/radio/Config.in
fi
endmenu
......@@ -2,53 +2,51 @@
# Multimedia Video device configuration
#
mainmenu_option next_comment
comment 'Radio Adapters'
if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
comment 'Radio Adapters'
dep_tristate ' ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
dep_tristate ' AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
fi
dep_tristate ' AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then
hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c
fi
dep_tristate ' Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
fi
dep_tristate ' GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
fi
dep_tristate ' Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
dep_tristate ' SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
fi
dep_tristate ' TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then
hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590
fi
dep_tristate ' Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_TRUST" = "y" ]; then
hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350
fi
dep_tristate ' Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV
if [ "$CONFIG_PROC_FS" = "y" ]; then
if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then
bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS
fi
fi
if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then
hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316
int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500
fi
dep_tristate ' Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
dep_tristate ' ADS Cadet AM/FM Tuner' CONFIG_RADIO_CADET $CONFIG_VIDEO_DEV
dep_tristate ' AIMSlab RadioTrack (aka RadioReveal) support' CONFIG_RADIO_RTRACK $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_RTRACK" = "y" ]; then
hex ' RadioTrack i/o port (0x20f or 0x30f)' CONFIG_RADIO_RTRACK_PORT 20f
fi
dep_tristate ' AIMSlab RadioTrack II support' CONFIG_RADIO_RTRACK2 $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_RTRACK2" = "y" ]; then
hex ' RadioTrack II i/o port (0x20c or 0x30c)' CONFIG_RADIO_RTRACK2_PORT 30c
fi
dep_tristate ' Aztech/Packard Bell Radio' CONFIG_RADIO_AZTECH $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_AZTECH" = "y" ]; then
hex ' Aztech/Packard Bell I/O port (0x350 or 0x358)' CONFIG_RADIO_AZTECH_PORT 350
fi
dep_tristate ' GemTek Radio Card support' CONFIG_RADIO_GEMTEK $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_GEMTEK" = "y" ]; then
hex ' GemTek i/o port (0x20c, 0x30c, 0x24c or 0x34c)' CONFIG_RADIO_GEMTEK_PORT 34c
fi
dep_tristate ' Miro PCM20 Radio' CONFIG_RADIO_MIROPCM20 $CONFIG_VIDEO_DEV
dep_tristate ' SF16FMI Radio' CONFIG_RADIO_SF16FMI $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_SF16FMI" = "y" ]; then
hex ' SF16FMI I/O port (0x284 or 0x384)' CONFIG_RADIO_SF16FMI_PORT 284
fi
dep_tristate ' TerraTec ActiveRadio ISA Standalone' CONFIG_RADIO_TERRATEC $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_TERRATEC" = "y" ]; then
hex ' Terratec i/o port (normally 0x590)' CONFIG_RADIO_TERRATEC_PORT 590
fi
dep_tristate ' Trust FM radio card' CONFIG_RADIO_TRUST $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_TRUST" = "y" ]; then
hex ' Trust i/o port (usually 0x350 or 0x358)' CONFIG_RADIO_TRUST_PORT 350
fi
dep_tristate ' Typhoon Radio (a.k.a. EcoRadio)' CONFIG_RADIO_TYPHOON $CONFIG_VIDEO_DEV
if [ "$CONFIG_PROC_FS" = "y" ]; then
if [ "$CONFIG_RADIO_TYPHOON" != "n" ]; then
bool ' Support for /proc/radio-typhoon' CONFIG_RADIO_TYPHOON_PROC_FS
fi
fi
if [ "$CONFIG_RADIO_TYPHOON" = "y" ]; then
hex ' Typhoon I/O port (0x316 or 0x336)' CONFIG_RADIO_TYPHOON_PORT 316
int ' Typhoon frequency set when muting the device (kHz)' CONFIG_RADIO_TYPHOON_MUTEFREQ 87500
fi
dep_tristate ' Zoltrix Radio' CONFIG_RADIO_ZOLTRIX $CONFIG_VIDEO_DEV
if [ "$CONFIG_RADIO_ZOLTRIX" = "y" ]; then
hex ' ZOLTRIX I/O port (0x20c or 0x30c)' CONFIG_RADIO_ZOLTRIX_PORT 20c
fi
endmenu
......@@ -4,45 +4,42 @@
mainmenu_option next_comment
comment 'Video For Linux'
tristate 'Video For Linux' CONFIG_VIDEO_DEV
if [ "$CONFIG_VIDEO_DEV" != "n" ]; then
bool ' V4L information in proc filesystem' CONFIG_VIDEO_PROC_FS Y
dep_tristate ' I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT $CONFIG_I2C
bool ' V4L information in proc filesystem' CONFIG_VIDEO_PROC_FS
dep_tristate ' I2C on parallel port' CONFIG_I2C_PARPORT $CONFIG_PARPORT $CONFIG_I2C
comment 'Video Adapters'
if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then
dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT
fi
dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
if [ "$CONFIG_ALL_PPC" = "y" ]; then
dep_tristate ' PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV
fi
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
dep_tristate ' QuickCam Colour Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
fi
fi
dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV
if [ "$CONFIG_VIDEO_CPIA" != "n" ]; then
if [ "CONFIG_PARPORT_1284" != "n" ]; then
dep_tristate ' CPiA Parallel Port Lowlevel Support' CONFIG_VIDEO_CPIA_PP $CONFIG_VIDEO_CPIA $CONFIG_PARPORT
fi
if [ "$CONFIG_USB" != "n" ]; then
dep_tristate ' CPiA USB Lowlevel Support' CONFIG_VIDEO_CPIA_USB $CONFIG_VIDEO_CPIA $CONFIG_USB
fi
fi
dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C
dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C
comment 'Video Adapters'
if [ "$CONFIG_I2C_ALGOBIT" = "y" -o "$CONFIG_I2C_ALGOBIT" = "m" ]; then
dep_tristate ' BT848 Video For Linux' CONFIG_VIDEO_BT848 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C_ALGOBIT
fi
dep_tristate ' Mediavision Pro Movie Studio Video For Linux' CONFIG_VIDEO_PMS $CONFIG_VIDEO_DEV
if [ "$CONFIG_ALL_PPC" = "y" ]; then
dep_tristate ' PlanB Video-In on PowerMac' CONFIG_VIDEO_PLANB $CONFIG_VIDEO_DEV
fi
if [ "$CONFIG_PARPORT" != "n" ]; then
dep_tristate ' Quickcam BW Video For Linux' CONFIG_VIDEO_BWQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_SGI" = "y" ]; then
dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI
fi
dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI
dep_tristate ' QuickCam Colour Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_CQCAM $CONFIG_VIDEO_DEV $CONFIG_PARPORT
fi
fi
dep_tristate ' CPiA Video For Linux' CONFIG_VIDEO_CPIA $CONFIG_VIDEO_DEV
if [ "$CONFIG_VIDEO_CPIA" != "n" ]; then
if [ "CONFIG_PARPORT_1284" != "n" ]; then
dep_tristate ' CPiA Parallel Port Lowlevel Support' CONFIG_VIDEO_CPIA_PP $CONFIG_VIDEO_CPIA $CONFIG_PARPORT
fi
if [ "$CONFIG_USB" != "n" ]; then
dep_tristate ' CPiA USB Lowlevel Support' CONFIG_VIDEO_CPIA_USB $CONFIG_VIDEO_CPIA $CONFIG_USB
fi
fi
dep_tristate ' SAA5249 Teletext processor' CONFIG_VIDEO_SAA5249 $CONFIG_VIDEO_DEV $CONFIG_I2C
dep_tristate ' SAB3036 tuner' CONFIG_TUNER_3036 $CONFIG_VIDEO_DEV $CONFIG_I2C
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_SGI" = "y" ]; then
dep_tristate ' SGI Vino Video For Linux (EXPERIMENTAL)' CONFIG_VIDEO_VINO $CONFIG_VIDEO_DEV $CONFIG_SGI
fi
dep_tristate ' Zoran ZR36057/36060 Video For Linux' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN
dep_tristate ' Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
dep_tristate ' Stradis 4:2:2 MPEG-2 video driver (EXPERIMENTAL)' CONFIG_VIDEO_STRADIS $CONFIG_VIDEO_DEV $CONFIG_PCI
fi
dep_tristate ' Zoran ZR36057/36060 Video For Linux' CONFIG_VIDEO_ZORAN $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
dep_tristate ' Include support for Iomega Buz' CONFIG_VIDEO_BUZ $CONFIG_VIDEO_ZORAN
dep_tristate ' Zoran ZR36120/36125 Video For Linux' CONFIG_VIDEO_ZR36120 $CONFIG_VIDEO_DEV $CONFIG_PCI $CONFIG_I2C
endmenu
......@@ -8,9 +8,10 @@ source drivers/net/appletalk/Config.in
tristate 'Dummy net driver support' CONFIG_DUMMY
tristate 'Bonding driver support' CONFIG_BONDING
tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER
tristate 'Universal TUN/TAP device driver support' CONFIG_TUN
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_NETLINK" = "y" ]; then
tristate 'Ethertap network tap (EXPERIMENTAL)' CONFIG_ETHERTAP
tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP
fi
fi
......
......@@ -273,7 +273,7 @@ obj-$(CONFIG_CS89x0) += cs89x0.o
obj-$(CONFIG_MACSONIC) += macsonic.o
obj-$(CONFIG_MACMACE) += macmace.o
obj-$(CONFIG_MAC89x0) += mac89x0.o
obj-$(CONFIG_TUN) += tun.o
#
# HIPPI adapters
#
......
......@@ -677,8 +677,15 @@ static struct net_device tr0_dev = {
#undef NEXT_DEV
#define NEXT_DEV (&escon0_dev)
#endif
#ifdef CONFIG_TUN
extern int tun_init(struct net_device *dev);
static struct net_device tun_dev = {
"tun", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, tun_init };
# undef NEXT_DEV
# define NEXT_DEV (&tun_dev)
#endif
/*
* The loopback device is global so it can be directly referenced
* by the network code. Also, it must be first on device list.
......
/*
* TUN - Universal TUN/TAP device driver.
* Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.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 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.
*
* $Id: tun.c,v 1.1 2000/08/23 05:59:28 davem Exp $
*/
/*
* Daniel Podlejski <underley@underley.eu.org>
* Modifications for 2.3.99-pre5 kernel.
*/
#define TUN_VER "1.1"
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/sched.h>
#include <linux/malloc.h>
#include <linux/poll.h>
#include <linux/fcntl.h>
#include <linux/init.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/random.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/rtnetlink.h>
#include <linux/if.h>
#include <linux/if_arp.h>
#include <linux/if_ether.h>
#include <linux/if_tun.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#ifdef TUN_DEBUG
static int debug=0;
#endif
/* Network device part of the driver */
/* Net device open. */
static int tun_net_open(struct net_device *dev)
{
#ifdef TUN_DEBUG
struct tun_struct *tun = (struct tun_struct *)dev->priv;
DBG(KERN_INFO "%s: tun_net_open\n", tun->name);
#endif
netif_start_queue(dev);
return 0;
}
/* Net device close. */
static int tun_net_close(struct net_device *dev)
{
#ifdef TUN_DEBUG
struct tun_struct *tun = (struct tun_struct *)dev->priv;
DBG(KERN_INFO "%s: tun_net_close\n", tun->name);
#endif
netif_stop_queue(dev);
return 0;
}
/* Net device start xmit */
static int tun_net_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct tun_struct *tun = (struct tun_struct *)dev->priv;
DBG(KERN_INFO "%s: tun_net_xmit %d\n", tun->name, skb->len);
if (netif_queue_stopped(dev))
return 1;
tun->stats.tx_packets++;
/* Queue frame */
skb_queue_tail(&tun->txq, skb);
if (skb_queue_len(&tun->txq) >= TUN_TXQ_SIZE)
netif_stop_queue(dev);
if (tun->flags & TUN_FASYNC)
kill_fasync(&tun->fasync, SIGIO, POLL_IN);
/* Wake up process */
wake_up_interruptible(&tun->read_wait);
return 0;
}
static void tun_net_mclist(struct net_device *dev)
{
#ifdef TUN_DEBUG
struct tun_struct *tun = (struct tun_struct *)dev->priv;
DBG(KERN_INFO "%s: tun_net_mclist\n", tun->name);
#endif
/* Nothing to do for multicast filters.
* We always accept all frames.
*/
return;
}
static struct net_device_stats *tun_net_stats(struct net_device *dev)
{
struct tun_struct *tun = (struct tun_struct *)dev->priv;
return &tun->stats;
}
/* Initialize net device. */
int tun_net_init(struct net_device *dev)
{
struct tun_struct *tun = (struct tun_struct *)dev->priv;
DBG(KERN_INFO "%s: tun_net_init\n", tun->name);
dev->open = tun_net_open;
dev->hard_start_xmit = tun_net_xmit;
dev->stop = tun_net_close;
dev->get_stats = tun_net_stats;
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
/* Point-to-Point TUN Device */
dev->hard_header_len = 0;
dev->addr_len = 0;
dev->mtu = 1500;
/* Type PPP seems most suitable */
dev->type = ARPHRD_PPP;
dev->flags = IFF_POINTOPOINT | IFF_NOARP | IFF_MULTICAST;
dev->tx_queue_len = 10;
dev_init_buffers(dev);
break;
case TUN_TAP_DEV:
/* Ethernet TAP Device */
dev->set_multicast_list = tun_net_mclist;
/* Generate random Ethernet address. */
*(u16 *)dev->dev_addr = htons(0x00FF);
get_random_bytes(dev->dev_addr + sizeof(u16), 4);
ether_setup(dev);
break;
};
return 0;
}
/* Character device part */
/* Poll */
static unsigned int tun_chr_poll(struct file *file, poll_table * wait)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
DBG(KERN_INFO "%s: tun_chr_poll\n", tun->name);
poll_wait(file, &tun->read_wait, wait);
if (skb_queue_len(&tun->txq))
return POLLIN | POLLRDNORM;
return POLLOUT | POLLWRNORM;
}
/* Get packet from user space buffer(already verified) */
static __inline__ ssize_t tun_get_user(struct tun_struct *tun, const char *buf, size_t count)
{
struct tun_pi pi = { 0, __constant_htons(ETH_P_IP) };
register const char *ptr = buf;
register int len = count;
struct sk_buff *skb;
if (len > TUN_MAX_FRAME)
return -EINVAL;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) < 0)
return -EINVAL;
copy_from_user(&pi, ptr, sizeof(pi));
ptr += sizeof(pi);
}
if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
tun->stats.rx_dropped++;
return -ENOMEM;
}
skb_reserve(skb, 2);
copy_from_user(skb_put(skb, count), ptr, len);
skb->dev = &tun->dev;
switch (tun->flags & TUN_TYPE_MASK) {
case TUN_TUN_DEV:
skb->mac.raw = skb->data;
skb->protocol = pi.proto;
break;
case TUN_TAP_DEV:
skb->protocol = eth_type_trans(skb, &tun->dev);
break;
};
if (tun->flags & TUN_NOCHECKSUM)
skb->ip_summed = CHECKSUM_UNNECESSARY;
netif_rx(skb);
tun->stats.rx_packets++;
return count;
}
/* Write */
static ssize_t tun_chr_write(struct file * file, const char * buf,
size_t count, loff_t *pos)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
DBG(KERN_INFO "%s: tun_chr_write %d\n", tun->name, count);
if (!(tun->flags & TUN_IFF_SET))
return -EBUSY;
if (verify_area(VERIFY_READ, buf, count))
return -EFAULT;
return tun_get_user(tun, buf, count);
}
/* Put packet to user space buffer(already verified) */
static __inline__ ssize_t tun_put_user(struct tun_struct *tun,
struct sk_buff *skb,
char *buf, int count)
{
struct tun_pi pi = { 0, skb->protocol };
int len = count, total = 0;
char *ptr = buf;
if (!(tun->flags & TUN_NO_PI)) {
if ((len -= sizeof(pi)) < 0)
return -EINVAL;
if (len < skb->len) {
/* Packet will be striped */
pi.flags |= TUN_PKT_STRIP;
}
copy_to_user(ptr, &pi, sizeof(pi));
total += sizeof(pi);
ptr += sizeof(pi);
}
len = MIN(skb->len, len);
copy_to_user(ptr, skb->data, len);
total += len;
return total;
}
/* Read */
static ssize_t tun_chr_read(struct file * file, char * buf,
size_t count, loff_t *pos)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
DECLARE_WAITQUEUE(wait, current);
struct sk_buff *skb;
ssize_t ret = 0;
DBG(KERN_INFO "%s: tun_chr_read\n", tun->name);
add_wait_queue(&tun->read_wait, &wait);
while (count) {
current->state = TASK_INTERRUPTIBLE;
/* Read frames from device queue */
if (!(skb=skb_dequeue(&tun->txq))) {
if (file->f_flags & O_NONBLOCK) {
ret = -EAGAIN;
break;
}
if (signal_pending(current)) {
ret = -ERESTARTSYS;
break;
}
/* Nothing to read, let's sleep */
schedule();
continue;
}
netif_start_queue(&tun->dev);
if (!verify_area(VERIFY_WRITE, buf, count))
ret = tun_put_user(tun, skb, buf, count);
else
ret = -EFAULT;
kfree_skb(skb);
break;
}
current->state = TASK_RUNNING;
remove_wait_queue(&tun->read_wait, &wait);
return ret;
}
static loff_t tun_chr_lseek(struct file * file, loff_t offset, int origin)
{
return -ESPIPE;
}
static int tun_set_iff(struct tun_struct *tun, unsigned long arg)
{
struct ifreq ifr;
char *mask;
if (copy_from_user(&ifr, (void *)arg, sizeof(ifr)))
return -EFAULT;
ifr.ifr_name[IFNAMSIZ-1] = '\0';
if (tun->flags & TUN_IFF_SET)
return -EEXIST;
/* Set dev type */
if (ifr.ifr_flags & IFF_TUN) {
/* TUN device */
tun->flags |= TUN_TUN_DEV;
mask = "tun%d";
} else if (ifr.ifr_flags & IFF_TAP) {
/* TAP device */
tun->flags |= TUN_TAP_DEV;
mask = "tap%d";
} else
return -EINVAL;
if (ifr.ifr_flags & IFF_NO_PI)
tun->flags |= TUN_NO_PI;
if (*ifr.ifr_name)
strcpy(tun->dev.name, ifr.ifr_name);
else
strcpy(tun->dev.name, mask);
/* Register net device */
if (register_netdev(&tun->dev))
return -EBUSY;
tun->flags |= TUN_IFF_SET;
strcpy(tun->name, tun->dev.name);
/* Return iface info to the user space */
strcpy(ifr.ifr_name, tun->dev.name);
copy_to_user((void *)arg, &ifr, sizeof(ifr));
return 0;
}
static int tun_chr_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
DBG(KERN_INFO "%s: tun_chr_ioctl\n", tun->name);
switch (cmd) {
case TUNSETIFF:
return tun_set_iff(tun, arg);
case TUNSETNOCSUM:
/* Disable/Enable checksum on net iface */
if (arg)
tun->flags |= TUN_NOCHECKSUM;
else
tun->flags &= ~TUN_NOCHECKSUM;
DBG(KERN_INFO "%s: checksum %s\n",
tun->name, arg ? "disabled" : "enabled");
break;
#ifdef TUN_DEBUG
case TUNSETDEBUG:
tun->debug = arg;
break;
#endif
default:
return -EINVAL;
};
return 0;
}
static int tun_chr_fasync(int fd, struct file *file, int on)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
int ret;
DBG(KERN_INFO "%s: tun_chr_fasync %d\n", tun->name, on);
if ((ret = fasync_helper(fd, file, on, &tun->fasync)) < 0)
return ret;
if (on)
tun->flags |= TUN_FASYNC;
else
tun->flags &= ~TUN_FASYNC;
return 0;
}
static int tun_chr_open(struct inode *inode, struct file * file)
{
struct tun_struct *tun = NULL;
DBG1(KERN_INFO "tunX: tun_chr_open\n");
tun = kmalloc(sizeof(struct tun_struct), GFP_KERNEL);
if (tun == NULL)
return -ENOMEM;
memset(tun, 0, sizeof(struct tun_struct));
file->private_data = tun;
skb_queue_head_init(&tun->txq);
init_waitqueue_head(&tun->read_wait);
sprintf(tun->name, "tunX");
tun->dev.init = tun_net_init;
tun->dev.priv = tun;
MOD_INC_USE_COUNT;
return 0;
}
static int tun_chr_close(struct inode *inode, struct file *file)
{
struct tun_struct *tun = (struct tun_struct *)file->private_data;
DBG(KERN_INFO "%s: tun_chr_close\n", tun->name);
if (tun->flags & TUN_IFF_SET) {
rtnl_lock();
dev_close(&tun->dev);
rtnl_unlock();
/* Drop TX queue */
skb_queue_purge(&tun->txq);
unregister_netdev(&tun->dev);
}
kfree(tun);
file->private_data = NULL;
MOD_DEC_USE_COUNT;
return 0;
}
static struct file_operations tun_fops = {
owner: THIS_MODULE,
llseek: tun_chr_lseek,
read: tun_chr_read,
write: tun_chr_write,
poll: tun_chr_poll,
ioctl: tun_chr_ioctl,
open: tun_chr_open,
release:tun_chr_close,
fasync: tun_chr_fasync
};
static devfs_handle_t devfs_handle = NULL;
int __init tun_init(void)
{
printk(KERN_INFO "Universal TUN/TAP device driver %s "
"(C)1999-2000 Maxim Krasnyansky\n", TUN_VER);
if (devfs_register_chrdev(TUN_MAJOR, "tun", &tun_fops)) {
printk(KERN_ERR "tun: Can't register char device %d\n",
TUN_MAJOR);
return -EIO;
}
devfs_handle = devfs_register(NULL, "net/tun", DEVFS_FL_DEFAULT,
TUN_MAJOR, 0,
S_IFCHR | S_IRUSR | S_IWUSR,
&tun_fops, NULL);
#ifdef MODULE
return 0;
#else
/* If driver is not module, tun_init will be called from Space.c.
* Return non-zero not to register fake device.
*/
return 1;
#endif
}
void tun_cleanup(void)
{
devfs_unregister_chrdev(TUN_MAJOR,"tun");
devfs_unregister(devfs_handle);
}
module_init(tun_init);
module_exit(tun_cleanup);
......@@ -596,9 +596,11 @@ static void unreset_socket(socket_info_t *s)
s->state &= ~SOCKET_SETUP_PENDING;
} else {
send_event(s, CS_EVENT_CARD_RESET, CS_EVENT_PRI_LOW);
s->reset_handle->event_callback_args.info = NULL;
EVENT(s->reset_handle, CS_EVENT_RESET_COMPLETE,
CS_EVENT_PRI_LOW);
if (s->reset_handle) {
s->reset_handle->event_callback_args.info = NULL;
EVENT(s->reset_handle, CS_EVENT_RESET_COMPLETE,
CS_EVENT_PRI_LOW);
}
s->state &= ~EVENT_MASK;
}
} /* unreset_socket */
......
/* $Id: rtc.c,v 1.21 2000/07/13 08:06:40 davem Exp $
/* $Id: rtc.c,v 1.22 2000/08/22 06:56:33 davem Exp $
*
* Linux/SPARC Real Time Clock Driver
* Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
......
......@@ -74,16 +74,16 @@ comment 'USB Devices'
dep_tristate ' USB Bluetooth support (EXPERIMENTAL)' CONFIG_USB_BLUETOOTH $CONFIG_USB
fi
comment 'USB HID'
if [ "$CONFIG_INPUT" != "n" ]; then
comment 'USB Human Interface Devices (HID)'
if [ "$CONFIG_INPUT" = "n" ]; then
comment ' Input core support is needed for USB HID'
else
dep_tristate ' USB Human Interface Device (HID) support' CONFIG_USB_HID $CONFIG_USB $CONFIG_INPUT
if [ "$CONFIG_USB_HID" != "y" ]; then
dep_tristate ' USB HIDBP Keyboard support' CONFIG_USB_KBD $CONFIG_USB $CONFIG_INPUT
dep_tristate ' USB HIDBP Mouse support' CONFIG_USB_MOUSE $CONFIG_USB $CONFIG_INPUT
fi
dep_tristate ' Wacom Intuos/Graphire tablet support' CONFIG_USB_WACOM $CONFIG_USB $CONFIG_INPUT
else
comment ' Input core support is needed for USB HID'
fi
fi
......
......@@ -42,7 +42,10 @@
#include <linux/usb.h>
static const char *version = __FILE__ ": v0.4.1 2000/08/08 (C) 1999-2000 Petko Manolov (petkan@dce.bg)\n";
static const char *version = __FILE__ ": v0.4.3 2000/08/22 (C) 1999-2000 Petko Manolov (petkan@dce.bg)\n";
#define PEGASUS_USE_WAITQ
#define PEGASUS_MTU 1500
......@@ -58,6 +61,7 @@ static const char *version = __FILE__ ": v0.4.1 2000/08/08 (C) 1999-2000 Petko M
#define PEGASUS_REQ_GET_REGS 0xf0
#define PEGASUS_REQ_SET_REGS 0xf1
#define PEGASUS_REQ_SET_REG PEGASUS_REQ_SET_REGS
#define NUM_CTRL_URBS 0x10
#define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
......@@ -81,17 +85,26 @@ enum pegasus_registers {
};
struct pegasus;
struct ctrl_urb_pool {
struct pegasus *pegasus;
struct urb urb;
devrequest dr;
__u8 busy;
};
struct pegasus {
struct usb_device *usb;
struct net_device *net;
struct net_device_stats stats;
int flags;
struct urb rx_urb, tx_urb, intr_urb, ctrl_urb;
devrequest dr;
struct urb rx_urb, tx_urb, intr_urb;
struct ctrl_urb_pool ALIGN(ctrl[NUM_CTRL_URBS]);
wait_queue_head_t ctrl_wait;
struct semaphore ctrl_sem;
unsigned char ALIGN(rx_buff[PEGASUS_MAX_MTU]);
unsigned char ALIGN(tx_buff[PEGASUS_MAX_MTU]);
unsigned char ALIGN(rx_buff[PEGASUS_MAX_MTU]);
unsigned char ALIGN(tx_buff[PEGASUS_MAX_MTU]);
unsigned char ALIGN(intr_buff[8]);
};
......@@ -137,113 +150,144 @@ static struct usb_eth_dev usb_dev_id[] = {
};
static void pegasus_ctrl_end( urb_t *urb )
static void pegasus_unlink_ctrl_urbs( struct pegasus *pegasus )
{
struct pegasus *pegasus = urb->context;
int i;
if ( pegasus->flags & PEGASUS_CTRL_WAIT ) {
wake_up_interruptible(&pegasus->ctrl_wait);
pegasus->flags &= ~PEGASUS_CTRL_WAIT;
for ( i=0; i < NUM_CTRL_URBS; i++ ) {
if ( pegasus->ctrl[i].urb.status == -EINPROGRESS )
usb_unlink_urb( &pegasus->ctrl[i].urb );
}
if ( urb->status )
warn("ctrl_urb end status %d", urb->status);
}
static int pegasus_ctrl_timeout( urb_t *ctrl_urb )
static int pegasus_find_ctrl_urb( struct pegasus *pegasus )
{
struct pegasus *pegasus = ctrl_urb->context;
int timeout=PEGASUS_CTRL_TIMEOUT;
while ( ctrl_urb->status == -EINPROGRESS ) {
if ( timeout ) {
pegasus->flags |= PEGASUS_CTRL_WAIT;
timeout = interruptible_sleep_on_timeout(&pegasus->ctrl_wait,timeout);
pegasus->flags &= PEGASUS_CTRL_WAIT;
continue;
}
err("ctrl urb busy %d", ctrl_urb->status);
usb_unlink_urb( ctrl_urb );
return ctrl_urb->status;
}
return 0;
int i=0;
while( i < NUM_CTRL_URBS && (pegasus->ctrl[i].busy == 1 ||
(pegasus->ctrl[i].urb.status == -EINPROGRESS)) )
i++;
return i;
}
static void pegasus_ctrl_end( urb_t *urb )
{
struct ctrl_urb_pool *ctrl = urb->context;
struct pegasus *pegasus = ctrl->pegasus;
if ( !pegasus )
return;
if ( urb->status )
warn("ctrl_urb end status %d", urb->status);
ctrl->busy = 0;
#ifdef PEGASUS_USE_WAITQ
wake_up_interruptible( &pegasus->ctrl_wait );
#endif
}
static int pegasus_get_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
{
int ret;
down( &pegasus->ctrl_sem);
pegasus->dr.requesttype = PEGASUS_REQT_READ;
pegasus->dr.request = PEGASUS_REQ_GET_REGS;
pegasus->dr.value = 0;
pegasus->dr.index = cpu_to_le16p(&indx);
pegasus->dr.length =
pegasus->ctrl_urb.transfer_buffer_length = cpu_to_le16p(&size);
FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
usb_rcvctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
data, size, pegasus_ctrl_end, pegasus );
if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
err("BAD CTRLs %d", ret);
else
ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
up( &pegasus->ctrl_sem );
int ret, i;
struct ctrl_urb_pool *ctrl;
if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {
return -1;
}
ctrl = &pegasus->ctrl[i];
ctrl->busy = 1;
ctrl->pegasus = pegasus;
ctrl->dr.requesttype = PEGASUS_REQT_READ;
ctrl->dr.request = PEGASUS_REQ_GET_REGS;
ctrl->dr.value = 0;
ctrl->dr.index = cpu_to_le16p(&indx);
ctrl->dr.length =
ctrl->urb.transfer_buffer_length = cpu_to_le16p(&size);
FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
usb_rcvctrlpipe(pegasus->usb,0),
(char *)&ctrl->dr,
data, size, pegasus_ctrl_end, ctrl );
if ( (ret = usb_submit_urb( &ctrl->urb )) )
err( __FUNCTION__ " BAD CTRLs %d", ret);
#ifdef PEGASUS_USE_WAITQ
interruptible_sleep_on( &pegasus->ctrl_wait );
#endif
return ret;
}
static int pegasus_set_registers( struct pegasus *pegasus, __u16 indx, __u16 size, void *data )
{
int ret;
down( &pegasus->ctrl_sem );
pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
pegasus->dr.request = PEGASUS_REQ_SET_REGS;
pegasus->dr.value = 0;
pegasus->dr.index = cpu_to_le16p( &indx );
pegasus->dr.length =
pegasus->ctrl_urb.transfer_buffer_length = cpu_to_le16p( &size );
FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
data, size, pegasus_ctrl_end, pegasus );
if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
err("BAD CTRL %d", ret);
else
ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
up( &pegasus->ctrl_sem );
int ret, i;
struct ctrl_urb_pool *ctrl;
if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {
return -1;
}
ctrl = &pegasus->ctrl[i];
ctrl->busy = 1;
ctrl->pegasus = pegasus;
ctrl->dr.requesttype = PEGASUS_REQT_WRITE;
ctrl->dr.request = PEGASUS_REQ_SET_REGS;
ctrl->dr.value = 0;
ctrl->dr.index = cpu_to_le16p( &indx );
ctrl->dr.length =
ctrl->urb.transfer_buffer_length = cpu_to_le16p( &size );
FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
usb_sndctrlpipe(pegasus->usb,0),
(char *)&ctrl->dr,
data, size, pegasus_ctrl_end, ctrl );
if ( (ret = usb_submit_urb( &ctrl->urb )) )
err( __FUNCTION__ " BAD CTRL %d", ret);
#ifdef PEGASUS_USE_WAITQ
interruptible_sleep_on( &pegasus->ctrl_wait );
#endif
return ret;
}
static int pegasus_set_register( struct pegasus *pegasus, __u16 indx,__u8 data )
{
int ret;
int ret, i;
struct ctrl_urb_pool *ctrl;
down( &pegasus->ctrl_sem );
pegasus->dr.requesttype = PEGASUS_REQT_WRITE;
pegasus->dr.request = PEGASUS_REQ_SET_REG;
pegasus->dr.value = cpu_to_le16p( &data );
pegasus->dr.index = cpu_to_le16p( &indx );
pegasus->dr.length = pegasus->ctrl_urb.transfer_buffer_length = 1;
FILL_CONTROL_URB( &pegasus->ctrl_urb, pegasus->usb,
usb_sndctrlpipe(pegasus->usb,0), (char *)&pegasus->dr,
&data, 1, pegasus_ctrl_end, pegasus );
if ( (ret = usb_submit_urb( &pegasus->ctrl_urb )) )
err("BAD CTRL %d", ret);
else
ret = pegasus_ctrl_timeout( &pegasus->ctrl_urb );
up( &pegasus->ctrl_sem );
if ( (i = pegasus_find_ctrl_urb( pegasus )) == NUM_CTRL_URBS ) {
return -1;
}
ctrl = &pegasus->ctrl[i];
ctrl->busy = 1;
ctrl->pegasus = pegasus;
ctrl->dr.requesttype = PEGASUS_REQT_WRITE;
ctrl->dr.request = PEGASUS_REQ_SET_REG;
ctrl->dr.value = cpu_to_le16p( &data );
ctrl->dr.index = cpu_to_le16p( &indx );
ctrl->dr.length = ctrl->urb.transfer_buffer_length = 1;
FILL_CONTROL_URB( &ctrl->urb, pegasus->usb,
usb_sndctrlpipe(pegasus->usb,0),
(char *)&ctrl->dr,
&data, 1, pegasus_ctrl_end, ctrl );
if ( (ret = usb_submit_urb( &ctrl->urb )) )
err( __FUNCTION__ " BAD CTRL %d", ret);
#ifdef PEGASUS_USE_WAITQ
interruptible_sleep_on( &pegasus->ctrl_wait );
#endif
return ret;
}
......@@ -372,18 +416,21 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
}
static void pegasus_read_bulk(struct urb *urb)
static void pegasus_read_bulk_callback( struct urb *urb )
{
struct pegasus *pegasus = urb->context;
struct net_device *net = pegasus->net;
struct net_device *net; /* = pegasus->net;*/
int count = urb->actual_length, res;
int rx_status = *(int *)(pegasus->rx_buff + count - 4);
int rx_status; /*= *(int *)(pegasus->rx_buff + count - 4);*/
struct sk_buff *skb;
__u16 pkt_len;
if ( !(pegasus->flags & PEGASUS_RUNNING) )
if ( !pegasus || !(pegasus->flags & PEGASUS_RUNNING) )
return;
net = pegasus->net;
rx_status = *(int *)(pegasus->rx_buff + count - 4);
if (urb->status) {
dbg("%s: RX status %d", net->name, urb->status);
goto goon;
......@@ -427,19 +474,22 @@ static void pegasus_read_bulk(struct urb *urb)
}
static void pegasus_irq(urb_t *urb)
static void pegasus_irq_callback( urb_t *urb )
{
__u8 *d = urb->transfer_buffer;
if ( d[0] )
dbg("txst0=0x%2x", d[0]);
}
static void pegasus_write_bulk(struct urb *urb)
static void pegasus_write_bulk_callback(struct urb *urb)
{
struct pegasus *pegasus = urb->context;
if ( !pegasus )
return;
if (urb->status)
info("%s: TX status %d", pegasus->net->name, urb->status);
......@@ -450,6 +500,8 @@ static void pegasus_tx_timeout(struct net_device *net)
{
struct pegasus *pegasus = net->priv;
if ( !pegasus )
return;
usb_unlink_urb(&pegasus->tx_urb);
warn("%s: Tx timed out.", net->name);
......@@ -473,6 +525,7 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
((__u16 *)pegasus->tx_buff)[0] = skb->len;
memcpy(pegasus->tx_buff+2, skb->data, skb->len);
pegasus->tx_urb.transfer_buffer_length = count;
pegasus->tx_urb.transfer_flags |= USB_ASYNC_UNLINK;
if ((res = usb_submit_urb(&pegasus->tx_urb))) {
warn("failed tx_urb %d", res);
......@@ -537,10 +590,10 @@ static int pegasus_close(struct net_device *net)
netif_stop_queue(net);
usb_unlink_urb(&pegasus->ctrl_urb);
usb_unlink_urb(&pegasus->rx_urb);
usb_unlink_urb(&pegasus->tx_urb);
usb_unlink_urb(&pegasus->intr_urb);
pegasus_unlink_ctrl_urbs( pegasus );
return 0;
}
......@@ -570,22 +623,31 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
static void pegasus_set_rx_mode(struct net_device *net)
{
/* struct pegasus *pegasus = net->priv;*/
#ifndef PEGASUS_USE_WAITQ
struct pegasus *pegasus = net->priv;
__u8 tmp;
#endif
netif_stop_queue(net);
if (net->flags & IFF_PROMISC) {
/* pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
pegasus_set_register(pegasus, EthCtrl2, tmp | 4);*/
#ifndef PEGASUS_USE_WAITQ
pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
pegasus_set_register(pegasus, EthCtrl2, tmp | 4);
#endif
info("%s: Promiscuous mode enabled", net->name);
} else if ((net->mc_count > multicast_filter_limit) ||
(net->flags & IFF_ALLMULTI)) {
/* pegasus_set_register(pegasus, EthCtrl0, 0xfa);
pegasus_set_register(pegasus, EthCtrl2, 0);*/
#ifndef PEGASUS_USE_WAITQ
pegasus_set_register(pegasus, EthCtrl0, 0xfa);
pegasus_set_register(pegasus, EthCtrl2, 0);
#endif
info("%s set allmulti", net->name);
} else {
/* pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
pegasus_set_register(pegasus, EthCtrl2, tmp & ~4);*/
#ifndef PEGASUS_USE_WAITQ
pegasus_get_registers(pegasus, EthCtrl2, 1, &tmp);
pegasus_set_register(pegasus, EthCtrl2, tmp & ~4);
#endif
info("%s: set Rx mode", net->name);
}
......@@ -640,28 +702,30 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
net->get_stats = pegasus_netdev_stats;
net->mtu = PEGASUS_MTU;
init_MUTEX( &pegasus-> ctrl_sem );
init_waitqueue_head( &pegasus->ctrl_wait );
pegasus->usb = dev;
pegasus->net = net;
init_waitqueue_head( &pegasus->ctrl_wait );
init_MUTEX( &pegasus->ctrl_sem );
FILL_BULK_URB(&pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1),
pegasus->rx_buff, PEGASUS_MAX_MTU, pegasus_read_bulk,
pegasus);
FILL_BULK_URB(&pegasus->tx_urb, dev, usb_sndbulkpipe(dev, 2),
pegasus->tx_buff, PEGASUS_MAX_MTU, pegasus_write_bulk,
pegasus);
FILL_INT_URB(&pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
pegasus->intr_buff, 8, pegasus_irq, pegasus, 128);
FILL_BULK_URB( &pegasus->rx_urb, dev, usb_rcvbulkpipe(dev, 1),
pegasus->rx_buff, PEGASUS_MAX_MTU,
pegasus_read_bulk_callback, pegasus );
FILL_BULK_URB( &pegasus->tx_urb, dev, usb_sndbulkpipe(dev, 2),
pegasus->tx_buff, PEGASUS_MAX_MTU,
pegasus_write_bulk_callback, pegasus );
FILL_INT_URB( &pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
pegasus->intr_buff, 8, pegasus_irq_callback,
pegasus, 128 );
if (pegasus_reset_mac(pegasus)) {
err("can't reset MAC");
kfree(pegasus);
pegasus = NULL;
return NULL;
}
printk(KERN_INFO "%s: %s\n", net->name, usb_dev_id[dev_indx].name);
info( "%s: %s\n", net->name, usb_dev_id[dev_indx].name );
MOD_INC_USE_COUNT;
......@@ -681,15 +745,13 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr)
pegasus->flags &= ~PEGASUS_RUNNING;
unregister_netdev(pegasus->net);
if ( pegasus->flags & PEGASUS_CTRL_WAIT )
wake_up_interruptible( &pegasus->ctrl_wait );
usb_unlink_urb(&pegasus->ctrl_urb);
usb_unlink_urb(&pegasus->rx_urb);
usb_unlink_urb(&pegasus->tx_urb);
usb_unlink_urb(&pegasus->intr_urb);
pegasus_unlink_ctrl_urbs( pegasus );
kfree(pegasus);
pegasus = NULL;
MOD_DEC_USE_COUNT;
}
......@@ -703,7 +765,7 @@ static struct usb_driver pegasus_driver = {
int __init pegasus_init(void)
{
printk( version );
info( "%s", version );
return usb_register(&pegasus_driver);
}
......
......@@ -29,6 +29,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/config.h>
#include "transport.h"
#include "protocol.h"
#include "usb.h"
......
......@@ -41,6 +41,7 @@
#ifndef _TRANSPORT_H_
#define _TRANSPORT_H_
#include <linux/config.h>
#include <linux/blk.h>
#include "usb.h"
#include "scsi.h"
......
......@@ -43,6 +43,7 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/config.h>
#include "usb.h"
#include "scsiglue.h"
#include "transport.h"
......
......@@ -124,13 +124,13 @@ int usb_kbd_event(struct input_dev *dev, unsigned int type, unsigned int code, i
static void usb_kbd_led(struct urb *urb)
{
struct usb_kbd *kbd = urb->private;
struct usb_kbd *kbd = urb->context;
if (urb->status)
warn("led urb status %d received", urb->status);
if (kbd->leds == kbd->newleds)
return 0;
return;
kbd->leds = kbd->newleds;
if (usb_submit_urb(&kbd->led))
......
......@@ -39,7 +39,7 @@ typedef struct {
/*
* Are we in an interrupt context? Either doing bottom half
* or hardware interrupt processing? On any cpu?
* or hardware interrupt processing?
*/
#define in_interrupt() ((local_irq_count(smp_processor_id()) + \
local_bh_count(smp_processor_id())) != 0)
......@@ -52,22 +52,18 @@ typedef struct {
#define hardirq_trylock(cpu) ((void)(cpu), local_irq_count(smp_processor_id()) == 0)
#define hardirq_endlock(cpu) do { (void)(cpu); } while(0)
#define hardirq_enter(cpu) ((void)(cpu), local_irq_count(smp_processor_id())++)
#define hardirq_exit(cpu) ((void)(cpu), local_irq_count(smp_processor_id())--)
#define synchronize_irq() barrier()
#else /* (CONFIG_SMP) */
static __inline__ int irqs_running(void)
{
enum brlock_indices idx = BR_GLOBALIRQ_LOCK;
int i, count = 0;
int i;
for (i = 0; i < smp_num_cpus; i++)
count += (__brlock_array[cpu_logical_map(i)][idx] != 0);
return count;
if (local_irq_count(cpu_logical_map(i)))
return 1;
return 0;
}
extern unsigned char global_irq_holder;
......@@ -85,7 +81,7 @@ static inline int hardirq_trylock(int cpu)
{
spinlock_t *lock = &__br_write_locks[BR_GLOBALIRQ_LOCK].lock;
return (!irqs_running() && !spin_is_locked(lock));
return (!local_irq_count(cpu) && !spin_is_locked(lock));
}
#define hardirq_endlock(cpu) do { (void)(cpu); } while (0)
......
......@@ -12,9 +12,9 @@ static inline int get_close_on_exec(unsigned int fd)
{
struct files_struct *files = current->files;
int res;
write_lock(&files->file_lock);
read_lock(&files->file_lock);
res = FD_ISSET(fd, files->close_on_exec);
write_unlock(&files->file_lock);
read_unlock(&files->file_lock);
return res;
}
......
/*
* Universal TUN/TAP device driver.
* Copyright (C) 1999-2000 Maxim Krasnyansky <max_mk@yahoo.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 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.
*
* $Id: if_tun.h,v 1.1 2000/08/23 05:59:28 davem Exp $
*/
#ifndef __IF_TUN_H
#define __IF_TUN_H
/* Uncomment to enable debugging */
/* #define TUN_DEBUG 1 */
#ifdef __KERNEL__
#ifdef TUN_DEBUG
#define DBG if(tun->debug)printk
#define DBG1 if(debug==2)printk
#else
#define DBG( a... )
#define DBG1( a... )
#endif
struct tun_struct {
char name[8];
unsigned long flags;
struct fasync_struct *fasync;
wait_queue_head_t read_wait;
struct net_device dev;
struct sk_buff_head txq;
struct net_device_stats stats;
#ifdef TUN_DEBUG
int debug;
#endif
};
#ifndef MIN
#define MIN(a,b) ( (a)<(b) ? (a):(b) )
#endif
#endif /* __KERNEL__ */
/* Number of devices */
#define TUN_MAX_DEV 255
/* TX queue size */
#define TUN_TXQ_SIZE 10
/* Max frame size */
#define TUN_MAX_FRAME 4096
/* TUN device flags */
#define TUN_TUN_DEV 0x0001
#define TUN_TAP_DEV 0x0002
#define TUN_TYPE_MASK 0x000f
#define TUN_FASYNC 0x0010
#define TUN_NOCHECKSUM 0x0020
#define TUN_NO_PI 0x0040
#define TUN_IFF_SET 0x1000
/* Ioctl defines */
#define TUNSETNOCSUM (('T'<< 8) | 200)
#define TUNSETDEBUG (('T'<< 8) | 201)
#define TUNSETIFF (('T'<< 8) | 202)
/* TUNSETIFF ifr flags */
#define IFF_TUN 0x0001
#define IFF_TAP 0x0002
#define IFF_NO_PI 0x1000
struct tun_pi {
unsigned short flags;
unsigned short proto;
};
#define TUN_PKT_STRIP 0x0001
#endif /* __IF_TUN_H */
......@@ -134,6 +134,8 @@
#define USB_ACM_AUX_MAJOR 167
#define USB_CHAR_MAJOR 180
#define TUN_MAJOR 195
#define UNIX98_PTY_MASTER_MAJOR 128
#define UNIX98_PTY_MAJOR_COUNT 8
#define UNIX98_PTY_SLAVE_MAJOR (UNIX98_PTY_MASTER_MAJOR+UNIX98_PTY_MAJOR_COUNT)
......
/*
* Header for Microchannel Architecture Bus
* Header for Microchannel Architecture Bus
* Written by Martin Kolinek, February 1996
*/
*/
#ifndef _LINUX_MCA_H
#define _LINUX_MCA_H
/* The detection of MCA bus is done in the real mode (using BIOS).
* The information is exported to the protected code, where this
* The information is exported to the protected code, where this
* variable is set to one in case MCA bus was detected.
*/
*/
#ifndef MCA_bus__is_a_macro
extern int MCA_bus;
#endif
/* maximal number of MCA slots - actually, some machines have less, but
they all have sufficient number of POS registers to cover 8. */
/* Maximal number of MCA slots - actually, some machines have less, but
* they all have sufficient number of POS registers to cover 8.
*/
#define MCA_MAX_SLOT_NR 8
/* MCA_NOTFOUND is an error condition. The other two indicate
motherboard POS registers contain the adapter. They might be
returned by the mca_find_adapter() function, and can be used as
arguments to mca_read_stored_pos(). I'm not going to allow direct
access to the motherboard registers until we run across an adapter
that requires it. We don't know enough about them to know if it's
safe.
See Documentation/mca.txt or one of the existing drivers for
more information.
*/
* motherboard POS registers contain the adapter. They might be
* returned by the mca_find_adapter() function, and can be used as
* arguments to mca_read_stored_pos(). I'm not going to allow direct
* access to the motherboard registers until we run across an adapter
* that requires it. We don't know enough about them to know if it's
* safe.
*
* See Documentation/mca.txt or one of the existing drivers for
* more information.
*/
#define MCA_NOTFOUND (-1)
#define MCA_INTEGSCSI (MCA_MAX_SLOT_NR)
#define MCA_INTEGVIDEO (MCA_MAX_SLOT_NR+1)
/* max number of adapters, including both slots and various integrated
things. */
#define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+2)
/* returns the slot of the first enabled adapter matching id. User can
specify a starting slot beyond zero, to deal with detecting multiple
devices. Returns MCA_NOTFOUND if id not found. Also checks the
integrated adapters. */
#define MCA_MOTHERBOARD (MCA_MAX_SLOT_NR+2)
/* Max number of adapters, including both slots and various integrated
* things.
*/
#define MCA_NUMADAPTERS (MCA_MAX_SLOT_NR+3)
/* Returns the slot of the first enabled adapter matching id. User can
* specify a starting slot beyond zero, to deal with detecting multiple
* devices. Returns MCA_NOTFOUND if id not found. Also checks the
* integrated adapters.
*/
extern int mca_find_adapter(int id, int start);
extern int mca_find_unused_adapter(int id, int start);
......@@ -55,39 +59,37 @@ extern void mca_mark_as_unused(int slot);
/* gets a byte out of POS register (stored in memory) */
extern unsigned char mca_read_stored_pos(int slot, int reg);
/*
This can be expanded later. Right now, it gives us a way of
getting meaningful information into the MCA_info structure,
so we can have a more interesting /proc/mca.
*/
/* This can be expanded later. Right now, it gives us a way of
* getting meaningful information into the MCA_info structure,
* so we can have a more interesting /proc/mca.
*/
extern void mca_set_adapter_name(int slot, char* name);
extern char* mca_get_adapter_name(int slot);
/*
This sets up an information callback for /proc/mca/slot?. The
function is called with the buffer, slot, and device pointer (or
some equally informative context information, or nothing, if you
prefer), and is expected to put useful information into the
buffer. The adapter name, id, and POS registers get printed
before this is called though, so don't do it again.
This should be called with a NULL procfn when a module
unregisters, thus preventing kernel crashes and other such
nastiness.
*/
/* This sets up an information callback for /proc/mca/slot?. The
* function is called with the buffer, slot, and device pointer (or
* some equally informative context information, or nothing, if you
* prefer), and is expected to put useful information into the
* buffer. The adapter name, id, and POS registers get printed
* before this is called though, so don't do it again.
*
* This should be called with a NULL procfn when a module
* unregisters, thus preventing kernel crashes and other such
* nastiness.
*/
typedef int (*MCA_ProcFn)(char* buf, int slot, void* dev);
extern void mca_set_adapter_procfn(int slot, MCA_ProcFn, void* dev);
/* These routines actually mess with the hardware POS registers. They
temporarily disable the device (and interrupts), so make sure you know
what you're doing if you use them. Furthermore, writing to a POS may
result in two devices trying to share a resource, which in turn can
result in multiple devices sharing memory spaces, IRQs, or even trashing
hardware. YOU HAVE BEEN WARNED.
You can only access slots with this. Motherboard registers are off
limits.
*/
* temporarily disable the device (and interrupts), so make sure you know
* what you're doing if you use them. Furthermore, writing to a POS may
* result in two devices trying to share a resource, which in turn can
* result in multiple devices sharing memory spaces, IRQs, or even trashing
* hardware. YOU HAVE BEEN WARNED.
*
* You can only access slots with this. Motherboard registers are off
* limits.
*/
/* read a byte from the specified POS register. */
extern unsigned char mca_read_pos(int slot, int reg);
......@@ -96,7 +98,8 @@ extern unsigned char mca_read_pos(int slot, int reg);
extern void mca_write_pos(int slot, int reg, unsigned char byte);
/* Should only be called by the NMI interrupt handler, this will do some
fancy stuff to figure out what might have generated a NMI. */
* fancy stuff to figure out what might have generated a NMI.
*/
extern void mca_handle_nmi(void);
#endif /* _LINUX_MCA_H */
......@@ -551,8 +551,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
*p = *current;
lock_kernel();
retval = -EAGAIN;
if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur)
goto bad_fork_free;
......@@ -675,8 +673,6 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
wake_up_process(p); /* do this last */
++total_forks;
bad_fork:
unlock_kernel();
fork_out:
if ((clone_flags & CLONE_VFORK) && (retval > 0))
down(&sem);
......@@ -697,7 +693,7 @@ int do_fork(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs)
free_uid(p->user);
bad_fork_free:
free_task_struct(p);
goto bad_fork;
goto fork_out;
}
/* SLAB cache for signal_struct structures (tsk->sig) */
......
......@@ -247,7 +247,7 @@ static inline void reschedule_idle(struct task_struct * p, unsigned long flags)
* one will have the least active cache context.) Also find
* the executing process which has the least priority.
*/
oldest_idle = -1ULL;
oldest_idle = (cycles_t) -1;
target_tsk = NULL;
max_prio = 1;
......@@ -283,17 +283,11 @@ static inline void reschedule_idle(struct task_struct * p, unsigned long flags)
goto send_now_idle;
goto preempt_now;
}
if (p->has_cpu) {
p->need_resched = 1;
cpu_curr(p->processor)->need_resched = 1;
}
spin_unlock_irqrestore(&runqueue_lock, flags);
return;
send_now_idle:
/*
* If need_resched == -1 then we can skip sending the IPI
* altogether, tsk->need_resched is actively watched by the
......@@ -460,22 +454,19 @@ signed long schedule_timeout(signed long timeout)
*/
static inline void __schedule_tail(struct task_struct *prev)
{
unsigned long flags;
/*
* Wakeups to the previous process could result in
* the process not being rescheduled properly, because
* has_cpu is 1 until now. (so both the currently running
* process and the previous process has has_cpu==1)
*/
spin_lock_irqsave(&runqueue_lock, flags);
current->need_resched |= prev->need_resched;
prev->has_cpu = 0;
#ifdef CONFIG_SMP
if ((prev->state == TASK_RUNNING) &&
(prev != idle_task(smp_processor_id())))
(prev != idle_task(smp_processor_id()))) {
unsigned long flags;
spin_lock_irqsave(&runqueue_lock, flags);
prev->has_cpu = 0;
reschedule_idle(prev, flags); // spin_unlocks runqueue
else
spin_unlock_irqrestore(&runqueue_lock, flags);
} else {
wmb();
prev->has_cpu = 0;
}
#endif /* CONFIG_SMP */
}
void schedule_tail(struct task_struct *prev)
......
......@@ -369,8 +369,15 @@ rpc_sleep_locked(struct rpc_wait_queue *q, struct rpc_task *task,
spin_unlock_bh(&rpc_queue_lock);
}
/*
* Wake up a single task -- must be invoked with spin lock held.
/**
* __rpc_wake_up_task - wake up a single rpc_task
* @task: task to be woken up
*
* If the task is locked, it is merely removed from the queue, and
* 'task->tk_wakeup' is set. rpc_unlock_task() will then ensure
* that it is woken up as soon as the lock count goes to zero.
*
* Caller must hold rpc_queue_lock
*/
static void
__rpc_wake_up_task(struct rpc_task *task)
......@@ -395,6 +402,8 @@ __rpc_wake_up_task(struct rpc_task *task)
return;
__rpc_disable_timer(task);
if (task->tk_rpcwait != &schedq)
__rpc_remove_wait_queue(task);
/* If the task has been locked, then set tk_wakeup so that
* rpc_unlock_task() wakes us up... */
......@@ -404,8 +413,6 @@ __rpc_wake_up_task(struct rpc_task *task)
} else
task->tk_wakeup = 0;
if (task->tk_rpcwait != &schedq)
__rpc_remove_wait_queue(task);
rpc_make_runnable(task);
dprintk("RPC: __rpc_wake_up_task done\n");
......@@ -452,8 +459,11 @@ rpc_wake_up_next(struct rpc_wait_queue *queue)
return task;
}
/*
* Wake up all tasks on a queue
/**
* rpc_wake_up - wake up all rpc_tasks
* @queue: rpc_wait_queue on which the tasks are sleeping
*
* Grabs rpc_queue_lock
*/
void
rpc_wake_up(struct rpc_wait_queue *queue)
......@@ -464,8 +474,12 @@ rpc_wake_up(struct rpc_wait_queue *queue)
spin_unlock_bh(&rpc_queue_lock);
}
/*
* Wake up all tasks on a queue, and set their status value.
/**
* rpc_wake_up_status - wake up all rpc_tasks and set their status value.
* @queue: rpc_wait_queue on which the tasks are sleeping
* @status: status value to set
*
* Grabs rpc_queue_lock
*/
void
rpc_wake_up_status(struct rpc_wait_queue *queue, int status)
......@@ -931,20 +945,27 @@ rpc_release_task(struct rpc_task *task)
task->tk_release(task);
}
/*
* Handling of RPC child tasks
* We can't simply call wake_up(parent) here, because the
* parent task may already have gone away
/**
* rpc_find_parent - find the parent of a child task.
* @child: child task
*
* Checks that the parent task is still sleeping on the
* queue 'childq'. If so returns a pointer to the parent.
* Upon failure returns NULL.
*
* Caller must hold rpc_queue_lock
*/
static inline struct rpc_task *
rpc_find_parent(struct rpc_task *child)
{
struct rpc_task *temp, *parent;
struct rpc_task *task, *parent;
parent = (struct rpc_task *) child->tk_calldata;
for (temp = childq.task; temp; temp = temp->tk_next) {
if (temp == parent)
return parent;
if ((task = childq.task) != NULL) {
do {
if (task == parent)
return parent;
} while ((task = task->tk_next) != childq.task);
}
return NULL;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment