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

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