root/drivers/parport/daisy.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. add_dev
  2. clone_parport
  3. parport_daisy_init
  4. parport_daisy_fini
  5. parport_open
  6. parport_close
  7. cpp_daisy
  8. cpp_mux
  9. parport_daisy_deselect_all
  10. parport_daisy_select
  11. mux_present
  12. num_mux_ports
  13. select_port
  14. assign_addrs

   1 /*
   2  * IEEE 1284.3 Parallel port daisy chain and multiplexor code
   3  * 
   4  * Copyright (C) 1999, 2000  Tim Waugh <tim@cyberelk.demon.co.uk>
   5  *
   6  * This program is free software; you can redistribute it and/or
   7  * modify it under the terms of the GNU General Public License
   8  * as published by the Free Software Foundation; either version
   9  * 2 of the License, or (at your option) any later version.
  10  *
  11  * ??-12-1998: Initial implementation.
  12  * 31-01-1999: Make port-cloning transparent.
  13  * 13-02-1999: Move DeviceID technique from parport_probe.
  14  * 13-03-1999: Get DeviceID from non-IEEE 1284.3 devices too.
  15  * 22-02-2000: Count devices that are actually detected.
  16  *
  17  * Any part of this program may be used in documents licensed under
  18  * the GNU Free Documentation License, Version 1.1 or any later version
  19  * published by the Free Software Foundation.
  20  */
  21 
  22 #include <linux/module.h>
  23 #include <linux/parport.h>
  24 #include <linux/delay.h>
  25 #include <linux/slab.h>
  26 #include <linux/sched/signal.h>
  27 
  28 #include <asm/current.h>
  29 #include <linux/uaccess.h>
  30 
  31 #undef DEBUG
  32 
  33 #ifdef DEBUG
  34 #define DPRINTK(stuff...) printk(stuff)
  35 #else
  36 #define DPRINTK(stuff...)
  37 #endif
  38 
  39 static struct daisydev {
  40         struct daisydev *next;
  41         struct parport *port;
  42         int daisy;
  43         int devnum;
  44 } *topology = NULL;
  45 static DEFINE_SPINLOCK(topology_lock);
  46 
  47 static int numdevs;
  48 
  49 /* Forward-declaration of lower-level functions. */
  50 static int mux_present(struct parport *port);
  51 static int num_mux_ports(struct parport *port);
  52 static int select_port(struct parport *port);
  53 static int assign_addrs(struct parport *port);
  54 
  55 /* Add a device to the discovered topology. */
  56 static void add_dev(int devnum, struct parport *port, int daisy)
  57 {
  58         struct daisydev *newdev, **p;
  59         newdev = kmalloc(sizeof(struct daisydev), GFP_KERNEL);
  60         if (newdev) {
  61                 newdev->port = port;
  62                 newdev->daisy = daisy;
  63                 newdev->devnum = devnum;
  64                 spin_lock(&topology_lock);
  65                 for (p = &topology; *p && (*p)->devnum<devnum; p = &(*p)->next)
  66                         ;
  67                 newdev->next = *p;
  68                 *p = newdev;
  69                 spin_unlock(&topology_lock);
  70         }
  71 }
  72 
  73 /* Clone a parport (actually, make an alias). */
  74 static struct parport *clone_parport(struct parport *real, int muxport)
  75 {
  76         struct parport *extra = parport_register_port(real->base,
  77                                                        real->irq,
  78                                                        real->dma,
  79                                                        real->ops);
  80         if (extra) {
  81                 extra->portnum = real->portnum;
  82                 extra->physport = real;
  83                 extra->muxport = muxport;
  84                 real->slaves[muxport-1] = extra;
  85         }
  86 
  87         return extra;
  88 }
  89 
  90 /* Discover the IEEE1284.3 topology on a port -- muxes and daisy chains.
  91  * Return value is number of devices actually detected. */
  92 int parport_daisy_init(struct parport *port)
  93 {
  94         int detected = 0;
  95         char *deviceid;
  96         static const char *th[] = { /*0*/"th", "st", "nd", "rd", "th" };
  97         int num_ports;
  98         int i;
  99         int last_try = 0;
 100 
 101 again:
 102         /* Because this is called before any other devices exist,
 103          * we don't have to claim exclusive access.  */
 104 
 105         /* If mux present on normal port, need to create new
 106          * parports for each extra port. */
 107         if (port->muxport < 0 && mux_present(port) &&
 108             /* don't be fooled: a mux must have 2 or 4 ports. */
 109             ((num_ports = num_mux_ports(port)) == 2 || num_ports == 4)) {
 110                 /* Leave original as port zero. */
 111                 port->muxport = 0;
 112                 printk(KERN_INFO
 113                         "%s: 1st (default) port of %d-way multiplexor\n",
 114                         port->name, num_ports);
 115                 for (i = 1; i < num_ports; i++) {
 116                         /* Clone the port. */
 117                         struct parport *extra = clone_parport(port, i);
 118                         if (!extra) {
 119                                 if (signal_pending(current))
 120                                         break;
 121 
 122                                 schedule();
 123                                 continue;
 124                         }
 125 
 126                         printk(KERN_INFO
 127                                 "%s: %d%s port of %d-way multiplexor on %s\n",
 128                                 extra->name, i + 1, th[i + 1], num_ports,
 129                                 port->name);
 130 
 131                         /* Analyse that port too.  We won't recurse
 132                            forever because of the 'port->muxport < 0'
 133                            test above. */
 134                         parport_daisy_init(extra);
 135                 }
 136         }
 137 
 138         if (port->muxport >= 0)
 139                 select_port(port);
 140 
 141         parport_daisy_deselect_all(port);
 142         detected += assign_addrs(port);
 143 
 144         /* Count the potential legacy device at the end. */
 145         add_dev(numdevs++, port, -1);
 146 
 147         /* Find out the legacy device's IEEE 1284 device ID. */
 148         deviceid = kmalloc(1024, GFP_KERNEL);
 149         if (deviceid) {
 150                 if (parport_device_id(numdevs - 1, deviceid, 1024) > 2)
 151                         detected++;
 152 
 153                 kfree(deviceid);
 154         }
 155 
 156         if (!detected && !last_try) {
 157                 /* No devices were detected.  Perhaps they are in some
 158                    funny state; let's try to reset them and see if
 159                    they wake up. */
 160                 parport_daisy_fini(port);
 161                 parport_write_control(port, PARPORT_CONTROL_SELECT);
 162                 udelay(50);
 163                 parport_write_control(port,
 164                                        PARPORT_CONTROL_SELECT |
 165                                        PARPORT_CONTROL_INIT);
 166                 udelay(50);
 167                 last_try = 1;
 168                 goto again;
 169         }
 170 
 171         return detected;
 172 }
 173 
 174 /* Forget about devices on a physical port. */
 175 void parport_daisy_fini(struct parport *port)
 176 {
 177         struct daisydev **p;
 178 
 179         spin_lock(&topology_lock);
 180         p = &topology;
 181         while (*p) {
 182                 struct daisydev *dev = *p;
 183                 if (dev->port != port) {
 184                         p = &dev->next;
 185                         continue;
 186                 }
 187                 *p = dev->next;
 188                 kfree(dev);
 189         }
 190 
 191         /* Gaps in the numbering could be handled better.  How should
 192            someone enumerate through all IEEE1284.3 devices in the
 193            topology?. */
 194         if (!topology) numdevs = 0;
 195         spin_unlock(&topology_lock);
 196         return;
 197 }
 198 
 199 /**
 200  *      parport_open - find a device by canonical device number
 201  *      @devnum: canonical device number
 202  *      @name: name to associate with the device
 203  *
 204  *      This function is similar to parport_register_device(), except
 205  *      that it locates a device by its number rather than by the port
 206  *      it is attached to.
 207  *
 208  *      All parameters except for @devnum are the same as for
 209  *      parport_register_device().  The return value is the same as
 210  *      for parport_register_device().
 211  **/
 212 
 213 struct pardevice *parport_open(int devnum, const char *name)
 214 {
 215         struct daisydev *p = topology;
 216         struct parport *port;
 217         struct pardevice *dev;
 218         int daisy;
 219 
 220         spin_lock(&topology_lock);
 221         while (p && p->devnum != devnum)
 222                 p = p->next;
 223 
 224         if (!p) {
 225                 spin_unlock(&topology_lock);
 226                 return NULL;
 227         }
 228 
 229         daisy = p->daisy;
 230         port = parport_get_port(p->port);
 231         spin_unlock(&topology_lock);
 232 
 233         dev = parport_register_device(port, name, NULL, NULL, NULL, 0, NULL);
 234         parport_put_port(port);
 235         if (!dev)
 236                 return NULL;
 237 
 238         dev->daisy = daisy;
 239 
 240         /* Check that there really is a device to select. */
 241         if (daisy >= 0) {
 242                 int selected;
 243                 parport_claim_or_block(dev);
 244                 selected = port->daisy;
 245                 parport_release(dev);
 246 
 247                 if (selected != daisy) {
 248                         /* No corresponding device. */
 249                         parport_unregister_device(dev);
 250                         return NULL;
 251                 }
 252         }
 253 
 254         return dev;
 255 }
 256 
 257 /**
 258  *      parport_close - close a device opened with parport_open()
 259  *      @dev: device to close
 260  *
 261  *      This is to parport_open() as parport_unregister_device() is to
 262  *      parport_register_device().
 263  **/
 264 
 265 void parport_close(struct pardevice *dev)
 266 {
 267         parport_unregister_device(dev);
 268 }
 269 
 270 /* Send a daisy-chain-style CPP command packet. */
 271 static int cpp_daisy(struct parport *port, int cmd)
 272 {
 273         unsigned char s;
 274 
 275         parport_data_forward(port);
 276         parport_write_data(port, 0xaa); udelay(2);
 277         parport_write_data(port, 0x55); udelay(2);
 278         parport_write_data(port, 0x00); udelay(2);
 279         parport_write_data(port, 0xff); udelay(2);
 280         s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 281                                           | PARPORT_STATUS_PAPEROUT
 282                                           | PARPORT_STATUS_SELECT
 283                                           | PARPORT_STATUS_ERROR);
 284         if (s != (PARPORT_STATUS_BUSY
 285                   | PARPORT_STATUS_PAPEROUT
 286                   | PARPORT_STATUS_SELECT
 287                   | PARPORT_STATUS_ERROR)) {
 288                 DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff(%02x)\n",
 289                          port->name, s);
 290                 return -ENXIO;
 291         }
 292 
 293         parport_write_data(port, 0x87); udelay(2);
 294         s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 295                                           | PARPORT_STATUS_PAPEROUT
 296                                           | PARPORT_STATUS_SELECT
 297                                           | PARPORT_STATUS_ERROR);
 298         if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
 299                 DPRINTK(KERN_DEBUG "%s: cpp_daisy: aa5500ff87(%02x)\n",
 300                          port->name, s);
 301                 return -ENXIO;
 302         }
 303 
 304         parport_write_data(port, 0x78); udelay(2);
 305         parport_write_data(port, cmd); udelay(2);
 306         parport_frob_control(port,
 307                               PARPORT_CONTROL_STROBE,
 308                               PARPORT_CONTROL_STROBE);
 309         udelay(1);
 310         s = parport_read_status(port);
 311         parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
 312         udelay(1);
 313         parport_write_data(port, 0xff); udelay(2);
 314 
 315         return s;
 316 }
 317 
 318 /* Send a mux-style CPP command packet. */
 319 static int cpp_mux(struct parport *port, int cmd)
 320 {
 321         unsigned char s;
 322         int rc;
 323 
 324         parport_data_forward(port);
 325         parport_write_data(port, 0xaa); udelay(2);
 326         parport_write_data(port, 0x55); udelay(2);
 327         parport_write_data(port, 0xf0); udelay(2);
 328         parport_write_data(port, 0x0f); udelay(2);
 329         parport_write_data(port, 0x52); udelay(2);
 330         parport_write_data(port, 0xad); udelay(2);
 331         parport_write_data(port, cmd); udelay(2);
 332 
 333         s = parport_read_status(port);
 334         if (!(s & PARPORT_STATUS_ACK)) {
 335                 DPRINTK(KERN_DEBUG "%s: cpp_mux: aa55f00f52ad%02x(%02x)\n",
 336                          port->name, cmd, s);
 337                 return -EIO;
 338         }
 339 
 340         rc = (((s & PARPORT_STATUS_SELECT   ? 1 : 0) << 0) |
 341               ((s & PARPORT_STATUS_PAPEROUT ? 1 : 0) << 1) |
 342               ((s & PARPORT_STATUS_BUSY     ? 0 : 1) << 2) |
 343               ((s & PARPORT_STATUS_ERROR    ? 0 : 1) << 3));
 344 
 345         return rc;
 346 }
 347 
 348 void parport_daisy_deselect_all(struct parport *port)
 349 {
 350         cpp_daisy(port, 0x30);
 351 }
 352 
 353 int parport_daisy_select(struct parport *port, int daisy, int mode)
 354 {
 355         switch (mode)
 356         {
 357                 // For these modes we should switch to EPP mode:
 358                 case IEEE1284_MODE_EPP:
 359                 case IEEE1284_MODE_EPPSL:
 360                 case IEEE1284_MODE_EPPSWE:
 361                         return !(cpp_daisy(port, 0x20 + daisy) &
 362                                  PARPORT_STATUS_ERROR);
 363 
 364                 // For these modes we should switch to ECP mode:
 365                 case IEEE1284_MODE_ECP:
 366                 case IEEE1284_MODE_ECPRLE:
 367                 case IEEE1284_MODE_ECPSWE: 
 368                         return !(cpp_daisy(port, 0xd0 + daisy) &
 369                                  PARPORT_STATUS_ERROR);
 370 
 371                 // Nothing was told for BECP in Daisy chain specification.
 372                 // May be it's wise to use ECP?
 373                 case IEEE1284_MODE_BECP:
 374                 // Others use compat mode
 375                 case IEEE1284_MODE_NIBBLE:
 376                 case IEEE1284_MODE_BYTE:
 377                 case IEEE1284_MODE_COMPAT:
 378                 default:
 379                         return !(cpp_daisy(port, 0xe0 + daisy) &
 380                                  PARPORT_STATUS_ERROR);
 381         }
 382 }
 383 
 384 static int mux_present(struct parport *port)
 385 {
 386         return cpp_mux(port, 0x51) == 3;
 387 }
 388 
 389 static int num_mux_ports(struct parport *port)
 390 {
 391         return cpp_mux(port, 0x58);
 392 }
 393 
 394 static int select_port(struct parport *port)
 395 {
 396         int muxport = port->muxport;
 397         return cpp_mux(port, 0x60 + muxport) == muxport;
 398 }
 399 
 400 static int assign_addrs(struct parport *port)
 401 {
 402         unsigned char s;
 403         unsigned char daisy;
 404         int thisdev = numdevs;
 405         int detected;
 406         char *deviceid;
 407 
 408         parport_data_forward(port);
 409         parport_write_data(port, 0xaa); udelay(2);
 410         parport_write_data(port, 0x55); udelay(2);
 411         parport_write_data(port, 0x00); udelay(2);
 412         parport_write_data(port, 0xff); udelay(2);
 413         s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 414                                           | PARPORT_STATUS_PAPEROUT
 415                                           | PARPORT_STATUS_SELECT
 416                                           | PARPORT_STATUS_ERROR);
 417         if (s != (PARPORT_STATUS_BUSY
 418                   | PARPORT_STATUS_PAPEROUT
 419                   | PARPORT_STATUS_SELECT
 420                   | PARPORT_STATUS_ERROR)) {
 421                 DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff(%02x)\n",
 422                          port->name, s);
 423                 return 0;
 424         }
 425 
 426         parport_write_data(port, 0x87); udelay(2);
 427         s = parport_read_status(port) & (PARPORT_STATUS_BUSY
 428                                           | PARPORT_STATUS_PAPEROUT
 429                                           | PARPORT_STATUS_SELECT
 430                                           | PARPORT_STATUS_ERROR);
 431         if (s != (PARPORT_STATUS_SELECT | PARPORT_STATUS_ERROR)) {
 432                 DPRINTK(KERN_DEBUG "%s: assign_addrs: aa5500ff87(%02x)\n",
 433                          port->name, s);
 434                 return 0;
 435         }
 436 
 437         parport_write_data(port, 0x78); udelay(2);
 438         s = parport_read_status(port);
 439 
 440         for (daisy = 0;
 441              (s & (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT))
 442                      == (PARPORT_STATUS_PAPEROUT|PARPORT_STATUS_SELECT)
 443                      && daisy < 4;
 444              ++daisy) {
 445                 parport_write_data(port, daisy);
 446                 udelay(2);
 447                 parport_frob_control(port,
 448                                       PARPORT_CONTROL_STROBE,
 449                                       PARPORT_CONTROL_STROBE);
 450                 udelay(1);
 451                 parport_frob_control(port, PARPORT_CONTROL_STROBE, 0);
 452                 udelay(1);
 453 
 454                 add_dev(numdevs++, port, daisy);
 455 
 456                 /* See if this device thought it was the last in the
 457                  * chain. */
 458                 if (!(s & PARPORT_STATUS_BUSY))
 459                         break;
 460 
 461                 /* We are seeing pass through status now. We see
 462                    last_dev from next device or if last_dev does not
 463                    work status lines from some non-daisy chain
 464                    device. */
 465                 s = parport_read_status(port);
 466         }
 467 
 468         parport_write_data(port, 0xff); udelay(2);
 469         detected = numdevs - thisdev;
 470         DPRINTK(KERN_DEBUG "%s: Found %d daisy-chained devices\n", port->name,
 471                  detected);
 472 
 473         /* Ask the new devices to introduce themselves. */
 474         deviceid = kmalloc(1024, GFP_KERNEL);
 475         if (!deviceid) return 0;
 476 
 477         for (daisy = 0; thisdev < numdevs; thisdev++, daisy++)
 478                 parport_device_id(thisdev, deviceid, 1024);
 479 
 480         kfree(deviceid);
 481         return detected;
 482 }

/* [<][>][^][v][top][bottom][index][help] */