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

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