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 irq, struct pt_regs *regs);
 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 irq, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 692 {
 693     struct device *dev = (struct device *) irq2dev_map[irq];
 694     struct net_local *nl = (struct net_local *)dev->priv;
 695     struct plip_local *rcv = &nl->rcv_data;
 696     unsigned char c0;
 697 
 698     if (dev == NULL) {
 699         if (net_debug)
 700             printk ("plip_interrupt: irq %d for unknown device.\n", irq);
 701         return;
 702     }
 703 
 704     if (dev->interrupt)
 705         return;
 706 
 707     c0 = inb(PAR_STATUS(dev));
 708     if ((c0 & 0xf8) != 0xc0) {
 709         if (net_debug > 3)
 710             printk("plip: spurious interrupt\n");
 711         return;
 712     }
 713     dev->interrupt = 1;
 714     if (net_debug > 3)
 715         printk("%s: interrupt.\n", dev->name);
 716 
 717     cli();
 718     switch (nl->connection) {
 719     case PLIP_CN_CLOSING:
 720         dev->tbusy = 0;
 721     case PLIP_CN_NONE:
 722     case PLIP_CN_SEND:
 723         sti();
 724         dev->last_rx = jiffies;
 725         rcv->state = PLIP_PK_TRIGGER;
 726         nl->connection = PLIP_CN_RECEIVE;
 727         nl->timeout_count = 0;
 728         queue_task(&nl->immediate, &tq_immediate);
 729         mark_bh(IMMEDIATE_BH);
 730         break;
 731 
 732     case PLIP_CN_RECEIVE:
 733         sti();
 734         printk("%s: receive interrupt when receiving packet\n", dev->name);
 735         break;
 736 
 737     case PLIP_CN_ERROR:
 738         sti();
 739         printk("%s: receive interrupt in error state\n", dev->name);
 740         break;
 741     }
 742 }
 743 
 744 /* PLIP_SEND --- send a byte (two nibbles) 
 745    Returns 0 on success, 1 on failure        */
 746 inline static int
 747 plip_send(unsigned short nibble_timeout, unsigned short unit_us,
     /* [previous][next][first][last][top][bottom][index][help] */
 748           unsigned short status_addr, unsigned short data_addr,
 749           enum plip_nibble_state *ns_p, unsigned char data)
 750 {
 751     unsigned char c0;
 752     unsigned int cx;
 753 
 754     switch (*ns_p) {
 755     case PLIP_NB_BEGIN:
 756         outb((data & 0x0f), data_addr);
 757         *ns_p = PLIP_NB_1;
 758 
 759     case PLIP_NB_1:
 760         outb(0x10 | (data & 0x0f), data_addr);
 761         cx = nibble_timeout;
 762         while (1) {
 763             c0 = inb(status_addr);
 764             if ((c0 & 0x80) == 0) 
 765                 break;
 766             if (--cx == 0) /* time out */
 767                 return 1;
 768             udelay(unit_us);
 769         }
 770         outb(0x10 | (data >> 4), data_addr);
 771         *ns_p = PLIP_NB_2;
 772 
 773     case PLIP_NB_2:
 774         outb((data >> 4), data_addr);
 775         cx = nibble_timeout;
 776         while (1) {
 777             c0 = inb(status_addr);
 778             if (c0 & 0x80)
 779                 break;
 780             if (--cx == 0) /* time out */
 781                 return 1;
 782             udelay(unit_us);
 783         }
 784         *ns_p = PLIP_NB_BEGIN;
 785         return 0;
 786     }
 787 }
 788 
 789 /* PLIP_SEND_PACKET --- send a packet
 790    Returns 0 on success, 1 when timeout, -1 when interrupted  */
 791 static int
 792 plip_send_packet(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 793 {
 794     unsigned short data_addr = PAR_DATA(dev), status_addr = PAR_STATUS(dev);
 795     struct net_local *nl = (struct net_local *)dev->priv;
 796     unsigned short nibble_timeout = nl->nibble_us, unit_us = nl->unit_us;
 797     struct plip_local *snd = &nl->snd_data;
 798     unsigned char *lbuf = snd->skb->data;
 799     unsigned char c0;
 800     unsigned int cx;
 801     struct enet_statistics *stats = (struct enet_statistics *) dev->priv;
 802 
 803     switch (snd->state) {
 804     case PLIP_PK_TRIGGER:
 805         /* Trigger remote rx interrupt. */
 806         outb(0x08, PAR_DATA(dev));
 807         cx = nl->trigger_us;
 808         while (1) {
 809             if (nl->connection == PLIP_CN_RECEIVE) { /* interrupted */
 810                 stats->collisions++;
 811                 if (net_debug > 3)
 812                     printk("%s: collision.\n", dev->name);
 813                 return -1;
 814             }
 815             cli();
 816             c0 = inb(PAR_STATUS(dev));
 817             if (c0 & 0x08) {
 818                 disable_irq(dev->irq);
 819                 outb(LP_PINITP|LP_PSELECP, PAR_CONTROL(dev));
 820                 if (net_debug > 3)
 821                     printk("+");
 822                 /* OK, connection established! */
 823                 snd->state = PLIP_PK_LENGTH_LSB;
 824                 snd->nibble = PLIP_NB_BEGIN;
 825                 nl->timeout_count = 0;
 826                 sti();
 827                 break;
 828             }
 829             sti();
 830             udelay(nl->unit_us);
 831             if (--cx == 0) {
 832                 outb(0x00, PAR_DATA(dev));
 833                 return 1;
 834             }
 835         }
 836 
 837     case PLIP_PK_LENGTH_LSB:
 838         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 839                       &snd->nibble, snd->length & 0xff)) /* timeout */
 840             return 1;
 841         snd->state = PLIP_PK_LENGTH_MSB;
 842 
 843     case PLIP_PK_LENGTH_MSB:
 844         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 845                       &snd->nibble, snd->length >> 8)) /* timeout */
 846             return 1;
 847         snd->state = PLIP_PK_DATA;
 848         snd->byte = 0;
 849         snd->checksum = 0;
 850 
 851     case PLIP_PK_DATA:
 852         do {
 853             if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 854                           &snd->nibble, lbuf[snd->byte])) /* timeout */
 855                 return 1;
 856             snd->checksum += lbuf[snd->byte];
 857         } while (++snd->byte < snd->length);
 858         snd->state = PLIP_PK_CHECKSUM;
 859 
 860     case PLIP_PK_CHECKSUM:
 861         if (plip_send(nibble_timeout, unit_us, status_addr, data_addr,
 862                       &snd->nibble, snd->checksum)) /* timeout */
 863             return 1;
 864 
 865         dev_kfree_skb(snd->skb, FREE_WRITE);
 866         stats->tx_packets++;
 867 
 868     case PLIP_PK_DONE:
 869     }
 870     return 0;
 871 }
 872 
 873 static int plip_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
 874 {
 875         if(dev->flags&IFF_UP)
 876                 return -EBUSY;
 877 /*
 878  *      We could probe this for verification, but since they told us
 879  *      to do it then they can suffer.
 880  */
 881         if(map->base_addr!= (unsigned short)-1)
 882                 dev->base_addr=map->base_addr;
 883         if(map->irq!= (unsigned char)-1)
 884                 dev->irq= map->irq;
 885         return 0;
 886 }
 887 
 888 static int plip_ioctl(struct device *dev, struct ifreq *rq, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
 889 {
 890         struct net_local *nl = (struct net_local *) dev->priv;
 891         struct plipconf *pc = (struct plipconf *) &rq->ifr_data;
 892         
 893         switch(pc->pcmd)
 894         {
 895                 case PLIP_GET_TIMEOUT:
 896                         pc->trigger=nl->trigger_us;
 897                         pc->nibble=nl->nibble_us;
 898                         pc->unit=nl->unit_us;
 899                         break;
 900                 case PLIP_SET_TIMEOUT:
 901                         nl->trigger_us=pc->trigger;
 902                         nl->nibble_us=pc->nibble;
 903                         nl->unit_us=pc->unit;
 904                         break;
 905                 default:
 906                         return -EOPNOTSUPP;
 907         }
 908         return 0;
 909 }
 910 
 911 
 912 #ifdef MODULE
 913 char kernel_version[] = UTS_RELEASE;
 914 
 915 static struct device dev_plip0 = 
 916 {
 917         "plip0" /*"plip"*/,
 918         0, 0, 0, 0,             /* memory */
 919         0x3BC, 5,               /* base, irq */
 920         0, 0, 0, NULL, plip_init 
 921 };
 922 
 923 static struct device dev_plip1 = 
 924 {
 925         "plip1" /*"plip"*/,
 926         0, 0, 0, 0,             /* memory */
 927         0x378, 7,               /* base, irq */
 928         0, 0, 0, NULL, plip_init 
 929 };
 930 
 931 static struct device dev_plip2 = 
 932 {
 933         "plip2" /*"plip"*/,
 934         0, 0, 0, 0,             /* memory */
 935         0x278, 2,               /* base, irq */
 936         0, 0, 0, NULL, plip_init 
 937 };
 938 
 939 int
 940 init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 941 {
 942     int devices=0;
 943 
 944     if (register_netdev(&dev_plip0) != 0)
 945         devices++;
 946     if (register_netdev(&dev_plip1) != 0)
 947         devices++;
 948     if (register_netdev(&dev_plip2) != 0)
 949         devices++;
 950     if (devices == 0)
 951         return -EIO;
 952     return 0;
 953 }
 954 
 955 void
 956 cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 957 {
 958     if (MOD_IN_USE)
 959         printk("plip: device busy, remove delayed\n");
 960     else {
 961         if (dev_plip0.priv) {
 962             unregister_netdev(&dev_plip0);
 963             release_region(PAR_DATA(&dev_plip0), 3);
 964             kfree_s(dev_plip0.priv, sizeof(struct net_local));
 965             dev_plip0.priv = NULL;
 966         }
 967         if (dev_plip1.priv) {
 968             unregister_netdev(&dev_plip1);
 969             release_region(PAR_DATA(&dev_plip1), 3);
 970             kfree_s(dev_plip1.priv, sizeof(struct net_local));
 971             dev_plip1.priv = NULL;
 972         }
 973         if (dev_plip2.priv) {
 974             unregister_netdev(&dev_plip2);
 975             release_region(PAR_DATA(&dev_plip2), 3);
 976             kfree_s(dev_plip2.priv, sizeof(struct net_local));
 977             dev_plip2.priv = NULL;
 978         }
 979     }
 980 }
 981 #endif /* MODULE */
 982 
 983 /*
 984  * Local variables:
 985  * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -m486 -I../../net/inet -c plip.c"
 986  * c-indent-level: 4
 987  * c-continued-statement-offset: 4
 988  * c-brace-offset: -4
 989  * c-argdecl-indent: 4
 990  * c-label-offset: -4
 991  * version-control: t
 992  * kept-new-versions: 10
 993  * End:
 994  */

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