]> git.neil.brown.name Git - history.git/commitdiff
Import 2.3.99pre9-5 2.3.99pre9-5
authorLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:01 +0000 (15:35 -0500)
committerLinus Torvalds <torvalds@linuxfoundation.org>
Fri, 23 Nov 2007 20:35:01 +0000 (15:35 -0500)
22 files changed:
Documentation/Configure.help
Documentation/DocBook/parportbook.tmpl
arch/i386/config.in
arch/i386/kernel/apm.c
drivers/net/setup.c
drivers/net/slhc.c
drivers/parport/ChangeLog
drivers/usb/pegasus.c
drivers/usb/serial/Makefile
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/omninet.c
drivers/usb/serial/usbserial.c
drivers/usb/serial/visor.c
drivers/usb/serial/whiteheat.c
drivers/usb/usb-ohci.c
drivers/usb/usb-ohci.h
fs/cramfs/inode.c
include/net/slhc.h [deleted file]
kernel/ksyms.c
net/core/dev.c

index 311a4a4a079e1e828d36a0430fbf7177ef73a077..4d7b936a3d123452ded77b48f34e75f7c751e241 100644 (file)
@@ -12468,14 +12468,6 @@ CONFIG_APM_DISPLAY_BLANK
   backlight at all, or it might print a lot of errors to the console,
   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
 CONFIG_APM_IGNORE_SUSPEND_BOUNCE
   This option is necessary on the Dell Inspiron 3200 and others, but
index 8d7791df5c8bcdd3fbdcb8ee6bdc5bdd4ab2dd9d..bf4d77873c050eb8dcbbf0adc2ccab458857472d 100644 (file)
@@ -62,7 +62,7 @@
 
    <para>
     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
     writing, via <function>write</function>, and configuration and
     statistics reporting via <function>ioctl</function>.
   -->
 
    <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
     ports, of port-sharing between devices with pass-through ports,
     and of lack of support for IEEE 1284 transfer modes.
    <!-- platform differences -->
 
    <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.
     The other layer deals with sharing and IEEE 1284 transfer modes.
     In this way, parallel support for a particular architecture comes
    <!-- sharing model -->
 
    <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
-    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
     access has been granted.  When it has finished a
     <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.
    </para>
 
    <title>Sharing core</title>
 
    <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
     <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
     interested in new ports, and whether or not each port is available
     for use (or if not, which driver is currently using it).
    <title>Parports and their overrides</title>
 
    <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
-    by <quote>low-level</quote> <filename>parport</filename> drivers.
-    The function of a low-level <filename>parport</filename> driver is
+    by <quote>low-level</quote> <literal>parport</literal> drivers.
+    The function of a low-level <literal>parport</literal> driver is
     to detect parallel ports, register them with the sharing code, and
     provide a list of access functions for each port.
    </para>
 
    <para>
     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
     use, and are very much like library routines.  Since these
     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
     the control lines, examine the status lines, and use the data
     lines.  With some parallel ports the data lines can only be set
    </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
     list.  The low-level driver can just name the generic IEEE 1284
     transfer functions for this.  Some parallel ports can do IEEE 1284
 
    <para>
     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>.
     The information is put into a <structname>struct
     parport_driver</structname>, which is put into a linked list.  The
     the draft specifies the on-the-wire protocol for daisy-chaining
     and multiplexing, and also suggests a programming interface for
     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>
     <function>parport_device_coords</function>.
    </para>
 
-   <funcsynopsis><funcprototype>
+   <funcsynopsis>
+    <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+    </funcsynopsisinfo>
+    <funcprototype>
      <funcdef>int <function>parport_device_num</function></funcdef>
      <paramdef>int <parameter>parport</parameter></paramdef>
      <paramdef>int <parameter>mux</parameter></paramdef>
      <paramdef>int <parameter>daisy</parameter></paramdef>
-    </funcprototype></funcsynopsis>
+    </funcprototype>
+   </funcsynopsis>
 
-   <funcsynopsis><funcprototype>
+   <funcsynopsis>
+    <funcprototype>
      <funcdef>int <function>parport_device_coords</function></funcdef>
      <paramdef>int <parameter>devnum</parameter></paramdef>
      <paramdef>int *<parameter>parport</parameter></paramdef>
      <paramdef>int *<parameter>mux</parameter></paramdef>
      <paramdef>int *<parameter>daisy</parameter></paramdef>
-    </funcprototype></funcsynopsis>
+    </funcprototype>
+   </funcsynopsis>
 
    <para>
     Any parallel port peripheral will be connected directly or
     <function>parport_find_class</function>.
    </para>
 
-   <funcsynopsis><funcprototype>
+   <funcsynopsis>
+    <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+    </funcsynopsisinfo>
+    <funcprototype>
      <funcdef>int <function>parport_find_device</function></funcdef>
      <paramdef>const char *<parameter>mfg</parameter></paramdef>
      <paramdef>const char *<parameter>mdl</parameter></paramdef>
      <paramdef>int <parameter>from</parameter></paramdef>
-    </funcprototype></funcsynopsis>
+    </funcprototype>
+   </funcsynopsis>
 
-   <funcsynopsis><funcprototype>
+   <funcsynopsis>
+    <funcprototype>
      <funcdef>int <function>parport_find_class</function></funcdef>
      <paramdef>parport_device_class <parameter>cls</parameter></paramdef>
      <paramdef>int <parameter>from</parameter></paramdef>
-    </funcprototype></funcsynopsis>
+    </funcprototype>
+   </funcsynopsis>
 
    <para>
     These functions take a device number (in addition to some other
    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
    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
    drivers.
   </para>
 
   <para>
    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
-   <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
    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
    order to talk to its device.
   </para>
 
   <para>
    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
    <function>parport_register_device</function> function:
   </para>
 
-  <programlisting>
-   <![CDATA[
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+
 struct parport_driver {
         const char *name;
         void (*attach) (struct parport *);
         void (*detach) (struct parport *);
         struct parport_driver *next;
 };
-   ]]></programlisting>
+   </funcsynopsisinfo>
 
-  <funcsynopsis><funcprototype>
+   <funcprototype>
     <funcdef>int <function>parport_register_driver</function></funcdef>
     <paramdef>struct parport_driver *<parameter>driver</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    In other words, the device driver passes pointers to a couple of
-   functions to <filename>parport</filename>, and
-   <filename>parport</filename> calls <function>attach</function> for
+   functions to <literal>parport</literal>, and
+   <literal>parport</literal> calls <function>attach</function> for
    each port that's detected (and <function>detach</function> for each
    port that disappears---yes, this can happen).
   </para>
 
   <para>
    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
    <function>attach</function> function, and is done with
    <function>parport_register_device</function>:
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
     <paramdef>struct parport *<parameter>port</parameter></paramdef>
     <paramdef>const char *<parameter>name</parameter></paramdef>
@@ -645,7 +666,8 @@ struct parport_driver {
      <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
     <paramdef>int <parameter>flags</parameter></paramdef>
     <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    The <parameter>port</parameter> comes from the parameter supplied
@@ -705,7 +727,7 @@ struct parport_driver {
 
   <para>
    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
    <constant>0</constant>, which is the usual value) is
    <constant>PARPORT_DEV_EXCL</constant>.  The point of that flag is
@@ -738,7 +760,11 @@ struct parport_driver {
    than a pointer to a <structname>struct parport</structname>.
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>struct pardevice *<function>parport_open</function></funcdef>
     <paramdef>int <parameter>devnum</parameter></paramdef>
     <paramdef>int <parameter>(*pf)</parameter>
@@ -749,14 +775,18 @@ struct parport_driver {
      <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
     <paramdef>int <parameter>flags</parameter></paramdef>
     <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>void <function>parport_close</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>struct pardevice *<function>parport_register_device</function></funcdef>
     <paramdef>struct parport *<parameter>port</parameter></paramdef>
     <paramdef>const char *<parameter>name</parameter></paramdef>
@@ -768,12 +798,15 @@ struct parport_driver {
      <funcparams>int, void *, struct pt_regs *</funcparams></paramdef>
     <paramdef>int <parameter>flags</parameter></paramdef>
     <paramdef>void *<parameter>handle</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>void <function>parport_unregister_device</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    The intended use of these functions is during driver initialisation
@@ -799,20 +832,29 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
    port.
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>int <function>parport_claim</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>int <function>parport_claim_or_block</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>void <function>parport_release</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    To claim access to the port, use <function>parport_claim</function>
@@ -866,15 +908,22 @@ while ((devnum = parport_find_class (PARPORT_CLASS_DIGCAM,
    a <filename>/proc</filename> entry.
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>int <function>parport_yield</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcprototype>
     <funcdef>int <function>parport_yield_blocking</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    The first of these, <function>parport_yield</function>, will not
@@ -919,14 +968,14 @@ port->ops->write_data (port, d);
 
    <listitem>
     <para>
-     The device driver registers itself with <filename>parport</filename>.
+     The device driver registers itself with <literal>parport</literal>.
     </para>
    </listitem>
 
    <listitem>
     <para>
      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
      parport</structname> which is linked onto a list of known ports.
     </para>
@@ -934,7 +983,7 @@ port->ops->write_data (port, d);
 
    <listitem>
     <para>
-     <filename>parport</filename> calls the
+     <literal>parport</literal> calls the
      <function>attach</function> function of each registered device
      driver, passing it the pointer to the new <structname>struct
      parport</structname>.
@@ -944,7 +993,7 @@ port->ops->write_data (port, d);
    <listitem>
     <para>
      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>.
      This handle takes the form of a pointer to a <structname>struct
      pardevice</structname>, representing a particular device on the
@@ -993,18 +1042,18 @@ port->ops->write_data (port, d);
   <!-- Could even talk about parallel port console here. -->
 
   <para>
-   The printer driver, <filename>lp</filename> is a character special
-   device driver and a <filename>parport</filename> client.  As a
+   The printer driver, <literal>lp</literal> is a character special
+   device driver and a <literal>parport</literal> client.  As a
    character special device driver it registers a <structname>struct
    file_operations</structname> using
    <function>register_chrdev</function>, with pointers filled in for
    <structfield>write</structfield>, <structfield>ioctl</structfield>,
    <structfield>open</structfield> and
    <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
    <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
    discovered (and <function>lp_detach</function> when it goes
    away).
@@ -1012,8 +1061,8 @@ port->ops->write_data (port, d);
 
   <para>
    The parallel port console functionality is also implemented in
-   <filename>lp.c</filename>, but that won't be covered here (it's
-   quite simple though).
+   <filename>drivers/char/lp.c</filename>, but that won't be covered
+   here (it's quite simple though).
   </para>
 
   <para>
@@ -1037,7 +1086,7 @@ port->ops->write_data (port, d);
   <para>
    After successfully registering itself as a character special device
    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
    to this structure:
   </para>
@@ -1076,14 +1125,14 @@ static struct parport_driver lp_driver = {
 
   <para>
    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
    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>
-   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>,
    <function>parport_set_timeout</function>, and
    <function>parport_write</function>.  These functions are part of
@@ -1106,11 +1155,16 @@ static struct parport_driver lp_driver = {
    <function>parport_negotiate</function>.
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>int <function>parport_negotiate</function></funcdef>
     <paramdef>struct parport *<parameter>port</parameter></paramdef>
     <paramdef>int <parameter>mode</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    The <parameter>modes</parameter> parameter is a symbolic constant
@@ -1132,7 +1186,7 @@ static struct parport_driver lp_driver = {
 
   <para>
    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>
 
 <programlisting>
@@ -1147,19 +1201,26 @@ static struct parport_driver lp_driver = {
    successfully written:
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>ssize_t <function>parport_write</function></funcdef>
     <paramdef>struct parport *<parameter>port</parameter></paramdef>
     <paramdef>const void *<parameter>buf</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>
     <paramdef>struct parport *<parameter>port</parameter></paramdef>
     <paramdef>void *<parameter>buf</parameter></paramdef>
     <paramdef>size_t <parameter>len</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    (<function>parport_read</function> does what it sounds like, but
@@ -1186,49 +1247,106 @@ struct parport_operations {
         [...]
 
         /* 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 (*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);
-        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 (*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);
 
-        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 (*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);
-        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 (*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 (*nibble_read_data) (struct parport *port, void *buf,
-                                    size_t len, int flags);
-        size_t (*byte_read_data) (struct parport *port, void *buf,
-                                  size_t len, int flags);
+        size_t (*nibble_read_data) (struct parport *port,
+                                    void *buf, size_t len,
+                                    int flags);
+        size_t (*byte_read_data) (struct parport *port,
+                                  void *buf, size_t len,
+                                  int flags);
 };
    ]]></programlisting>
 
   <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
    specified with <function>parport_set_timeout</function>, which
    returns the previous timeout:
   </para>
 
-  <funcsynopsis><funcprototype>
+  <funcsynopsis>
+   <funcsynopsisinfo>
+#include &lt;parport.h&gt;
+   </funcsynopsisinfo>
+   <funcprototype>
     <funcdef>long <function>parport_set_timeout</function></funcdef>
     <paramdef>struct pardevice *<parameter>dev</parameter></paramdef>
     <paramdef>long <parameter>inactivity</parameter></paramdef>
-   </funcprototype></funcsynopsis>
+   </funcprototype>
+  </funcsynopsis>
 
   <para>
    This timeout is specific to the device, and is restored on
    <function>parport_claim</function>.
   </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 id="ppdev">
@@ -1260,7 +1378,7 @@ struct parport_operations {
    </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:
    </para>
 
@@ -1344,11 +1462,13 @@ struct parport_operations {
    <title>Programming interface</title>
 
    <para>
-    The <filename>ppdev</filename> interface is largely the same as
-    that of other character special devices, in that it supports
+    The <literal>ppdev</literal> interface is largely the same as that
+    of other character special devices, in that it supports
     <function>open</function>, <function>close</function>,
     <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>
 
    <sect2>
@@ -1379,7 +1499,7 @@ struct parport_operations {
      Most of the control is done, naturally enough, via the
      <function>ioctl</function> call.  Using
      <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>
      call takes as parameters a file descriptor (the one returned from
      opening the device node), a command, and optionally (a pointer
@@ -1395,7 +1515,7 @@ struct parport_operations {
        writer, you will need to do this before you are able to
        actually change the state of the parallel port in any way.
        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
        access to the port is not claimed.
        </para>
@@ -1486,7 +1606,7 @@ struct parport_operations {
        <para>
        The <function>ioctl</function> parameter should be a pointer
        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>
 
        <itemizedlist spacing=compact>
@@ -1566,7 +1686,7 @@ struct parport_operations {
        Sets the control lines.  The <function>ioctl</function>
        parameter is a pointer to an <type>unsigned char</type>, the
        bitwise OR of the control line values in
-       <filename>parport.h</filename>.
+       <filename>include/linux/parport.h</filename>.
        </para>
 
       </listitem></varlistentry>
@@ -1591,7 +1711,7 @@ struct parport_operations {
 
        <para>
        The control lines bits are defined in
-       <filename>parport.h</filename>:
+       <filename>include/linux/parport.h</filename>:
        </para>
 
        <itemizedlist spacing=compact>
@@ -1619,7 +1739,7 @@ struct parport_operations {
        course, each driver could remember what state the control
        lines are supposed to be in (they are never changed by
        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.
        </para>
 
@@ -1728,7 +1848,7 @@ struct ppdev_frob_struct {
       <listitem>
 
        <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.
        <constant>PPCLRIRQ</constant> stores this count in an
        <type>int</type>, a pointer to which is passed in as the
@@ -1790,7 +1910,7 @@ struct ppdev_frob_struct {
      <function>select</function></title>
 
     <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
      using <function>poll</function> (and <function>select</function>,
      which is implemented in terms of <function>poll</function>).
@@ -1799,7 +1919,7 @@ struct ppdev_frob_struct {
     <para>
      When a user-land device driver wants to wait for an interrupt, it
      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
      nothing to actually <function>read</function>).
     </para>
@@ -1813,7 +1933,7 @@ struct ppdev_frob_struct {
 
    <para>
     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
     will drive the control and data lines directly.
    </para>
@@ -1998,7 +2118,7 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
     ]]></programlisting>
 
    <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
     printer's side of printer protocol.
    </para>
@@ -2048,6 +2168,43 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
     }
     ]]></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>
 
  </chapter>
@@ -2078,6 +2235,85 @@ ssize_t write_printer (int fd, const void *ptr, size_t count)
 !Fdrivers/parport/ieee1284.c parport_set_timeout
 
  </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>
 
 <!-- Local Variables: -->
index 8f4782ca80f9c9be3fbde38f2663f212c37620cf..1208a6b82a6cc9e221d42066cf2cde1e54b4fc37 100644 (file)
@@ -180,7 +180,6 @@ if [ "$CONFIG_APM" != "n" ]; then
    bool '    Enable PM at boot time' CONFIG_APM_DO_ENABLE
    bool '    Make CPU Idle calls when idle' CONFIG_APM_CPU_IDLE
    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 '    RTC stores time in GMT' CONFIG_APM_RTC_IS_GMT
    bool '    Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
index 99e2587565ad7b14e29a2532a71b72f5e1cb3e83..b1e0e8b7c612a017b5869d5f61cdee8525cfc667 100644 (file)
  *   1.13: Changes for new pm_ interfaces (Andy Henroid
  *         <andy_henroid@yahoo.com>).
  *         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:
  *
@@ -308,9 +311,7 @@ static int                  clock_slowed = 0;
 #endif
 static int                     suspends_pending = 0;
 static int                     standbys_pending = 0;
-#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
 static int                     waiting_for_resume = 0;
-#endif
 
 #ifdef CONFIG_APM_RTC_IS_GMT
 #      define  clock_cmos_diff 0
@@ -866,22 +867,22 @@ static void reinit_timer(void)
 static int suspend(void)
 {
        int             err;
-       int             ret;
        struct apm_user *as;
 
        get_time_diff();
        err = apm_set_power_state(APM_STATE_SUSPEND);
        reinit_timer();
        set_time();
-       ret = (err == APM_SUCCESS) || (err == APM_NO_ERROR);
-       if (!ret)
+       if (err == APM_NO_ERROR)
+               err = APM_SUCCESS;
+       if (err != APM_SUCCESS)
                apm_error("suspend", err);
        for (as = user_list; as != NULL; as = as->next) {
                as->suspend_wait = 0;
-               as->suspend_result = (ret ? 0 : -EIO);
+               as->suspend_result = ((err == APM_SUCCESS) ? 0 : -EIO);
        }
        wake_up_interruptible(&apm_suspend_waitqueue);
-       return ret;
+       return err;
 }
 
 static void standby(void)
@@ -962,14 +963,7 @@ static void check_events(void)
                switch (event) {
                case APM_SYS_STANDBY:
                case APM_USER_STANDBY:
-#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
-                       if (waiting_for_resume)
-                               break;
-#endif
                        if (send_event(event, NULL)) {
-#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
-                               waiting_for_resume = 1;
-#endif
                                if (standbys_pending <= 0)
                                        standby();
                        }
@@ -986,14 +980,18 @@ static void check_events(void)
                        if (ignore_bounce)
                                break;
 #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)
-                               break;
-#endif
+                               return;
                        if (send_event(event, NULL)) {
-#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
                                waiting_for_resume = 1;
-#endif
                                if (suspends_pending <= 0)
                                        (void) suspend();
                        }
@@ -1002,9 +1000,7 @@ static void check_events(void)
                case APM_NORMAL_RESUME:
                case APM_CRITICAL_RESUME:
                case APM_STANDBY_RESUME:
-#ifdef CONFIG_APM_IGNORE_MULTIPLE_SUSPEND
                        waiting_for_resume = 0;
-#endif
 #ifdef CONFIG_APM_IGNORE_SUSPEND_BOUNCE
                        last_resume = jiffies;
                        ignore_bounce = 1;
@@ -1036,8 +1032,10 @@ static void apm_event_handler(void)
        int             err;
 
        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;
+                       if (debug)
+                               printk(KERN_DEBUG "apm: setting state busy\n");
                        err = apm_set_power_state(APM_STATE_BUSY);
                        if (err)
                                apm_error("busy", err);
@@ -1097,7 +1095,7 @@ static void apm_mainloop(void)
 static int check_apm_user(struct apm_user *as, const char *func)
 {
        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 0;
@@ -1200,7 +1198,7 @@ static int do_ioctl(struct inode * inode, struct file *filp,
                } else if (!send_event(APM_USER_SUSPEND, as))
                        return -EAGAIN;
                if (suspends_pending <= 0) {
-                       if (!suspend())
+                       if (suspend() != APM_SUCCESS)
                                return -EIO;
                } else {
                        as->suspend_wait = 1;
@@ -1251,7 +1249,7 @@ static int do_release(struct inode * inode, struct file * filp)
                     as1 = as1->next)
                        ;
                if (as1 == NULL)
-                       printk(KERN_ERR "apm: filp not in user list");
+                       printk(KERN_ERR "apm: filp not in user list\n");
                else
                        as1->next = as->next;
        }
@@ -1268,7 +1266,7 @@ static int do_open(struct inode * inode, struct file * filp)
 
        as = (struct apm_user *)kmalloc(sizeof(*as), GFP_KERNEL);
        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));
                MOD_DEC_USE_COUNT;
                return -ENOMEM;
index a5442e68a79473be567982603d7b4a2e001c3d92..b4e5da200129ac511e814cc6c3f94c839c486386 100644 (file)
@@ -12,7 +12,6 @@ extern int mkiss_init_ctrl_dev(void);
 extern int slip_init_ctrl_dev(void);
 extern int strip_init_ctrl_dev(void);
 extern int x25_asy_init_ctrl_dev(void);
-extern int slhc_install(void);
   
 extern int dmascc_init(void);
 extern int yam_init(void);
@@ -78,22 +77,12 @@ struct net_probe pci_probes[] __initdata = {
 #endif
 #if defined(CONFIG_COMX)
        {comx_init, 0},
-#endif /*
-        *      SLHC if present needs attaching so other people see it
-        *      even if not opened.
-        */
+#endif
+        
 #if defined(CONFIG_LANMEDIA)
        {lmc_setup, 0},
 #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
index ccc8a93d662cb40b2c152f69f4805b22e7f2e9c3..10df972259cac393acde4a9e72586be1f1cf3627 100644 (file)
@@ -77,7 +77,6 @@
 #include <linux/timer.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <linux/init.h>
 #include <net/checksum.h>
 #include <net/slhc_vj.h>
 #include <asm/unaligned.h>
@@ -751,12 +750,6 @@ void cleanup_module(void)
        return;
 }
 
-#else /* MODULE */
-int __init slhc_install(void)
-{
-       return 0;
-}
-
 #endif /* MODULE */
 #else /* CONFIG_INET */
 
index 0d1fd72e6d4362c96d22f6a95b5a1143fee56dd3..97b7c53c99d907fc03c69d31b420b81109c4d7f5 100644 (file)
@@ -1,3 +1,7 @@
+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>
 
        * parport_pc.c (parport_pc_compat_write_block_pio): Check for
index 7f4459d2f0b7e083ab2b5ae75e9bd452360f9790..b40a947edc83d3f8eea752b1250d8bbfa9ab340b 100644 (file)
@@ -16,7 +16,7 @@
 #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
@@ -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_READ               0x02
 #define        PEGASUS_TX_TIMEOUT      (HZ*5)
+#define        PEGASUS_RESET           1
 #define        ALIGN(x)                x __attribute__((aligned(L1_CACHE_BYTES)))
 
+
 struct pegasus {
        struct usb_device       *usb;
        struct net_device       *net;
        struct net_device_stats stats;
+       int                     flags;
        spinlock_t              pegasus_lock;
        struct urb              rx_urb, tx_urb, intr_urb;
        unsigned char           ALIGN(rx_buff[PEGASUS_MAX_MTU]); 
@@ -44,9 +47,11 @@ struct usb_eth_dev {
        void    *private;
 };
 
+
 static int loopback = 0;
 static int multicast_filter_limit = 32;
 
+
 MODULE_AUTHOR("Petko Manolov <petkan@spct.net>");
 MODULE_DESCRIPTION("ADMtek AN986 Pegasus USB Ethernet driver");
 MODULE_PARM(loopback, "i");
@@ -98,6 +103,7 @@ static int pegasus_read_phy_word(struct usb_device *dev, __u8 index, __u16 *regd
        return 1;
 }
 
+
 static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regdata)
 {
        int i;
@@ -115,6 +121,7 @@ static int pegasus_write_phy_word(struct usb_device *dev, __u8 index, __u16 regd
        return 1;
 }
 
+
 static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retdata, __u8 direction)
 {
        int i;
@@ -134,6 +141,7 @@ static int pegasus_rw_srom_word(struct usb_device *dev, __u8 index, __u16 *retda
        return 1;
 }
 
+
 static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
 {
        int i;
@@ -143,6 +151,7 @@ static int pegasus_get_node_id(struct usb_device *dev, __u8 *id)
        return 0;
 }
 
+
 static int pegasus_reset_mac(struct usb_device *dev)
 {
        __u8 data = 0x8;
@@ -165,6 +174,7 @@ static int pegasus_reset_mac(struct usb_device *dev)
        return 1;
 }
 
+
 static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
 {
        __u16 partmedia, temp;
@@ -195,13 +205,14 @@ static int pegasus_start_net(struct net_device *dev, struct usb_device *usb)
 
        data[0] = 0xc9;
        data[1] = (partmedia & 0x100) ? 0x30 : ((partmedia & 0x80) ? 0x10 : 0);
-       data[2] = (loopback & 1) ? 0x08 : 0x00;
+       data[2] = (loopback & 1) ? 0x09 : 0x01;
 
        pegasus_set_registers(usb, 0, 3, data);
 
        return 0;
 }
 
+
 static void pegasus_read_bulk(struct urb *urb)
 {
        struct pegasus *pegasus = urb->context;
@@ -253,15 +264,16 @@ goon:
                warn("(prb)failed rx_urb %d", res);
 }
 
+
 static void pegasus_irq(urb_t *urb)
 {
-       if(urb->status) {
-               __u8    *d = urb->transfer_buffer;
-               printk("txst0 %x, txst1 %x, rxst %x, rxlst0 %x, rxlst1 %x, wakest %x",
-                       d[0], d[1], d[2], d[3], d[4], d[5]);
-       }
+       __u8    *d = urb->transfer_buffer;
+       
+       if ( d[0] )
+               dbg("txst0=0x%2x", d[0]);
 }
 
+
 static void pegasus_write_bulk(struct urb *urb)
 {
        struct pegasus *pegasus = urb->context;
@@ -280,12 +292,15 @@ static void pegasus_tx_timeout(struct net_device *net)
        struct pegasus *pegasus = net->priv;
 
        warn("%s: Tx timed out. Reseting...", net->name);
+       usb_unlink_urb(&pegasus->tx_urb);
        pegasus->stats.tx_errors++;
        net->trans_start = jiffies;
+       pegasus->flags |= PEGASUS_RESET;
 
        netif_wake_queue(net);
 }
 
+
 static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
 {
        struct pegasus  *pegasus = net->priv;
@@ -317,11 +332,13 @@ static int pegasus_start_xmit(struct sk_buff *skb, struct net_device *net)
        return 0;
 }
 
+
 static struct net_device_stats *pegasus_netdev_stats(struct net_device *dev)
 {
        return &((struct pegasus *)dev->priv)->stats;
 }
 
+
 static int pegasus_open(struct net_device *net)
 {
        struct pegasus *pegasus = (struct pegasus *)net->priv;
@@ -334,8 +351,10 @@ static int pegasus_open(struct net_device *net)
 
        if ((res = usb_submit_urb(&pegasus->rx_urb)))
                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);
 
        MOD_INC_USE_COUNT;
@@ -343,6 +362,7 @@ static int pegasus_open(struct net_device *net)
        return 0;
 }
 
+
 static int pegasus_close(struct net_device *net)
 {
        struct pegasus  *pegasus = net->priv;
@@ -351,13 +371,14 @@ static int pegasus_close(struct net_device *net)
 
        usb_unlink_urb(&pegasus->rx_urb);
        usb_unlink_urb(&pegasus->tx_urb);
-/*     usb_unlink_urb(&pegasus->intr_urb); */
+       usb_unlink_urb(&pegasus->intr_urb);
 
        MOD_DEC_USE_COUNT;
 
        return 0;
 }
 
+
 static int pegasus_ioctl(struct net_device *net, struct ifreq *rq, int cmd)
 {
        __u16 *data = (__u16 *)&rq->ifr_data;
@@ -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)
 {
        struct pegasus *pegasus = net->priv;
@@ -400,6 +422,7 @@ static void pegasus_set_rx_mode(struct net_device *net)
        netif_wake_queue(net);
 }
 
+
 static int check_device_ids( __u16 vendor, __u16 product )
 {
        int i=0;
@@ -413,6 +436,7 @@ static int check_device_ids( __u16 vendor, __u16 product )
        return  -1;
 }
 
+
 static void * pegasus_probe(struct usb_device *dev, unsigned int ifnum)
 {
        struct net_device *net;
@@ -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);
        FILL_INT_URB(&pegasus->intr_urb, dev, usb_rcvintpipe(dev, 3),
-                       pegasus->intr_buff, 8, pegasus_irq, pegasus, 250);
+                       pegasus->intr_buff, 8, pegasus_irq, pegasus, 500);
 
 
        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)
        return pegasus;
 }
 
+
 static void pegasus_disconnect(struct usb_device *dev, void *ptr)
 {
        struct pegasus *pegasus = 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->tx_urb);
-/*     usb_unlink_urb(&pegasus->intr_urb);*/
+       usb_unlink_urb(&pegasus->intr_urb);
 
        kfree(pegasus);
 }
 
+
 static struct usb_driver pegasus_driver = {
        name:           "pegasus",
        probe:          pegasus_probe,
index fa69fa52aa0a9acd2ce4a72457c60949dbb7f86d..7d24c34f915f9115ab52381cb604adf9d5226484 100644 (file)
@@ -4,8 +4,26 @@
 
 O_TARGET       := 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
 
+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
-
index 618898b0c40d6bd4a52b9eb01da533ef340b9bc2..fe2d2013b3251f9e61d818133a8fb79309419f15 100644 (file)
@@ -47,9 +47,6 @@
 */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_DIGI_ACCELEPORT
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -1276,4 +1273,3 @@ resubmit:
 
 }
 
-#endif /* CONFIG_USB_SERIAL_DIGI_ACCELEPORT */
index cdad3cabe3b75112181ab17469fbf7c6e44c9835..8aec735697bc7e93461471c5ebb732ef79a98490 100644 (file)
@@ -32,9 +32,6 @@
 
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_FTDI_SIO
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -723,6 +720,3 @@ static int ftdi_sio_ioctl (struct usb_serial_port *port, struct file * file, uns
        return 0;
 } /* ftdi_sio_ioctl */
 
-#endif         /* CONFIG_USB_SERIAL_FTDI_SIO */
-
-
index f91e1b592a4558b541a59f95fe11696078ca98c9..c18137ffa39a798a37d65998ee1ae0ea8f6441c8 100644 (file)
@@ -18,9 +18,6 @@
 
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_KEYSPAN_PDA
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -700,4 +697,3 @@ struct usb_serial_device_type keyspan_pda_device = {
        shutdown:               keyspan_pda_shutdown,
 };
 
-#endif /* CONFIG_USB_SERIAL_KEYSPAN_PDA */
index 9eb6767f08f1cf9060ca3c989855c694c91c9bc9..2e5e50849f14709b9f40de320e48f093cdd016d5 100644 (file)
@@ -13,9 +13,6 @@
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_OMNINET
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -336,6 +333,3 @@ static void omninet_write_bulk_callback (struct urb *urb)
        return;
 }
 
-#endif /* CONFIG_USB_SERIAL_OMNINET */
-
-
index 9fe65ae8dcf95b9cea9f4ca530c87db63396fd13..b2e18bd8eb94a6c2ce975bac5a57b9cd796d7146 100644 (file)
  *
  * 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
  *     Added the Digi Acceleport driver from Al Borchers and Peter Berger.
  * 
index 979a56f0119462732bb1c41df646c8f1412b5f25..5cfb4c42ab5c040d5c891a41714736bf66b92c7a 100644 (file)
@@ -20,9 +20,6 @@
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_VISOR
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -207,7 +204,3 @@ static int  visor_startup (struct usb_serial *serial)
        return (0);
 }
 
-
-#endif /* CONFIG_USB_SERIAL_VISOR*/
-
-
index 58f761fbfe1fa689f78418b04bafffca3ca95393..c168efa02dfeaa38647e0a0b1fe8b704affe3a7e 100644 (file)
@@ -21,9 +21,6 @@
  */
 
 #include <linux/config.h>
-
-#ifdef CONFIG_USB_SERIAL_WHITEHEAT
-
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/signal.h>
@@ -407,6 +404,3 @@ static void whiteheat_shutdown (struct usb_serial *serial)
        return;
 }
 
-#endif /* CONFIG_USB_SERIAL_WHITEHEAT */
-
-
index ebe22a9d301989a139c0d840ad59205b7c9ca886..a37e805f0f018cb5eae35e610c43e0312d7bfec2 100644 (file)
@@ -92,7 +92,6 @@ static void urb_rm_priv (urb_t * urb)
        kfree (urb->hcpriv);
        urb->hcpriv = NULL;
 
-       wake_up (&op_wakeup);
 }
 
 /*-------------------------------------------------------------------------*/
@@ -493,6 +492,8 @@ static int sohci_submit_urb (urb_t * urb)
                urb->start_frame = ((ed->state == ED_OPER)? (ed->last_iso + 1): 
                                                                (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 */
                ep_link (ohci, ed);
@@ -527,6 +528,8 @@ static int sohci_unlink_urb (urb_t * urb)
        urb_print (urb, "UNLINK", 1);
 #endif           
 
+       usb_dec_dev_use (urb->dev);     
+       
        if (usb_pipedevice (urb->pipe) == ohci->rh.devnum) 
                return rh_unlink_urb (urb); /* a request to the virtual root hub */
        
@@ -544,19 +547,23 @@ static int sohci_unlink_urb (urb_t * urb)
                        ep_rm_ed (urb->dev, urb_priv->ed);
                        urb_priv->ed->state |= ED_URB_DEL;
                        spin_unlock_irqrestore (&usb_ed_lock, flags);
-
-                       add_wait_queue (&op_wakeup, &wait);
-                       current->state = TASK_UNINTERRUPTIBLE;
-                       if (!schedule_timeout (HZ / 10)) /* wait until all TDs are deleted */
-                               err("unlink URB timeout!");
-                       remove_wait_queue (&op_wakeup, &wait); 
-               } else 
+                       if (!(urb->transfer_flags & USB_ASYNC_UNLINK)) {
+                               add_wait_queue (&op_wakeup, &wait);
+                               current->state = TASK_UNINTERRUPTIBLE;
+                               if (!schedule_timeout (HZ / 10)) /* wait until all TDs are deleted */
+                                       err("unlink URB timeout!");
+                               remove_wait_queue (&op_wakeup, &wait); 
+                               urb->status = -ENOENT;
+                       } else
+                               urb->status = -EINPROGRESS;
+               } else {
                        urb_rm_priv (urb);
-
-               urb->status = -ENOENT;  // mark urb as killed           
-               if (urb->complete)
-                       urb->complete ((struct urb *) urb);
-               usb_dec_dev_use (urb->dev);             
+                       if (urb->complete && (urb->transfer_flags & USB_ASYNC_UNLINK)) {
+                               urb->complete (urb); 
+                               urb->status = 0;        
+                       } else 
+                               urb->status = -ENOENT;
+               }       
        }       
        return 0;
 }
@@ -965,7 +972,7 @@ static void ep_rm_ed (struct usb_device * usb_dev, ed_t * ed)
 
 /* 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;
        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
        td->index = index;
        td->urb = urb; 
        td->hwINFO = cpu_to_le32 (info);
-       td->type = type;
        if ((td->ed->type & 3) == PIPE_ISOCHRONOUS) {
                td->hwCBP = cpu_to_le32 (((!data || !len)? 
                                                                0 : virt_to_bus (data)) & 0xFFFFF000);
@@ -1029,12 +1035,12 @@ static void td_submit_urb (urb_t * urb)
                        info = usb_pipeout (urb->pipe)? 
                                TD_CC | TD_DP_OUT : TD_CC | TD_DP_IN ;
                        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++;
                        }
                        info = usb_pipeout (urb->pipe)?
                                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++;
                        writel (OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
                        break;
@@ -1042,20 +1048,20 @@ static void td_submit_urb (urb_t * urb)
                case PIPE_INTERRUPT:
                        info = usb_pipeout (urb->pipe)? 
                                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;
 
                case PIPE_CONTROL:
                        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) {  
                                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_fill (info, data, data_len, urb, ADD_LEN, cnt++);  
+                               td_fill (info, data, data_len, urb, cnt++);  
                        } 
                        info = usb_pipeout (urb->pipe)? 
                                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 */
                        break;
 
@@ -1063,7 +1069,7 @@ static void td_submit_urb (urb_t * urb)
                        for (cnt = 0; cnt < urb->number_of_packets; cnt++) {
                                td_fill (TD_CC|TD_ISO | ((urb->start_frame + cnt) & 0xffff), 
                                        (__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;
        } 
@@ -1074,7 +1080,55 @@ static void td_submit_urb (urb_t * urb)
 /*-------------------------------------------------------------------------*
  * 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
  * we reverse the reversed done-list */
  
@@ -1128,6 +1182,7 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
        unsigned long flags;
        ed_t * ed;
        __u32 edINFO;
+       __u32 tdINFO;
        td_t * td = NULL, * td_next = NULL, * tdHeadP = NULL, * tdTailP;
        __u32 * td_p;
        int ctrl = 0, bulk = 0;
@@ -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);
                edINFO = le32_to_cpup (&ed->hwINFO);
                td_p = &ed->hwHeadP;
-                       
+
                for (td = tdHeadP; td != tdTailP; td = td_next) { 
                        urb_t * urb = td->urb;
                        urb_priv_t * urb_priv = td->urb->hcpriv;
                        
                        td_next = bus_to_virt (le32_to_cpup (&td->hwNextTD) & 0xfffffff0);
                        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));
                                if(++ (urb_priv->td_cnt) == urb_priv->length) 
                                        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 {
                                td_p = &td->hwNextTD;
                        }
@@ -1165,7 +1229,7 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
                }
                else {
                        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;
@@ -1183,6 +1247,8 @@ static void dl_del_list (ohci_t  * ohci, unsigned int frame)
        spin_unlock_irqrestore (&usb_ed_lock, flags);
 }
 
+
+               
 /*-------------------------------------------------------------------------*/
 
 /* td done list */
@@ -1191,12 +1257,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
 {
        td_t * td_list_next = NULL;
        ed_t * ed;
-       int dlen = 0;
        int cc = 0;
        urb_t * urb;
        urb_priv_t * urb_priv;
-       __u32 tdINFO, tdBE, tdCBP, edHeadP, edTailP;
-       __u16 tdPSW;
+       __u32 tdINFO, edHeadP, edTailP;
+       
        unsigned long flags;
        
        while (td_list) {
@@ -1205,40 +1270,11 @@ static void dl_done_list (ohci_t * ohci, td_t * td_list)
                urb = td_list->urb;
                urb_priv = urb->hcpriv;
                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;
                
-               if (td_list->type & ST_ADDR) 
-                       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;
-                           }
-                       }
-               }
+               dl_transfer_length(td_list);
+                       
                /* error code of transfer */
                cc = TD_CC_GET (tdINFO);
                if( cc == TD_CC_STALL) usb_endpoint_halt(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
index e854e0c1d3d16842f52c8c6682184ef31cdfd8f8..3ac5dafb24cb26947afb0908498bf93f4718815f 100644 (file)
@@ -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 void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed);
 /* 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);
 /* root hub */
 static int rh_submit_urb(urb_t * urb);
index 279b0bfef762271f875dff48a29d8b9657faa930..550b54295432e3c6447c6976fedad44ddbe7b2f6 100644 (file)
@@ -84,15 +84,17 @@ static struct inode *get_cramfs_inode(struct super_block *sb, struct cramfs_inod
 #define NEXT_BUFFER(_ix) ((_ix) ^ 1)
 
 /*
- * BLKS_PER_BUF_SHIFT must be at least 1 to allow for "compressed"
- * data that takes up more space than the original.  1 is guaranteed
- * to suffice, though.  Larger values provide more read-ahead and
- * proportionally less wastage at the end of the buffer.
+ * BLKS_PER_BUF_SHIFT should be at least 2 to allow for "compressed"
+ * data that takes up more space than the original and with unlucky
+ * alignment.
  */
-#define BLKS_PER_BUF_SHIFT (2)
-#define BLKS_PER_BUF (1 << BLKS_PER_BUF_SHIFT)
-static unsigned char read_buffers[READ_BUFFERS][BLKS_PER_BUF][PAGE_CACHE_SIZE];
+#define BLKS_PER_BUF_SHIFT     (2)
+#define BLKS_PER_BUF           (1 << BLKS_PER_BUF_SHIFT)
+#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 struct super_block * buffer_dev[READ_BUFFERS];
 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)
 {
        struct buffer_head * bh_array[BLKS_PER_BUF];
-       unsigned i, blocknr, last_blocknr, buffer;
+       unsigned i, blocknr, buffer;
+       char *data;
 
        if (!len)
                return NULL;
        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;
+
+       /* Check if an existing buffer already has the data.. */
        for (i = 0; i < READ_BUFFERS; i++) {
-               if ((blocknr >= buffer_blocknr[i]) &&
-                   (last_blocknr - buffer_blocknr[i] < BLKS_PER_BUF))
-                       return &read_buffers[i][blocknr - buffer_blocknr[i]][offset];
+               unsigned int blk_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. */
@@ -125,24 +135,18 @@ static void *cramfs_read(struct super_block *sb, unsigned int offset, unsigned i
        buffer = next_buffer;
        next_buffer = NEXT_BUFFER(buffer);
        buffer_blocknr[buffer] = blocknr;
+       buffer_dev[buffer] = sb;
+       data = read_buffers[buffer];
        for (i = 0; i < BLKS_PER_BUF; i++) {
                struct buffer_head * bh = bh_array[i];
                if (bh) {
-                       memcpy(read_buffers[buffer][i], bh->b_data, PAGE_CACHE_SIZE);
+                       memcpy(data, bh->b_data, PAGE_CACHE_SIZE);
                        bforget(bh);
                } 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;
-
- 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;
+       return read_buffers[buffer] + offset;
 }
                        
 
diff --git a/include/net/slhc.h b/include/net/slhc.h
deleted file mode 100644 (file)
index c7b39db..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef __NET_SLHC_H
-#define __NET_SLHC_H
-
-extern void slhc_install(void);
-
-#endif
index d5660d90c7cbdc0ffd01e23fb70d4a49f85b4835..597d292f5fb146cdca0a6b9cf0c58cc75d6bb072 100644 (file)
@@ -118,6 +118,7 @@ EXPORT_SYMBOL(kfree);
 EXPORT_SYMBOL(kfree_s);
 EXPORT_SYMBOL(vmalloc);
 EXPORT_SYMBOL(vfree);
+EXPORT_SYMBOL(__vmalloc);
 EXPORT_SYMBOL(mem_map);
 EXPORT_SYMBOL(remap_page_range);
 EXPORT_SYMBOL(max_mapnr);
index ff5ff69dd712e75170146ef1a736b181a5e34c2b..bd3670a93c1423f20c4f61b482801ebafa30f989 100644 (file)
@@ -79,7 +79,6 @@
 #include <linux/brlock.h>
 #include <net/sock.h>
 #include <linux/rtnetlink.h>
-#include <net/slhc.h>
 #include <linux/proc_fs.h>
 #include <linux/stat.h>
 #include <linux/if_bridge.h>