root/drivers/net/sdla.c

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

DEFINITIONS

This source file includes following definitions.
  1. sdla_read
  2. sdla_write
  3. sdla_clear
  4. sdla_byte
  5. sdla_stop
  6. sdla_start
  7. sdla_z80_poll
  8. sdla_cpuspeed
  9. sdla_errors
  10. sdla_cmd
  11. sdla_activate
  12. sdla_deactivate
  13. sdla_assoc
  14. sdla_deassoc
  15. sdla_dlci_conf
  16. sdla_transmit
  17. sdla_receive
  18. sdla_isr
  19. sdla_poll
  20. sdla_close
  21. sdla_open
  22. sdla_config
  23. sdla_xfer
  24. sdla_reconfig
  25. sdla_ioctl
  26. sdla_change_mtu
  27. sdla_set_config
  28. sdla_stats
  29. sdla_init
  30. sdla_setup
  31. init_module
  32. cleanup_module

   1 /*
   2  * SDLA      An implementation of a driver for the Sangoma S502/S508 series
   3  *           multi-protocol PC interface card.  Initial offering is with 
   4  *           the DLCI driver, providing Frame Relay support for linux.
   5  *
   6  *           Global definitions for the Frame relay interface.
   7  *
   8  * Version:  @(#)sdla.c   0.10   23 Mar 1996
   9  *
  10  * Credits:  Sangoma Technologies, for the use of 2 cards for an extended
  11  *                                 period of time.
  12  *           David Mandelstam <dm@sangoma.com> for getting me started on 
  13  *                            this project, and incentive to complete it.
  14  *           Gene Kozen <74604.152@compuserve.com> for providing me with
  15  *                      important information about the cards.
  16  *
  17  * Author:   Mike McLagan <mike.mclagan@linux.org>
  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 #include <linux/module.h>
  26 
  27 #include <linux/kernel.h>
  28 #include <linux/sched.h>
  29 #include <linux/types.h>
  30 #include <linux/fcntl.h>
  31 #include <linux/interrupt.h>
  32 #include <linux/ptrace.h>
  33 #include <linux/ioport.h>
  34 #include <linux/in.h>
  35 #include <linux/malloc.h>
  36 #include <linux/string.h>
  37 #include <linux/timer.h>
  38 #include <linux/errno.h>
  39 
  40 #include <asm/system.h>
  41 #include <asm/bitops.h>
  42 #include <asm/io.h>
  43 #include <asm/dma.h>
  44 
  45 #include <linux/netdevice.h>
  46 #include <linux/skbuff.h>
  47 #include <linux/if_arp.h>
  48 #include <linux/if_frad.h>
  49 
  50 #include <linux/sdla.h>
  51 
  52 static const char* version = "SDLA driver v0.10, 23 Mar 1996, mike.mclagan@linux.org";
  53 
  54 static const char* devname = "sdla";
  55 
  56 static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};
  57 
  58 static unsigned int valid_mem[]  = {0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 
  59                                     0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
  60                                     0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
  61                                     0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
  62                                     0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 
  63 
  64 /*********************************************************
  65  *
  66  * these are the core routines that access the card itself 
  67  *
  68  *********************************************************/
  69 
  70 #define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)
  71 
  72 static void sdla_read(struct device *dev, int addr, void *buf, short len)
     /* [previous][next][first][last][top][bottom][index][help] */
  73 {
  74    unsigned long flags;
  75    char          *temp, *base;
  76    int           offset, bytes;
  77 
  78    temp = buf;
  79    while(len)
  80    {
  81       offset = addr & 0x1FFF;
  82       if (offset + len > 0x2000)
  83          bytes = 0x2000 - offset;
  84       else
  85          bytes = len;
  86 
  87       base = (void *) dev->mem_start;
  88       base += offset;
  89 
  90       save_flags(flags);
  91       cli();
  92       SDLA_WINDOW(dev, addr);
  93       memcpy(temp, base, bytes);
  94       restore_flags(flags);
  95 
  96       addr += bytes;
  97       temp += bytes;
  98       len  -= bytes;
  99    }  
 100 }
 101 
 102 static void sdla_write(struct device *dev, int addr, void *buf, short len)
     /* [previous][next][first][last][top][bottom][index][help] */
 103 {
 104    unsigned long flags;
 105    char          *temp, *base;
 106    int           offset, bytes;
 107 
 108    temp = buf;
 109    while(len)
 110    {
 111       offset = addr & 0x1FFF;
 112       if (offset + len > 0x2000)
 113          bytes = 0x2000 - offset;
 114       else
 115          bytes = len;
 116 
 117       base = (void *) dev->mem_start;
 118       base += offset;
 119 
 120       save_flags(flags);
 121       cli();
 122       SDLA_WINDOW(dev, addr);
 123       memcpy(base, temp, bytes);
 124       restore_flags(flags);
 125 
 126       addr += bytes;
 127       temp += bytes;
 128       len  -= bytes;
 129    }
 130 }
 131 
 132 static void sdla_clear(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 133 {
 134    unsigned long flags;
 135    char          *base;
 136    int           offset, len, addr, bytes;
 137 
 138    len = 65536;
 139    addr = 0;
 140    while(len)
 141    {
 142       offset = addr & 0x1FFF;
 143       if (offset + len > 0x2000)
 144          bytes = offset + len - 0x2000;
 145       else
 146          bytes = len;
 147 
 148       base = (void *) dev->mem_start;
 149       base += offset;
 150 
 151       save_flags(flags);
 152       cli();
 153       SDLA_WINDOW(dev, addr);
 154       memset(base, 0, bytes);
 155       restore_flags(flags);
 156 
 157       addr += bytes;
 158       len  -= bytes;
 159    }
 160 }
 161 
 162 static char sdla_byte(struct device *dev, int addr)
     /* [previous][next][first][last][top][bottom][index][help] */
 163 {
 164    unsigned long flags;
 165    char          byte, *temp;
 166 
 167    temp = (void *) dev->mem_start;
 168    temp += addr & 0x1FFF;
 169 
 170    save_flags(flags);
 171    cli();
 172    SDLA_WINDOW(dev, addr);
 173    byte = *temp;
 174    restore_flags(flags);
 175 
 176    return(byte);
 177 }
 178 
 179 void sdla_stop(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181    struct frad_local *flp;
 182 
 183    flp = dev->priv;
 184    switch(flp->type)
 185    {
 186       case SDLA_S502A:
 187          outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
 188          flp->state = SDLA_HALT;
 189          break;
 190       case SDLA_S502E:
 191          outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
 192          outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
 193          flp->state = SDLA_S502E_ENABLE;
 194          break;
 195       case SDLA_S507:
 196          flp->state &= ~SDLA_CPUEN;
 197          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 198          break;
 199       case SDLA_S508:
 200          flp->state &= ~SDLA_CPUEN;
 201          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 202          break;
 203    }
 204 }
 205 
 206 void sdla_start(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 207 {
 208    struct frad_local *flp;
 209 
 210    flp = dev->priv;
 211    switch(flp->type)
 212    {
 213       case SDLA_S502A:
 214          outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
 215          outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
 216          flp->state = SDLA_S502A_START;
 217          break;
 218       case SDLA_S502E:
 219          outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
 220          outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
 221          flp->state = 0;
 222          break;
 223       case SDLA_S507:
 224          flp->state |= SDLA_CPUEN;
 225          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 226          break;
 227       case SDLA_S508:
 228          flp->state |= SDLA_CPUEN;
 229          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 230          break;
 231    }
 232 }
 233 
 234 /****************************************************
 235  *
 236  * this is used for the S502A/E cards to determine
 237  * the speed of the onboard CPU.  Calibration is
 238  * necessary for the Frame Relay code uploaded 
 239  * later.  Incorrect results cause timing problems
 240  * with link checks & status messages
 241  *
 242  ***************************************************/
 243 
 244 int sdla_z80_poll(struct device *dev, int z80_addr, int jiffs, char resp1, char resp2)
     /* [previous][next][first][last][top][bottom][index][help] */
 245 {
 246    unsigned long start, done, now;
 247    char          resp, *temp;
 248 
 249    start = now = jiffies;
 250    done = jiffies + jiffs;
 251 
 252    temp = (void *)dev->mem_start;
 253    temp += z80_addr & 0x1FFF;
 254 
 255    resp = ~resp1;
 256    while ((jiffies < done) && (resp != resp1) && (!resp2 || (resp != resp2)))
 257    {
 258       if (jiffies != now)
 259       {
 260          SDLA_WINDOW(dev, z80_addr);
 261          now = jiffies;
 262          resp = *temp;
 263       }
 264    }
 265    return(jiffies < done ? jiffies - start : -1);
 266 }
 267 
 268 /* constants for Z80 CPU speed */
 269 #define Z80_READY               '1'     /* Z80 is ready to begin */
 270 #define LOADER_READY            '2'     /* driver is ready to begin */
 271 #define Z80_SCC_OK              '3'     /* SCC is on board */
 272 #define Z80_SCC_BAD             '4'     /* SCC was not found */
 273 
 274 static int sdla_cpuspeed(struct device *dev, struct ifreq *ifr)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276    int  jiffs;
 277    char data;
 278 
 279    sdla_start(dev);
 280    if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
 281       return(-EIO);
 282 
 283    data = LOADER_READY;
 284    sdla_write(dev, 0, &data, 1);
 285 
 286    if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
 287       return(-EIO);
 288 
 289    sdla_stop(dev);
 290    sdla_read(dev, 0, &data, 1);
 291 
 292    if (data == Z80_SCC_BAD)
 293       return(-EIO);
 294 
 295    if (data != Z80_SCC_OK)
 296       return(-EINVAL);
 297 
 298    if (jiffs < 165)
 299       ifr->ifr_mtu = SDLA_CPU_16M;
 300    else
 301       if (jiffs < 220)
 302          ifr->ifr_mtu = SDLA_CPU_10M;
 303       else
 304          if (jiffs < 258)
 305             ifr->ifr_mtu = SDLA_CPU_8M;
 306          else
 307             if (jiffs < 357)
 308                ifr->ifr_mtu = SDLA_CPU_7M;
 309             else
 310                if (jiffs < 467)
 311                   ifr->ifr_mtu = SDLA_CPU_5M;
 312                else
 313                   ifr->ifr_mtu = SDLA_CPU_3M;
 314  
 315    return(0);
 316 }
 317 
 318 /************************************************
 319  *
 320  *  Direct interaction with the Frame Relay code 
 321  *  starts here.
 322  *
 323  ************************************************/
 324 
 325 struct _dlci_stat {
 326    short dlci           __attribute__((packed));
 327    char  flags          __attribute__((packed));
 328 };
 329 
 330 struct _frad_stat {
 331    char    flags;
 332    struct _dlci_stat dlcis[SDLA_MAX_DLCI];
 333 };
 334 
 335 static void sdla_errors(struct device *dev, int cmd, int dlci, int ret, int len, void *data) 
     /* [previous][next][first][last][top][bottom][index][help] */
 336 {
 337    struct _dlci_stat *pstatus;
 338    short             *pdlci;
 339    int               i;
 340    char              *state;
 341 
 342    switch (ret)
 343    {
 344       case SDLA_RET_MODEM:
 345          state = data;
 346          if (*state & SDLA_MODEM_DCD_LOW)
 347             printk(KERN_NOTICE "%s: Modem DCD unexpectedly low!\n", dev->name);
 348          if (*state & SDLA_MODEM_CTS_LOW)
 349             printk(KERN_NOTICE "%s: Modem CTS unexpectedly low!\n", dev->name);
 350 /* I should probably do something about this! */
 351          break;
 352 
 353       case SDLA_RET_CHANNEL_OFF:
 354          printk(KERN_NOTICE "%s: Channel became inoperative!\n", dev->name);
 355 /* same here */
 356          break;
 357 
 358       case SDLA_RET_CHANNEL_ON:
 359          printk(KERN_NOTICE "%s: Channel became operative!\n", dev->name);
 360 /* same here */
 361          break;
 362 
 363       case SDLA_RET_DLCI_STATUS:
 364          printk(KERN_NOTICE "%s: Status change reported by Access Node.\n", dev->name);
 365          len /= sizeof(struct _dlci_stat);
 366          for(pstatus = data, i=0;i < len;i++,pstatus++)
 367          {
 368             if (pstatus->flags & SDLA_DLCI_NEW)
 369                state = "new";
 370             else
 371                if (pstatus->flags & SDLA_DLCI_DELETED)
 372                   state = "deleted";
 373                else
 374                   if (pstatus->flags & SDLA_DLCI_ACTIVE)
 375                      state = "active";
 376                   else
 377                      state = "unknown status";
 378  
 379             printk(KERN_NOTICE "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
 380 /* same here */
 381          }
 382          break;
 383 
 384       case SDLA_RET_DLCI_UNKNOWN:
 385          printk(KERN_DEBUG "%s: Received unknown DLCIs:", dev->name);
 386          len /= 2;
 387          for(pdlci = data,i=0;i < len;i++,pdlci++)
 388             printk(" %i", *pdlci);
 389          printk("\n");
 390          break;
 391 
 392       case SDLA_RET_TIMEOUT:
 393          printk(KERN_ERR "%s: Command timed out!\n", dev->name);
 394          break;
 395 
 396       default: 
 397          /*
 398           * Further processing could be done here 
 399           * printk(KERN_DEBUG "%s: Unhandled return code 0x%2.2X\n", dev->name, ret);
 400           *
 401           */
 402    }
 403 }
 404 
 405 static int sdla_cmd(struct device *dev, int cmd, short dlci, short flags, 
     /* [previous][next][first][last][top][bottom][index][help] */
 406                         void *inbuf, short inlen, void *outbuf, short *outlen)
 407 {
 408    static struct _frad_stat status;
 409    struct frad_local        *flp;
 410    struct sdla_cmd          *cmd_buf;
 411    unsigned long            pflags;
 412    int                      jiffs, ret, waiting, len;
 413    long                     temp, window;
 414 
 415    flp = dev->priv;
 416 
 417    window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
 418    temp = (int) dev->mem_start;
 419    temp += window & 0x1FFF;
 420    cmd_buf = (struct sdla_cmd *)temp;
 421    ret = 0;
 422    jiffs = jiffies + HZ / 2;  /* 1/2 second timeout */
 423    save_flags(pflags);
 424    cli();
 425    SDLA_WINDOW(dev, window);
 426    cmd_buf->cmd = cmd;
 427    cmd_buf->dlci = dlci;
 428    cmd_buf->flags = flags;
 429 
 430    if (inbuf)
 431       memcpy(cmd_buf->data, inbuf, inlen);
 432 
 433    cmd_buf->length = inlen;
 434 
 435    cmd_buf->opp_flag = 1;
 436    restore_flags(pflags);
 437 
 438    waiting = 1;
 439    len = 0;
 440    while (waiting && (jiffies <= jiffs))
 441    {
 442       if (waiting++ % 4) 
 443       {
 444          save_flags(pflags);
 445          cli();
 446          SDLA_WINDOW(dev, window);
 447          waiting = ((volatile)(cmd_buf->opp_flag));
 448          restore_flags(pflags);
 449       }
 450    }
 451    
 452    if (!waiting)
 453    {
 454       save_flags(pflags);
 455       cli();
 456       SDLA_WINDOW(dev, window);
 457       ret = cmd_buf->retval;
 458       len = cmd_buf->length;
 459       if (outbuf && len)
 460       {
 461          *outlen = *outlen >= len ? len : *outlen;
 462          memcpy(outbuf, cmd_buf->data, *outlen);
 463       }
 464       if (ret)
 465          memcpy(&status, cmd_buf->data, len);
 466       restore_flags(pflags);
 467    }
 468    else
 469       ret = SDLA_RET_TIMEOUT;
 470 
 471    if (ret != SDLA_RET_OK)
 472       sdla_errors(dev, cmd, dlci, ret, len, &status);
 473 
 474    return(ret);
 475 }
 476 
 477 /***********************************************
 478  *
 479  * these functions are called by the DLCI driver 
 480  *
 481  ***********************************************/
 482 
 483 static int sdla_reconfig(struct device *dev);
 484 
 485 int sdla_activate(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 486 {
 487    struct frad_local *flp;
 488    int               i;
 489 
 490    flp = slave->priv;
 491 
 492    for(i=0;i<CONFIG_DLCI_MAX;i++)
 493       if (flp->master[i] == master)
 494          break;
 495 
 496    if (i == CONFIG_DLCI_MAX)
 497       return(-ENODEV);
 498 
 499    flp->dlci[i] = abs(flp->dlci[i]);
 500 
 501    if (slave->start && (flp->config.station == FRAD_STATION_NODE))
 502       sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
 503 
 504    return(0);
 505 }
 506 
 507 int sdla_deactivate(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 508 {
 509    struct frad_local *flp;
 510    int               i;
 511 
 512    flp = slave->priv;
 513 
 514    for(i=0;i<CONFIG_DLCI_MAX;i++)
 515       if (flp->master[i] == master)
 516          break;
 517 
 518    flp->dlci[i] = -abs(flp->dlci[i]);
 519 
 520    if (slave->start && (flp->config.station == FRAD_STATION_NODE))
 521       sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);
 522 
 523    return(0);
 524 }
 525 
 526 int sdla_assoc(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 527 {
 528    struct frad_local *flp;
 529    int               i;
 530 
 531    if (master->type != ARPHRD_DLCI)
 532       return(-EINVAL);
 533 
 534    flp = slave->priv;
 535 
 536    for(i=0;i<CONFIG_DLCI_MAX;i++)
 537    {
 538       if (!flp->master[i])
 539          break;
 540       if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
 541          return(-EADDRINUSE);
 542    } 
 543 
 544    if (i == CONFIG_DLCI_MAX)
 545       return(-EMLINK);  /* #### Alan: Comments on this ?? */
 546 
 547    MOD_INC_USE_COUNT;
 548 
 549    flp->master[i] = master;
 550    flp->dlci[i] = -*(short *)(master->dev_addr);
 551    master->mtu = slave->mtu;
 552 
 553    if (slave->start)
 554       if (flp->config.station == FRAD_STATION_CPE)
 555          sdla_reconfig(slave);
 556       else
 557          sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
 558 
 559    return(0);
 560 }
 561 
 562 int sdla_deassoc(struct device *slave, struct device *master)
     /* [previous][next][first][last][top][bottom][index][help] */
 563 {
 564    struct frad_local *flp;
 565    int               i;
 566 
 567    flp = slave->priv;
 568 
 569    for(i=0;i<CONFIG_DLCI_MAX;i++)
 570       if (flp->master[i] == master)
 571          break;
 572 
 573    if (i == CONFIG_DLCI_MAX)
 574       return(-ENODEV);
 575 
 576    flp->master[i] = NULL;
 577    flp->dlci[i] = 0;
 578 
 579    MOD_DEC_USE_COUNT;
 580 
 581    if (slave->start)
 582       if (flp->config.station == FRAD_STATION_CPE)
 583          sdla_reconfig(slave);
 584       else
 585          sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
 586 
 587    return(0);
 588 }
 589 
 590 int sdla_dlci_conf(struct device *slave, struct device *master, int get)
     /* [previous][next][first][last][top][bottom][index][help] */
 591 {
 592    struct frad_local *flp;
 593    struct frad_local *dlp;
 594    int               i;
 595 
 596    flp = slave->priv;
 597 
 598    for(i=0;i<CONFIG_DLCI_MAX;i++)
 599       if (flp->master[i] == master)
 600          break;
 601 
 602    if (i == CONFIG_DLCI_MAX)
 603       return(-ENODEV);
 604 
 605    dlp = master->priv;
 606    if (slave->start)
 607       sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, flp->dlci[i], 0,  
 608                   &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
 609 
 610    return(0);
 611 }
 612 
 613 /**************************
 614  *
 615  * now for the Linux driver 
 616  *
 617  **************************/
 618 
 619 static int sdla_transmit(struct sk_buff *skb, struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 620 {
 621    struct frad_local *flp;
 622    int               ret, addr;
 623    short             size;
 624    unsigned long     flags;
 625    struct buf_entry  *pbuf;
 626 
 627    flp = dev->priv;
 628    ret = 0;
 629 
 630    if (dev->tbusy) 
 631       return(1);
 632 
 633    if (skb == NULL) 
 634       return(0);
 635 
 636    if (set_bit(0, (void*)&dev->tbusy) != 0)
 637       printk(KERN_WARNING "%s: transmitter access conflict.\n", dev->name);
 638    else
 639    {
 640       switch (flp->type)
 641       {
 642          case SDLA_S502A:
 643          case SDLA_S502E:
 644             ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
 645             break;
 646 
 647          case SDLA_S508:
 648             size = sizeof(addr);
 649             ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
 650             if (ret == SDLA_RET_OK)
 651             {
 652                save_flags(flags); 
 653                cli();
 654                SDLA_WINDOW(dev, addr);
 655                pbuf = (void *)(((int) dev->mem_start) + (addr & 0x1FFF));
 656 
 657                sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
 658 
 659                SDLA_WINDOW(dev, addr);
 660                pbuf->opp_flag = 1;
 661                restore_flags(flags);
 662             }
 663             break;
 664       }
 665  
 666       switch (ret)
 667       {
 668          case SDLA_RET_OK:
 669             flp->stats.tx_packets++;
 670             ret = 0;
 671             break;
 672  
 673          default:
 674             flp->stats.tx_errors++;
 675             ret = 1;
 676       }
 677 
 678       /* per Alan Cox, we can drop the packet on the floor if it doesn't go */
 679       dev_kfree_skb(skb, FREE_WRITE);
 680 
 681       dev->tbusy = 0;
 682    }
 683    return(ret);
 684 }
 685 
 686 static void sdla_receive(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 687 {
 688    struct device     *master;
 689    struct frad_local *flp;
 690    struct dlci_local *dlp;
 691    struct sk_buff    *skb;
 692 
 693    struct sdla_cmd   *cmd;
 694    struct buf_info   *pbufi;
 695    struct buf_entry  *pbuf;
 696 
 697    unsigned long     flags;
 698    int               i, received, success, addr;
 699    short             dlci, len, split;
 700    char              bogus;
 701 
 702    flp = dev->priv;
 703    bogus = 0;
 704    success = 0;
 705    received = 0;
 706    addr = 0;
 707    skb = NULL;
 708    master = NULL;
 709 
 710    save_flags(flags);
 711    cli();
 712 
 713    switch (flp->type)
 714    {
 715       case SDLA_S502A:
 716       case SDLA_S502E:
 717          cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & 0x1FFF));
 718          SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
 719          if (!cmd->opp_flag)
 720             break;
 721 
 722          dlci = cmd->dlci;
 723          len = cmd->length;
 724 
 725          for (i=0;i<CONFIG_DLCI_MAX;i++)
 726             if (flp->dlci[i] == dlci)
 727                break;
 728 
 729          if (i == CONFIG_DLCI_MAX)
 730          {
 731             printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
 732             flp->stats.rx_errors++;
 733             cmd->opp_flag = 0;
 734             break;
 735          }
 736 
 737          master = flp->master[i];
 738          skb = dev_alloc_skb(len);
 739          if (skb == NULL) 
 740          {
 741             printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 742             flp->stats.rx_dropped++;
 743             cmd->opp_flag = 0;
 744             break;
 745          }
 746 
 747          /* pick up the data */
 748          sdla_read(dev, dev->mem_start + ((SDLA_502_RCV_BUF + SDLA_502_DATA_OFS) & 0x1FFF), skb_put(skb,len), len);
 749          cmd->opp_flag = 0;
 750          success = 1;
 751          break;
 752 
 753       case SDLA_S508:
 754          pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & 0x1FFF));
 755          SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 756          pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & 0x1FFF));
 757          if (!pbuf->opp_flag)
 758             break;
 759 
 760          dlci = pbuf->dlci;
 761          len = pbuf->length;
 762          addr = pbuf->buf_addr;
 763 
 764          for (i=0;i<CONFIG_DLCI_MAX;i++)
 765             if (flp->dlci[i] == dlci)
 766                break;
 767 
 768          if (i == CONFIG_DLCI_MAX)
 769          {
 770             printk(KERN_NOTICE "%s: Recieved packet from invalid DLCI %i, ignoring.", dev->name, dlci);
 771             flp->stats.rx_errors++;
 772             pbuf->opp_flag = 0;
 773             break;
 774          }
 775 
 776          master = flp->master[i];
 777          skb = dev_alloc_skb(len);
 778          if (skb == NULL) 
 779          {
 780             printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
 781             flp->stats.rx_dropped++;
 782             pbuf->opp_flag = 0;
 783             break;
 784          }
 785 
 786          /* is this buffer split off the end of the internal ring buffer */
 787          split = addr + len > pbufi->buf_top + 1 ? pbufi->buf_top - addr + 1 : 0;
 788          len -= split;
 789 
 790          /* lets get the data */
 791          sdla_read(dev, addr, skb_put(skb, len), len);
 792          if (split)
 793          {
 794             SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 795             sdla_read(dev, pbufi->buf_base, skb_put(skb, split), split);
 796          }
 797 
 798          SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
 799          pbuf->opp_flag = 0;
 800          success = 1;
 801 
 802          /* increment the buffer we're looking at */
 803          flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
 804          break;
 805    }
 806 
 807    if (success)
 808    {
 809       flp->stats.rx_packets++;
 810       dlp = master->priv;
 811       (*dlp->receive)(skb, master);
 812    }
 813 
 814    restore_flags(flags);
 815 }
 816 
 817 static void sdla_isr(int irq, void *dev_id, struct pt_regs * regs)
     /* [previous][next][first][last][top][bottom][index][help] */
 818 {
 819    struct device     *dev;
 820    struct frad_local *flp;
 821    char              byte;
 822 
 823    dev = irq2dev_map[irq];
 824 
 825    if (dev == NULL)
 826    {
 827       printk(KERN_WARNING "sdla_isr(): irq %d for unknown device.\n", irq);
 828       return;
 829    }
 830 
 831    flp = dev->priv;
 832 
 833    if (!flp->initialized)
 834    {
 835       printk(KERN_WARNING "%s: irq %d for unintialiazed device.\n", dev->name, irq);
 836       return;
 837    }
 838 
 839    dev->interrupt = 1;
 840    byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
 841    switch (byte)
 842    {
 843       case SDLA_INTR_RX:
 844          sdla_receive(dev);
 845          break;
 846 
 847       /* the command will get an error return, which is processed above */
 848       case SDLA_INTR_MODEM:
 849       case SDLA_INTR_STATUS:
 850          sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
 851          break;
 852 
 853       case SDLA_INTR_TX:
 854       case SDLA_INTR_COMPLETE:
 855       case SDLA_INTR_TIMER:
 856          printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
 857          break;
 858    }
 859 
 860    /* the S502E requires a manual acknowledgement of the interrupt */ 
 861    if (flp->type == SDLA_S502E)
 862    {
 863       flp->state &= ~SDLA_S502E_INTACK;
 864       outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 865       flp->state |= SDLA_S502E_INTACK;
 866       outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 867    }
 868 
 869    dev->interrupt = 0;
 870    /* this clears the byte, informing the Z80 we're done */
 871    byte = 0;
 872    sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
 873 }
 874 
 875 static void sdla_poll(unsigned long device)
     /* [previous][next][first][last][top][bottom][index][help] */
 876 {
 877    struct device     *dev;
 878    struct frad_local *flp;
 879 
 880    dev = (struct device *) device;
 881    flp = dev->priv;
 882 
 883    if (sdla_byte(dev, SDLA_502_RCV_BUF))
 884       sdla_receive(dev);
 885 
 886    flp->timer.expires = 1;
 887    add_timer(&flp->timer);
 888 }
 889 
 890 static int sdla_close(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 891 {
 892    struct frad_local *flp;
 893    struct intr_info  intr;
 894    int               len, i;
 895    short             dlcis[CONFIG_DLCI_MAX];
 896 
 897    flp = dev->priv;
 898 
 899    len = 0;
 900    for(i=0;i<CONFIG_DLCI_MAX;i++)
 901       if (flp->dlci[i])
 902          dlcis[len++] = abs(flp->dlci[i]);
 903    len *= 2;
 904 
 905    if (flp->config.station == FRAD_STATION_NODE)
 906    {
 907       for(i=0;i<CONFIG_DLCI_MAX;i++)
 908          if (flp->dlci[i] > 0) 
 909             sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
 910       sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
 911    }
 912 
 913    memset(&intr, 0, sizeof(intr));
 914    /* lets start up the reception */
 915    switch(flp->type)
 916    {
 917       case SDLA_S502A:
 918          del_timer(&flp->timer); 
 919          break;
 920 
 921       case SDLA_S502E:
 922          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
 923          flp->state &= ~SDLA_S502E_INTACK;
 924          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 925          break;
 926 
 927       case SDLA_S507:
 928          break;
 929 
 930       case SDLA_S508:
 931          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
 932          flp->state &= ~SDLA_S508_INTEN;
 933          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
 934          break;
 935    }
 936 
 937    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 938    sdla_stop(dev);
 939 
 940    dev->tbusy = 1;
 941    dev->start = 0;
 942 
 943    MOD_DEC_USE_COUNT;
 944 
 945    return(0);
 946 }
 947 
 948 struct conf_data {
 949    struct frad_conf config;
 950    short            dlci[CONFIG_DLCI_MAX];
 951 };
 952 
 953 static int sdla_open(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 954 {
 955    struct frad_local *flp;
 956    struct dlci_local *dlp;
 957    struct conf_data  data;
 958    struct intr_info  intr;
 959    int               len, i;
 960    char              byte;
 961 
 962    flp = dev->priv;
 963 
 964    if (!flp->initialized)
 965       return(-EPERM);
 966 
 967    if (!flp->configured)
 968       return(-EPERM);
 969 
 970    /* off to the races! */
 971    sdla_start(dev);
 972 
 973    /* time to send in the configuration */
 974    len = 0;
 975    for(i=0;i<CONFIG_DLCI_MAX;i++)
 976       if (flp->dlci[i])
 977          data.dlci[len++] = abs(flp->dlci[i]);
 978    len *= 2;
 979 
 980    memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
 981    len += sizeof(struct frad_conf);
 982 
 983    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 984    sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
 985 
 986    if (flp->type == SDLA_S508)
 987       flp->buffer = 0;
 988 
 989    sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
 990 
 991    /* lets start up the reception */
 992    memset(&intr, 0, sizeof(intr));
 993    switch(flp->type)
 994    {
 995       case SDLA_S502A:
 996          flp->timer.expires = 1;
 997          add_timer(&flp->timer);
 998          break;
 999 
1000       case SDLA_S502E:
1001          flp->state |= SDLA_S502E_ENABLE;
1002          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1003          flp->state |= SDLA_S502E_INTACK;
1004          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1005          byte = 0;
1006          sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
1007          intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1008          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
1009          break;
1010 
1011       case SDLA_S507:
1012          break;
1013 
1014       case SDLA_S508:
1015          flp->state |= SDLA_S508_INTEN;
1016          outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1017          byte = 0;
1018          sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
1019          intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
1020          intr.irq = dev->irq;
1021          sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
1022          break;
1023    }
1024 
1025    if (flp->config.station == FRAD_STATION_CPE)
1026    {
1027       byte = SDLA_ICS_STATUS_ENQ;
1028       sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
1029    }
1030    else
1031    {
1032       sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
1033       for(i=0;i<CONFIG_DLCI_MAX;i++)
1034          if (flp->dlci[i] > 0)
1035             sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
1036    }
1037 
1038    /* configure any specific DLCI settings */
1039    for(i=0;i<CONFIG_DLCI_MAX;i++)
1040       if (flp->dlci[i])
1041       {
1042          dlp = flp->master[i]->priv;
1043          if (dlp->configured)
1044             sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
1045       }
1046 
1047    dev->tbusy = 0;
1048    dev->interrupt = 0;
1049    dev->start = 1;
1050 
1051    MOD_INC_USE_COUNT;
1052 
1053    return(0);
1054 }
1055 
1056 static int sdla_config(struct device *dev, struct frad_conf *conf, int get)
     /* [previous][next][first][last][top][bottom][index][help] */
1057 {
1058    struct frad_local *flp;
1059    struct conf_data  data;
1060    int               i, err;
1061 
1062    if (dev->type == 0xFFFF)
1063       return(-EUNATCH);
1064 
1065    flp = dev->priv;
1066 
1067    if (!get)
1068    {
1069       if (dev->start)
1070          return(-EBUSY);
1071 
1072       err = verify_area(VERIFY_READ, conf, sizeof(struct frad_conf));
1073       if (err)
1074          return(err);
1075 
1076       memcpy_fromfs(&data.config, conf, sizeof(struct frad_conf));
1077 
1078       if (data.config.station & ~FRAD_STATION_NODE)
1079          return(-EINVAL);
1080 
1081       if (data.config.flags & ~FRAD_VALID_FLAGS)
1082          return(-EINVAL);
1083 
1084       if ((data.config.kbaud < 0) || 
1085           ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
1086          return(-EINVAL);
1087 
1088       if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
1089          return(-EINVAL);
1090 
1091       if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
1092          return(-EINVAL);
1093 
1094       if ((data.config.T391 < 5) || (data.config.T391 > 30))
1095          return(-EINVAL);
1096 
1097       if ((data.config.T392 < 5) || (data.config.T392 > 30))
1098          return(-EINVAL);
1099 
1100       if ((data.config.N391 < 1) || (data.config.N391 > 255))
1101          return(-EINVAL);
1102 
1103       if ((data.config.N392 < 1) || (data.config.N392 > 10))
1104          return(-EINVAL);
1105 
1106       if ((data.config.N393 < 1) || (data.config.N393 > 10))
1107          return(-EINVAL);
1108 
1109       memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1110       flp->config.flags |= SDLA_DIRECT_RECV;
1111 
1112       if (dev->mtu != flp->config.mtu)
1113       {
1114          /* this is required to change the MTU */
1115          dev->mtu = flp->config.mtu;
1116          for(i=0;i<CONFIG_DLCI_MAX;i++)
1117             if (flp->master[i])
1118                flp->master[i]->mtu = flp->config.mtu;
1119       }
1120 
1121       flp->config.mtu += sizeof(struct fradhdr);
1122       flp->configured = 1;
1123    }
1124    else
1125    {
1126       err = verify_area(VERIFY_WRITE, conf, sizeof(struct frad_conf));
1127       if (err)
1128          return(err);
1129 
1130       sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, &data, sizeof(data), NULL, NULL);
1131       memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
1132 
1133       data.config.flags &= ~SDLA_DIRECT_RECV;
1134       data.config.mtu -= sizeof(struct fradhdr);
1135       memcpy_tofs(conf, &data.config, sizeof(struct frad_conf));
1136    }
1137 
1138    return(0);
1139 }
1140 
1141 static int sdla_xfer(struct device *dev, struct sdla_mem *info, int read)
     /* [previous][next][first][last][top][bottom][index][help] */
1142 {
1143    struct sdla_mem mem;
1144    int    err;
1145    char   *temp;
1146 
1147    err = verify_area(VERIFY_READ, info, sizeof(struct sdla_mem));
1148    if (err)
1149       return(err);
1150 
1151    memcpy_fromfs(&mem, info, sizeof(mem));
1152    if (read)
1153    {
1154       err = verify_area(VERIFY_WRITE, mem.data, mem.len);
1155       if (err)
1156          return(err);
1157 
1158       temp = kmalloc(mem.len, GFP_KERNEL);
1159       if (!temp)
1160          return(-ENOMEM);
1161       sdla_read(dev, mem.addr, temp, mem.len);
1162       memcpy_tofs(mem.data, temp, mem.len);
1163       kfree(temp);
1164    }
1165    else
1166    {
1167       err = verify_area(VERIFY_READ, mem.data, mem.len);
1168       if (err)
1169          return(err);
1170 
1171       temp = kmalloc(mem.len, GFP_KERNEL);
1172       if (!temp)
1173          return(-ENOMEM);
1174       memcpy_fromfs(temp, mem.data, mem.len);
1175       sdla_write(dev, mem.addr, temp, mem.len);
1176       kfree(temp);
1177    }
1178    return(0);
1179 }
1180 
1181 static int sdla_reconfig(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1182 {
1183    struct frad_local *flp;
1184    struct conf_data  data;
1185    int               i, len;
1186 
1187    flp = dev->priv;
1188 
1189    memcpy(&data, &flp->config, sizeof(struct frad_conf));
1190 
1191    len = 0;
1192    for(i=0;i<CONFIG_DLCI_MAX;i++)
1193       if (flp->dlci[i])
1194          data.dlci[len++] = flp->dlci[i];
1195    len *= 2;
1196    len += sizeof(struct frad_conf);
1197 
1198    sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1199    sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
1200    sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
1201 
1202    return(0);
1203 }
1204 
1205 static int sdla_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
     /* [previous][next][first][last][top][bottom][index][help] */
1206 {
1207    struct frad_local *flp;
1208 
1209    flp = dev->priv;
1210 
1211    if (!flp->initialized)
1212       return(-EPERM);
1213 
1214    switch (cmd)
1215    {
1216       case FRAD_GET_CONF:
1217       case FRAD_SET_CONF:
1218          return(sdla_config(dev, (struct frad_conf *)ifr->ifr_data, cmd == FRAD_GET_CONF));
1219 
1220       case SDLA_IDENTIFY:
1221          ifr->ifr_flags = flp->type;
1222          break;
1223 
1224       case SDLA_CPUSPEED:
1225          return(sdla_cpuspeed(dev, ifr)); 
1226 
1227 /* ==========================================================
1228 NOTE:  This is rather a useless action right now, as the
1229        driver does not support protocols other than FR right
1230        now.  However, Sangoma has modules for a number of
1231        other protocols.
1232 ============================================================*/
1233       case SDLA_PROTOCOL:
1234          if (flp->configured)
1235             return(-EALREADY);
1236 
1237          switch (ifr->ifr_flags)
1238          {
1239             case ARPHRD_FRAD:
1240                dev->type = ifr->ifr_flags;
1241                dev->family = AF_UNSPEC;
1242                break;
1243 
1244             default:
1245                return(-ENOPROTOOPT);
1246          }
1247          break;
1248 
1249       case SDLA_CLEARMEM:
1250          sdla_clear(dev);
1251          break;
1252 
1253       case SDLA_WRITEMEM:
1254       case SDLA_READMEM:
1255          return(sdla_xfer(dev, (struct sdla_mem *)ifr->ifr_data, cmd == SDLA_READMEM));
1256 
1257       case SDLA_START:
1258          sdla_start(dev);
1259          break;
1260 
1261       case SDLA_STOP:
1262          sdla_stop(dev);
1263          break;
1264 
1265       default:
1266          return(-EOPNOTSUPP);
1267    }
1268    return(0);
1269 }
1270 
1271 int sdla_change_mtu(struct device *dev, int new_mtu)
     /* [previous][next][first][last][top][bottom][index][help] */
1272 {
1273    struct frad_local *flp;
1274 
1275    flp = dev->priv;
1276 
1277    if (dev->start)
1278       return(-EBUSY);
1279 
1280    /* for now, you can't change the MTU! */
1281    return(-EACCES);
1282 }
1283 
1284 int sdla_set_config(struct device *dev, struct ifmap *map)
     /* [previous][next][first][last][top][bottom][index][help] */
1285 {
1286    struct frad_local *flp;
1287    int               i;
1288    char              byte;
1289 
1290    flp = dev->priv;
1291 
1292    if (flp->initialized)
1293       return(-EINVAL);
1294 
1295    for(i=0;i < sizeof(valid_port) / sizeof (int) ; i++)
1296       if (valid_port[i] == map->base_addr)
1297          break;   
1298 
1299    if (i == sizeof(valid_port) / sizeof(int))
1300       return(-EINVAL);
1301 
1302    dev->base_addr = map->base_addr;
1303    request_region(dev->base_addr, SDLA_IO_EXTENTS, dev->name);
1304 
1305    /* test for card types, S502A, S502E, S507, S508                 */
1306    /* these tests shut down the card completely, so clear the state */
1307    flp->type = SDLA_UNKNOWN;
1308    flp->state = 0;
1309    
1310    for(i=1;i<SDLA_IO_EXTENTS;i++)
1311       if (inb(dev->base_addr + i) != 0xFF)
1312         break;
1313 
1314    if (i == SDLA_IO_EXTENTS)
1315    {   
1316       outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
1317       if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x08)
1318       {
1319          outb(SDLA_S502E_INTACK, dev->base_addr + SDLA_REG_CONTROL);
1320          if ((inb(dev->base_addr + SDLA_S502_STS) & 0x0F) == 0x0C)
1321          {
1322             outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1323             flp->type = SDLA_S502E;
1324          }
1325       }
1326    }
1327 
1328    if (flp->type == SDLA_UNKNOWN)
1329    {
1330       for(byte=inb(dev->base_addr),i=0;i<SDLA_IO_EXTENTS;i++)
1331          if (inb(dev->base_addr + i) != byte)
1332             break;
1333 
1334       if (i == SDLA_IO_EXTENTS)
1335       {
1336          outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1337          if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x30)
1338          {
1339             outb(SDLA_S507_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
1340             if ((inb(dev->base_addr + SDLA_S502_STS) & 0x7E) == 0x32)
1341             {
1342                outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1343                flp->type = SDLA_S507;
1344             }
1345          }
1346       }
1347    }
1348 
1349    if (flp->type == SDLA_UNKNOWN)
1350    {
1351       outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1352       if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x00)
1353       {
1354          outb(SDLA_S508_INTEN, dev->base_addr + SDLA_REG_CONTROL);
1355          if ((inb(dev->base_addr + SDLA_S508_STS) & 0x3F) == 0x10)
1356          {
1357             outb(SDLA_HALT, dev->base_addr + SDLA_REG_CONTROL);
1358             flp->type = SDLA_S508;
1359          }
1360       }
1361    }
1362 
1363    if (flp->type == SDLA_UNKNOWN)
1364    {
1365       outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
1366       if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
1367       {
1368          outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
1369          if (inb(dev->base_addr + SDLA_S502_STS) == 0x40)
1370          {
1371             outb(SDLA_S502A_INTEN, dev->base_addr + SDLA_REG_CONTROL);
1372             if (inb(dev->base_addr + SDLA_S502_STS) == 0x44)
1373             {
1374                outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
1375                flp->type = SDLA_S502A;
1376             }
1377          }
1378       }
1379    }
1380 
1381    if (flp->type == SDLA_UNKNOWN)
1382    {
1383       printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
1384       return(-ENODEV);
1385    }
1386 
1387    switch(dev->base_addr)
1388    {
1389       case 0x270:
1390       case 0x280:
1391       case 0x380: 
1392       case 0x390:
1393          if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
1394             return(-EINVAL);
1395    }
1396 
1397    switch (map->irq)
1398    {
1399       case 2:
1400          if (flp->type != SDLA_S502E)
1401             return(-EINVAL);
1402          break;
1403 
1404       case 10:
1405       case 11:
1406       case 12:
1407       case 15:
1408       case 4:
1409          if ((flp->type != SDLA_S508) && (flp->type != SDLA_S507))
1410             return(-EINVAL);
1411 
1412       case 3:
1413       case 5:
1414       case 7:
1415          if (flp->type == SDLA_S502A)
1416             return(-EINVAL);
1417          break;
1418 
1419       default:
1420          return(-EINVAL);
1421    }
1422    dev->irq = map->irq;
1423 
1424    if (request_irq(dev->irq, &sdla_isr, 0, dev->name, NULL)) 
1425       return(-EADDRINUSE);
1426 
1427    irq2dev_map[dev->irq] = dev;
1428 
1429    if (flp->type == SDLA_S507)
1430    {
1431       switch(dev->irq)
1432       {
1433          case 3:
1434             flp->state = SDLA_S507_IRQ3;
1435             break;
1436          case 4:
1437             flp->state = SDLA_S507_IRQ4;
1438             break;
1439          case 5:
1440             flp->state = SDLA_S507_IRQ5;
1441             break;
1442          case 7:
1443             flp->state = SDLA_S507_IRQ7;
1444             break;
1445          case 10:
1446             flp->state = SDLA_S507_IRQ10;
1447             break;
1448          case 11:
1449             flp->state = SDLA_S507_IRQ11;
1450             break;
1451          case 12:
1452             flp->state = SDLA_S507_IRQ12;
1453             break;
1454          case 15:
1455             flp->state = SDLA_S507_IRQ15;
1456             break;
1457       }
1458    }
1459 
1460    for(i=0;i < sizeof(valid_mem) / sizeof (int) ; i++)
1461       if (valid_mem[i] == map->mem_start)
1462          break;   
1463 
1464    if (i == sizeof(valid_mem) / sizeof(int))
1465       return(-EINVAL);
1466 
1467    if ((flp->type == SDLA_S502A) && (((map->mem_start & 0xF000) >> 12) == 0x0E))
1468       return(-EINVAL);
1469 
1470    if ((flp->type != SDLA_S507) && ((map->mem_start >> 16) == 0x0B))
1471       return(-EINVAL);
1472 
1473    if ((flp->type == SDLA_S507) && ((map->mem_start >> 16) == 0x0D))
1474       return(-EINVAL);
1475 
1476    dev->mem_start = map->mem_start;
1477    dev->mem_end = dev->mem_start + 0x2000;
1478 
1479    byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
1480    byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
1481    switch(flp->type)
1482    {
1483       case SDLA_S502A:
1484       case SDLA_S502E:
1485          switch (map->mem_start >> 16)
1486          {
1487             case 0x0A:
1488                byte |= SDLA_S502_SEG_A;
1489                break;
1490             case 0x0C:
1491                byte |= SDLA_S502_SEG_C;
1492                break;
1493             case 0x0D:
1494                byte |= SDLA_S502_SEG_D;
1495                break;
1496             case 0x0E:
1497                byte |= SDLA_S502_SEG_E;
1498                break;
1499          }
1500          break;
1501       case SDLA_S507:
1502          switch (map->mem_start >> 16)
1503          {
1504             case 0x0A:
1505                byte |= SDLA_S507_SEG_A;
1506                break;
1507             case 0x0B:
1508                byte |= SDLA_S507_SEG_B;
1509                break;
1510             case 0x0C:
1511                byte |= SDLA_S507_SEG_C;
1512                break;
1513             case 0x0E:
1514                byte |= SDLA_S507_SEG_E;
1515                break;
1516          }
1517          break;
1518       case SDLA_S508:
1519          switch (map->mem_start >> 16)
1520          {
1521             case 0x0A:
1522                byte |= SDLA_S508_SEG_A;
1523                break;
1524             case 0x0C:
1525                byte |= SDLA_S508_SEG_C;
1526                break;
1527             case 0x0D:
1528                byte |= SDLA_S508_SEG_D;
1529                break;
1530             case 0x0E:
1531                byte |= SDLA_S508_SEG_E;
1532                break;
1533          }
1534          break;
1535    }
1536 
1537    /* set the memory bits, and enable access */
1538    outb(byte, dev->base_addr + SDLA_REG_PC_WINDOW);
1539    switch(flp->type)
1540    {
1541       case SDLA_S502E:
1542          flp->state = SDLA_S502E_ENABLE;
1543          break;
1544       case SDLA_S507:
1545          flp->state |= SDLA_MEMEN;
1546          break;
1547       case SDLA_S508:
1548          flp->state = SDLA_MEMEN;
1549          break;
1550    }
1551    outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
1552 
1553    flp->initialized = 1;
1554    return(0);
1555 }
1556  
1557 static struct enet_statistics *sdla_stats(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1558 {
1559    struct frad_local *flp;
1560 
1561    flp = dev->priv;
1562 
1563    return(&flp->stats);
1564 }
1565 
1566 int sdla_init(struct device *dev)
     /* [previous][next][first][last][top][bottom][index][help] */
1567 {
1568    struct frad_local *flp;
1569    int               i;
1570 
1571    /* allocate the private data structure */
1572    flp = kmalloc(sizeof(struct frad_local), GFP_KERNEL);
1573    if (!flp)
1574       return(-ENOMEM);
1575 
1576    memset(flp, 0, sizeof(struct frad_local));
1577    dev->priv = flp;
1578 
1579    dev->flags           = 0;
1580    dev->open            = sdla_open;
1581    dev->stop            = sdla_close;
1582    dev->do_ioctl        = sdla_ioctl;
1583    dev->set_config      = sdla_set_config;
1584    dev->get_stats       = sdla_stats;
1585    dev->hard_start_xmit = sdla_transmit;
1586    dev->change_mtu      = sdla_change_mtu;
1587 
1588    dev->type            = 0xFFFF;
1589    dev->family          = AF_UNSPEC;
1590    dev->pa_alen         = sizeof(unsigned long);
1591    dev->hard_header_len = 0;
1592    dev->mtu             = SDLA_MAX_MTU;
1593 
1594    for (i = 0; i < DEV_NUMBUFFS; i++) 
1595       skb_queue_head_init(&dev->buffs[i]);
1596 
1597    flp->activate        = sdla_activate;
1598    flp->deactivate      = sdla_deactivate;
1599    flp->assoc           = sdla_assoc;
1600    flp->deassoc         = sdla_deassoc;
1601    flp->dlci_conf       = sdla_dlci_conf;
1602 
1603    init_timer(&flp->timer);
1604    flp->timer.expires   = 1;
1605    flp->timer.data      = (unsigned long) dev;
1606    flp->timer.function  = sdla_poll;
1607 
1608    return(0);
1609 }
1610 
1611 void sdla_setup(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1612 {
1613    printk("%s.\n", version);
1614    register_frad(devname);
1615 }
1616 
1617 #ifdef MODULE
1618 static struct device sdla0 = {"sdla0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, sdla_init};
1619 
1620 int init_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1621 {
1622    int result;
1623 
1624    sdla_setup();
1625    if ((result = register_netdev(&sdla0)) != 0)
1626       return result;
1627 
1628    return 0;
1629 }
1630 
1631 void cleanup_module(void)
     /* [previous][next][first][last][top][bottom][index][help] */
1632 {
1633    unregister_netdev(&sdla0);
1634    if (sdla0.priv)
1635       kfree(sdla0.priv);
1636    if (sdla0.irq)
1637       free_irq(sdla0.irq, NULL);
1638 }
1639 #endif /* MODULE */

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