root/drivers/net/plip.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. plip_init
  2. plip_kick_bh
  3. plip_bh
  4. plip_tx_packet
  5. plip_open
  6. plip_close
  7. plip_get_stats
  8. plip_rebuild_header
  9. plip_device_clear
  10. plip_error
  11. plip_receive
  12. plip_receive_packet
  13. plip_interrupt
  14. plip_send
  15. plip_send_packet
  16. plip_config
  17. plip_ioctl
  18. init_module
  19. cleanup_module

   1 /* $Id: plip.c,v 1.7 1994/12/16 06:20:02 gniibe Exp $ */
   2 /* plip.c: A parallel port "network" driver for linux. */
   3 /* This driver is for parallel port with 5-bit cable (LapLink (R) cable). */
   4 /*
   5  * Authors:     Donald Becker,  <becker@super.org>
   6  *              Tommy Thorn, <thorn@daimi.aau.dk>
   7  *              Tanabe Hiroyasu, <hiro@sanpo.t.u-tokyo.ac.jp>
   8  *              Alan Cox, <gw4pts@gw4pts.ampr.org>
   9  *              Peter Bauer, <100136.3530@compuserve.com>
  10  *              Niibe Yutaka, <gniibe@mri.co.jp>
  11  *
  12  *              This is the all improved state based PLIP that Niibe Yutaka has contributed.
  13  *
  14  *              Modularization by Alan Cox. I also added the plipconfig program to tune the timeouts
  15  *              and ifmap support for funny serial port settings or setting odd values using the 
  16  *              modular plip. I also took the panic() calls out. I don't like panic - especially when
  17  *              it can be avoided.
  18  *
  19  *              This program is free software; you can redistribute it and/or
  20  *              modify it under the terms of the GNU General Public License
  21  *              as published by the Free Software Foundation; either version
  22  *              2 of the License, or (at your option) any later version.
  23  */
  24 
  25 /*
  26  * Original version and the name 'PLIP' from Donald Becker <becker@super.org>
  27  * inspired by Russ Nelson's parallel port packet driver.
  28  */
  29 
  30 static char *version =
  31     "NET3 "
  32 #ifdef MODULE
  33     "MODULAR "    
  34 #endif    
  35     "PLIP $Revision: 1.7 $ gniibe@mri.co.jp\n";
  36 
  37 #include <linux/config.h>
  38 
  39 /*
  40   Sources:
  41         Ideas and protocols came from Russ Nelson's <nelson@crynwr.com>
  42         "parallel.asm" parallel port packet driver.
  43 
  44   The "Crynwr" parallel port standard specifies the following protocol:
  45    send header nibble '8'
  46    count-low octet
  47    count-high octet
  48    ... data octets
  49    checksum octet
  50   Each octet is sent as <wait for rx. '0x1?'> <send 0x10+(octet&0x0F)>
  51                         <wait for rx. '0x0?'> <send 0x00+((octet>>4)&0x0F)>
  52 
  53 The cable used is a de facto standard parallel null cable -- sold as
  54 a "LapLink" cable by various places.  You'll need a 10-conductor cable to
  55 make one yourself.  The wiring is:
  56     SLCTIN      17 - 17
  57     GROUND      25 - 25
  58     D0->ERROR   2 - 15          15 - 2
  59     D1->SLCT    3 - 13          13 - 3
  60     D2->PAPOUT  4 - 12          12 - 4
  61     D3->ACK     5 - 10          10 - 5
  62     D4->BUSY    6 - 11          11 - 6
  63   Do not connect the other pins.  They are
  64     D5,D6,D7 are 7,8,9
  65     STROBE is 1, FEED is 14, INIT is 16
  66     extra grounds are 18,19,20,21,22,23,24
  67 */
  68 
  69 #include <linux/kernel.h>
  70 #include <linux/sched.h>
  71 #include <linux/types.h>
  72 #include <linux/fcntl.h>
  73 #include <linux/interrupt.h>
  74 #include <linux/string.h>
  75 #include <linux/ptrace.h>
  76 #include <linux/if_ether.h>
  77 #include <asm/system.h>
  78 #include <asm/io.h>
  79 #include <linux/in.h>
  80 #include <linux/errno.h>
  81 #include <linux/delay.h>
  82 #include <linux/lp.h>
  83 
  84 #include <linux/netdevice.h>
  85 #include <linux/etherdevice.h>
  86 #include <linux/skbuff.h>
  87 #include <linux/if_plip.h>
  88 
  89 #include <linux/tqueue.h>
  90 #include <linux/ioport.h>
  91 #include <asm/bitops.h>
  92 #include <asm/irq.h>
  93 
  94 #ifdef MODULE
  95 #include <linux/module.h>
  96 #include <linux/version.h>
  97 #endif
  98 
  99 /* use 0 for production, 1 for verification, >2 for debug */
 100 #ifndef NET_DEBUG
 101 #define NET_DEBUG 3
 102 #endif
 103 static unsigned int net_debug = NET_DEBUG;
 104 
 105 /* In micro second */
 106 #define PLIP_DELAY_UNIT            1
 107 
 108 /* Connection time out = PLIP_TRIGGER_WAIT * PLIP_DELAY_UNIT usec */
 109 #define PLIP_TRIGGER_WAIT        500
 110 
 111 /* Nibble time out = PLIP_NIBBLE_WAIT * PLIP_DELAY_UNIT usec */
 112 #define PLIP_NIBBLE_WAIT        5000
 113 
 114 #define PAR_DATA(dev)           ((dev)->base_addr+0)
 115 #define PAR_STATUS(dev)         ((dev)->base_addr+1)
 116 #define PAR_CONTROL(dev)        ((dev)->base_addr+2)
 117 
 118 /* Index to functions, as function prototypes. */
 119 static int plip_tx_packet(struct sk_buff *skb, struct device *dev);
 120 static int plip_open(struct device *dev);
 121 static int plip_close(struct device *dev);
 122 static struct enet_statistics *plip_get_stats(struct device *dev);
 123 static int plip_rebuild_header(void *buff, struct device *dev,
 124                                unsigned long raddr, struct sk_buff *skb);
 125 static void plip_kick_bh(struct device *dev);
 126 static void plip_bh(struct device *dev);
 127 
 128 enum plip_connection_state {
 129     PLIP_CN_NONE=0,
 130     PLIP_CN_RECEIVE,
 131     PLIP_CN_SEND,
 132     PLIP_CN_CLOSING,
 133     PLIP_CN_ERROR
 134 };
 135 
 136 enum plip_packet_state {
 137     PLIP_PK_DONE=0,
 138     PLIP_PK_TRIGGER,
 139     PLIP_PK_LENGTH_LSB,
 140     PLIP_PK_LENGTH_MSB,
 141     PLIP_PK_DATA,
 142     PLIP_PK_CHECKSUM
 143 };
 144 
 145 enum plip_nibble_state {
 146     PLIP_NB_BEGIN,
 147     PLIP_NB_1,
 148     PLIP_NB_2,
 149 };
 150 
 151 #define PLIP_STATE_STRING(x) \
 152     (((x) == PLIP_PK_DONE)?"0":\
 153      ((x) == PLIP_PK_TRIGGER)?"t":\
 154      ((x) == PLIP_PK_LENGTH_LSB)?"l":\
 155      ((x) == PLIP_PK_LENGTH_MSB)?"m":\
 156      ((x) == PLIP_PK_DATA)?"d":\
 157      ((x) == PLIP_PK_CHECKSUM)?"s":"B")
 158 
 159 struct plip_local {
 160     enum plip_packet_state state;
 161     enum plip_nibble_state nibble;
 162     unsigned short length;
 163     unsigned short byte;
 164     unsigned char  checksum;
 165     unsigned char  data;
 166     struct sk_buff *skb;
 167 };
 168 
 169 struct net_local {
 170     struct enet_statistics e;
 171     struct tq_struct immediate;
 172     struct tq_struct deferred;
 173     struct plip_local snd_data;
 174     struct plip_local rcv_data;
 175     unsigned long  trigger_us;
 176     unsigned long  nibble_us;
 177     unsigned long  unit_us;
 178     enum plip_connection_state connection;
 179     unsigned short timeout_count;
 180 };
 181 
 182 /* Routines used internally. */
 183 static void plip_device_clear(struct device *dev);
 184 static void plip_interrupt(int reg_ptr);
 185 
 186 static int plip_error(struct device *dev);
 187 static int plip_receive_packet(struct device *dev);
 188 static int plip_send_packet(struct device *dev);
 189 static int plip_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
 190 static int plip_config(struct device *dev, struct ifmap *map);
 191 
 192 int
 193 plip_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195     struct net_local *nl;
 196 
 197     /* Check that there is something at base_addr. */
 198     outb(LP_PINITP, PAR_CONTROL(dev));
 199     outb(0x00, PAR_DATA(dev));
 200     if (inb(PAR_DATA(dev)) != 0x00)
 201         return -ENODEV;
 202 
 203     /* Alpha testers must have the version number to report bugs. */
 204     if (net_debug)
 205         printk(version);
 206 
 207     if (dev->irq) {
 208         printk("%s: configured for parallel port at %#3x, IRQ %d.\n",
 209                dev->name, dev->base_addr, dev->irq);
 210     } else {
 211         printk("%s: configured for parallel port at %#3x",
 212                dev->name, dev->base_addr);
 213 #ifdef MODULE
 214         /* autoirq doesn't work :(, but we can set it by ifconfig */
 215 #else
 216         autoirq_setup(0);
 217         outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 218         outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 219         outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 220         dev->irq = autoirq_report(1);
 221 #endif
 222         if (dev->irq)
 223             printk(", probed IRQ %d.\n", dev->irq);
 224         else {
 225             printk(", failed to detect IRQ line.\n");
 226             return -ENODEV;
 227         }
 228     }
 229 
 230     snarf_region(PAR_DATA(dev), 3);
 231 
 232     /* Fill in the generic fields of the device structure. */
 233     ether_setup(dev);
 234 
 235     /* And, override parts of it */
 236     dev->rebuild_header         = plip_rebuild_header;
 237     dev->hard_start_xmit        = plip_tx_packet;
 238     dev->open                   = plip_open;
 239     dev->stop                   = plip_close;
 240     dev->get_stats              = plip_get_stats;
 241     dev->set_config             = plip_config;
 242     dev->do_ioctl               = plip_ioctl;
 243     dev->flags                  = IFF_POINTOPOINT;
 244 
 245     /* Set private structure */
 246     dev->priv = kmalloc(sizeof (struct net_local), GFP_KERNEL);
 247     memset(dev->priv, 0, sizeof(struct net_local));
 248     nl = (struct net_local *) dev->priv;
 249     
 250     /* initialize constants */
 251     nl->trigger_us      = PLIP_TRIGGER_WAIT;
 252     nl->nibble_us       = PLIP_NIBBLE_WAIT;
 253     nl->unit_us         = PLIP_DELAY_UNIT;
 254 
 255     /* initialize task queue structures */
 256     nl->immediate.next = &tq_last;
 257     nl->immediate.sync = 0;
 258     nl->immediate.routine = (void *)(void *)plip_bh;
 259     nl->immediate.data = dev;
 260 
 261     nl->deferred.next = &tq_last;
 262     nl->deferred.sync = 0;
 263     nl->deferred.routine = (void *)(void *)plip_kick_bh;
 264     nl->deferred.data = dev;
 265 
 266     return 0;
 267 }
 268 
 269 static void
 270 plip_kick_bh(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 271 {
 272     struct net_local *nl = (struct net_local *)dev->priv;
 273 
 274     if (nl->connection == PLIP_CN_NONE)
 275         return;
 276     queue_task(&nl->immediate, &tq_immediate);
 277     mark_bh(IMMEDIATE_BH);
 278     return;
 279 }
 280 
 281 static void
 282 plip_bh(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 283 {
 284     struct net_local *nl = (struct net_local *)dev->priv;
 285     struct enet_statistics *stats = (struct enet_statistics *) dev->priv;
 286     struct plip_local *rcv = &nl->rcv_data;
 287     struct plip_local *snd = &nl->snd_data;
 288     int result, timeout=0;
 289     unsigned char *s;
 290     unsigned char c0;
 291     struct sk_buff *skb;
 292 
 293     while (!timeout) {
 294         cli();
 295         switch (nl->connection) {
 296         case PLIP_CN_NONE:
 297             sti();
 298             return;
 299 
 300         case PLIP_CN_RECEIVE:
 301             sti();
 302             disable_irq(dev->irq);
 303             outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 304             outb(0x01, PAR_DATA(dev));   /* send ACK */
 305             dev->interrupt = 0;
 306             result = plip_receive_packet(dev);
 307             if (result == 0) { /* success */
 308                 outb (0x00, PAR_DATA(dev));
 309                 skb = rcv->skb;
 310                 rcv->skb = NULL;
 311                 stats->rx_packets++;
 312                 netif_rx(skb);
 313                 if (snd->state != PLIP_PK_DONE) {
 314                     nl->connection = PLIP_CN_SEND;
 315                     outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 316                     enable_irq(dev->irq);
 317                 } else {
 318                     nl->connection = PLIP_CN_NONE;
 319                     outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 320                     enable_irq(dev->irq);
 321                     return;
 322                 }
 323             } else if (result == -1) { /* failure */
 324                 outb(0x00, PAR_DATA(dev));
 325                 if (rcv->skb)
 326                     dev_kfree_skb(rcv->skb, FREE_WRITE);
 327                 rcv->state = PLIP_PK_DONE;
 328                 rcv->skb = NULL;
 329                 if (snd->skb)
 330                     dev_kfree_skb(snd->skb, FREE_WRITE);
 331                 snd->state = PLIP_PK_DONE;
 332                 snd->skb = NULL;
 333                 dev->tbusy = 1;
 334                 nl->connection = PLIP_CN_ERROR;
 335             } else
 336                 timeout = 1;
 337             break;
 338 
 339         case PLIP_CN_SEND:
 340             sti();
 341             result = plip_send_packet(dev);
 342             if (result == -1) /* interrupted */
 343                 break;
 344             if (result == 0) { /* success */
 345                 outb (0x00, PAR_DATA(dev));
 346                 snd->state = PLIP_PK_DONE;
 347                 snd->skb = NULL;
 348                 nl->connection = PLIP_CN_CLOSING;
 349                 queue_task(&nl->deferred, &tq_timer);
 350                 outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 351                 enable_irq(dev->irq);
 352                 return;
 353             } else
 354                 timeout = 1;
 355             break;
 356 
 357         case PLIP_CN_CLOSING:
 358             sti();
 359             nl->connection = PLIP_CN_NONE;
 360             mark_bh(NET_BH);
 361             dev->tbusy = 0;
 362             return;
 363 
 364         case PLIP_CN_ERROR:
 365             sti();
 366             result = plip_error(dev);
 367             if (result == 0) {
 368                 nl->connection = PLIP_CN_NONE;
 369                 dev->tbusy = 0;
 370                 outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 371                 enable_irq(dev->irq);
 372                 return;
 373             } else {
 374                 queue_task(&nl->deferred, &tq_timer);
 375                 return;
 376             }
 377             break;
 378         }
 379     }
 380 
 381     /* timeout */
 382     if (++nl->timeout_count > 3) { /* cable problem? */
 383         c0 = inb(PAR_STATUS(dev));
 384 
 385         if (nl->connection == PLIP_CN_SEND) {
 386             stats->tx_errors++;
 387             stats->tx_aborted_errors++;
 388             s =  PLIP_STATE_STRING(snd->state);
 389             if (net_debug > 1)
 390                 printk("%s: transmit timeout(%s,%02x)... reset interface.\n",
 391                        dev->name, s, (unsigned int)c0);
 392             if (snd->skb)
 393                 dev_kfree_skb(snd->skb, FREE_WRITE);
 394         } else if (nl->connection == PLIP_CN_RECEIVE) {
 395             stats->rx_dropped++;
 396             s =  PLIP_STATE_STRING(rcv->state);
 397             if (net_debug > 1)
 398                 printk("%s: receive timeout(%s,%02x)... reset interface.\n",
 399                        dev->name, s, (unsigned int)c0);
 400             if (rcv->skb)
 401                 dev_kfree_skb(rcv->skb, FREE_WRITE);
 402         }
 403         disable_irq(dev->irq);
 404         outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 405         dev->tbusy = 1;
 406         nl->connection = PLIP_CN_ERROR;
 407         outb(0x00, PAR_DATA(dev));
 408     }
 409 
 410     queue_task(&nl->deferred, &tq_timer);
 411     return;
 412 }
 413 
 414 static int
 415 plip_tx_packet(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 416 {
 417     struct net_local *nl = (struct net_local *)dev->priv;
 418     struct plip_local *snd = &nl->snd_data;
 419 
 420     if (dev->tbusy)
 421         return 1;
 422 
 423     /* If some higher layer thinks we've missed an tx-done interrupt
 424        we are passed NULL. Caution: dev_tint() handles the cli()/sti()
 425        itself. */
 426     if (skb == NULL) {
 427         dev_tint(dev);
 428         return 0;
 429     }
 430 
 431     if (set_bit(0, (void*)&dev->tbusy) != 0) {
 432         printk("%s: Transmitter access conflict.\n", dev->name);
 433         return 1;
 434     }
 435 
 436     if (skb->len > dev->mtu) {
 437         printk("%s: packet too big, %d.\n", dev->name, (int)skb->len);
 438         dev->tbusy = 0;
 439         return 0;
 440     }
 441 
 442     snd->state = PLIP_PK_TRIGGER;
 443     dev->trans_start = jiffies;
 444 
 445     snd->skb = skb;
 446     snd->length = skb->len;
 447 
 448     cli();
 449     if (nl->connection == PLIP_CN_NONE) {
 450         nl->connection = PLIP_CN_SEND;
 451         nl->timeout_count = 0;
 452     }
 453     sti();
 454     queue_task(&nl->immediate, &tq_immediate);
 455     mark_bh(IMMEDIATE_BH);
 456 
 457     return 0;
 458 }
 459 
 460 /* Open/initialize the board.  This is called (in the current kernel)
 461    sometime after booting when the 'ifconfig' program is run.
 462 
 463    This routine gets exclusive access to the parallel port by allocating
 464    its IRQ line.
 465  */
 466 static int
 467 plip_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 468 {
 469     int i;
 470 
 471     cli();
 472     if (request_irq(dev->irq , plip_interrupt, 0, "plip") != 0) {
 473         sti();
 474         printk("%s: couldn't get IRQ %d.\n", dev->name, dev->irq);
 475         return -EAGAIN;
 476     }
 477     irq2dev_map[dev->irq] = dev;
 478     sti();
 479     /* enable rx interrupt. */
 480     outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 481     plip_device_clear(dev);
 482 
 483     /* Fill in the MAC-level header. */
 484     for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++)
 485         dev->dev_addr[i] = 0xfc;
 486     memcpy(&(dev->dev_addr[i]), &dev->pa_addr, sizeof(unsigned long));
 487 
 488     dev->start = 1;
 489 #ifdef MODULE
 490     MOD_INC_USE_COUNT;
 491 #endif        
 492     return 0;
 493 }
 494 
 495 /* The inverse routine to plip_open (). */
 496 static int
 497 plip_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 498 {
 499     dev->tbusy = 1;
 500     dev->start = 0;
 501     cli();
 502     free_irq(dev->irq);
 503     irq2dev_map[dev->irq] = NULL;
 504     sti();
 505     outb(0x00, PAR_DATA(dev));
 506     /* release the interrupt. */
 507     outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 508 #ifdef MODULE
 509     MOD_DEC_USE_COUNT;
 510 #endif        
 511     return 0;
 512 }
 513 
 514 static struct enet_statistics *
 515 plip_get_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 516 {
 517     struct enet_statistics *localstats = (struct enet_statistics*)dev->priv;
 518     return localstats;
 519 }
 520 
 521 /* We don't need to send arp, for plip is point-to-point. */
 522 static int
 523 plip_rebuild_header(void *buff, struct device *dev, unsigned long dst,
     /* [previous][next][first][last][top][bottom][index][help] */
 524                     struct sk_buff *skb)
 525 {
 526     struct ethhdr *eth = (struct ethhdr *)buff;
 527     int i;
 528 
 529     if (eth->h_proto != htons(ETH_P_IP)) {
 530         printk("plip_rebuild_header: Don't know how to resolve type %d addresses?\n", (int)eth->h_proto);
 531         memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
 532         return 0;
 533     }
 534 
 535     for (i=0; i < ETH_ALEN - sizeof(unsigned long); i++)
 536         eth->h_dest[i] = 0xfc;
 537     memcpy(&(eth->h_dest[i]), &dst, sizeof(unsigned long));
 538     return 0;
 539 }
 540 
 541 static void
 542 plip_device_clear(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 543 {
 544     struct net_local *nl = (struct net_local *)dev->priv;
 545 
 546     outb (0x00, PAR_DATA(dev));
 547     nl->rcv_data.state = PLIP_PK_DONE;
 548     nl->snd_data.state = PLIP_PK_DONE;
 549     nl->rcv_data.skb = NULL;
 550     nl->snd_data.skb = NULL;
 551     nl->connection = PLIP_CN_NONE;
 552     cli();
 553     dev->tbusy = 0;
 554     sti();
 555     outb(LP_PINITP|LP_PSELECP|LP_PINTEN, PAR_CONTROL(dev));
 556     enable_irq(dev->irq);
 557 }
 558 
 559 /* PLIP_ERROR --- wait till other end settled */
 560 static int
 561 plip_error(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 562 {
 563     unsigned char status;
 564 
 565     status = inb(PAR_STATUS(dev));
 566     if ((status & 0xf8) == 0x80)
 567         return 0;
 568     return 1;
 569 }
 570 
 571 /* PLIP_RECEIVE --- receive a byte(two nibbles)
 572    Returns 0 on success, 1 on failure          */
 573 inline static int
 574 plip_receive(unsigned short nibble_timeout, unsigned short unit_us,
     /* [previous][next][first][last][top][bottom][index][help] */
 575              unsigned short status_addr, unsigned short data_addr,
 576              enum plip_nibble_state *ns_p, unsigned char *data_p)
 577 {
 578     unsigned char c0, c1;
 579     unsigned int cx;
 580 
 581     switch (*ns_p) {
 582     case PLIP_NB_BEGIN:
 583         cx = nibble_timeout;
 584         while (1) {
 585             c0 = inb(status_addr);
 586             udelay(unit_us);
 587             if ((c0 & 0x80) == 0) {
 588                 c1 = inb(status_addr);
 589                 if (c0 == c1)
 590                     break;
 591             }
 592             if (--cx == 0)
 593                 return 1;
 594         }
 595         *data_p = (c0 >> 3) & 0x0f;
 596         outb(0x10, data_addr); /* send ACK */
 597         *ns_p = PLIP_NB_1;
 598 
 599     case PLIP_NB_1:
 600         cx = nibble_timeout;
 601         while (1) {
 602             c0 = inb(status_addr);
 603             udelay(unit_us);
 604             if (c0 & 0x80) {
 605                 c1 = inb(status_addr);
 606                 if (c0 == c1)
 607                     break;
 608             }
 609             if (--cx == 0)
 610                 return 1;
 611         }
 612         *data_p |= (c0 << 1) & 0xf0;
 613         outb(0x00, data_addr); /* send ACK */
 614         *ns_p = PLIP_NB_BEGIN;
 615         return 0;
 616 
 617     case PLIP_NB_2:
 618     }
 619 }
 620 
 621 /* PLIP_RECEIVE_PACKET --- receive a packet
 622    Returns 0 on success, 1 when timeout, -1 on failure */
 623 static int
 624 plip_receive_packet(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 625 {
 626     unsigned short data_addr = PAR_DATA(dev), status_addr = PAR_STATUS(dev);
 627     struct net_local *nl = (struct net_local *)dev->priv;
 628     unsigned short nibble_timeout = nl->nibble_us, unit_us = nl->unit_us;
 629     struct plip_local *rcv = &nl->rcv_data;
 630     unsigned char *lbuf;
 631     struct enet_statistics *stats = (struct enet_statistics *) dev->priv;
 632 
 633     switch (rcv->state) {
 634     case PLIP_PK_TRIGGER:
 635         rcv->state = PLIP_PK_LENGTH_LSB;
 636         rcv->nibble = PLIP_NB_BEGIN;
 637 
 638     case PLIP_PK_LENGTH_LSB:
 639         if (plip_receive(nibble_timeout, unit_us, status_addr, data_addr,
 640                          &rcv->nibble, (unsigned char *)&rcv->length))
 641             return 1;
 642         rcv->state = PLIP_PK_LENGTH_MSB;
 643 
 644     case PLIP_PK_LENGTH_MSB:
 645         if (plip_receive(nibble_timeout, unit_us, status_addr, data_addr,
 646                          &rcv->nibble, (unsigned char *)&rcv->length+1))
 647             return 1;
 648         if (rcv->length > dev->mtu || rcv->length < 8) {
 649             printk("%s: bogus packet size %d.\n", dev->name, rcv->length);
 650             return -1;
 651         }
 652         /* Malloc up new buffer. */
 653         rcv->skb = alloc_skb(rcv->length, GFP_ATOMIC);
 654         if (rcv->skb == NULL) {
 655             printk("%s: Memory squeeze.\n", dev->name);
 656             return -1;
 657         }
 658         rcv->skb->len = rcv->length;
 659         rcv->skb->dev = dev;
 660         rcv->state = PLIP_PK_DATA;
 661         rcv->byte = 0;
 662         rcv->checksum = 0;
 663 
 664     case PLIP_PK_DATA:
 665         lbuf = rcv->skb->data;
 666         do {
 667             if (plip_receive(nibble_timeout, unit_us, status_addr, data_addr,
 668                              &rcv->nibble, &lbuf[rcv->byte]))
 669                 return 1;
 670             rcv->checksum += lbuf[rcv->byte];
 671         } while (++rcv->byte < rcv->length);
 672         rcv->state = PLIP_PK_CHECKSUM;
 673 
 674     case PLIP_PK_CHECKSUM:
 675         if (plip_receive(nibble_timeout, unit_us, status_addr, data_addr,
 676                          &rcv->nibble, &rcv->data))
 677             return 1;
 678         if (rcv->data != rcv->checksum) {
 679             stats->rx_crc_errors++;
 680             if (net_debug)
 681                 printk("%s: checksum error\n", dev->name);
 682             return -1;
 683         }
 684         rcv->state = PLIP_PK_DONE;
 685 
 686     case PLIP_PK_DONE:
 687     }
 688     return 0;
 689 }
 690 
 691 /* Handle the parallel port interrupts. */
 692 static void
 693 plip_interrupt(int reg_ptr)
     /* [previous][next][first][last][top][bottom][index][help] */
 694 {
 695     int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
 696     struct device *dev = (struct device *) irq2dev_map[irq];
 697     struct net_local *nl = (struct net_local *)dev->priv;
 698     struct plip_local *rcv = &nl->rcv_data;
 699     unsigned char c0;
 700 
 701     if (dev == NULL) {
 702         if (net_debug)
 703             printk ("plip_interrupt: irq %d for unknown device.\n", irq);
 704         return;
 705     }
 706 
 707     if (dev->interrupt)
 708         return;
 709 
 710     c0 = inb(PAR_STATUS(dev));
 711     if ((c0 & 0xf8) != 0xc0) {
 712         if (net_debug > 3)
 713             printk("plip: spurious interrupt\n");
 714         return;
 715     }
 716     dev->interrupt = 1;
 717     if (net_debug > 3)
 718         printk("%s: interrupt.\n", dev->name);
 719 
 720     cli();
 721     switch (nl->connection) {
 722     case PLIP_CN_CLOSING:
 723         dev->tbusy = 0;
 724     case PLIP_CN_NONE:
 725     case PLIP_CN_SEND:
 726         sti();
 727         dev->last_rx = jiffies;
 728         rcv->state = PLIP_PK_TRIGGER;
 729         nl->connection = PLIP_CN_RECEIVE;
 730         nl->timeout_count = 0;
 731         queue_task(&nl->immediate, &tq_immediate);
 732         mark_bh(IMMEDIATE_BH);
 733         break;
 734 
 735     case PLIP_CN_RECEIVE:
 736         sti();
 737         printk("%s: receive interrupt when receiving packet\n", dev->name);
 738         break;
 739 
 740     case PLIP_CN_ERROR:
 741         sti();
 742         printk("%s: receive interrupt in error state\n", dev->name);
 743         break;
 744     }
 745 }
 746 
 747 /* PLIP_SEND --- send a byte (two nibbles) 
 748    Returns 0 on success, 1 on failure        */
 749 inline static int
 750 plip_send(unsigned short nibble_timeout, unsigned short unit_us,
     /* [previous][next][first][last][top][bottom][index][help] */
 751           unsigned short status_addr, unsigned short data_addr,
 752           enum plip_nibble_state *ns_p, unsigned char data)
 753 {
 754     unsigned char c0;
 755     unsigned int cx;
 756 
 757     switch (*ns_p) {
 758     case PLIP_NB_BEGIN:
 759         outb((data & 0x0f), data_addr);
 760         *ns_p = PLIP_NB_1;
 761 
 762     case PLIP_NB_1:
 763         outb(0x10 | (data & 0x0f), data_addr);
 764         cx = nibble_timeout;
 765         while (1) {
 766             c0 = inb(status_addr);
 767             if ((c0 & 0x80) == 0) 
 768                 break;
 769             if (--cx == 0) /* time out */
 770                 return 1;
 771             udelay(unit_us);
 772         }
 773         outb(0x10 | (data >> 4), data_addr);
 774         *ns_p = PLIP_NB_2;
 775 
 776     case PLIP_NB_2:
 777         outb((data >> 4), data_addr);
 778         cx = nibble_timeout;
 779         while (1) {
 780             c0 = inb(status_addr);
 781             if (c0 & 0x80)
 782                 break;
 783             if (--cx == 0) /* time out */
 784                 return 1;
 785             udelay(unit_us);
 786         }
 787         *ns_p = PLIP_NB_BEGIN;
 788         return 0;
 789     }
 790 }
 791 
 792 /* PLIP_SEND_PACKET --- send a packet
 793    Returns 0 on success, 1 when timeout, -1 when interrupted  */
 794 static int
 795 plip_send_packet(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 796 {
 797     unsigned short data_addr = PAR_DATA(dev), status_addr = PAR_STATUS(dev);
 798     struct net_local *nl = (struct net_local *)dev->priv;
 799     unsigned short nibble_timeout = nl->nibble_us, unit_us = nl->unit_us;
 800     struct plip_local *snd = &nl->snd_data;
 801     unsigned char *lbuf = snd->skb->data;
 802     unsigned char c0;
 803     unsigned int cx;
 804     struct enet_statistics *stats = (struct enet_statistics *) dev->priv;
 805 
 806     switch (snd->state) {
 807     case PLIP_PK_TRIGGER:
 808         /* Trigger remote rx interrupt. */
 809         outb(0x08, PAR_DATA(dev));
 810         cx = nl->trigger_us;
 811         while (1) {
 812             if (nl->connection == PLIP_CN_RECEIVE) { /* interrupted */
 813                 stats->collisions++;
 814                 if (net_debug > 3)
 815                     printk("%s: collision.\n", dev->name);
 816                 return -1;
 817             }
 818             cli();
 819             c0 = inb(PAR_STATUS(dev));
 820             if (c0 & 0x08) {
 821                 disable_irq(dev->irq);
 822                 outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 823                 if (net_debug > 3)
 824                     printk("+");
 825                 /* OK, connection established! */
 826                 snd->state = PLIP_PK_LENGTH_LSB;
 827                 snd->nibble = PLIP_NB_BEGIN;
 828                 nl->timeout_count = 0;
 829                 sti();
 830                 break;
 831             }
 832             sti();
 833             udelay(nl->unit_us);
 834             if (--cx == 0) {
 835                 outb(0x00, PAR_DATA(dev));
 836                 return 1;
 837             }
 838         }
 839 
 840     case PLIP_PK_LENGTH_LSB:
 841         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 842                       &snd->nibble, snd->length & 0xff)) /* timeout */
 843             return 1;
 844         snd->state = PLIP_PK_LENGTH_MSB;
 845 
 846     case PLIP_PK_LENGTH_MSB:
 847         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 848                       &snd->nibble, snd->length >> 8)) /* timeout */
 849             return 1;
 850         snd->state = PLIP_PK_DATA;
 851         snd->byte = 0;
 852         snd->checksum = 0;
 853 
 854     case PLIP_PK_DATA:
 855         do {
 856             if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 857                           &snd->nibble, lbuf[snd->byte])) /* timeout */
 858                 return 1;
 859             snd->checksum += lbuf[snd->byte];
 860         } while (++snd->byte < snd->length);
 861         snd->state = PLIP_PK_CHECKSUM;
 862 
 863     case PLIP_PK_CHECKSUM:
 864         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 865                       &snd->nibble, snd->checksum)) /* timeout */
 866             return 1;
 867 
 868         dev_kfree_skb(snd->skb, FREE_WRITE);
 869         stats->tx_packets++;
 870 
 871     case PLIP_PK_DONE:
 872     }
 873     return 0;
 874 }
 875 
 876 static int plip_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
 877 {
 878         if(dev->flags&IFF_UP)
 879                 return -EBUSY;
 880 /*
 881  *      We could probe this for verification, but since they told us
 882  *      to do it then they can suffer.
 883  */
 884         if(map->base_addr!= (unsigned short)-1)
 885                 dev->base_addr=map->base_addr;
 886         if(map->irq!= (unsigned char)-1)
 887                 dev->irq= map->irq;
 888         return 0;
 889 }
 890 
 891 static int plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 892 {
 893         struct net_local *nl = (struct net_local *) dev->priv;
 894         struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
 895         
 896         switch(pc->pcmd)
 897         {
 898                 case PLIP_GET_TIMEOUT:
 899                         pc->trigger=nl->trigger_us;
 900                         pc->nibble=nl->nibble_us;
 901                         pc->unit=nl->unit_us;
 902                         break;
 903                 case PLIP_SET_TIMEOUT:
 904                         nl->trigger_us=pc->trigger;
 905                         nl->nibble_us=pc->nibble;
 906                         nl->unit_us=pc->unit;
 907                         break;
 908                 default:
 909                         return -EOPNOTSUPP;
 910         }
 911         return 0;
 912 }
 913 
 914 
 915 #ifdef MODULE
 916 char kernel_version[] = UTS_RELEASE;
 917 
 918 static struct device dev_plip0 = 
 919 {
 920         "plip0" /*"plip"*/,
 921         0, 0, 0, 0,             /* memory */
 922         0x3BC, 5,               /* base, irq */
 923         0, 0, 0, NULL, plip_init 
 924 };
 925 
 926 static struct device dev_plip1 = 
 927 {
 928         "plip1" /*"plip"*/,
 929         0, 0, 0, 0,             /* memory */
 930         0x378, 7,               /* base, irq */
 931         0, 0, 0, NULL, plip_init 
 932 };
 933 
 934 static struct device dev_plip2 = 
 935 {
 936         "plip2" /*"plip"*/,
 937         0, 0, 0, 0,             /* memory */
 938         0x278, 2,               /* base, irq */
 939         0, 0, 0, NULL, plip_init 
 940 };
 941 
 942 int
 943 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 944 {
 945     int devices=0;
 946 
 947     if (register_netdev(&dev_plip0) != 0)
 948         devices++;
 949     if (register_netdev(&dev_plip1) != 0)
 950         devices++;
 951     if (register_netdev(&dev_plip2) != 0)
 952         devices++;
 953     if (devices == 0)
 954         return -EIO;
 955     return 0;
 956 }
 957 
 958 void
 959 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 960 {
 961     if (MOD_IN_USE)
 962         printk("plip: device busy, remove delayed\n");
 963     else {
 964         if (dev_plip0.priv) {
 965             unregister_netdev(&dev_plip0);
 966             release_region(PAR_DATA(&dev_plip0), 3);
 967             kfree_s(dev_plip0.priv, sizeof(struct net_local));
 968             dev_plip0.priv = NULL;
 969         }
 970         if (dev_plip1.priv) {
 971             unregister_netdev(&dev_plip1);
 972             release_region(PAR_DATA(&dev_plip1), 3);
 973             kfree_s(dev_plip1.priv, sizeof(struct net_local));
 974             dev_plip1.priv = NULL;
 975         }
 976         if (dev_plip2.priv) {
 977             unregister_netdev(&dev_plip2);
 978             release_region(PAR_DATA(&dev_plip2), 3);
 979             kfree_s(dev_plip2.priv, sizeof(struct net_local));
 980             dev_plip2.priv = NULL;
 981         }
 982     }
 983 }
 984 #endif /* MODULE */
 985 
 986 /*
 987  * Local variables:
 988  * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -m486 -I../../net/inet -c plip.c"
 989  * c-indent-level: 4
 990  * c-continued-statement-offset: 4
 991  * c-brace-offset: -4
 992  * c-argdecl-indent: 4
 993  * c-label-offset: -4
 994  * version-control: t
 995  * kept-new-versions: 10
 996  * End:
 997  */

/* [previous][next][first][last][top][bottom][index][help] */