root/drivers/isdn/pcbit/layer2.c

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

DEFINITIONS

This source file includes following definitions.
  1. do_pcbit_bh
  2. pcbit_sched_delivery
  3. pcbit_l2_write
  4. pcbit_tx_update
  5. pcbit_transmit
  6. pcbit_deliver
  7. pcbit_receive
  8. pcbit_fake_conf
  9. pcbit_firmware_bug
  10. pcbit_irq_handler
  11. pcbit_l2_active_conf
  12. pcbit_l2_err_recover
  13. pcbit_l2_error
  14. pcbit_recv_ack
  15. pcbit_frame_read

   1 /*
   2  * Copyright (C) 1996 Universidade de Lisboa
   3  * 
   4  * Written by Pedro Roque Marques (roque@di.fc.ul.pt)
   5  *
   6  * This software may be used and distributed according to the terms of 
   7  * the GNU Public License, incorporated herein by reference.
   8  */
   9 
  10 /*        
  11  *        PCBIT-D low-layer interface
  12  */
  13 
  14 /*
  15  *        Based on documentation provided by Inesc:
  16  *        - "Interface com bus do PC para o PCBIT e PCBIT-D", Inesc, Jan 93
  17  */
  18 
  19 /*
  20  *        TODO: better handling of errors
  21  *              re-write/remove debug printks
  22  */ 
  23 
  24 #define __NO_VERSION__
  25 
  26 
  27 #ifdef MODULE
  28 #define INCLUDE_INLINE_FUNCS
  29 #endif
  30 
  31 
  32 #include <linux/module.h>
  33 
  34 #include <linux/sched.h>
  35 #include <linux/string.h>
  36 #include <linux/kernel.h>
  37 #include <linux/types.h>
  38 #include <linux/malloc.h>
  39 #include <linux/interrupt.h>
  40 #include <linux/tqueue.h>
  41 #include <linux/mm.h>
  42 #include <linux/skbuff.h>
  43 
  44 #include <linux/isdnif.h>
  45 
  46 #include <asm/system.h>
  47 #include <asm/io.h>
  48 
  49 
  50 #include "pcbit.h"
  51 #include "layer2.h"
  52 #include "edss1.h"
  53 
  54 #undef DEBUG_FRAG
  55 
  56 
  57 
  58 /*
  59  *  task queue struct
  60  */ 
  61 struct tq_struct *tq_delivery=NULL;
  62 
  63 static void do_pcbit_bh(task_queue *list)
     /* [previous][next][first][last][top][bottom][index][help] */
  64 {
  65         run_task_queue(list);
  66 }
  67 
  68 struct tq_struct run_delivery= {
  69         0, 0, (void *)(void *) do_pcbit_bh, &tq_delivery,
  70 };
  71 
  72 
  73 /*
  74  *  Layer 3 packet demultiplexer
  75  *  drv.c
  76  */
  77 
  78 extern void pcbit_l3_receive(struct pcbit_dev * dev, ulong msg, 
  79                              struct sk_buff * skb,
  80                              ushort hdr_len, ushort refnum);
  81 
  82 /*
  83  *  Prototypes
  84  */
  85 
  86 void pcbit_deliver(void * data);
  87 static void pcbit_transmit(struct pcbit_dev * dev);
  88 
  89 static void pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack);
  90 static void pcbit_frame_read(struct pcbit_dev * dev, unsigned char read_seq);
  91 
  92 static void pcbit_l2_error(struct pcbit_dev *dev);
  93 static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info);
  94 static void pcbit_l2_err_recover(unsigned long data);
  95 
  96 static void pcbit_firmware_bug(struct pcbit_dev * dev);
  97 
  98 static void pcbit_sched_delivery(struct pcbit_dev *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100   queue_task_irq_off(&dev->qdelivery, &tq_delivery);
 101   queue_task_irq_off(&run_delivery, &tq_immediate);
 102   mark_bh(IMMEDIATE_BH);
 103 }
 104 
 105 
 106 /*
 107  *  Called from layer3
 108  */
 109 
 110 int pcbit_l2_write(struct pcbit_dev * dev, ulong msg, ushort refnum, 
     /* [previous][next][first][last][top][bottom][index][help] */
 111                    struct sk_buff *skb, unsigned short hdr_len)
 112         
 113 {
 114         struct frame_buf * frame, * ptr;
 115         unsigned long flags;
 116 
 117         if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) {
 118                 dev_kfree_skb(skb, FREE_WRITE);
 119                 return -1;
 120         }
 121 
 122         if ( (frame = (struct frame_buf *) kmalloc(sizeof(struct frame_buf), 
 123                                                    GFP_ATOMIC)) == NULL ) {
 124                 printk(KERN_WARNING "pcbit_2_write: kmalloc failed\n");
 125                 dev_kfree_skb(skb, FREE_WRITE);
 126                 return -1;
 127         }
 128 
 129         frame->msg = msg;
 130         frame->refnum = refnum;
 131         frame->copied = 0;        
 132         frame->hdr_len = hdr_len;
 133 
 134         if (skb) {
 135                 frame->dt_len = skb->len - hdr_len;
 136                 if (frame->dt_len == 0)
 137                         skb->lock++;
 138         }
 139         else
 140                 frame->dt_len = 0;
 141 
 142         frame->skb = skb;
 143 
 144         frame->next = NULL;
 145 
 146         save_flags(flags);
 147         cli();
 148 
 149         if (dev->write_queue == NULL) {
 150                 dev->write_queue = frame;
 151                 restore_flags(flags);
 152                 pcbit_transmit(dev);
 153         }
 154         else {        
 155                 for(ptr=dev->write_queue; ptr->next; ptr=ptr->next);
 156                 ptr->next = frame;
 157                 
 158                 restore_flags(flags);
 159         }
 160         return 0;
 161 }
 162 
 163 static __inline__ void pcbit_tx_update(struct pcbit_dev *dev, ushort len)
     /* [previous][next][first][last][top][bottom][index][help] */
 164 {
 165         u_char info;
 166 
 167         dev->send_seq = (dev->send_seq + 1) % 8;
 168 
 169         dev->fsize[dev->send_seq] = len;
 170         info = 0;
 171         info |= dev->rcv_seq  << 3;
 172         info |= dev->send_seq;
 173 
 174         writeb(info, dev->sh_mem + BANK4);
 175 
 176 }
 177 
 178 /*
 179  * called by interrupt service routine or by write_2
 180  */
 181 
 182 static void pcbit_transmit(struct pcbit_dev * dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 183 {
 184         struct frame_buf * frame = NULL;
 185         unsigned char unacked;
 186         int flen;           /* fragment frame length including all headers */
 187         int totlen;         /* non-fragmented frame length */
 188         int free;
 189         int count, cp_len;
 190         unsigned long flags;
 191         unsigned short tt;
 192 
 193         if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
 194                 return;
 195 
 196         unacked = (dev->send_seq + (8 - dev->unack_seq) ) & 0x07;
 197 
 198         if (dev->free > 16 && dev->write_queue && unacked < 7) {
 199 
 200                 save_flags(flags);
 201                 cli();
 202 
 203 
 204                 if (!dev->w_busy)
 205                         dev->w_busy = 1;
 206                 else
 207                 {
 208                         restore_flags(flags);
 209                         return;
 210                 }
 211 
 212                 restore_flags(flags);
 213 
 214                 frame = dev->write_queue;
 215                 free = dev->free;
 216 
 217                 if (frame->copied == 0) {
 218 
 219                         /* Type 0 frame */
 220 
 221                         struct msg_fmt * msg;
 222 
 223                         if (frame->skb)
 224                                 totlen = FRAME_HDR_LEN + PREHDR_LEN + frame->skb->len;
 225                         else
 226                                 totlen = FRAME_HDR_LEN + PREHDR_LEN;
 227 
 228                         flen = MIN(totlen, free);
 229 
 230                         msg = (struct msg_fmt *) &(frame->msg);
 231 
 232                         /*
 233                          *  Board level 2 header 
 234                          */
 235 
 236                         pcbit_writew(dev, flen - FRAME_HDR_LEN);
 237 
 238                         pcbit_writeb(dev, msg->cpu);
 239 
 240                         pcbit_writeb(dev, msg->proc);
 241 
 242                         /* TH */
 243                         pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
 244 
 245                         /* TD */
 246                         pcbit_writew(dev, frame->dt_len);
 247 
 248 
 249                         /*
 250                          *  Board level 3 fixed-header 
 251                          */
 252         
 253                         /* LEN = TH */
 254                         pcbit_writew(dev, frame->hdr_len + PREHDR_LEN);
 255         
 256                         /* XX */
 257                         pcbit_writew(dev, 0);
 258 
 259                         /* C + S */
 260                         pcbit_writeb(dev, msg->cmd);
 261                         pcbit_writeb(dev, msg->scmd);
 262 
 263                         /* NUM */
 264                         pcbit_writew(dev, frame->refnum);
 265                         
 266                         count = FRAME_HDR_LEN + PREHDR_LEN;
 267                 }
 268                 else {
 269                         /* Type 1 frame */
 270 
 271                         totlen = 2 + (frame->skb->len - frame->copied);
 272           
 273                         flen = MIN(totlen, free);
 274 
 275                         /* TT */
 276                         tt = ((ushort) (flen - 2)) | 0x8000U; /* Type 1 */
 277                         pcbit_writew(dev, tt);
 278 
 279                         count = 2;
 280                 }
 281 
 282                 if (frame->skb) {
 283                         cp_len = MIN(frame->skb->len - frame->copied, 
 284                                      flen - count);
 285                 
 286                         memcpy_topcbit(dev, frame->skb->data + frame->copied, 
 287                                        cp_len);
 288                         frame->copied += cp_len;
 289                 }
 290 
 291                 /* bookkeeping */
 292                 dev->free -= flen;
 293                 pcbit_tx_update(dev, flen);
 294 
 295                 save_flags(flags);
 296                 cli();
 297 
 298 
 299                 if (frame->skb == NULL || frame->copied == frame->skb->len) {
 300 
 301                         dev->write_queue = frame->next;
 302 
 303                         if (frame->skb != NULL) {
 304                                 /* free frame */
 305                                 dev_kfree_skb(frame->skb, FREE_WRITE);
 306                         }
 307 
 308                         kfree(frame);
 309                 }
 310 
 311                 dev->w_busy = 0;
 312                 restore_flags(flags);                           
 313         }
 314 #ifdef DEBUG
 315         else
 316                 printk(KERN_DEBUG "unacked %d free %d write_queue %s\n",
 317                        unacked, dev->free, dev->write_queue ? "not empty" : 
 318                        "empty");
 319 #endif
 320 }
 321 
 322 
 323 /*
 324  *  deliver a queued frame to the upper layer
 325  */
 326 
 327 void pcbit_deliver(void * data)
     /* [previous][next][first][last][top][bottom][index][help] */
 328 { 
 329         struct frame_buf *frame;
 330         unsigned long flags;
 331         struct msg_fmt msg;
 332         struct pcbit_dev *dev = (struct pcbit_dev *) data;
 333 
 334         save_flags(flags);
 335         cli();
 336 
 337         /* get frame from queue */
 338         if (!(frame=dev->read_queue)) {
 339                 restore_flags(flags);
 340                 return;
 341         }
 342 
 343         dev->read_queue = frame->next;
 344         restore_flags(flags);
 345 
 346         msg.cpu = 0;
 347         msg.proc = 0;
 348         msg.cmd = frame->skb->data[2];
 349         msg.scmd = frame->skb->data[3];
 350 
 351         frame->refnum = *((ushort*) frame->skb->data + 4);
 352         frame->msg = *((ulong*) &msg);
 353         
 354         skb_pull(frame->skb, 6);
 355 
 356         pcbit_l3_receive(dev, frame->msg, frame->skb, frame->hdr_len, 
 357                          frame->refnum);
 358 
 359         kfree(frame);
 360 }
 361 
 362 /*
 363  * Reads BANK 2 & Reassembles 
 364  */
 365 
 366 static void pcbit_receive(struct pcbit_dev * dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 367 {
 368         unsigned short tt;
 369         u_char cpu, proc;
 370         struct frame_buf * frame = NULL;
 371         unsigned long flags;
 372         u_char type1;
 373 
 374         if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING)
 375                 return;
 376 
 377         tt = pcbit_readw(dev);
 378 
 379         if ((tt & 0x7fffU) > 511) {
 380                 printk(KERN_INFO "pcbit: invalid frame length -> TT=%04x\n", 
 381                        tt);
 382                 pcbit_l2_error(dev);
 383                 return;
 384         }
 385 
 386         if (!(tt & 0x8000U))
 387         {                       /* Type 0 */
 388                 type1 = 0;
 389 
 390                 if (dev->read_frame) {
 391                         printk(KERN_DEBUG "pcbit_receive: Type 0 frame and read_frame != NULL\n");
 392 #if 0
 393                         pcbit_l2_error(dev);
 394                         return;
 395 #else
 396                         /* discard previous queued frame */
 397                         if (dev->read_frame->skb) {
 398                                 dev->read_frame->skb->free = 1;
 399                                 kfree_skb(dev->read_frame->skb, FREE_READ);
 400                         }
 401                         kfree(dev->read_frame);
 402                         dev->read_frame = NULL;
 403 #endif
 404                 }
 405 
 406                 frame = kmalloc(sizeof(struct frame_buf), GFP_ATOMIC);
 407       
 408                 if (frame == NULL) {
 409                         printk(KERN_WARNING "kmalloc failed\n");
 410                         return;
 411                 }
 412                 memset(frame, 0, sizeof(struct frame_buf));
 413       
 414                 cpu = pcbit_readb(dev);
 415                 proc = pcbit_readb(dev);
 416 
 417 
 418                 if (cpu != 0x06 && cpu != 0x02)
 419                 {
 420                         printk (KERN_DEBUG "pcbit: invalid cpu value\n");
 421                         kfree(frame);
 422                         pcbit_l2_error(dev);
 423                         return;
 424                 }
 425 
 426                 /*
 427                  * we discard cpu & proc on receiving
 428                  * but we read it to update the pointer
 429                  */
 430       
 431                 frame->hdr_len = pcbit_readw(dev);
 432                 frame->dt_len = pcbit_readw(dev);
 433 
 434                 /* 
 435                  * 0 sized packet 
 436                  * I don't know if they are an error or not...
 437                  * But they are very frequent
 438                  * Not documented
 439                  */
 440 
 441                 if (frame->hdr_len == 0) {
 442                         kfree(frame);
 443 #ifdef DEBUG
 444                         printk(KERN_DEBUG "0 sized frame\n");
 445 #endif
 446                         pcbit_firmware_bug(dev);
 447                         return;
 448                 }
 449                 
 450                 /* sanity check the length values */
 451                 if (frame->hdr_len > 1024 || frame->dt_len > 2048)
 452                 {
 453 #ifdef DEBUG
 454                         printk(KERN_DEBUG "length problem: ");
 455                         printk(KERN_DEBUG "TH=%04x TD=%04x\n", 
 456                                frame->hdr_len, 
 457                                frame->dt_len);
 458 #endif
 459                         pcbit_l2_error(dev);
 460                         kfree(frame);
 461                         return;
 462                 }
 463 
 464                 /* minimum frame read */
 465 
 466                 frame->skb = dev_alloc_skb(frame->hdr_len + frame->dt_len + 
 467                                            ((frame->hdr_len + 15) & ~15));
 468 
 469                 if (!frame->skb) {
 470                         printk(KERN_DEBUG "pcbit_receive: out of memory\n");
 471                         kfree(frame);
 472                         return;
 473                 }
 474 
 475                 /* 16 byte alignment for IP */                 
 476                 if (frame->dt_len)
 477                         skb_reserve(frame->skb, (frame->hdr_len + 15) & ~15);
 478 
 479         }
 480         else {
 481                 /* Type 1 */
 482                 type1 = 1;
 483                 tt &= 0x7fffU;
 484 
 485                 if (!(frame = dev->read_frame)) {                
 486                         printk("Type 1 frame and no frame queued\n");
 487 #if 1
 488                         /* usually after an error: toss frame */
 489                         dev->readptr += tt;
 490                         if (dev->readptr > dev->sh_mem + BANK2 + BANKLEN)
 491                                 dev->readptr -= BANKLEN;
 492 #else
 493                         pcbit_l2_error(dev);
 494 #endif
 495                         return;
 496 
 497                 }
 498         }
 499 
 500         memcpy_frompcbit(dev, skb_put(frame->skb, tt), tt);
 501 
 502         frame->copied += tt;
 503 
 504         if (frame->copied == frame->hdr_len + frame->dt_len) {
 505            
 506                 save_flags(flags);
 507                 cli();
 508       
 509                 if (type1) {
 510                         dev->read_frame = NULL;
 511                 }
 512       
 513                 if (dev->read_queue) {
 514                         struct frame_buf *ptr;
 515                         for(ptr=dev->read_queue;ptr->next;ptr=ptr->next);
 516                         ptr->next = frame;
 517                 }
 518                 else
 519                         dev->read_queue = frame;
 520 
 521                 pcbit_sched_delivery(dev);
 522                 restore_flags(flags);
 523 
 524         }
 525         else {        
 526                 save_flags(flags);
 527                 cli();
 528                 dev->read_frame = frame;
 529                 restore_flags(flags);
 530         }
 531 }
 532 
 533 /*
 534  *  The board sends 0 sized frames
 535  *  They are TDATA_CONFs that get messed up somehow
 536  *  gotta send a fake acknowledgment to the upper layer somehow
 537  */
 538 
 539 static __inline__ void pcbit_fake_conf(struct pcbit_dev *dev, struct pcbit_chan * chan)
     /* [previous][next][first][last][top][bottom][index][help] */
 540 {
 541      isdn_ctrl ictl;
 542 
 543      if (chan->queued) {
 544              chan->queued--;
 545              
 546              ictl.driver = dev->id;
 547              ictl.command = ISDN_STAT_BSENT;
 548              ictl.arg = chan->id;
 549              dev->dev_if->statcallb(&ictl);     
 550      }
 551 }
 552 
 553 static void pcbit_firmware_bug(struct pcbit_dev * dev) 
     /* [previous][next][first][last][top][bottom][index][help] */
 554 {
 555         struct pcbit_chan *chan;
 556         
 557         chan = dev->b1;
 558 
 559         if (chan->fsm_state == ST_ACTIVE) {
 560             pcbit_fake_conf(dev, chan);
 561         }
 562 
 563         chan = dev->b2;
 564 
 565         if (chan->fsm_state == ST_ACTIVE) {
 566             pcbit_fake_conf(dev, chan);
 567         }
 568  
 569 }
 570 
 571 void pcbit_irq_handler(int interrupt, void * devptr, struct pt_regs *regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 572 {
 573         struct pcbit_dev * dev;
 574         u_char info, ack_seq, read_seq;
 575         u_char ack_int = 1;
 576 
 577         dev = (struct pcbit_dev *) devptr;
 578 
 579         if (!dev)
 580         {
 581                 printk(KERN_WARNING "pcbit_irq_handler: wrong device\n");
 582                 return;
 583         }
 584 
 585         if (dev->interrupt) {
 586                 printk(KERN_DEBUG "pcbit: reentering interrupt hander\n");
 587                 return;
 588         }
 589 
 590         dev->interrupt = 1;
 591 
 592         info = readb(dev->sh_mem + BANK3);
 593 
 594         if (dev->l2_state == L2_STARTING || dev->l2_state == L2_ERROR)
 595         {
 596                 pcbit_l2_active_conf(dev, info);
 597                 dev->interrupt = 0;
 598                 return;
 599         }
 600 
 601         if (info & 0x40U)       /* E bit set */
 602         {
 603 #ifdef DEBUG
 604                 printk(KERN_DEBUG "pcbit_irq_handler: E bit on\n");
 605 #endif
 606                 pcbit_l2_error(dev);
 607                 dev->interrupt = 0;
 608                 return;
 609         }
 610 
 611         if (dev->l2_state != L2_RUNNING && dev->l2_state != L2_LOADING) 
 612         {
 613                 dev->interrupt = 0;
 614                 return;
 615         }
 616 
 617         ack_seq =  (info >> 3) & 0x07U;
 618         read_seq = (info & 0x07U); 
 619         
 620         dev->interrupt = 0;
 621         sti();
 622 
 623         /*
 624          *      Bottom Half
 625          *      Runs with ints enabled
 626          */
 627 
 628         if (read_seq != dev->rcv_seq)
 629         {
 630                 pcbit_frame_read(dev, read_seq);
 631                 ack_int = 0;
 632         }
 633 
 634         if (ack_seq != dev->unack_seq)
 635         {
 636                 pcbit_recv_ack(dev, ack_seq);
 637                 ack_int = 0;
 638         }
 639 
 640         if (ack_int) 
 641         {
 642                 info = 0;
 643                 info |= dev->rcv_seq << 3;
 644                 info |= dev->send_seq;
 645     
 646                 writeb(info, dev->sh_mem + BANK4);  
 647         }       
 648 }
 649 
 650 
 651 static void pcbit_l2_active_conf(struct pcbit_dev *dev, u_char info)
     /* [previous][next][first][last][top][bottom][index][help] */
 652 {
 653         u_char state;
 654 
 655         state = dev->l2_state;
 656 
 657 #ifdef DEBUG
 658         printk(KERN_DEBUG "layer2_active_confirm\n");
 659 #endif
 660         
 661 
 662         if (info & 0x80U ) {
 663                 dev->rcv_seq = info & 0x07U;
 664                 dev->l2_state = L2_RUNNING;
 665         }
 666         else
 667                 dev->l2_state = L2_DOWN;
 668                 
 669         if (state == L2_STARTING)
 670                 wake_up_interruptible(&dev->set_running_wq);
 671 
 672         if (state == L2_ERROR && dev->l2_state == L2_RUNNING) {
 673                 pcbit_transmit(dev);
 674         }
 675 
 676 }
 677 
 678 static void pcbit_l2_err_recover(unsigned long data) 
     /* [previous][next][first][last][top][bottom][index][help] */
 679 {
 680 
 681         struct pcbit_dev * dev;
 682         struct frame_buf *frame;
 683 
 684         dev = (struct pcbit_dev *) data;
 685 
 686         del_timer(&dev->error_recover_timer);
 687         if (dev->w_busy || dev->r_busy)
 688           {
 689             init_timer(&dev->error_recover_timer);
 690             dev->error_recover_timer.expires = jiffies + ERRTIME;
 691             add_timer(&dev->error_recover_timer);
 692             return;
 693           }
 694 
 695         dev->w_busy = dev->r_busy = 1;
 696 
 697         if (dev->read_frame) {
 698                 if (dev->read_frame->skb) {
 699                         dev->read_frame->skb->free = 1; 
 700                         kfree_skb(dev->read_frame->skb, FREE_READ);
 701                 }
 702                 kfree(dev->read_frame);
 703                 dev->read_frame = NULL;
 704         }
 705 
 706 
 707         if (dev->write_queue) {
 708                 frame = dev->write_queue;
 709 #ifdef FREE_ON_ERROR
 710                 dev->write_queue = dev->write_queue->next;
 711 
 712                 if (frame->skb) {
 713                         dev_kfree_skb(frame->skb, FREE_WRITE);
 714                 }
 715                 
 716                 kfree(frame);
 717 #else           
 718                 frame->copied = 0;
 719 #endif
 720         }
 721 
 722         dev->rcv_seq = dev->send_seq = dev->unack_seq = 0;
 723         dev->free = 511;
 724         dev->l2_state = L2_ERROR;
 725 
 726         /* this is an hack... */
 727         pcbit_firmware_bug(dev);
 728 
 729         dev->writeptr = dev->sh_mem;
 730         dev->readptr = dev->sh_mem + BANK2;
 731 
 732         writeb((0x80U | ((dev->rcv_seq & 0x07) << 3) | (dev->send_seq & 0x07)),
 733                dev->sh_mem + BANK4);
 734         dev->w_busy = dev->r_busy = 0;
 735 
 736 }
 737 
 738 static void pcbit_l2_error(struct pcbit_dev *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 739 {
 740         if (dev->l2_state == L2_RUNNING) {
 741 
 742                 printk(KERN_INFO "pcbit: layer 2 error\n");
 743 
 744 #ifdef DEBUG
 745                 log_state(dev);
 746 #endif
 747                 
 748                 dev->l2_state = L2_DOWN;
 749 
 750                 init_timer(&dev->error_recover_timer);
 751                 dev->error_recover_timer.function = &pcbit_l2_err_recover;
 752                 dev->error_recover_timer.data = (ulong) dev;
 753                 dev->error_recover_timer.expires = jiffies + ERRTIME;
 754                 add_timer(&dev->error_recover_timer);
 755         }
 756 }
 757 
 758 /*
 759  * Description:
 760  * if board acks frames
 761  *   update dev->free
 762  *   call pcbit_transmit to write possible queued frames
 763  */
 764 
 765 static void  pcbit_recv_ack(struct pcbit_dev *dev, unsigned char ack)
     /* [previous][next][first][last][top][bottom][index][help] */
 766 {
 767         int i, count;
 768         int unacked;
 769 
 770         unacked = (dev->send_seq + (8 - dev->unack_seq) ) & 0x07;
 771 
 772         /* dev->unack_seq < ack <= dev->send_seq; */
 773 
 774         if (unacked) 
 775         {
 776 
 777                 if (dev->send_seq > dev->unack_seq)
 778                         if (ack <= dev->unack_seq || ack > dev->send_seq) 
 779                         {
 780                                 printk("layer 2 ack unacceptable - dev %d", dev->id);
 781                                 pcbit_l2_error(dev);
 782                         }
 783                         else
 784                                 if (ack > dev->send_seq && ack <= dev->unack_seq) {
 785                                         printk("layer 2 ack unacceptable - dev %d", dev->id);
 786                                         pcbit_l2_error(dev);
 787                                 }
 788 
 789                 /* ack is acceptable */
 790 
 791 
 792                 i = dev->unack_seq;
 793 
 794                 do {
 795                         dev->unack_seq = i = (i + 1) % 8;
 796                         dev->free += dev->fsize[i];
 797                 } while (i != ack);
 798 
 799                 count = 0;
 800                 while (count < 7 && dev->write_queue) 
 801                 {
 802                         u8 lsend_seq = dev->send_seq;
 803 
 804                         pcbit_transmit(dev);
 805 
 806                         if (dev->send_seq == lsend_seq)
 807                                 break;
 808                         count++;                        
 809                 }
 810     
 811                 if (!count) {
 812                         u_char info;
 813 
 814                         info = 0;
 815                         info |= dev->rcv_seq << 3;
 816                         info |= dev->send_seq;
 817         
 818                         writeb(info, dev->sh_mem + BANK4);  
 819                 }
 820         }
 821         else
 822                 printk(KERN_DEBUG "recv_ack: unacked = 0\n");
 823 }
 824 
 825 static void pcbit_frame_read(struct pcbit_dev * dev, unsigned char read_seq)
     /* [previous][next][first][last][top][bottom][index][help] */
 826 {
 827         unsigned long flags;
 828         int busy;
 829         u_char info;
 830 
 831         save_flags(flags);
 832         cli();
 833         if (!(busy=dev->r_busy))
 834                 dev->r_busy = 1;
 835         restore_flags(flags);
 836 
 837         if (busy)
 838                 return;
 839         
 840 
 841         while (read_seq != dev->rcv_seq) {
 842                 pcbit_receive(dev);
 843                 dev->rcv_seq = (dev->rcv_seq + 1) % 8;  
 844         }
 845 
 846         dev->r_busy = 0;
 847 
 848         info = 0;
 849         info |= dev->rcv_seq << 3;
 850         info |= dev->send_seq;
 851   
 852         writeb(info, dev->sh_mem + BANK4);  
 853 }
 854 
 855 
 856 
 857 
 858 
 859 

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