Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
9521288f
Commit
9521288f
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 2.3.99pre9-5
parent
dad12642
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
564 additions
and
304 deletions
+564
-304
Documentation/Configure.help
Documentation/Configure.help
+0
-8
Documentation/DocBook/parportbook.tmpl
Documentation/DocBook/parportbook.tmpl
+345
-109
arch/i386/config.in
arch/i386/config.in
+0
-1
arch/i386/kernel/apm.c
arch/i386/kernel/apm.c
+24
-26
drivers/net/setup.c
drivers/net/setup.c
+2
-13
drivers/net/slhc.c
drivers/net/slhc.c
+0
-7
drivers/parport/ChangeLog
drivers/parport/ChangeLog
+4
-0
drivers/usb/pegasus.c
drivers/usb/pegasus.c
+38
-12
drivers/usb/serial/Makefile
drivers/usb/serial/Makefile
+20
-2
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/digi_acceleport.c
+0
-4
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.c
+0
-6
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/keyspan_pda.c
+0
-4
drivers/usb/serial/omninet.c
drivers/usb/serial/omninet.c
+0
-6
drivers/usb/serial/usbserial.c
drivers/usb/serial/usbserial.c
+4
-0
drivers/usb/serial/visor.c
drivers/usb/serial/visor.c
+0
-7
drivers/usb/serial/whiteheat.c
drivers/usb/serial/whiteheat.c
+0
-6
drivers/usb/usb-ohci.c
drivers/usb/usb-ohci.c
+95
-59
drivers/usb/usb-ohci.h
drivers/usb/usb-ohci.h
+1
-1
fs/cramfs/inode.c
fs/cramfs/inode.c
+30
-26
include/net/slhc.h
include/net/slhc.h
+0
-6
kernel/ksyms.c
kernel/ksyms.c
+1
-0
net/core/dev.c
net/core/dev.c
+0
-1
No files found.
Documentation/Configure.help
View file @
9521288f
...
@@ -12468,14 +12468,6 @@ CONFIG_APM_DISPLAY_BLANK
...
@@ -12468,14 +12468,6 @@ CONFIG_APM_DISPLAY_BLANK
backlight at all, or it might print a lot of errors to the console,
backlight at all, or it might print a lot of errors to the console,
especially if you are using gpm.
especially if you are using gpm.
Ignore multiple suspend/standby events
CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
This option is necessary on the IBM Thinkpad 560, but should work on
all other laptops. When the APM BIOS returns multiple suspend or
standby events while one is already being processed they will be
ignored. Without this the Thinkpad 560 has troubles with the user
level daemon apmd, and with the PCMCIA package pcmcia-cs.
Ignore multiple suspend/resume cycles
Ignore multiple suspend/resume cycles
CONFIG_APM_IGNORE_SUSPEND_BOUNCE
CONFIG_APM_IGNORE_SUSPEND_BOUNCE
This option is necessary on the Dell Inspiron 3200 and others, but
This option is necessary on the Dell Inspiron 3200 and others, but
...
...
Documentation/DocBook/parportbook.tmpl
View file @
9521288f
...
@@ -62,7 +62,7 @@
...
@@ -62,7 +62,7 @@
<para>
<para>
The first parallel port support for Linux came with the line
The first parallel port support for Linux came with the line
printer driver, <
filename>lp</filename
>. The printer driver is a
printer driver, <
literal>lp</literal
>. The printer driver is a
character special device, and (in Linux 2.0) had support for
character special device, and (in Linux 2.0) had support for
writing, via <function>write</function>, and configuration and
writing, via <function>write</function>, and configuration and
statistics reporting via <function>ioctl</function>.
statistics reporting via <function>ioctl</function>.
...
@@ -152,7 +152,7 @@
...
@@ -152,7 +152,7 @@
-->
-->
<para>
<para>
The <
filename>parport</filename
> code in Linux 2.2 was designed to
The <
literal>parport</literal
> code in Linux 2.2 was designed to
meet these problems of architectural differences in parallel
meet these problems of architectural differences in parallel
ports, of port-sharing between devices with pass-through ports,
ports, of port-sharing between devices with pass-through ports,
and of lack of support for IEEE 1284 transfer modes.
and of lack of support for IEEE 1284 transfer modes.
...
@@ -161,7 +161,7 @@
...
@@ -161,7 +161,7 @@
<!-- platform differences -->
<!-- platform differences -->
<para>
<para>
There are two layers to the <
filename>parport</filename
>
There are two layers to the <
literal>parport</literal
>
subsystem, only one of which deals directly with the hardware.
subsystem, only one of which deals directly with the hardware.
The other layer deals with sharing and IEEE 1284 transfer modes.
The other layer deals with sharing and IEEE 1284 transfer modes.
In this way, parallel support for a particular architecture comes
In this way, parallel support for a particular architecture comes
...
@@ -172,13 +172,13 @@
...
@@ -172,13 +172,13 @@
<!-- sharing model -->
<!-- sharing model -->
<para>
<para>
The sharing model provided by the <
filename>parport</filename
>
The sharing model provided by the <
literal>parport</literal
>
subsystem is one of exclusive access. A device driver, such as
subsystem is one of exclusive access. A device driver, such as
the printer driver, must ask the <
filename>parport</filename
>
the printer driver, must ask the <
literal>parport</literal
>
layer for access to the port, and can only use the port once
layer for access to the port, and can only use the port once
access has been granted. When it has finished a
access has been granted. When it has finished a
<quote>transaction</quote>, it can tell the
<quote>transaction</quote>, it can tell the
<
filename>parport</filename
> layer that it may release the port
<
literal>parport</literal
> layer that it may release the port
for other device drivers to use.
for other device drivers to use.
</para>
</para>
...
@@ -299,10 +299,10 @@
...
@@ -299,10 +299,10 @@
<title>Sharing core</title>
<title>Sharing core</title>
<para>
<para>
At the core of the <
filename>parport</filename
> subsystem is the
At the core of the <
literal>parport</literal
> subsystem is the
sharing mechanism (see
sharing mechanism (see
<filename>drivers/parport/share.c</filename>). This module,
<filename>drivers/parport/share.c</filename>). This module,
<
filename>parport</filename
>, is responsible for keeping track of
<
literal>parport</literal
>, is responsible for keeping track of
which ports there are in the system, which device drivers might be
which ports there are in the system, which device drivers might be
interested in new ports, and whether or not each port is available
interested in new ports, and whether or not each port is available
for use (or if not, which driver is currently using it).
for use (or if not, which driver is currently using it).
...
@@ -314,10 +314,10 @@
...
@@ -314,10 +314,10 @@
<title>Parports and their overrides</title>
<title>Parports and their overrides</title>
<para>
<para>
The generic <
filename>parport</filename
> sharing code doesn't
The generic <
literal>parport</literal
> sharing code doesn't
directly handle the parallel port hardware. That is done instead
directly handle the parallel port hardware. That is done instead
by <quote>low-level</quote> <
filename>parport</filename
> drivers.
by <quote>low-level</quote> <
literal>parport</literal
> drivers.
The function of a low-level <
filename>parport</filename
> driver is
The function of a low-level <
literal>parport</literal
> driver is
to detect parallel ports, register them with the sharing code, and
to detect parallel ports, register them with the sharing code, and
provide a list of access functions for each port.
provide a list of access functions for each port.
</para>
</para>
...
@@ -340,11 +340,11 @@
...
@@ -340,11 +340,11 @@
<para>
<para>
Stacked on top of the sharing mechanism, but still in the
Stacked on top of the sharing mechanism, but still in the
<
filename>parport</filename
> module, are functions for
<
literal>parport</literal
> module, are functions for
transferring data. They are provided for the device drivers to
transferring data. They are provided for the device drivers to
use, and are very much like library routines. Since these
use, and are very much like library routines. Since these
transfer functions are provided by the generic
transfer functions are provided by the generic
<
filename>parport</filename
> core they must use the <quote>lowest
<
literal>parport</literal
> core they must use the <quote>lowest
common denominator</quote> set of access functions: they can set
common denominator</quote> set of access functions: they can set
the control lines, examine the status lines, and use the data
the control lines, examine the status lines, and use the data
lines. With some parallel ports the data lines can only be set
lines. With some parallel ports the data lines can only be set
...
@@ -356,7 +356,7 @@
...
@@ -356,7 +356,7 @@
</para>
</para>
<para>
<para>
The low-level <
filename>parport</filename
> drivers also provide
The low-level <
literal>parport</literal
> drivers also provide
IEEE 1284 transfer functions, as names in the access function
IEEE 1284 transfer functions, as names in the access function
list. The low-level driver can just name the generic IEEE 1284
list. The low-level driver can just name the generic IEEE 1284
transfer functions for this. Some parallel ports can do IEEE 1284
transfer functions for this. Some parallel ports can do IEEE 1284
...
@@ -373,7 +373,7 @@
...
@@ -373,7 +373,7 @@
<para>
<para>
When a parallel port device driver (such as
When a parallel port device driver (such as
<
filename>lp</filename
>) initialises it tells the sharing layer
<
literal>lp</literal
>) initialises it tells the sharing layer
about itself using <function>parport_register_driver</function>.
about itself using <function>parport_register_driver</function>.
The information is put into a <structname>struct
The information is put into a <structname>struct
parport_driver</structname>, which is put into a linked list. The
parport_driver</structname>, which is put into a linked list. The
...
@@ -441,7 +441,7 @@
...
@@ -441,7 +441,7 @@
the draft specifies the on-the-wire protocol for daisy-chaining
the draft specifies the on-the-wire protocol for daisy-chaining
and multiplexing, and also suggests a programming interface for
and multiplexing, and also suggests a programming interface for
using it. That interface (or most of it) has been implemented in
using it. That interface (or most of it) has been implemented in
the <
filename>parport</filename
> code in Linux.
the <
literal>parport</literal
> code in Linux.
</para>
</para>
<para>
<para>
...
@@ -494,20 +494,27 @@
...
@@ -494,20 +494,27 @@
<function>parport_device_coords</function>.
<function>parport_device_coords</function>.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>parport_device_num</function></funcdef>
<funcdef>int <function>parport_device_num</function></funcdef>
<paramdef>int <parameter>parport</parameter></paramdef>
<paramdef>int <parameter>parport</parameter></paramdef>
<paramdef>int <parameter>mux</parameter></paramdef>
<paramdef>int <parameter>mux</parameter></paramdef>
<paramdef>int <parameter>daisy</parameter></paramdef>
<paramdef>int <parameter>daisy</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>parport_device_coords</function></funcdef>
<funcdef>int <function>parport_device_coords</function></funcdef>
<paramdef>int <parameter>devnum</parameter></paramdef>
<paramdef>int <parameter>devnum</parameter></paramdef>
<paramdef>int *<parameter>parport</parameter></paramdef>
<paramdef>int *<parameter>parport</parameter></paramdef>
<paramdef>int *<parameter>mux</parameter></paramdef>
<paramdef>int *<parameter>mux</parameter></paramdef>
<paramdef>int *<parameter>daisy</parameter></paramdef>
<paramdef>int *<parameter>daisy</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
Any parallel port peripheral will be connected directly or
Any parallel port peripheral will be connected directly or
...
@@ -524,18 +531,25 @@
...
@@ -524,18 +531,25 @@
<function>parport_find_class</function>.
<function>parport_find_class</function>.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>parport_find_device</function></funcdef>
<funcdef>int <function>parport_find_device</function></funcdef>
<paramdef>const char *<parameter>mfg</parameter></paramdef>
<paramdef>const char *<parameter>mfg</parameter></paramdef>
<paramdef>const char *<parameter>mdl</parameter></paramdef>
<paramdef>const char *<parameter>mdl</parameter></paramdef>
<paramdef>int <parameter>from</parameter></paramdef>
<paramdef>int <parameter>from</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>parport_find_class</function></funcdef>
<funcdef>int <function>parport_find_class</function></funcdef>
<paramdef>parport_device_class <parameter>cls</parameter></paramdef>
<paramdef>parport_device_class <parameter>cls</parameter></paramdef>
<paramdef>int <parameter>from</parameter></paramdef>
<paramdef>int <parameter>from</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
These functions take a device number (in addition to some other
These functions take a device number (in addition to some other
...
@@ -572,7 +586,7 @@
...
@@ -572,7 +586,7 @@
This section is written from the point of view of the device driver
This section is written from the point of view of the device driver
programmer, who might be writing a driver for a printer or a
programmer, who might be writing a driver for a printer or a
scanner or else anything that plugs into the parallel port. It
scanner or else anything that plugs into the parallel port. It
explains how to use the <
filename>parport</filename
> interface to
explains how to use the <
literal>parport</literal
> interface to
find parallel ports, use them, and share them with other device
find parallel ports, use them, and share them with other device
drivers.
drivers.
</para>
</para>
...
@@ -585,55 +599,62 @@
...
@@ -585,55 +599,62 @@
<para>
<para>
The interactions between the device driver and the
The interactions between the device driver and the
<
filename>parport</filename
> layer are as follows. First, the
<
literal>parport</literal
> layer are as follows. First, the
device driver registers its existence with
device driver registers its existence with
<
filename>parport</filename
>, in order to get told about any
<
literal>parport</literal
>, in order to get told about any
parallel ports that have been (or will be) detected. When it gets
parallel ports that have been (or will be) detected. When it gets
told about a parallel port, it then tells
told about a parallel port, it then tells
<
filename>parport</filename
> that it wants to drive a device on
<
literal>parport</literal
> that it wants to drive a device on
that port. Thereafter it can claim exclusive access to the port in
that port. Thereafter it can claim exclusive access to the port in
order to talk to its device.
order to talk to its device.
</para>
</para>
<para>
<para>
So, the first thing for the device driver to do is tell
So, the first thing for the device driver to do is tell
<
filename>parport</filename
> that it wants to know what parallel
<
literal>parport</literal
> that it wants to know what parallel
ports are on the system. To do this, it uses the
ports are on the system. To do this, it uses the
<function>parport_register_device</function> function:
<function>parport_register_device</function> function:
</para>
</para>
<programlisting>
<funcsynopsis>
<![CDATA[
<funcsynopsisinfo>
#include <parport.h>
struct parport_driver {
struct parport_driver {
const char *name;
const char *name;
void (*attach) (struct parport *);
void (*attach) (struct parport *);
void (*detach) (struct parport *);
void (*detach) (struct parport *);
struct parport_driver *next;
struct parport_driver *next;
};
};
]]></programlisting
>
</funcsynopsisinfo
>
<funcsynopsis>
<funcprototype>
<funcprototype>
<funcdef>int <function>parport_register_driver</function></funcdef>
<funcdef>int <function>parport_register_driver</function></funcdef>
<paramdef>struct parport_driver *<parameter>driver</parameter></paramdef>
<paramdef>struct parport_driver *<parameter>driver</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
In other words, the device driver passes pointers to a couple of
In other words, the device driver passes pointers to a couple of
functions to <
filename>parport</filename
>, and
functions to <
literal>parport</literal
>, and
<
filename>parport</filename
> calls <function>attach</function> for
<
literal>parport</literal
> calls <function>attach</function> for
each port that's detected (and <function>detach</function> for each
each port that's detected (and <function>detach</function> for each
port that disappears---yes, this can happen).
port that disappears---yes, this can happen).
</para>
</para>
<para>
<para>
The next thing that happens is that the device driver tells
The next thing that happens is that the device driver tells
<
filename>parport</filename
> that it thinks there's a device on the
<
literal>parport</literal
> that it thinks there's a device on the
port that it can drive. This typically will happen in the driver's
port that it can drive. This typically will happen in the driver's
<function>attach</function> function, and is done with
<function>attach</function> function, and is done with
<function>parport_register_device</function>:
<function>parport_register_device</function>:
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
<funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
...
@@ -645,7 +666,8 @@ struct parport_driver {
...
@@ -645,7 +666,8 @@ struct parport_driver {
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
The <parameter>port</parameter> comes from the parameter supplied
The <parameter>port</parameter> comes from the parameter supplied
...
@@ -705,7 +727,7 @@ struct parport_driver {
...
@@ -705,7 +727,7 @@ struct parport_driver {
<para>
<para>
The <parameter>flags</parameter> are for telling
The <parameter>flags</parameter> are for telling
<
filename>parport</filename
> any requirements or hints that are
<
literal>parport</literal
> any requirements or hints that are
useful. The only useful value here (other than
useful. The only useful value here (other than
<constant>0</constant>, which is the usual value) is
<constant>0</constant>, which is the usual value) is
<constant>PARPORT_DEV_EXCL</constant>. The point of that flag is
<constant>PARPORT_DEV_EXCL</constant>. The point of that flag is
...
@@ -738,7 +760,11 @@ struct parport_driver {
...
@@ -738,7 +760,11 @@ struct parport_driver {
than a pointer to a <structname>struct parport</structname>.
than a pointer to a <structname>struct parport</structname>.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>struct pardevice *<function>parport_open</function></funcdef>
<funcdef>struct pardevice *<function>parport_open</function></funcdef>
<paramdef>int <parameter>devnum</parameter></paramdef>
<paramdef>int <parameter>devnum</parameter></paramdef>
<paramdef>int <parameter>(*pf)</parameter>
<paramdef>int <parameter>(*pf)</parameter>
...
@@ -749,14 +775,18 @@ struct parport_driver {
...
@@ -749,14 +775,18 @@ struct parport_driver {
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>parport_close</function></funcdef>
<funcdef>void <function>parport_close</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
<funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
...
@@ -768,12 +798,15 @@ struct parport_driver {
...
@@ -768,12 +798,15 @@ struct parport_driver {
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>int <parameter>flags</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
<paramdef>void *<parameter>handle</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>parport_unregister_device</function></funcdef>
<funcdef>void <function>parport_unregister_device</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
The intended use of these functions is during driver initialisation
The intended use of these functions is during driver initialisation
...
@@ -799,20 +832,29 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
...
@@ -799,20 +832,29 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
port.
port.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>parport_claim</function></funcdef>
<funcdef>int <function>parport_claim</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>parport_claim_or_block</function></funcdef>
<funcdef>int <function>parport_claim_or_block</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>void <function>parport_release</function></funcdef>
<funcdef>void <function>parport_release</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
To claim access to the port, use <function>parport_claim</function>
To claim access to the port, use <function>parport_claim</function>
...
@@ -866,15 +908,22 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
...
@@ -866,15 +908,22 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
a <filename>/proc</filename> entry.
a <filename>/proc</filename> entry.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>parport_yield</function></funcdef>
<funcdef>int <function>parport_yield</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>parport_yield_blocking</function></funcdef>
<funcdef>int <function>parport_yield_blocking</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
The first of these, <function>parport_yield</function>, will not
The first of these, <function>parport_yield</function>, will not
...
@@ -919,14 +968,14 @@ port->ops->write_data (port, d);
...
@@ -919,14 +968,14 @@ port->ops->write_data (port, d);
<listitem>
<listitem>
<para>
<para>
The device driver registers itself with <
filename>parport</filename
>.
The device driver registers itself with <
literal>parport</literal
>.
</para>
</para>
</listitem>
</listitem>
<listitem>
<listitem>
<para>
<para>
A low-level driver finds a parallel port and registers it with
A low-level driver finds a parallel port and registers it with
<
filename>parport</filename
> (these first two things can happen
<
literal>parport</literal
> (these first two things can happen
in either order). This registration creates a <structname>struct
in either order). This registration creates a <structname>struct
parport</structname> which is linked onto a list of known ports.
parport</structname> which is linked onto a list of known ports.
</para>
</para>
...
@@ -934,7 +983,7 @@ port->ops->write_data (port, d);
...
@@ -934,7 +983,7 @@ port->ops->write_data (port, d);
<listitem>
<listitem>
<para>
<para>
<
filename>parport</filename
> calls the
<
literal>parport</literal
> calls the
<function>attach</function> function of each registered device
<function>attach</function> function of each registered device
driver, passing it the pointer to the new <structname>struct
driver, passing it the pointer to the new <structname>struct
parport</structname>.
parport</structname>.
...
@@ -944,7 +993,7 @@ port->ops->write_data (port, d);
...
@@ -944,7 +993,7 @@ port->ops->write_data (port, d);
<listitem>
<listitem>
<para>
<para>
The device driver gets a handle from
The device driver gets a handle from
<
filename>parport</filename
>, for use with
<
literal>parport</literal
>, for use with
<function>parport_claim</function>/<function>release</function>.
<function>parport_claim</function>/<function>release</function>.
This handle takes the form of a pointer to a <structname>struct
This handle takes the form of a pointer to a <structname>struct
pardevice</structname>, representing a particular device on the
pardevice</structname>, representing a particular device on the
...
@@ -993,18 +1042,18 @@ port->ops->write_data (port, d);
...
@@ -993,18 +1042,18 @@ port->ops->write_data (port, d);
<!-- Could even talk about parallel port console here. -->
<!-- Could even talk about parallel port console here. -->
<para>
<para>
The printer driver, <
filename>lp</filename
> is a character special
The printer driver, <
literal>lp</literal
> is a character special
device driver and a <
filename>parport</filename
> client. As a
device driver and a <
literal>parport</literal
> client. As a
character special device driver it registers a <structname>struct
character special device driver it registers a <structname>struct
file_operations</structname> using
file_operations</structname> using
<function>register_chrdev</function>, with pointers filled in for
<function>register_chrdev</function>, with pointers filled in for
<structfield>write</structfield>, <structfield>ioctl</structfield>,
<structfield>write</structfield>, <structfield>ioctl</structfield>,
<structfield>open</structfield> and
<structfield>open</structfield> and
<structfield>release</structfield>. As a client of
<structfield>release</structfield>. As a client of
<
filename>parport</filename
>, it registers a <structname>struct
<
literal>parport</literal
>, it registers a <structname>struct
parport_driver</structname> using
parport_driver</structname> using
<function>parport_register_driver</function>, so that
<function>parport_register_driver</function>, so that
<
filename>parport</filename
> knows to call
<
literal>parport</literal
> knows to call
<function>lp_attach</function> when a new parallel port is
<function>lp_attach</function> when a new parallel port is
discovered (and <function>lp_detach</function> when it goes
discovered (and <function>lp_detach</function> when it goes
away).
away).
...
@@ -1012,8 +1061,8 @@ port->ops->write_data (port, d);
...
@@ -1012,8 +1061,8 @@ port->ops->write_data (port, d);
<para>
<para>
The parallel port console functionality is also implemented in
The parallel port console functionality is also implemented in
<filename>
lp.c</filename>, but that won't be covered here (it's
<filename>
drivers/char/lp.c</filename>, but that won't be covered
quite simple though).
here (it's
quite simple though).
</para>
</para>
<para>
<para>
...
@@ -1037,7 +1086,7 @@ port->ops->write_data (port, d);
...
@@ -1037,7 +1086,7 @@ port->ops->write_data (port, d);
<para>
<para>
After successfully registering itself as a character special device
After successfully registering itself as a character special device
driver, the printer driver registers itself as a
driver, the printer driver registers itself as a
<
filename>parport</filename
> client using
<
literal>parport</literal
> client using
<function>parport_register_driver</function>. It passes a pointer
<function>parport_register_driver</function>. It passes a pointer
to this structure:
to this structure:
</para>
</para>
...
@@ -1076,14 +1125,14 @@ static struct parport_driver lp_driver = {
...
@@ -1076,14 +1125,14 @@ static struct parport_driver lp_driver = {
<para>
<para>
The other interesting piece of the printer driver, from the point
The other interesting piece of the printer driver, from the point
of view of <
filename>parport</filename
>, is
of view of <
literal>parport</literal
>, is
<function>lp_write</function>. In this function, the user space
<function>lp_write</function>. In this function, the user space
process has data that it wants printed, and the printer driver
process has data that it wants printed, and the printer driver
hands it off to the <
filename>parport</filename
> code to deal with.
hands it off to the <
literal>parport</literal
> code to deal with.
</para>
</para>
<para>
<para>
The <
filename>parport</filename
> functions it uses that we have not
The <
literal>parport</literal
> functions it uses that we have not
seen yet are <function>parport_negotiate</function>,
seen yet are <function>parport_negotiate</function>,
<function>parport_set_timeout</function>, and
<function>parport_set_timeout</function>, and
<function>parport_write</function>. These functions are part of
<function>parport_write</function>. These functions are part of
...
@@ -1106,11 +1155,16 @@ static struct parport_driver lp_driver = {
...
@@ -1106,11 +1155,16 @@ static struct parport_driver lp_driver = {
<function>parport_negotiate</function>.
<function>parport_negotiate</function>.
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>parport_negotiate</function></funcdef>
<funcdef>int <function>parport_negotiate</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>int <parameter>mode</parameter></paramdef>
<paramdef>int <parameter>mode</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
The <parameter>modes</parameter> parameter is a symbolic constant
The <parameter>modes</parameter> parameter is a symbolic constant
...
@@ -1132,7 +1186,7 @@ static struct parport_driver lp_driver = {
...
@@ -1132,7 +1186,7 @@ static struct parport_driver lp_driver = {
<para>
<para>
The main work is done in the write-loop. In particular, the line
The main work is done in the write-loop. In particular, the line
that hands the data over to <
filename>parport</filename
> reads:
that hands the data over to <
literal>parport</literal
> reads:
</para>
</para>
<programlisting>
<programlisting>
...
@@ -1147,19 +1201,26 @@ static struct parport_driver lp_driver = {
...
@@ -1147,19 +1201,26 @@ static struct parport_driver lp_driver = {
successfully written:
successfully written:
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>ssize_t <function>parport_write</function></funcdef>
<funcdef>ssize_t <function>parport_write</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>const void *<parameter>buf</parameter></paramdef>
<paramdef>const void *<parameter>buf</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcprototype>
<funcdef>ssize_t <function>parport_read</function></funcdef>
<funcdef>ssize_t <function>parport_read</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>void *<parameter>buf</parameter></paramdef>
<paramdef>void *<parameter>buf</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
<paramdef>size_t <parameter>len</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
(<function>parport_read</function> does what it sounds like, but
(<function>parport_read</function> does what it sounds like, but
...
@@ -1186,49 +1247,106 @@ struct parport_operations {
...
@@ -1186,49 +1247,106 @@ struct parport_operations {
[...]
[...]
/* Block read/write */
/* Block read/write */
size_t (*epp_write_data) (struct parport *port, const void *buf,
size_t (*epp_write_data) (struct parport *port,
const void *buf,
size_t len, int flags);
size_t len, int flags);
size_t (*epp_read_data) (struct parport *port, void *buf, size_t len,
size_t (*epp_read_data) (struct parport *port,
void *buf, size_t len,
int flags);
int flags);
size_t (*epp_write_addr) (struct parport *port, const void *buf,
size_t (*epp_write_addr) (struct parport *port,
const void *buf,
size_t len, int flags);
size_t len, int flags);
size_t (*epp_read_addr) (struct parport *port, void *buf, size_t len,
size_t (*epp_read_addr) (struct parport *port,
void *buf, size_t len,
int flags);
int flags);
size_t (*ecp_write_data) (struct parport *port, const void *buf,
size_t (*ecp_write_data) (struct parport *port,
const void *buf,
size_t len, int flags);
size_t len, int flags);
size_t (*ecp_read_data) (struct parport *port, void *buf, size_t len,
size_t (*ecp_read_data) (struct parport *port,
void *buf, size_t len,
int flags);
int flags);
size_t (*ecp_write_addr) (struct parport *port, const void *buf,
size_t (*ecp_write_addr) (struct parport *port,
const void *buf,
size_t len, int flags);
size_t len, int flags);
size_t (*compat_write_data) (struct parport *port, const void *buf,
size_t (*compat_write_data) (struct parport *port,
const void *buf,
size_t len, int flags);
size_t len, int flags);
size_t (*nibble_read_data) (struct parport *port, void *buf,
size_t (*nibble_read_data) (struct parport *port,
size_t len, int flags);
void *buf, size_t len,
size_t (*byte_read_data) (struct parport *port, void *buf,
int flags);
size_t len, int flags);
size_t (*byte_read_data) (struct parport *port,
void *buf, size_t len,
int flags);
};
};
]]></programlisting>
]]></programlisting>
<para>
<para>
The transfer code in <
filename>parport</filename
> will tolerate a
The transfer code in <
literal>parport</literal
> will tolerate a
data transfer stall only for so long, and this timeout can be
data transfer stall only for so long, and this timeout can be
specified with <function>parport_set_timeout</function>, which
specified with <function>parport_set_timeout</function>, which
returns the previous timeout:
returns the previous timeout:
</para>
</para>
<funcsynopsis><funcprototype>
<funcsynopsis>
<funcsynopsisinfo>
#include <parport.h>
</funcsynopsisinfo>
<funcprototype>
<funcdef>long <function>parport_set_timeout</function></funcdef>
<funcdef>long <function>parport_set_timeout</function></funcdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
<paramdef>long <parameter>inactivity</parameter></paramdef>
<paramdef>long <parameter>inactivity</parameter></paramdef>
</funcprototype></funcsynopsis>
</funcprototype>
</funcsynopsis>
<para>
<para>
This timeout is specific to the device, and is restored on
This timeout is specific to the device, and is restored on
<function>parport_claim</function>.
<function>parport_claim</function>.
</para>
</para>
<para>
The next function to look at is the one that allows processes to
read from <filename>/dev/lp0</filename>:
<function>lp_read</function>. It's short, like
<function>lp_write</function>.
</para>
<para>
The semantics of reading from a line printer device are as follows:
</para>
<itemizedlist>
<listitem>
<para>
Switch to reverse nibble mode.
</para>
</listitem>
<listitem>
<para>
Try to read data from the peripheral using reverse nibble mode,
until either the user-provided buffer is full or the peripheral
indicates that there is no more data.
</para>
</listitem>
<listitem>
<para>
If there was data, stop, and return it.
</para>
</listitem>
<listitem>
<para>
Otherwise, we tried to read data and there was none. If the user
opened the device node with the <constant>O_NONBLOCK</constant>
flag, return. Otherwise wait until an interrupt occurs on the
port (or a timeout elapses).
</para>
</listitem>
</itemizedlist>
</chapter>
</chapter>
<chapter id="ppdev">
<chapter id="ppdev">
...
@@ -1260,7 +1378,7 @@ struct parport_operations {
...
@@ -1260,7 +1378,7 @@ struct parport_operations {
</para>
</para>
<para>
<para>
In contrast, the <
filename>ppdev</filename
> driver (accessed via
In contrast, the <
literal>ppdev</literal
> driver (accessed via
<filename>/dev/parport0</filename>) allows you to:
<filename>/dev/parport0</filename>) allows you to:
</para>
</para>
...
@@ -1344,11 +1462,13 @@ struct parport_operations {
...
@@ -1344,11 +1462,13 @@ struct parport_operations {
<title>Programming interface</title>
<title>Programming interface</title>
<para>
<para>
The <
filename>ppdev</filename> interface is largely the same as
The <
literal>ppdev</literal> interface is largely the same as that
that
of other character special devices, in that it supports
of other character special devices, in that it supports
<function>open</function>, <function>close</function>,
<function>open</function>, <function>close</function>,
<function>read</function>, <function>write</function>, and
<function>read</function>, <function>write</function>, and
<function>ioctl</function>.
<function>ioctl</function>. The constants for the
<function>ioctl</function> commands are in
<filename>include/linux/ppdev.h</filename>.
</para>
</para>
<sect2>
<sect2>
...
@@ -1379,7 +1499,7 @@ struct parport_operations {
...
@@ -1379,7 +1499,7 @@ struct parport_operations {
Most of the control is done, naturally enough, via the
Most of the control is done, naturally enough, via the
<function>ioctl</function> call. Using
<function>ioctl</function> call. Using
<function>ioctl</function>, the user-land driver can control both
<function>ioctl</function>, the user-land driver can control both
the <
filename>ppdev</filename
> driver in the kernel and the
the <
literal>ppdev</literal
> driver in the kernel and the
physical parallel port itself. The <function>ioctl</function>
physical parallel port itself. The <function>ioctl</function>
call takes as parameters a file descriptor (the one returned from
call takes as parameters a file descriptor (the one returned from
opening the device node), a command, and optionally (a pointer
opening the device node), a command, and optionally (a pointer
...
@@ -1395,7 +1515,7 @@ struct parport_operations {
...
@@ -1395,7 +1515,7 @@ struct parport_operations {
writer, you will need to do this before you are able to
writer, you will need to do this before you are able to
actually change the state of the parallel port in any way.
actually change the state of the parallel port in any way.
Note that some operations only affect the
Note that some operations only affect the
<
filename>ppdev</filename
> driver and not the port, such as
<
literal>ppdev</literal
> driver and not the port, such as
<constant>PPSETMODE</constant>; they can be performed while
<constant>PPSETMODE</constant>; they can be performed while
access to the port is not claimed.
access to the port is not claimed.
</para>
</para>
...
@@ -1486,7 +1606,7 @@ struct parport_operations {
...
@@ -1486,7 +1606,7 @@ struct parport_operations {
<para>
<para>
The <function>ioctl</function> parameter should be a pointer
The <function>ioctl</function> parameter should be a pointer
to an <type>int</type>; values for this are in
to an <type>int</type>; values for this are in
<filename>parport.h</filename> and include:
<filename>
incluce/linux/
parport.h</filename> and include:
</para>
</para>
<itemizedlist spacing=compact>
<itemizedlist spacing=compact>
...
@@ -1566,7 +1686,7 @@ struct parport_operations {
...
@@ -1566,7 +1686,7 @@ struct parport_operations {
Sets the control lines. The <function>ioctl</function>
Sets the control lines. The <function>ioctl</function>
parameter is a pointer to an <type>unsigned char</type>, the
parameter is a pointer to an <type>unsigned char</type>, the
bitwise OR of the control line values in
bitwise OR of the control line values in
<filename>parport.h</filename>.
<filename>
include/linux/
parport.h</filename>.
</para>
</para>
</listitem></varlistentry>
</listitem></varlistentry>
...
@@ -1591,7 +1711,7 @@ struct parport_operations {
...
@@ -1591,7 +1711,7 @@ struct parport_operations {
<para>
<para>
The control lines bits are defined in
The control lines bits are defined in
<filename>parport.h</filename>:
<filename>
include/linux/
parport.h</filename>:
</para>
</para>
<itemizedlist spacing=compact>
<itemizedlist spacing=compact>
...
@@ -1619,7 +1739,7 @@ struct parport_operations {
...
@@ -1619,7 +1739,7 @@ struct parport_operations {
course, each driver could remember what state the control
course, each driver could remember what state the control
lines are supposed to be in (they are never changed by
lines are supposed to be in (they are never changed by
anything else), but in order to provide
anything else), but in order to provide
<constant>PPRCONTROL</constant>, <
filename>ppdev</filename
>
<constant>PPRCONTROL</constant>, <
literal>ppdev</literal
>
must remember the state of the control lines anyway.
must remember the state of the control lines anyway.
</para>
</para>
...
@@ -1728,7 +1848,7 @@ struct ppdev_frob_struct {
...
@@ -1728,7 +1848,7 @@ struct ppdev_frob_struct {
<listitem>
<listitem>
<para>
<para>
Clears the interrupt count. The <
filename>ppdev</filename
>
Clears the interrupt count. The <
literal>ppdev</literal
>
driver keeps a count of interrupts as they are triggered.
driver keeps a count of interrupts as they are triggered.
<constant>PPCLRIRQ</constant> stores this count in an
<constant>PPCLRIRQ</constant> stores this count in an
<type>int</type>, a pointer to which is passed in as the
<type>int</type>, a pointer to which is passed in as the
...
@@ -1790,7 +1910,7 @@ struct ppdev_frob_struct {
...
@@ -1790,7 +1910,7 @@ struct ppdev_frob_struct {
<function>select</function></title>
<function>select</function></title>
<para>
<para>
The <
filename>ppdev</filename
> driver provides user-land device
The <
literal>ppdev</literal
> driver provides user-land device
drivers with the ability to wait for interrupts, and this is done
drivers with the ability to wait for interrupts, and this is done
using <function>poll</function> (and <function>select</function>,
using <function>poll</function> (and <function>select</function>,
which is implemented in terms of <function>poll</function>).
which is implemented in terms of <function>poll</function>).
...
@@ -1799,7 +1919,7 @@ struct ppdev_frob_struct {
...
@@ -1799,7 +1919,7 @@ struct ppdev_frob_struct {
<para>
<para>
When a user-land device driver wants to wait for an interrupt, it
When a user-land device driver wants to wait for an interrupt, it
sleeps with <function>poll</function>. When the interrupt
sleeps with <function>poll</function>. When the interrupt
arrives, <
filename>ppdev</filename
> wakes it up (with a
arrives, <
literal>ppdev</literal
> wakes it up (with a
<quote>read</quote> event, although strictly speaking there is
<quote>read</quote> event, although strictly speaking there is
nothing to actually <function>read</function>).
nothing to actually <function>read</function>).
</para>
</para>
...
@@ -1813,7 +1933,7 @@ struct ppdev_frob_struct {
...
@@ -1813,7 +1933,7 @@ struct ppdev_frob_struct {
<para>
<para>
Presented here are two demonstrations of how to write a simple
Presented here are two demonstrations of how to write a simple
printer driver for <
filename>ppdev</filename
>. Firstly we will
printer driver for <
literal>ppdev</literal
>. Firstly we will
use the <function>write</function> function, and after that we
use the <function>write</function> function, and after that we
will drive the control and data lines directly.
will drive the control and data lines directly.
</para>
</para>
...
@@ -1998,7 +2118,7 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
...
@@ -1998,7 +2118,7 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
]]></programlisting>
]]></programlisting>
<para>
<para>
To show a bit more of the <
filename>ppdev</filename
> interface,
To show a bit more of the <
literal>ppdev</literal
> interface,
here is a small piece of code that is intended to mimic the
here is a small piece of code that is intended to mimic the
printer's side of printer protocol.
printer's side of printer protocol.
</para>
</para>
...
@@ -2048,6 +2168,43 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
...
@@ -2048,6 +2168,43 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
}
}
]]></programlisting>
]]></programlisting>
<para>
And here is an example (with no error checking at all) to show how
to read data from the port, using ECP mode, with optional
negotiation to ECP mode first.
</para>
<programlisting><![CDATA[
{
int fd, mode;
fd = open ("/dev/parport0", O_RDONLY | O_NOCTTY);
ioctl (fd, PPCLAIM);
mode = IEEE1284_MODE_ECP;
if (negotiate_first) {
ioctl (fd, PPNEGOT, &mode);
/* no need for PPSETMODE */
} else {
ioctl (fd, PPSETMODE, &mode);
}
/* Now do whatever we want with fd */
close (0);
dup2 (fd, 0);
if (!fork()) {
/* child */
execlp ("cat", "cat", NULL);
exit (1);
} else {
/* parent */
wait (NULL);
}
/* Okay, finished */
ioctl (fd, PPRELEASE);
close (fd);
}
]]></programlisting>
</sect1>
</sect1>
</chapter>
</chapter>
...
@@ -2078,6 +2235,85 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
...
@@ -2078,6 +2235,85 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
!Fdrivers/parport/ieee1284.c parport_set_timeout
!Fdrivers/parport/ieee1284.c parport_set_timeout
</appendix>
</appendix>
<appendix>
<title>
The Linux 2.2 Parallel Port Subsystem
</title>
<para>
Although the interface described in this document is largely new
with the 2.4 kernel, the sharing mechanism is available in the 2.2
kernel as well. The functions available in 2.2 are:
</para>
<itemizedlist>
<listitem>
<para>
<function>parport_register_device</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_unregister_device</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_claim</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_claim_or_block</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_release</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_yield</function>
</para>
</listitem>
<listitem>
<para>
<function>parport_yield_blocking</function>
</para>
</listitem>
</itemizedlist>
<para>
In addition, negotiation to reverse nibble mode is supported:
</para>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>parport_ieee1284_nibble_mode_ok</function></funcdef>
<paramdef>struct parport *<parameter>port</parameter></paramdef>
<paramdef>unsigned char <parameter>mode</parameter></paramdef>
</funcprototype>
</funcsynopsis>
<para>
The only valid values for <parameter>mode</parameter> are 0 (for
reverse nibble mode) and 4 (for Device ID in reverse nibble mode).
</para>
<para>
This function is obsoleted by
<function>parport_negotiate</function> in Linux 2.4, and has been
removed.
</para>
</appendix>
</book>
</book>
<!-- Local Variables: -->
<!-- Local Variables: -->
...
...
arch/i386/config.in
View file @
9521288f
...
@@ -180,7 +180,6 @@ if [ "$CONFIG_APM" != "n" ]; then
...
@@ -180,7 +180,6 @@ if [ "$CONFIG_APM" != "n" ]; then
bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE
bool ' Enable PM at boot time' CONFIG_APM_DO_ENABLE
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Enable console blanking using APM' CONFIG_APM_DISPLAY_BLANK
bool ' Ignore multiple suspend' CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
bool ' Ignore multiple suspend/resume cycles' CONFIG_APM_IGNORE_SUSPEND_BOUNCE
bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
bool ' RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
bool ' Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
...
...
arch/i386/kernel/apm.c
View file @
9521288f
...
@@ -132,6 +132,9 @@
...
@@ -132,6 +132,9 @@
* 1.13: Changes for new pm_ interfaces (Andy Henroid
* 1.13: Changes for new pm_ interfaces (Andy Henroid
* <andy_henroid@yahoo.com>).
* <andy_henroid@yahoo.com>).
* Modularize the code.
* Modularize the code.
* Fix the Thinkpad (again) :-( (CONFIG_APM_IGNORE_MULTIPLE_SUSPENDS
* is now the way life works).
* Fix thinko in suspend() (wrong return).
*
*
* APM 1.1 Reference:
* APM 1.1 Reference:
*
*
...
@@ -308,9 +311,7 @@ static int clock_slowed = 0;
...
@@ -308,9 +311,7 @@ static int clock_slowed = 0;
#endif
#endif
static
int
suspends_pending
=
0
;
static
int
suspends_pending
=
0
;
static
int
standbys_pending
=
0
;
static
int
standbys_pending
=
0
;
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
static
int
waiting_for_resume
=
0
;
static
int
waiting_for_resume
=
0
;
#endif
#ifdef CONFIG_APM_RTC_IS_GMT
#ifdef CONFIG_APM_RTC_IS_GMT
# define clock_cmos_diff 0
# define clock_cmos_diff 0
...
@@ -866,22 +867,22 @@ static void reinit_timer(void)
...
@@ -866,22 +867,22 @@ static void reinit_timer(void)
static
int
suspend
(
void
)
static
int
suspend
(
void
)
{
{
int
err
;
int
err
;
int
ret
;
struct
apm_user
*
as
;
struct
apm_user
*
as
;
get_time_diff
();
get_time_diff
();
err
=
apm_set_power_state
(
APM_STATE_SUSPEND
);
err
=
apm_set_power_state
(
APM_STATE_SUSPEND
);
reinit_timer
();
reinit_timer
();
set_time
();
set_time
();
ret
=
(
err
==
APM_SUCCESS
)
||
(
err
==
APM_NO_ERROR
);
if
(
err
==
APM_NO_ERROR
)
if
(
!
ret
)
err
=
APM_SUCCESS
;
if
(
err
!=
APM_SUCCESS
)
apm_error
(
"suspend"
,
err
);
apm_error
(
"suspend"
,
err
);
for
(
as
=
user_list
;
as
!=
NULL
;
as
=
as
->
next
)
{
for
(
as
=
user_list
;
as
!=
NULL
;
as
=
as
->
next
)
{
as
->
suspend_wait
=
0
;
as
->
suspend_wait
=
0
;
as
->
suspend_result
=
(
ret
?
0
:
-
EIO
);
as
->
suspend_result
=
(
(
err
==
APM_SUCCESS
)
?
0
:
-
EIO
);
}
}
wake_up_interruptible
(
&
apm_suspend_waitqueue
);
wake_up_interruptible
(
&
apm_suspend_waitqueue
);
return
ret
;
return
err
;
}
}
static
void
standby
(
void
)
static
void
standby
(
void
)
...
@@ -962,14 +963,7 @@ static void check_events(void)
...
@@ -962,14 +963,7 @@ static void check_events(void)
switch
(
event
)
{
switch
(
event
)
{
case
APM_SYS_STANDBY
:
case
APM_SYS_STANDBY
:
case
APM_USER_STANDBY
:
case
APM_USER_STANDBY
:
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
if
(
waiting_for_resume
)
break
;
#endif
if
(
send_event
(
event
,
NULL
))
{
if
(
send_event
(
event
,
NULL
))
{
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
waiting_for_resume
=
1
;
#endif
if
(
standbys_pending
<=
0
)
if
(
standbys_pending
<=
0
)
standby
();
standby
();
}
}
...
@@ -986,14 +980,18 @@ static void check_events(void)
...
@@ -986,14 +980,18 @@ static void check_events(void)
if
(
ignore_bounce
)
if
(
ignore_bounce
)
break
;
break
;
#endif
#endif
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
/*
* If we are already processing a SUSPEND,
* then further SUSPEND events from the BIOS
* will be ignored. We also return here to
* cope with the fact that the Thinkpads keep
* sending a SUSPEND event until something else
* happens!
*/
if
(
waiting_for_resume
)
if
(
waiting_for_resume
)
break
;
return
;
#endif
if
(
send_event
(
event
,
NULL
))
{
if
(
send_event
(
event
,
NULL
))
{
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
waiting_for_resume
=
1
;
waiting_for_resume
=
1
;
#endif
if
(
suspends_pending
<=
0
)
if
(
suspends_pending
<=
0
)
(
void
)
suspend
();
(
void
)
suspend
();
}
}
...
@@ -1002,9 +1000,7 @@ static void check_events(void)
...
@@ -1002,9 +1000,7 @@ static void check_events(void)
case
APM_NORMAL_RESUME
:
case
APM_NORMAL_RESUME
:
case
APM_CRITICAL_RESUME
:
case
APM_CRITICAL_RESUME
:
case
APM_STANDBY_RESUME
:
case
APM_STANDBY_RESUME
:
#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
waiting_for_resume
=
0
;
waiting_for_resume
=
0
;
#endif
#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
#ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
last_resume
=
jiffies
;
last_resume
=
jiffies
;
ignore_bounce
=
1
;
ignore_bounce
=
1
;
...
@@ -1036,8 +1032,10 @@ static void apm_event_handler(void)
...
@@ -1036,8 +1032,10 @@ static void apm_event_handler(void)
int
err
;
int
err
;
if
((
standbys_pending
>
0
)
||
(
suspends_pending
>
0
))
{
if
((
standbys_pending
>
0
)
||
(
suspends_pending
>
0
))
{
if
((
apm_bios_info
.
version
>
0x100
)
&&
(
pending_count
--
<
0
))
{
if
((
apm_bios_info
.
version
>
0x100
)
&&
(
pending_count
--
<
=
0
))
{
pending_count
=
4
;
pending_count
=
4
;
if
(
debug
)
printk
(
KERN_DEBUG
"apm: setting state busy
\n
"
);
err
=
apm_set_power_state
(
APM_STATE_BUSY
);
err
=
apm_set_power_state
(
APM_STATE_BUSY
);
if
(
err
)
if
(
err
)
apm_error
(
"busy"
,
err
);
apm_error
(
"busy"
,
err
);
...
@@ -1097,7 +1095,7 @@ static void apm_mainloop(void)
...
@@ -1097,7 +1095,7 @@ static void apm_mainloop(void)
static
int
check_apm_user
(
struct
apm_user
*
as
,
const
char
*
func
)
static
int
check_apm_user
(
struct
apm_user
*
as
,
const
char
*
func
)
{
{
if
((
as
==
NULL
)
||
(
as
->
magic
!=
APM_BIOS_MAGIC
))
{
if
((
as
==
NULL
)
||
(
as
->
magic
!=
APM_BIOS_MAGIC
))
{
printk
(
KERN_ERR
"apm: %s passed bad filp"
,
func
);
printk
(
KERN_ERR
"apm: %s passed bad filp
\n
"
,
func
);
return
1
;
return
1
;
}
}
return
0
;
return
0
;
...
@@ -1200,7 +1198,7 @@ static int do_ioctl(struct inode * inode, struct file *filp,
...
@@ -1200,7 +1198,7 @@ static int do_ioctl(struct inode * inode, struct file *filp,
}
else
if
(
!
send_event
(
APM_USER_SUSPEND
,
as
))
}
else
if
(
!
send_event
(
APM_USER_SUSPEND
,
as
))
return
-
EAGAIN
;
return
-
EAGAIN
;
if
(
suspends_pending
<=
0
)
{
if
(
suspends_pending
<=
0
)
{
if
(
!
suspend
()
)
if
(
suspend
()
!=
APM_SUCCESS
)
return
-
EIO
;
return
-
EIO
;
}
else
{
}
else
{
as
->
suspend_wait
=
1
;
as
->
suspend_wait
=
1
;
...
@@ -1251,7 +1249,7 @@ static int do_release(struct inode * inode, struct file * filp)
...
@@ -1251,7 +1249,7 @@ static int do_release(struct inode * inode, struct file * filp)
as1
=
as1
->
next
)
as1
=
as1
->
next
)
;
;
if
(
as1
==
NULL
)
if
(
as1
==
NULL
)
printk
(
KERN_ERR
"apm: filp not in user list"
);
printk
(
KERN_ERR
"apm: filp not in user list
\n
"
);
else
else
as1
->
next
=
as
->
next
;
as1
->
next
=
as
->
next
;
}
}
...
@@ -1268,7 +1266,7 @@ static int do_open(struct inode * inode, struct file * filp)
...
@@ -1268,7 +1266,7 @@ static int do_open(struct inode * inode, struct file * filp)
as
=
(
struct
apm_user
*
)
kmalloc
(
sizeof
(
*
as
),
GFP_KERNEL
);
as
=
(
struct
apm_user
*
)
kmalloc
(
sizeof
(
*
as
),
GFP_KERNEL
);
if
(
as
==
NULL
)
{
if
(
as
==
NULL
)
{
printk
(
KERN_ERR
"apm: cannot allocate struct of size %d bytes"
,
printk
(
KERN_ERR
"apm: cannot allocate struct of size %d bytes
\n
"
,
sizeof
(
*
as
));
sizeof
(
*
as
));
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
return
-
ENOMEM
;
return
-
ENOMEM
;
...
...
drivers/net/setup.c
View file @
9521288f
...
@@ -12,7 +12,6 @@ extern int mkiss_init_ctrl_dev(void);
...
@@ -12,7 +12,6 @@ extern int mkiss_init_ctrl_dev(void);
extern
int
slip_init_ctrl_dev
(
void
);
extern
int
slip_init_ctrl_dev
(
void
);
extern
int
strip_init_ctrl_dev
(
void
);
extern
int
strip_init_ctrl_dev
(
void
);
extern
int
x25_asy_init_ctrl_dev
(
void
);
extern
int
x25_asy_init_ctrl_dev
(
void
);
extern
int
slhc_install
(
void
);
extern
int
dmascc_init
(
void
);
extern
int
dmascc_init
(
void
);
extern
int
yam_init
(
void
);
extern
int
yam_init
(
void
);
...
@@ -78,22 +77,12 @@ struct net_probe pci_probes[] __initdata = {
...
@@ -78,22 +77,12 @@ struct net_probe pci_probes[] __initdata = {
#endif
#endif
#if defined(CONFIG_COMX)
#if defined(CONFIG_COMX)
{
comx_init
,
0
},
{
comx_init
,
0
},
#endif
/*
#endif
* SLHC if present needs attaching so other people see it
* even if not opened.
*/
#if defined(CONFIG_LANMEDIA)
#if defined(CONFIG_LANMEDIA)
{
lmc_setup
,
0
},
{
lmc_setup
,
0
},
#endif
#endif
#ifdef CONFIG_INET
#if (defined(CONFIG_SLIP) && defined(CONFIG_SLIP_COMPRESSED)) \
|| defined(CONFIG_PPP) \
|| (defined(CONFIG_ISDN) && defined(CONFIG_ISDN_PPP))
{
slhc_install
,
0
},
#endif
#endif
/*
/*
*
*
* Wireless non-HAM
* Wireless non-HAM
...
...
drivers/net/slhc.c
View file @
9521288f
...
@@ -77,7 +77,6 @@
...
@@ -77,7 +77,6 @@
#include <linux/timer.h>
#include <linux/timer.h>
#include <asm/system.h>
#include <asm/system.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <linux/init.h>
#include <net/checksum.h>
#include <net/checksum.h>
#include <net/slhc_vj.h>
#include <net/slhc_vj.h>
#include <asm/unaligned.h>
#include <asm/unaligned.h>
...
@@ -751,12 +750,6 @@ void cleanup_module(void)
...
@@ -751,12 +750,6 @@ void cleanup_module(void)
return
;
return
;
}
}
#else
/* MODULE */
int
__init
slhc_install
(
void
)
{
return
0
;
}
#endif
/* MODULE */
#endif
/* MODULE */
#else
/* CONFIG_INET */
#else
/* CONFIG_INET */
...
...
drivers/parport/ChangeLog
View file @
9521288f
2000-05-16 Tim Waugh <twaugh@redhat.com>
* share.c (parport_claim): Fix SMP race.
2000-05-15 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
2000-05-15 Gunther Mayer <gunther.mayer@braunschweig.okersurf.de>
* parport_pc.c (parport_pc_compat_write_block_pio): Check for
* parport_pc.c (parport_pc_compat_write_block_pio): Check for
...
...
drivers/usb/pegasus.c
View file @
9521288f
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
#include <linux/usb.h>
#include <linux/usb.h>
static
const
char
*
version
=
__FILE__
": v0.3.
9 2000/04/11 Written by
Petko Manolov (petkan@spct.net)
\n
"
;
static
const
char
*
version
=
__FILE__
": v0.3.
12 2000/05/22 (C) 1999-2000
Petko Manolov (petkan@spct.net)
\n
"
;
#define PEGASUS_MTU 1500
#define PEGASUS_MTU 1500
...
@@ -24,12 +24,15 @@ static const char *version = __FILE__ ": v0.3.9 2000/04/11 Written by Petko Mano
...
@@ -24,12 +24,15 @@ static const char *version = __FILE__ ": v0.3.9 2000/04/11 Written by Petko Mano
#define SROM_WRITE 0x01
#define SROM_WRITE 0x01
#define SROM_READ 0x02
#define SROM_READ 0x02
#define PEGASUS_TX_TIMEOUT (HZ*5)
#define PEGASUS_TX_TIMEOUT (HZ*5)
#define PEGASUS_RESET 1
#define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
#define ALIGN(x) x __attribute__((aligned(L1_CACHE_BYTES)))
struct
pegasus
{
struct
pegasus
{
struct
usb_device
*
usb
;
struct
usb_device
*
usb
;
struct
net_device
*
net
;
struct
net_device
*
net
;
struct
net_device_stats
stats
;
struct
net_device_stats
stats
;
int
flags
;
spinlock_t
pegasus_lock
;
spinlock_t
pegasus_lock
;
struct
urb
rx_urb
,
tx_urb
,
intr_urb
;
struct
urb
rx_urb
,
tx_urb
,
intr_urb
;
unsigned
char
ALIGN
(
rx_buff
[
PEGASUS_MAX_MTU
]);
unsigned
char
ALIGN
(
rx_buff
[
PEGASUS_MAX_MTU
]);
...
@@ -44,9 +47,11 @@ struct usb_eth_dev {
...
@@ -44,9 +47,11 @@ struct usb_eth_dev {
void
*
private
;
void
*
private
;
};
};
static
int
loopback
=
0
;
static
int
loopback
=
0
;
static
int
multicast_filter_limit
=
32
;
static
int
multicast_filter_limit
=
32
;
MODULE_AUTHOR
(
"Petko Manolov <petkan@spct.net>"
);
MODULE_AUTHOR
(
"Petko Manolov <petkan@spct.net>"
);
MODULE_DESCRIPTION
(
"ADMtek AN986 Pegasus USB Ethernet driver"
);
MODULE_DESCRIPTION
(
"ADMtek AN986 Pegasus USB Ethernet driver"
);
MODULE_PARM
(
loopback
,
"i"
);
MODULE_PARM
(
loopback
,
"i"
);
...
@@ -98,6 +103,7 @@ static int pegasus_read_phy_word(struct usb_device *dev, __u8 index, __u16 *regd
...
@@ -98,6 +103,7 @@ static int pegasus_read_phy_word(struct usb_device *dev, __u8 index, __u16 *regd
return
1
;
return
1
;
}
}
static
int
pegasus_write_phy_word
(
struct
usb_device
*
dev
,
__u8
index
,
__u16
regdata
)
static
int
pegasus_write_phy_word
(
struct
usb_device
*
dev
,
__u8
index
,
__u16
regdata
)
{
{
int
i
;
int
i
;
...
@@ -115,6 +121,7 @@ static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regd
...
@@ -115,6 +121,7 @@ static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regd
return
1
;
return
1
;
}
}
static
int
pegasus_rw_srom_word
(
struct
usb_device
*
dev
,
__u8
index
,
__u16
*
retdata
,
__u8
direction
)
static
int
pegasus_rw_srom_word
(
struct
usb_device
*
dev
,
__u8
index
,
__u16
*
retdata
,
__u8
direction
)
{
{
int
i
;
int
i
;
...
@@ -134,6 +141,7 @@ static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retda
...
@@ -134,6 +141,7 @@ static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retda
return
1
;
return
1
;
}
}
static
int
pegasus_get_node_id
(
struct
usb_device
*
dev
,
__u8
*
id
)
static
int
pegasus_get_node_id
(
struct
usb_device
*
dev
,
__u8
*
id
)
{
{
int
i
;
int
i
;
...
@@ -143,6 +151,7 @@ static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
...
@@ -143,6 +151,7 @@ static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
return
0
;
return
0
;
}
}
static
int
pegasus_reset_mac
(
struct
usb_device
*
dev
)
static
int
pegasus_reset_mac
(
struct
usb_device
*
dev
)
{
{
__u8
data
=
0x8
;
__u8
data
=
0x8
;
...
@@ -165,6 +174,7 @@ static int pegasus_reset_mac(struct usb_device *dev)
...
@@ -165,6 +174,7 @@ static int pegasus_reset_mac(struct usb_device *dev)
return
1
;
return
1
;
}
}
static
int
pegasus_start_net
(
struct
net_device
*
dev
,
struct
usb_device
*
usb
)
static
int
pegasus_start_net
(
struct
net_device
*
dev
,
struct
usb_device
*
usb
)
{
{
__u16
partmedia
,
temp
;
__u16
partmedia
,
temp
;
...
@@ -195,13 +205,14 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
...
@@ -195,13 +205,14 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
data
[
0
]
=
0xc9
;
data
[
0
]
=
0xc9
;
data
[
1
]
=
(
partmedia
&
0x100
)
?
0x30
:
((
partmedia
&
0x80
)
?
0x10
:
0
);
data
[
1
]
=
(
partmedia
&
0x100
)
?
0x30
:
((
partmedia
&
0x80
)
?
0x10
:
0
);
data
[
2
]
=
(
loopback
&
1
)
?
0x0
8
:
0x00
;
data
[
2
]
=
(
loopback
&
1
)
?
0x0
9
:
0x01
;
pegasus_set_registers
(
usb
,
0
,
3
,
data
);
pegasus_set_registers
(
usb
,
0
,
3
,
data
);
return
0
;
return
0
;
}
}
static
void
pegasus_read_bulk
(
struct
urb
*
urb
)
static
void
pegasus_read_bulk
(
struct
urb
*
urb
)
{
{
struct
pegasus
*
pegasus
=
urb
->
context
;
struct
pegasus
*
pegasus
=
urb
->
context
;
...
@@ -253,15 +264,16 @@ static void pegasus_read_bulk(struct urb *urb)
...
@@ -253,15 +264,16 @@ static void pegasus_read_bulk(struct urb *urb)
warn
(
"(prb)failed rx_urb %d"
,
res
);
warn
(
"(prb)failed rx_urb %d"
,
res
);
}
}
static
void
pegasus_irq
(
urb_t
*
urb
)
static
void
pegasus_irq
(
urb_t
*
urb
)
{
{
if
(
urb
->
status
)
{
__u8
*
d
=
urb
->
transfer_buffer
;
__u8
*
d
=
urb
->
transfer_buffer
;
printk
(
"txst0 %x, txst1 %x, rxst %x, rxlst0 %x, rxlst1 %x, wakest %x"
,
if
(
d
[
0
]
)
d
[
0
],
d
[
1
],
d
[
2
],
d
[
3
],
d
[
4
],
d
[
5
]);
dbg
(
"txst0=0x%2x"
,
d
[
0
]);
}
}
}
static
void
pegasus_write_bulk
(
struct
urb
*
urb
)
static
void
pegasus_write_bulk
(
struct
urb
*
urb
)
{
{
struct
pegasus
*
pegasus
=
urb
->
context
;
struct
pegasus
*
pegasus
=
urb
->
context
;
...
@@ -280,12 +292,15 @@ static void pegasus_tx_timeout(struct net_device *net)
...
@@ -280,12 +292,15 @@ static void pegasus_tx_timeout(struct net_device *net)
struct
pegasus
*
pegasus
=
net
->
priv
;
struct
pegasus
*
pegasus
=
net
->
priv
;
warn
(
"%s: Tx timed out. Reseting..."
,
net
->
name
);
warn
(
"%s: Tx timed out. Reseting..."
,
net
->
name
);
usb_unlink_urb
(
&
pegasus
->
tx_urb
);
pegasus
->
stats
.
tx_errors
++
;
pegasus
->
stats
.
tx_errors
++
;
net
->
trans_start
=
jiffies
;
net
->
trans_start
=
jiffies
;
pegasus
->
flags
|=
PEGASUS_RESET
;
netif_wake_queue
(
net
);
netif_wake_queue
(
net
);
}
}
static
int
pegasus_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
net
)
static
int
pegasus_start_xmit
(
struct
sk_buff
*
skb
,
struct
net_device
*
net
)
{
{
struct
pegasus
*
pegasus
=
net
->
priv
;
struct
pegasus
*
pegasus
=
net
->
priv
;
...
@@ -317,11 +332,13 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
...
@@ -317,11 +332,13 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
return
0
;
return
0
;
}
}
static
struct
net_device_stats
*
pegasus_netdev_stats
(
struct
net_device
*
dev
)
static
struct
net_device_stats
*
pegasus_netdev_stats
(
struct
net_device
*
dev
)
{
{
return
&
((
struct
pegasus
*
)
dev
->
priv
)
->
stats
;
return
&
((
struct
pegasus
*
)
dev
->
priv
)
->
stats
;
}
}
static
int
pegasus_open
(
struct
net_device
*
net
)
static
int
pegasus_open
(
struct
net_device
*
net
)
{
{
struct
pegasus
*
pegasus
=
(
struct
pegasus
*
)
net
->
priv
;
struct
pegasus
*
pegasus
=
(
struct
pegasus
*
)
net
->
priv
;
...
@@ -334,8 +351,10 @@ static int pegasus_open(struct net_device *net)
...
@@ -334,8 +351,10 @@ static int pegasus_open(struct net_device *net)
if
((
res
=
usb_submit_urb
(
&
pegasus
->
rx_urb
)))
if
((
res
=
usb_submit_urb
(
&
pegasus
->
rx_urb
)))
warn
(
"(open)failed rx_urb %d"
,
res
);
warn
(
"(open)failed rx_urb %d"
,
res
);
/* usb_submit_urb(&pegasus->intr_urb);*/
if
((
res
=
usb_submit_urb
(
&
pegasus
->
intr_urb
)))
warn
(
"(open)failed intr_urb %d"
,
res
);
netif_start_queue
(
net
);
netif_start_queue
(
net
);
MOD_INC_USE_COUNT
;
MOD_INC_USE_COUNT
;
...
@@ -343,6 +362,7 @@ static int pegasus_open(struct net_device *net)
...
@@ -343,6 +362,7 @@ static int pegasus_open(struct net_device *net)
return
0
;
return
0
;
}
}
static
int
pegasus_close
(
struct
net_device
*
net
)
static
int
pegasus_close
(
struct
net_device
*
net
)
{
{
struct
pegasus
*
pegasus
=
net
->
priv
;
struct
pegasus
*
pegasus
=
net
->
priv
;
...
@@ -351,13 +371,14 @@ static int pegasus_close(struct net_device *net)
...
@@ -351,13 +371,14 @@ static int pegasus_close(struct net_device *net)
usb_unlink_urb
(
&
pegasus
->
rx_urb
);
usb_unlink_urb
(
&
pegasus
->
rx_urb
);
usb_unlink_urb
(
&
pegasus
->
tx_urb
);
usb_unlink_urb
(
&
pegasus
->
tx_urb
);
/* usb_unlink_urb(&pegasus->intr_urb); */
usb_unlink_urb
(
&
pegasus
->
intr_urb
);
MOD_DEC_USE_COUNT
;
MOD_DEC_USE_COUNT
;
return
0
;
return
0
;
}
}
static
int
pegasus_ioctl
(
struct
net_device
*
net
,
struct
ifreq
*
rq
,
int
cmd
)
static
int
pegasus_ioctl
(
struct
net_device
*
net
,
struct
ifreq
*
rq
,
int
cmd
)
{
{
__u16
*
data
=
(
__u16
*
)
&
rq
->
ifr_data
;
__u16
*
data
=
(
__u16
*
)
&
rq
->
ifr_data
;
...
@@ -379,6 +400,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
...
@@ -379,6 +400,7 @@ static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
}
}
}
}
static
void
pegasus_set_rx_mode
(
struct
net_device
*
net
)
static
void
pegasus_set_rx_mode
(
struct
net_device
*
net
)
{
{
struct
pegasus
*
pegasus
=
net
->
priv
;
struct
pegasus
*
pegasus
=
net
->
priv
;
...
@@ -400,6 +422,7 @@ static void pegasus_set_rx_mode(struct net_device *net)
...
@@ -400,6 +422,7 @@ static void pegasus_set_rx_mode(struct net_device *net)
netif_wake_queue
(
net
);
netif_wake_queue
(
net
);
}
}
static
int
check_device_ids
(
__u16
vendor
,
__u16
product
)
static
int
check_device_ids
(
__u16
vendor
,
__u16
product
)
{
{
int
i
=
0
;
int
i
=
0
;
...
@@ -413,6 +436,7 @@ static int check_device_ids( __u16 vendor, __u16 product )
...
@@ -413,6 +436,7 @@ static int check_device_ids( __u16 vendor, __u16 product )
return
-
1
;
return
-
1
;
}
}
static
void
*
pegasus_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
)
static
void
*
pegasus_probe
(
struct
usb_device
*
dev
,
unsigned
int
ifnum
)
{
{
struct
net_device
*
net
;
struct
net_device
*
net
;
...
@@ -463,7 +487,7 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
...
@@ -463,7 +487,7 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
pegasus
->
tx_buff
,
PEGASUS_MAX_MTU
,
pegasus_write_bulk
,
pegasus
->
tx_buff
,
PEGASUS_MAX_MTU
,
pegasus_write_bulk
,
pegasus
);
pegasus
);
FILL_INT_URB
(
&
pegasus
->
intr_urb
,
dev
,
usb_rcvintpipe
(
dev
,
3
),
FILL_INT_URB
(
&
pegasus
->
intr_urb
,
dev
,
usb_rcvintpipe
(
dev
,
3
),
pegasus
->
intr_buff
,
8
,
pegasus_irq
,
pegasus
,
25
0
);
pegasus
->
intr_buff
,
8
,
pegasus_irq
,
pegasus
,
50
0
);
printk
(
KERN_INFO
"%s: %s
\n
"
,
net
->
name
,
usb_dev_id
[
dev_indx
].
name
);
printk
(
KERN_INFO
"%s: %s
\n
"
,
net
->
name
,
usb_dev_id
[
dev_indx
].
name
);
...
@@ -471,6 +495,7 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
...
@@ -471,6 +495,7 @@ static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
return
pegasus
;
return
pegasus
;
}
}
static
void
pegasus_disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
)
static
void
pegasus_disconnect
(
struct
usb_device
*
dev
,
void
*
ptr
)
{
{
struct
pegasus
*
pegasus
=
ptr
;
struct
pegasus
*
pegasus
=
ptr
;
...
@@ -487,11 +512,12 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr)
...
@@ -487,11 +512,12 @@ static void pegasus_disconnect(struct usb_device *dev, void *ptr)
usb_unlink_urb
(
&
pegasus
->
rx_urb
);
usb_unlink_urb
(
&
pegasus
->
rx_urb
);
usb_unlink_urb
(
&
pegasus
->
tx_urb
);
usb_unlink_urb
(
&
pegasus
->
tx_urb
);
/* usb_unlink_urb(&pegasus->intr_urb);*/
usb_unlink_urb
(
&
pegasus
->
intr_urb
);
kfree
(
pegasus
);
kfree
(
pegasus
);
}
}
static
struct
usb_driver
pegasus_driver
=
{
static
struct
usb_driver
pegasus_driver
=
{
name:
"pegasus"
,
name:
"pegasus"
,
probe:
pegasus_probe
,
probe:
pegasus_probe
,
...
...
drivers/usb/serial/Makefile
View file @
9521288f
...
@@ -4,8 +4,26 @@
...
@@ -4,8 +4,26 @@
O_TARGET
:=
usb-serial.o
O_TARGET
:=
usb-serial.o
M_OBJS
:=
usb-serial.o
M_OBJS
:=
usb-serial.o
O_OBJS
:=
usbserial.o
visor.o whiteheat.o ftdi_sio.o keyspan_pda.o omninet.o digi_acceleport.o
O_OBJS
:=
usbserial.o
MOD_LIST_NAME
:=
USB_SERIAL_MODULES
MOD_LIST_NAME
:=
USB_SERIAL_MODULES
ifeq
($(CONFIG_USB_SERIAL_VISOR),y)
O_OBJS
+=
visor.o
endif
ifeq
($(CONFIG_USB_SERIAL_WHITEHEAT),y)
O_OBJS
+=
whiteheat.o
endif
ifeq
($(CONFIG_USB_SERIAL_FTDI_SIO),y)
O_OBJS
+=
ftdi_sio.o
endif
ifeq
($(CONFIG_USB_SERIAL_KEYSPAN_PDA),y)
O_OBJS
+=
keyspan_pda.o
endif
ifeq
($(CONFIG_USB_SERIAL_OMNINET),y)
O_OBJS
+=
omninet.o
endif
ifeq
($(CONFIG_USB_SERIAL_DIGI_ACCELEPORT),y)
O_OBJS
+=
digi_acceleport.o
endif
include
$(TOPDIR)/Rules.make
include
$(TOPDIR)/Rules.make
drivers/usb/serial/digi_acceleport.c
View file @
9521288f
...
@@ -47,9 +47,6 @@
...
@@ -47,9 +47,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_DIGI_ACCELEPORT
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -1276,4 +1273,3 @@ dbg( "digi_read_oob: opcode=%d, line=%d, status=%d, ret=%d", oob_opcode, oob_lin
...
@@ -1276,4 +1273,3 @@ dbg( "digi_read_oob: opcode=%d, line=%d, status=%d, ret=%d", oob_opcode, oob_lin
}
}
#endif
/* CONFIG_USB_SERIAL_DIGI_ACCELEPORT */
drivers/usb/serial/ftdi_sio.c
View file @
9521288f
...
@@ -32,9 +32,6 @@
...
@@ -32,9 +32,6 @@
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_FTDI_SIO
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -723,6 +720,3 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
...
@@ -723,6 +720,3 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
return
0
;
return
0
;
}
/* ftdi_sio_ioctl */
}
/* ftdi_sio_ioctl */
#endif
/* CONFIG_USB_SERIAL_FTDI_SIO */
drivers/usb/serial/keyspan_pda.c
View file @
9521288f
...
@@ -18,9 +18,6 @@
...
@@ -18,9 +18,6 @@
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -700,4 +697,3 @@ struct usb_serial_device_type keyspan_pda_device = {
...
@@ -700,4 +697,3 @@ struct usb_serial_device_type keyspan_pda_device = {
shutdown:
keyspan_pda_shutdown
,
shutdown:
keyspan_pda_shutdown
,
};
};
#endif
/* CONFIG_USB_SERIAL_KEYSPAN_PDA */
drivers/usb/serial/omninet.c
View file @
9521288f
...
@@ -13,9 +13,6 @@
...
@@ -13,9 +13,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_OMNINET
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -336,6 +333,3 @@ static void omninet_write_bulk_callback (struct urb *urb)
...
@@ -336,6 +333,3 @@ static void omninet_write_bulk_callback (struct urb *urb)
return
;
return
;
}
}
#endif
/* CONFIG_USB_SERIAL_OMNINET */
drivers/usb/serial/usbserial.c
View file @
9521288f
...
@@ -14,6 +14,10 @@
...
@@ -14,6 +14,10 @@
*
*
* See Documentation/usb/usb-serial.txt for more information on using this driver
* See Documentation/usb/usb-serial.txt for more information on using this driver
*
*
* (05/22/2000) gkh
* Changed the makefile, enabling the big CONFIG_USB_SERIAL_SOMTHING to be
* removed from the individual device source files.
*
* (05/03/2000) gkh
* (05/03/2000) gkh
* Added the Digi Acceleport driver from Al Borchers and Peter Berger.
* Added the Digi Acceleport driver from Al Borchers and Peter Berger.
*
*
...
...
drivers/usb/serial/visor.c
View file @
9521288f
...
@@ -20,9 +20,6 @@
...
@@ -20,9 +20,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_VISOR
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -207,7 +204,3 @@ static int visor_startup (struct usb_serial *serial)
...
@@ -207,7 +204,3 @@ static int visor_startup (struct usb_serial *serial)
return
(
0
);
return
(
0
);
}
}
#endif
/* CONFIG_USB_SERIAL_VISOR*/
drivers/usb/serial/whiteheat.c
View file @
9521288f
...
@@ -21,9 +21,6 @@
...
@@ -21,9 +21,6 @@
*/
*/
#include <linux/config.h>
#include <linux/config.h>
#ifdef CONFIG_USB_SERIAL_WHITEHEAT
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <linux/signal.h>
...
@@ -407,6 +404,3 @@ static void whiteheat_shutdown (struct usb_serial *serial)
...
@@ -407,6 +404,3 @@ static void whiteheat_shutdown (struct usb_serial *serial)
return
;
return
;
}
}
#endif
/* CONFIG_USB_SERIAL_WHITEHEAT */
drivers/usb/usb-ohci.c
View file @
9521288f
...
@@ -92,7 +92,6 @@ static void urb_rm_priv (urb_t * urb)
...
@@ -92,7 +92,6 @@ static void urb_rm_priv (urb_t * urb)
kfree
(
urb
->
hcpriv
);
kfree
(
urb
->
hcpriv
);
urb
->
hcpriv
=
NULL
;
urb
->
hcpriv
=
NULL
;
wake_up
(
&
op_wakeup
);
}
}
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
...
@@ -493,6 +492,8 @@ static int sohci_submit_urb (urb_t * urb)
...
@@ -493,6 +492,8 @@ static int sohci_submit_urb (urb_t * urb)
urb
->
start_frame
=
((
ed
->
state
==
ED_OPER
)
?
(
ed
->
last_iso
+
1
)
:
urb
->
start_frame
=
((
ed
->
state
==
ED_OPER
)
?
(
ed
->
last_iso
+
1
)
:
(
le16_to_cpu
(
ohci
->
hcca
.
frame_no
)
+
10
))
&
0xffff
;
(
le16_to_cpu
(
ohci
->
hcca
.
frame_no
)
+
10
))
&
0xffff
;
}
}
urb
->
status
=
USB_ST_URB_PENDING
;
urb
->
actual_length
=
0
;
if
(
ed
->
state
!=
ED_OPER
)
/* link the ed into a chain if is not already */
if
(
ed
->
state
!=
ED_OPER
)
/* link the ed into a chain if is not already */
ep_link
(
ohci
,
ed
);
ep_link
(
ohci
,
ed
);
...
@@ -527,6 +528,8 @@ static int sohci_unlink_urb (urb_t * urb)
...
@@ -527,6 +528,8 @@ static int sohci_unlink_urb (urb_t * urb)
urb_print
(
urb
,
"UNLINK"
,
1
);
urb_print
(
urb
,
"UNLINK"
,
1
);
#endif
#endif
usb_dec_dev_use
(
urb
->
dev
);
if
(
usb_pipedevice
(
urb
->
pipe
)
==
ohci
->
rh
.
devnum
)
if
(
usb_pipedevice
(
urb
->
pipe
)
==
ohci
->
rh
.
devnum
)
return
rh_unlink_urb
(
urb
);
/* a request to the virtual root hub */
return
rh_unlink_urb
(
urb
);
/* a request to the virtual root hub */
...
@@ -544,19 +547,23 @@ static int sohci_unlink_urb (urb_t * urb)
...
@@ -544,19 +547,23 @@ static int sohci_unlink_urb (urb_t * urb)
ep_rm_ed
(
urb
->
dev
,
urb_priv
->
ed
);
ep_rm_ed
(
urb
->
dev
,
urb_priv
->
ed
);
urb_priv
->
ed
->
state
|=
ED_URB_DEL
;
urb_priv
->
ed
->
state
|=
ED_URB_DEL
;
spin_unlock_irqrestore
(
&
usb_ed_lock
,
flags
);
spin_unlock_irqrestore
(
&
usb_ed_lock
,
flags
);
if
(
!
(
urb
->
transfer_flags
&
USB_ASYNC_UNLINK
))
{
add_wait_queue
(
&
op_wakeup
,
&
wait
);
add_wait_queue
(
&
op_wakeup
,
&
wait
);
current
->
state
=
TASK_UNINTERRUPTIBLE
;
current
->
state
=
TASK_UNINTERRUPTIBLE
;
if
(
!
schedule_timeout
(
HZ
/
10
))
/* wait until all TDs are deleted */
if
(
!
schedule_timeout
(
HZ
/
10
))
/* wait until all TDs are deleted */
err
(
"unlink URB timeout!"
);
err
(
"unlink URB timeout!"
);
remove_wait_queue
(
&
op_wakeup
,
&
wait
);
remove_wait_queue
(
&
op_wakeup
,
&
wait
);
}
else
urb
->
status
=
-
ENOENT
;
}
else
urb
->
status
=
-
EINPROGRESS
;
}
else
{
urb_rm_priv
(
urb
);
urb_rm_priv
(
urb
);
if
(
urb
->
complete
&&
(
urb
->
transfer_flags
&
USB_ASYNC_UNLINK
))
{
urb
->
status
=
-
ENOENT
;
// mark urb as killed
urb
->
complete
(
urb
);
if
(
urb
->
complete
)
urb
->
status
=
0
;
urb
->
complete
((
struct
urb
*
)
urb
);
}
else
usb_dec_dev_use
(
urb
->
dev
);
urb
->
status
=
-
ENOENT
;
}
}
}
return
0
;
return
0
;
}
}
...
@@ -965,7 +972,7 @@ static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
...
@@ -965,7 +972,7 @@ static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
/* prepare a TD */
/* prepare a TD */
static
void
td_fill
(
unsigned
int
info
,
void
*
data
,
int
len
,
urb_t
*
urb
,
int
type
,
int
index
)
static
void
td_fill
(
unsigned
int
info
,
void
*
data
,
int
len
,
urb_t
*
urb
,
int
index
)
{
{
volatile
td_t
*
td
,
*
td_pt
;
volatile
td_t
*
td
,
*
td_pt
;
urb_priv_t
*
urb_priv
=
urb
->
hcpriv
;
urb_priv_t
*
urb_priv
=
urb
->
hcpriv
;
...
@@ -982,7 +989,6 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int t
...
@@ -982,7 +989,6 @@ static void td_fill (unsigned int info, void * data, int len, urb_t * urb, int t
td
->
index
=
index
;
td
->
index
=
index
;
td
->
urb
=
urb
;
td
->
urb
=
urb
;
td
->
hwINFO
=
cpu_to_le32
(
info
);
td
->
hwINFO
=
cpu_to_le32
(
info
);
td
->
type
=
type
;
if
((
td
->
ed
->
type
&
3
)
==
PIPE_ISOCHRONOUS
)
{
if
((
td
->
ed
->
type
&
3
)
==
PIPE_ISOCHRONOUS
)
{
td
->
hwCBP
=
cpu_to_le32
(((
!
data
||
!
len
)
?
td
->
hwCBP
=
cpu_to_le32
(((
!
data
||
!
len
)
?
0
:
virt_to_bus
(
data
))
&
0xFFFFF000
);
0
:
virt_to_bus
(
data
))
&
0xFFFFF000
);
...
@@ -1029,12 +1035,12 @@ static void td_submit_urb (urb_t * urb)
...
@@ -1029,12 +1035,12 @@ static void td_submit_urb (urb_t * urb)
info
=
usb_pipeout
(
urb
->
pipe
)
?
info
=
usb_pipeout
(
urb
->
pipe
)
?
TD_CC
|
TD_DP_OUT
:
TD_CC
|
TD_DP_IN
;
TD_CC
|
TD_DP_OUT
:
TD_CC
|
TD_DP_IN
;
while
(
data_len
>
4096
)
{
while
(
data_len
>
4096
)
{
td_fill
(
info
|
(
cnt
?
TD_T_TOGGLE
:
toggle
),
data
,
4096
,
urb
,
(
cnt
?
0
:
ST_ADDR
)
|
ADD_LEN
,
cnt
);
td_fill
(
info
|
(
cnt
?
TD_T_TOGGLE
:
toggle
),
data
,
4096
,
urb
,
cnt
);
data
+=
4096
;
data_len
-=
4096
;
cnt
++
;
data
+=
4096
;
data_len
-=
4096
;
cnt
++
;
}
}
info
=
usb_pipeout
(
urb
->
pipe
)
?
info
=
usb_pipeout
(
urb
->
pipe
)
?
TD_CC
|
TD_DP_OUT
:
TD_CC
|
TD_R
|
TD_DP_IN
;
TD_CC
|
TD_DP_OUT
:
TD_CC
|
TD_R
|
TD_DP_IN
;
td_fill
(
info
|
(
cnt
?
TD_T_TOGGLE
:
toggle
),
data
,
data_len
,
urb
,
(
cnt
?
0
:
ST_ADDR
)
|
ADD_LEN
,
cnt
);
td_fill
(
info
|
(
cnt
?
TD_T_TOGGLE
:
toggle
),
data
,
data_len
,
urb
,
cnt
);
cnt
++
;
cnt
++
;
writel
(
OHCI_BLF
,
&
ohci
->
regs
->
cmdstatus
);
/* start bulk list */
writel
(
OHCI_BLF
,
&
ohci
->
regs
->
cmdstatus
);
/* start bulk list */
break
;
break
;
...
@@ -1042,20 +1048,20 @@ static void td_submit_urb (urb_t * urb)
...
@@ -1042,20 +1048,20 @@ static void td_submit_urb (urb_t * urb)
case
PIPE_INTERRUPT
:
case
PIPE_INTERRUPT
:
info
=
usb_pipeout
(
urb
->
pipe
)
?
info
=
usb_pipeout
(
urb
->
pipe
)
?
TD_CC
|
TD_DP_OUT
|
toggle
:
TD_CC
|
TD_R
|
TD_DP_IN
|
toggle
;
TD_CC
|
TD_DP_OUT
|
toggle
:
TD_CC
|
TD_R
|
TD_DP_IN
|
toggle
;
td_fill
(
info
,
data
,
data_len
,
urb
,
ST_ADDR
|
ADD_LEN
,
cnt
++
);
td_fill
(
info
,
data
,
data_len
,
urb
,
cnt
++
);
break
;
break
;
case
PIPE_CONTROL
:
case
PIPE_CONTROL
:
info
=
TD_CC
|
TD_DP_SETUP
|
TD_T_DATA0
;
info
=
TD_CC
|
TD_DP_SETUP
|
TD_T_DATA0
;
td_fill
(
info
,
ctrl
,
8
,
urb
,
ST_ADDR
,
cnt
++
);
td_fill
(
info
,
ctrl
,
8
,
urb
,
cnt
++
);
if
(
data_len
>
0
)
{
if
(
data_len
>
0
)
{
info
=
usb_pipeout
(
urb
->
pipe
)
?
info
=
usb_pipeout
(
urb
->
pipe
)
?
TD_CC
|
TD_R
|
TD_DP_OUT
|
TD_T_DATA1
:
TD_CC
|
TD_R
|
TD_DP_IN
|
TD_T_DATA1
;
TD_CC
|
TD_R
|
TD_DP_OUT
|
TD_T_DATA1
:
TD_CC
|
TD_R
|
TD_DP_IN
|
TD_T_DATA1
;
td_fill
(
info
,
data
,
data_len
,
urb
,
ADD_LEN
,
cnt
++
);
td_fill
(
info
,
data
,
data_len
,
urb
,
cnt
++
);
}
}
info
=
usb_pipeout
(
urb
->
pipe
)
?
info
=
usb_pipeout
(
urb
->
pipe
)
?
TD_CC
|
TD_DP_IN
|
TD_T_DATA1
:
TD_CC
|
TD_DP_OUT
|
TD_T_DATA1
;
TD_CC
|
TD_DP_IN
|
TD_T_DATA1
:
TD_CC
|
TD_DP_OUT
|
TD_T_DATA1
;
td_fill
(
info
,
NULL
,
0
,
urb
,
0
,
cnt
++
);
td_fill
(
info
,
NULL
,
0
,
urb
,
cnt
++
);
writel
(
OHCI_CLF
,
&
ohci
->
regs
->
cmdstatus
);
/* start Control list */
writel
(
OHCI_CLF
,
&
ohci
->
regs
->
cmdstatus
);
/* start Control list */
break
;
break
;
...
@@ -1063,7 +1069,7 @@ static void td_submit_urb (urb_t * urb)
...
@@ -1063,7 +1069,7 @@ static void td_submit_urb (urb_t * urb)
for
(
cnt
=
0
;
cnt
<
urb
->
number_of_packets
;
cnt
++
)
{
for
(
cnt
=
0
;
cnt
<
urb
->
number_of_packets
;
cnt
++
)
{
td_fill
(
TD_CC
|
TD_ISO
|
((
urb
->
start_frame
+
cnt
)
&
0xffff
),
td_fill
(
TD_CC
|
TD_ISO
|
((
urb
->
start_frame
+
cnt
)
&
0xffff
),
(
__u8
*
)
data
+
urb
->
iso_frame_desc
[
cnt
].
offset
,
(
__u8
*
)
data
+
urb
->
iso_frame_desc
[
cnt
].
offset
,
urb
->
iso_frame_desc
[
cnt
].
length
,
urb
,
(
cnt
?
0
:
ST_ADDR
)
|
ADD_LEN
,
cnt
);
urb
->
iso_frame_desc
[
cnt
].
length
,
urb
,
cnt
);
}
}
break
;
break
;
}
}
...
@@ -1074,7 +1080,55 @@ static void td_submit_urb (urb_t * urb)
...
@@ -1074,7 +1080,55 @@ static void td_submit_urb (urb_t * urb)
/*-------------------------------------------------------------------------*
/*-------------------------------------------------------------------------*
* Done List handling functions
* Done List handling functions
*-------------------------------------------------------------------------*/
*-------------------------------------------------------------------------*/
/* calculate the transfer length and update the urb */
static
void
dl_transfer_length
(
td_t
*
td
)
{
__u32
tdINFO
,
tdBE
,
tdCBP
;
__u16
tdPSW
;
urb_t
*
urb
=
td
->
urb
;
urb_priv_t
*
urb_priv
=
urb
->
hcpriv
;
int
dlen
=
0
;
int
cc
=
0
;
tdINFO
=
le32_to_cpup
(
&
td
->
hwINFO
);
tdBE
=
le32_to_cpup
(
&
td
->
hwBE
);
tdCBP
=
le32_to_cpup
(
&
td
->
hwCBP
);
if
(
tdINFO
&
TD_ISO
)
{
tdPSW
=
le16_to_cpu
(
td
->
hwPSW
[
0
]);
cc
=
(
tdPSW
>>
12
)
&
0xF
;
if
(
cc
<
0xE
)
{
if
(
usb_pipeout
(
urb
->
pipe
))
{
dlen
=
urb
->
iso_frame_desc
[
td
->
index
].
length
;
}
else
{
dlen
=
tdPSW
&
0x3ff
;
}
urb
->
actual_length
+=
dlen
;
urb
->
iso_frame_desc
[
td
->
index
].
actual_length
=
dlen
;
if
(
!
(
urb
->
transfer_flags
&
USB_DISABLE_SPD
)
&&
(
cc
==
TD_DATAUNDERRUN
))
cc
=
TD_CC_NOERROR
;
urb
->
iso_frame_desc
[
td
->
index
].
status
=
cc_to_error
[
cc
];
}
}
else
{
/* BULK, INT, CONTROL DATA */
if
(
!
(
usb_pipetype
(
urb
->
pipe
)
==
PIPE_CONTROL
&&
((
td
->
index
==
0
)
||
(
td
->
index
==
urb_priv
->
length
-
1
))))
{
if
(
tdBE
!=
0
)
{
if
(
td
->
hwCBP
==
0
)
urb
->
actual_length
=
bus_to_virt
(
tdBE
)
-
urb
->
transfer_buffer
+
1
;
else
urb
->
actual_length
=
bus_to_virt
(
tdCBP
)
-
urb
->
transfer_buffer
;
}
}
}
}
/*-------------------------------------------------------------------------*/
/* replies to the request have to be on a FIFO basis so
/* replies to the request have to be on a FIFO basis so
* we reverse the reversed done-list */
* we reverse the reversed done-list */
...
@@ -1128,6 +1182,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
...
@@ -1128,6 +1182,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
unsigned
long
flags
;
unsigned
long
flags
;
ed_t
*
ed
;
ed_t
*
ed
;
__u32
edINFO
;
__u32
edINFO
;
__u32
tdINFO
;
td_t
*
td
=
NULL
,
*
td_next
=
NULL
,
*
tdHeadP
=
NULL
,
*
tdTailP
;
td_t
*
td
=
NULL
,
*
td_next
=
NULL
,
*
tdHeadP
=
NULL
,
*
tdTailP
;
__u32
*
td_p
;
__u32
*
td_p
;
int
ctrl
=
0
,
bulk
=
0
;
int
ctrl
=
0
,
bulk
=
0
;
...
@@ -1139,16 +1194,25 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
...
@@ -1139,16 +1194,25 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
tdHeadP
=
bus_to_virt
(
le32_to_cpup
(
&
ed
->
hwHeadP
)
&
0xfffffff0
);
tdHeadP
=
bus_to_virt
(
le32_to_cpup
(
&
ed
->
hwHeadP
)
&
0xfffffff0
);
edINFO
=
le32_to_cpup
(
&
ed
->
hwINFO
);
edINFO
=
le32_to_cpup
(
&
ed
->
hwINFO
);
td_p
=
&
ed
->
hwHeadP
;
td_p
=
&
ed
->
hwHeadP
;
for
(
td
=
tdHeadP
;
td
!=
tdTailP
;
td
=
td_next
)
{
for
(
td
=
tdHeadP
;
td
!=
tdTailP
;
td
=
td_next
)
{
urb_t
*
urb
=
td
->
urb
;
urb_t
*
urb
=
td
->
urb
;
urb_priv_t
*
urb_priv
=
td
->
urb
->
hcpriv
;
urb_priv_t
*
urb_priv
=
td
->
urb
->
hcpriv
;
td_next
=
bus_to_virt
(
le32_to_cpup
(
&
td
->
hwNextTD
)
&
0xfffffff0
);
td_next
=
bus_to_virt
(
le32_to_cpup
(
&
td
->
hwNextTD
)
&
0xfffffff0
);
if
((
urb_priv
->
state
==
URB_DEL
)
||
(
ed
->
state
&
ED_DEL
))
{
if
((
urb_priv
->
state
==
URB_DEL
)
||
(
ed
->
state
&
ED_DEL
))
{
tdINFO
=
le32_to_cpup
(
&
td
->
hwINFO
);
if
(
TD_CC_GET
(
tdINFO
)
<
0xE
)
dl_transfer_length
(
td
);
*
td_p
=
td
->
hwNextTD
|
(
*
td_p
&
cpu_to_le32
(
0x3
));
*
td_p
=
td
->
hwNextTD
|
(
*
td_p
&
cpu_to_le32
(
0x3
));
if
(
++
(
urb_priv
->
td_cnt
)
==
urb_priv
->
length
)
if
(
++
(
urb_priv
->
td_cnt
)
==
urb_priv
->
length
)
urb_rm_priv
(
urb
);
urb_rm_priv
(
urb
);
if
(
urb
->
transfer_flags
&
USB_ASYNC_UNLINK
)
{
usb_dec_dev_use
(
urb
->
dev
);
urb
->
status
=
-
ECONNRESET
;
urb
->
complete
(
urb
);
}
else
{
wake_up
(
&
op_wakeup
);
}
}
else
{
}
else
{
td_p
=
&
td
->
hwNextTD
;
td_p
=
&
td
->
hwNextTD
;
}
}
...
@@ -1165,7 +1229,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
...
@@ -1165,7 +1229,7 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
}
}
else
{
else
{
ed
->
state
&=
~
ED_URB_DEL
;
ed
->
state
&=
~
ED_URB_DEL
;
ed
->
hwINFO
&=
~
cpu_to_le32
(
OHCI_ED_SKIP
);
ed
->
hwINFO
&=
~
cpu_to_le32
(
OHCI_ED_SKIP
);
}
}
if
((
ed
->
type
&
3
)
==
CTRL
)
ctrl
|=
1
;
if
((
ed
->
type
&
3
)
==
CTRL
)
ctrl
|=
1
;
...
@@ -1183,6 +1247,8 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
...
@@ -1183,6 +1247,8 @@ static void dl_del_list (ohci_t * ohci, unsigned int frame)
spin_unlock_irqrestore
(
&
usb_ed_lock
,
flags
);
spin_unlock_irqrestore
(
&
usb_ed_lock
,
flags
);
}
}
/*-------------------------------------------------------------------------*/
/*-------------------------------------------------------------------------*/
/* td done list */
/* td done list */
...
@@ -1191,12 +1257,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
...
@@ -1191,12 +1257,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
{
{
td_t
*
td_list_next
=
NULL
;
td_t
*
td_list_next
=
NULL
;
ed_t
*
ed
;
ed_t
*
ed
;
int
dlen
=
0
;
int
cc
=
0
;
int
cc
=
0
;
urb_t
*
urb
;
urb_t
*
urb
;
urb_priv_t
*
urb_priv
;
urb_priv_t
*
urb_priv
;
__u32
tdINFO
,
tdBE
,
tdCBP
,
edHeadP
,
edTailP
;
__u32
tdINFO
,
edHeadP
,
edTailP
;
__u16
tdPSW
;
unsigned
long
flags
;
unsigned
long
flags
;
while
(
td_list
)
{
while
(
td_list
)
{
...
@@ -1205,40 +1270,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
...
@@ -1205,40 +1270,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
urb
=
td_list
->
urb
;
urb
=
td_list
->
urb
;
urb_priv
=
urb
->
hcpriv
;
urb_priv
=
urb
->
hcpriv
;
tdINFO
=
le32_to_cpup
(
&
td_list
->
hwINFO
);
tdINFO
=
le32_to_cpup
(
&
td_list
->
hwINFO
);
tdBE
=
le32_to_cpup
(
&
td_list
->
hwBE
);
tdCBP
=
le32_to_cpup
(
&
td_list
->
hwCBP
);
ed
=
td_list
->
ed
;
ed
=
td_list
->
ed
;
if
(
td_list
->
type
&
ST_ADDR
)
dl_transfer_length
(
td_list
);
urb
->
actual_length
=
0
;
if
(
td_list
->
type
&
ADD_LEN
)
{
/* accumulate length of multi td transfers */
if
(
tdINFO
&
TD_ISO
)
{
tdPSW
=
le16_to_cpu
(
td_list
->
hwPSW
[
0
]);
cc
=
(
tdPSW
>>
12
)
&
0xF
;
if
(
cc
<
0xE
)
{
if
(
usb_pipeout
(
urb
->
pipe
))
{
dlen
=
urb
->
iso_frame_desc
[
td_list
->
index
].
length
;
}
else
{
dlen
=
tdPSW
&
0x3ff
;
}
urb
->
actual_length
+=
dlen
;
urb
->
iso_frame_desc
[
td_list
->
index
].
actual_length
=
dlen
;
if
(
!
(
urb
->
transfer_flags
&
USB_DISABLE_SPD
)
&&
(
cc
==
TD_DATAUNDERRUN
))
cc
=
TD_CC_NOERROR
;
urb
->
iso_frame_desc
[
td_list
->
index
].
status
=
cc_to_error
[
cc
];
}
}
else
{
if
(
tdBE
!=
0
)
{
if
(
td_list
->
hwCBP
==
0
)
urb
->
actual_length
=
bus_to_virt
(
tdBE
)
-
urb
->
transfer_buffer
+
1
;
else
urb
->
actual_length
=
bus_to_virt
(
tdCBP
)
-
urb
->
transfer_buffer
;
}
}
}
/* error code of transfer */
/* error code of transfer */
cc
=
TD_CC_GET
(
tdINFO
);
cc
=
TD_CC_GET
(
tdINFO
);
if
(
cc
==
TD_CC_STALL
)
usb_endpoint_halt
(
urb
->
dev
,
usb_pipeendpoint
(
urb
->
pipe
),
usb_pipeout
(
urb
->
pipe
));
if
(
cc
==
TD_CC_STALL
)
usb_endpoint_halt
(
urb
->
dev
,
usb_pipeendpoint
(
urb
->
pipe
),
usb_pipeout
(
urb
->
pipe
));
...
...
drivers/usb/usb-ohci.h
View file @
9521288f
...
@@ -432,7 +432,7 @@ static int ep_unlink(ohci_t * ohci, ed_t * ed);
...
@@ -432,7 +432,7 @@ static int ep_unlink(ohci_t * ohci, ed_t * ed);
static
ed_t
*
ep_add_ed
(
struct
usb_device
*
usb_dev
,
unsigned
int
pipe
,
int
interval
,
int
load
);
static
ed_t
*
ep_add_ed
(
struct
usb_device
*
usb_dev
,
unsigned
int
pipe
,
int
interval
,
int
load
);
static
void
ep_rm_ed
(
struct
usb_device
*
usb_dev
,
ed_t
*
ed
);
static
void
ep_rm_ed
(
struct
usb_device
*
usb_dev
,
ed_t
*
ed
);
/* td */
/* td */
static
void
td_fill
(
unsigned
int
info
,
void
*
data
,
int
len
,
urb_t
*
urb
,
int
type
,
int
index
);
static
void
td_fill
(
unsigned
int
info
,
void
*
data
,
int
len
,
urb_t
*
urb
,
int
index
);
static
void
td_submit_urb
(
urb_t
*
urb
);
static
void
td_submit_urb
(
urb_t
*
urb
);
/* root hub */
/* root hub */
static
int
rh_submit_urb
(
urb_t
*
urb
);
static
int
rh_submit_urb
(
urb_t
*
urb
);
...
...
fs/cramfs/inode.c
View file @
9521288f
...
@@ -84,15 +84,17 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
...
@@ -84,15 +84,17 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
#define NEXT_BUFFER(_ix) ((_ix) ^ 1)
#define NEXT_BUFFER(_ix) ((_ix) ^ 1)
/*
/*
* BLKS_PER_BUF_SHIFT must be at least 1 to allow for "compressed"
* BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed"
* data that takes up more space than the original. 1 is guaranteed
* data that takes up more space than the original and with unlucky
* to suffice, though. Larger values provide more read-ahead and
* alignment.
* proportionally less wastage at the end of the buffer.
*/
*/
#define BLKS_PER_BUF_SHIFT (2)
#define BLKS_PER_BUF_SHIFT (2)
#define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT)
#define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT)
static
unsigned
char
read_buffers
[
READ_BUFFERS
][
BLKS_PER_BUF
][
PAGE_CACHE_SIZE
];
#define BUFFER_SIZE (BLKS_PER_BUF*PAGE_CACHE_SIZE)
static
unsigned
char
read_buffers
[
READ_BUFFERS
][
BUFFER_SIZE
];
static
unsigned
buffer_blocknr
[
READ_BUFFERS
];
static
unsigned
buffer_blocknr
[
READ_BUFFERS
];
static
struct
super_block
*
buffer_dev
[
READ_BUFFERS
];
static
int
next_buffer
=
0
;
static
int
next_buffer
=
0
;
/*
/*
...
@@ -102,19 +104,27 @@ static int next_buffer = 0;
...
@@ -102,19 +104,27 @@ static int next_buffer = 0;
static
void
*
cramfs_read
(
struct
super_block
*
sb
,
unsigned
int
offset
,
unsigned
int
len
)
static
void
*
cramfs_read
(
struct
super_block
*
sb
,
unsigned
int
offset
,
unsigned
int
len
)
{
{
struct
buffer_head
*
bh_array
[
BLKS_PER_BUF
];
struct
buffer_head
*
bh_array
[
BLKS_PER_BUF
];
unsigned
i
,
blocknr
,
last_blocknr
,
buffer
;
unsigned
i
,
blocknr
,
buffer
;
char
*
data
;
if
(
!
len
)
if
(
!
len
)
return
NULL
;
return
NULL
;
blocknr
=
offset
>>
PAGE_CACHE_SHIFT
;
blocknr
=
offset
>>
PAGE_CACHE_SHIFT
;
last_blocknr
=
(
offset
+
len
-
1
)
>>
PAGE_CACHE_SHIFT
;
if
(
last_blocknr
-
blocknr
>=
BLKS_PER_BUF
)
goto
eek
;
resume
:
offset
&=
PAGE_CACHE_SIZE
-
1
;
offset
&=
PAGE_CACHE_SIZE
-
1
;
/* Check if an existing buffer already has the data.. */
for
(
i
=
0
;
i
<
READ_BUFFERS
;
i
++
)
{
for
(
i
=
0
;
i
<
READ_BUFFERS
;
i
++
)
{
if
((
blocknr
>=
buffer_blocknr
[
i
])
&&
unsigned
int
blk_offset
;
(
last_blocknr
-
buffer_blocknr
[
i
]
<
BLKS_PER_BUF
))
return
&
read_buffers
[
i
][
blocknr
-
buffer_blocknr
[
i
]][
offset
];
if
(
buffer_dev
[
i
]
!=
sb
)
continue
;
if
(
blocknr
<
buffer_blocknr
[
i
])
continue
;
blk_offset
=
(
blocknr
-
buffer_blocknr
[
i
])
<<
PAGE_CACHE_SHIFT
;
blk_offset
+=
offset
;
if
(
blk_offset
+
len
>
BUFFER_SIZE
)
continue
;
return
read_buffers
[
i
]
+
blk_offset
;
}
}
/* Ok, read in BLKS_PER_BUF pages completely first. */
/* Ok, read in BLKS_PER_BUF pages completely first. */
...
@@ -125,24 +135,18 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
...
@@ -125,24 +135,18 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
buffer
=
next_buffer
;
buffer
=
next_buffer
;
next_buffer
=
NEXT_BUFFER
(
buffer
);
next_buffer
=
NEXT_BUFFER
(
buffer
);
buffer_blocknr
[
buffer
]
=
blocknr
;
buffer_blocknr
[
buffer
]
=
blocknr
;
buffer_dev
[
buffer
]
=
sb
;
data
=
read_buffers
[
buffer
];
for
(
i
=
0
;
i
<
BLKS_PER_BUF
;
i
++
)
{
for
(
i
=
0
;
i
<
BLKS_PER_BUF
;
i
++
)
{
struct
buffer_head
*
bh
=
bh_array
[
i
];
struct
buffer_head
*
bh
=
bh_array
[
i
];
if
(
bh
)
{
if
(
bh
)
{
memcpy
(
read_buffers
[
buffer
][
i
]
,
bh
->
b_data
,
PAGE_CACHE_SIZE
);
memcpy
(
data
,
bh
->
b_data
,
PAGE_CACHE_SIZE
);
bforget
(
bh
);
bforget
(
bh
);
}
else
}
else
memset
(
read_buffers
[
buffer
][
i
],
0
,
PAGE_CACHE_SIZE
);
memset
(
data
,
0
,
PAGE_CACHE_SIZE
);
data
+=
PAGE_CACHE_SIZE
;
}
}
return
read_buffers
[
buffer
][
0
]
+
offset
;
return
read_buffers
[
buffer
]
+
offset
;
eek:
printk
(
KERN_ERR
"cramfs (device %s): requested chunk (%u:+%u) bigger than buffer
\n
"
,
bdevname
(
sb
->
s_dev
),
offset
,
len
);
/* TODO: return EIO to process or kill the current process
instead of resuming. */
*
((
int
*
)
0
)
=
0
;
/* XXX: doesn't work on all archs */
goto
resume
;
}
}
...
...
include/net/slhc.h
deleted
100644 → 0
View file @
dad12642
#ifndef __NET_SLHC_H
#define __NET_SLHC_H
extern
void
slhc_install
(
void
);
#endif
kernel/ksyms.c
View file @
9521288f
...
@@ -118,6 +118,7 @@ EXPORT_SYMBOL(kfree);
...
@@ -118,6 +118,7 @@ EXPORT_SYMBOL(kfree);
EXPORT_SYMBOL
(
kfree_s
);
EXPORT_SYMBOL
(
kfree_s
);
EXPORT_SYMBOL
(
vmalloc
);
EXPORT_SYMBOL
(
vmalloc
);
EXPORT_SYMBOL
(
vfree
);
EXPORT_SYMBOL
(
vfree
);
EXPORT_SYMBOL
(
__vmalloc
);
EXPORT_SYMBOL
(
mem_map
);
EXPORT_SYMBOL
(
mem_map
);
EXPORT_SYMBOL
(
remap_page_range
);
EXPORT_SYMBOL
(
remap_page_range
);
EXPORT_SYMBOL
(
max_mapnr
);
EXPORT_SYMBOL
(
max_mapnr
);
...
...
net/core/dev.c
View file @
9521288f
...
@@ -79,7 +79,6 @@
...
@@ -79,7 +79,6 @@
#include <linux/brlock.h>
#include <linux/brlock.h>
#include <net/sock.h>
#include <net/sock.h>
#include <linux/rtnetlink.h>
#include <linux/rtnetlink.h>
#include <net/slhc.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/stat.h>
#include <linux/stat.h>
#include <linux/if_bridge.h>
#include <linux/if_bridge.h>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment