Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / drivers / parport / daisy.c
index 9f4f5f4..fd41e28 100644 (file)
@@ -41,7 +41,7 @@ static struct daisydev {
        int daisy;
        int devnum;
 } *topology = NULL;
-static spinlock_t topology_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(topology_lock);
 
 static int numdevs = 0;
 
@@ -144,9 +144,9 @@ again:
        add_dev (numdevs++, port, -1);
 
        /* Find out the legacy device's IEEE 1284 device ID. */
-       deviceid = kmalloc (1000, GFP_KERNEL);
+       deviceid = kmalloc (1024, GFP_KERNEL);
        if (deviceid) {
-               if (parport_device_id (numdevs - 1, deviceid, 1000) > 2)
+               if (parport_device_id (numdevs - 1, deviceid, 1024) > 2)
                        detected++;
 
                kfree (deviceid);
@@ -207,8 +207,7 @@ void parport_daisy_fini (struct parport *port)
  *
  *     This function is similar to parport_register_device(), except
  *     that it locates a device by its number rather than by the port
- *     it is attached to.  See parport_find_device() and
- *     parport_find_class().
+ *     it is attached to.
  *
  *     All parameters except for @devnum are the same as for
  *     parport_register_device().  The return value is the same as
@@ -253,7 +252,7 @@ struct pardevice *parport_open (int devnum, const char *name,
                selected = port->daisy;
                parport_release (dev);
 
-               if (selected != port->daisy) {
+               if (selected != daisy) {
                        /* No corresponding device. */
                        parport_unregister_device (dev);
                        return NULL;
@@ -284,7 +283,7 @@ void parport_close (struct pardevice *dev)
  *
  *     This tries to locate a device on the given parallel port,
  *     multiplexor port and daisy chain address, and returns its
- *     device number or -NXIO if no device with those coordinates
+ *     device number or %-ENXIO if no device with those coordinates
  *     exists.
  **/
 
@@ -305,53 +304,6 @@ int parport_device_num (int parport, int mux, int daisy)
        return res;
 }
 
-/**
- *     parport_device_coords - convert canonical device number
- *     @devnum: device number
- *     @parport: pointer to storage for parallel port number
- *     @mux: pointer to storage for multiplexor port number
- *     @daisy: pointer to storage for daisy chain address
- *
- *     This function converts a device number into its coordinates in
- *     terms of which parallel port in the system it is attached to,
- *     which multiplexor port it is attached to if there is a
- *     multiplexor on that port, and which daisy chain address it has
- *     if it is in a daisy chain.
- *
- *     The caller must allocate storage for @parport, @mux, and
- *     @daisy.
- *
- *     If there is no device with the specified device number, -ENXIO
- *     is returned.  Otherwise, the values pointed to by @parport,
- *     @mux, and @daisy are set to the coordinates of the device,
- *     with -1 for coordinates with no value.
- *
- *     This function is not actually very useful, but this interface
- *     was suggested by IEEE 1284.3.
- **/
-
-int parport_device_coords (int devnum, int *parport, int *mux, int *daisy)
-{
-       struct daisydev *dev;
-
-       spin_lock(&topology_lock);
-
-       dev = topology;
-       while (dev && dev->devnum != devnum)
-               dev = dev->next;
-
-       if (!dev) {
-               spin_unlock(&topology_lock);
-               return -ENXIO;
-       }
-
-       if (parport) *parport = dev->port->portnum;
-       if (mux) *mux = dev->port->muxport;
-       if (daisy) *daisy = dev->daisy;
-       spin_unlock(&topology_lock);
-       return 0;
-}
-
 /* Send a daisy-chain-style CPP command packet. */
 static int cpp_daisy (struct parport *port, int cmd)
 {
@@ -392,9 +344,9 @@ static int cpp_daisy (struct parport *port, int cmd)
                              PARPORT_CONTROL_STROBE,
                              PARPORT_CONTROL_STROBE);
        udelay (1);
+       s = parport_read_status (port);
        parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
        udelay (1);
-       s = parport_read_status (port);
        parport_write_data (port, 0xff); udelay (2);
 
        return s;
@@ -443,15 +395,15 @@ int parport_daisy_select (struct parport *port, int daisy, int mode)
                case IEEE1284_MODE_EPP:
                case IEEE1284_MODE_EPPSL:
                case IEEE1284_MODE_EPPSWE:
-                       return (cpp_daisy (port, 0x20 + daisy) &
-                               PARPORT_STATUS_ERROR);
+                       return !(cpp_daisy (port, 0x20 + daisy) &
+                                PARPORT_STATUS_ERROR);
 
                // For these modes we should switch to ECP mode:
                case IEEE1284_MODE_ECP:
                case IEEE1284_MODE_ECPRLE:
                case IEEE1284_MODE_ECPSWE: 
-                       return (cpp_daisy (port, 0xd0 + daisy) &
-                               PARPORT_STATUS_ERROR);
+                       return !(cpp_daisy (port, 0xd0 + daisy) &
+                                PARPORT_STATUS_ERROR);
 
                // Nothing was told for BECP in Daisy chain specification.
                // May be it's wise to use ECP?
@@ -461,8 +413,8 @@ int parport_daisy_select (struct parport *port, int daisy, int mode)
                case IEEE1284_MODE_BYTE:
                case IEEE1284_MODE_COMPAT:
                default:
-                       return (cpp_daisy (port, 0xe0 + daisy) &
-                               PARPORT_STATUS_ERROR);
+                       return !(cpp_daisy (port, 0xe0 + daisy) &
+                                PARPORT_STATUS_ERROR);
        }
 }
 
@@ -484,7 +436,7 @@ static int select_port (struct parport *port)
 
 static int assign_addrs (struct parport *port)
 {
-       unsigned char s, last_dev;
+       unsigned char s;
        unsigned char daisy;
        int thisdev = numdevs;
        int detected;
@@ -520,10 +472,13 @@ static int assign_addrs (struct parport *port)
        }
 
        parport_write_data (port, 0x78); udelay (2);
-       last_dev = 0; /* We've just been speaking to a device, so we
-                        know there must be at least _one_ out there. */
+       s = parport_read_status (port);
 
-       for (daisy = 0; daisy < 4; daisy++) {
+       for (daisy = 0;
+            (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT))
+                    == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)
+                    && daisy < 4;
+            ++daisy) {
                parport_write_data (port, daisy);
                udelay (2);
                parport_frob_control (port,
@@ -533,14 +488,18 @@ static int assign_addrs (struct parport *port)
                parport_frob_control (port, PARPORT_CONTROL_STROBE, 0);
                udelay (1);
 
-               if (last_dev)
-                       /* No more devices. */
-                       break;
+               add_dev (numdevs++, port, daisy);
 
-               last_dev = !(parport_read_status (port)
-                            & PARPORT_STATUS_BUSY);
+               /* See if this device thought it was the last in the
+                * chain. */
+               if (!(s & PARPORT_STATUS_BUSY))
+                       break;
 
-               add_dev (numdevs++, port, daisy);
+               /* We are seeing pass through status now. We see
+                  last_dev from next device or if last_dev does not
+                  work status lines from some non-daisy chain
+                  device. */
+               s = parport_read_status (port);
        }
 
        parport_write_data (port, 0xff); udelay (2);
@@ -549,117 +508,12 @@ static int assign_addrs (struct parport *port)
                 detected);
 
        /* Ask the new devices to introduce themselves. */
-       deviceid = kmalloc (1000, GFP_KERNEL);
+       deviceid = kmalloc (1024, GFP_KERNEL);
        if (!deviceid) return 0;
 
        for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
-               parport_device_id (thisdev, deviceid, 1000);
+               parport_device_id (thisdev, deviceid, 1024);
 
        kfree (deviceid);
        return detected;
 }
-
-/* Find a device with a particular manufacturer and model string,
-   starting from a given device number.  Like the PCI equivalent,
-   'from' itself is skipped. */
-
-/**
- *     parport_find_device - find a specific device
- *     @mfg: required manufacturer string
- *     @mdl: required model string
- *     @from: previous device number found in search, or %NULL for
- *            new search
- *
- *     This walks through the list of parallel port devices looking
- *     for a device whose 'MFG' string matches @mfg and whose 'MDL'
- *     string matches @mdl in their IEEE 1284 Device ID.
- *
- *     When a device is found matching those requirements, its device
- *     number is returned; if there is no matching device, a negative
- *     value is returned.
- *
- *     A new search it initiated by passing %NULL as the @from
- *     argument.  If @from is not %NULL, the search continues from
- *     that device.
- **/
-
-int parport_find_device (const char *mfg, const char *mdl, int from)
-{
-       struct daisydev *d;
-       int res = -1;
-
-       /* Find where to start. */
-
-       spin_lock(&topology_lock);
-       d = topology; /* sorted by devnum */
-       while (d && d->devnum <= from)
-               d = d->next;
-
-       /* Search. */
-       while (d) {
-               struct parport_device_info *info;
-               info = &d->port->probe_info[1 + d->daisy];
-               if ((!mfg || !strcmp (mfg, info->mfr)) &&
-                   (!mdl || !strcmp (mdl, info->model)))
-                       break;
-
-               d = d->next;
-       }
-
-       if (d)
-               res = d->devnum;
-
-       spin_unlock(&topology_lock);
-       return res;
-}
-
-/**
- *     parport_find_class - find a device in a specified class
- *     @cls: required class
- *     @from: previous device number found in search, or %NULL for
- *            new search
- *
- *     This walks through the list of parallel port devices looking
- *     for a device whose 'CLS' string matches @cls in their IEEE
- *     1284 Device ID.
- *
- *     When a device is found matching those requirements, its device
- *     number is returned; if there is no matching device, a negative
- *     value is returned.
- *
- *     A new search it initiated by passing %NULL as the @from
- *     argument.  If @from is not %NULL, the search continues from
- *     that device.
- **/
-
-int parport_find_class (parport_device_class cls, int from)
-{
-       struct daisydev *d;
-       int res = -1;
-
-       spin_lock(&topology_lock);
-       d = topology; /* sorted by devnum */
-       /* Find where to start. */
-       while (d && d->devnum <= from)
-               d = d->next;
-
-       /* Search. */
-       while (d && d->port->probe_info[1 + d->daisy].class != cls)
-               d = d->next;
-
-       if (d)
-               res = d->devnum;
-
-       spin_unlock(&topology_lock);
-       return res;
-}
-
-EXPORT_SYMBOL(parport_open);
-EXPORT_SYMBOL(parport_close);
-EXPORT_SYMBOL(parport_device_num);
-EXPORT_SYMBOL(parport_device_coords);
-EXPORT_SYMBOL(parport_daisy_deselect_all);
-EXPORT_SYMBOL(parport_daisy_select);
-EXPORT_SYMBOL(parport_daisy_init);
-EXPORT_SYMBOL(parport_find_device);
-EXPORT_SYMBOL(parport_find_class);