1/* $Id: b1.c,v 1.1.1.1 2007/08/03 18:52:34 Exp $ 2 * 3 * Common module for AVM B1 cards. 4 * 5 * Copyright 1999 by Carsten Paeth <calle@calle.de> 6 * 7 * This software may be used and distributed according to the terms 8 * of the GNU General Public License, incorporated herein by reference. 9 * 10 */ 11 12#include <linux/module.h> 13#include <linux/kernel.h> 14#include <linux/pci.h> 15#include <linux/skbuff.h> 16#include <linux/delay.h> 17#include <linux/mm.h> 18#include <linux/interrupt.h> 19#include <linux/ioport.h> 20#include <linux/capi.h> 21#include <linux/kernelcapi.h> 22#include <asm/io.h> 23#include <linux/init.h> 24#include <asm/uaccess.h> 25#include <linux/netdevice.h> 26#include <linux/isdn/capilli.h> 27#include "avmcard.h" 28#include <linux/isdn/capicmd.h> 29#include <linux/isdn/capiutil.h> 30 31static char *revision = "$Revision: 1.1.1.1 $"; 32 33/* ------------------------------------------------------------- */ 34 35MODULE_DESCRIPTION("CAPI4Linux: Common support for active AVM cards"); 36MODULE_AUTHOR("Carsten Paeth"); 37MODULE_LICENSE("GPL"); 38 39/* ------------------------------------------------------------- */ 40 41int b1_irq_table[16] = 42{0, 43 0, 44 0, 45 192, /* irq 3 */ 46 32, /* irq 4 */ 47 160, /* irq 5 */ 48 96, /* irq 6 */ 49 224, /* irq 7 */ 50 0, 51 64, /* irq 9 */ 52 80, /* irq 10 */ 53 208, /* irq 11 */ 54 48, /* irq 12 */ 55 0, 56 0, 57 112, /* irq 15 */ 58}; 59 60/* ------------------------------------------------------------- */ 61 62avmcard *b1_alloc_card(int nr_controllers) 63{ 64 avmcard *card; 65 avmctrl_info *cinfo; 66 int i; 67 68 card = kzalloc(sizeof(*card), GFP_KERNEL); 69 if (!card) 70 return NULL; 71 72 cinfo = kzalloc(sizeof(*cinfo) * nr_controllers, GFP_KERNEL); 73 if (!cinfo) { 74 kfree(card); 75 return NULL; 76 } 77 78 card->ctrlinfo = cinfo; 79 for (i = 0; i < nr_controllers; i++) { 80 INIT_LIST_HEAD(&cinfo[i].ncci_head); 81 cinfo[i].card = card; 82 } 83 spin_lock_init(&card->lock); 84 card->nr_controllers = nr_controllers; 85 86 return card; 87} 88 89/* ------------------------------------------------------------- */ 90 91void b1_free_card(avmcard *card) 92{ 93 kfree(card->ctrlinfo); 94 kfree(card); 95} 96 97/* ------------------------------------------------------------- */ 98 99int b1_detect(unsigned int base, enum avmcardtype cardtype) 100{ 101 int onoff, i; 102 103 /* 104 * Statusregister 0000 00xx 105 */ 106 if ((inb(base + B1_INSTAT) & 0xfc) 107 || (inb(base + B1_OUTSTAT) & 0xfc)) 108 return 1; 109 /* 110 * Statusregister 0000 001x 111 */ 112 b1outp(base, B1_INSTAT, 0x2); /* enable irq */ 113 /* b1outp(base, B1_OUTSTAT, 0x2); */ 114 if ((inb(base + B1_INSTAT) & 0xfe) != 0x2 115 /* || (inb(base + B1_OUTSTAT) & 0xfe) != 0x2 */) 116 return 2; 117 /* 118 * Statusregister 0000 000x 119 */ 120 b1outp(base, B1_INSTAT, 0x0); /* disable irq */ 121 b1outp(base, B1_OUTSTAT, 0x0); 122 if ((inb(base + B1_INSTAT) & 0xfe) 123 || (inb(base + B1_OUTSTAT) & 0xfe)) 124 return 3; 125 126 for (onoff = !0, i= 0; i < 10 ; i++) { 127 b1_set_test_bit(base, cardtype, onoff); 128 if (b1_get_test_bit(base, cardtype) != onoff) 129 return 4; 130 onoff = !onoff; 131 } 132 133 if (cardtype == avm_m1) 134 return 0; 135 136 if ((b1_rd_reg(base, B1_STAT1(cardtype)) & 0x0f) != 0x01) 137 return 5; 138 139 return 0; 140} 141 142void b1_getrevision(avmcard *card) 143{ 144 card->class = inb(card->port + B1_ANALYSE); 145 card->revision = inb(card->port + B1_REVISION); 146} 147 148#define FWBUF_SIZE 256 149int b1_load_t4file(avmcard *card, capiloaddatapart * t4file) 150{ 151 unsigned char buf[FWBUF_SIZE]; 152 unsigned char *dp; 153 int i, left; 154 unsigned int base = card->port; 155 156 dp = t4file->data; 157 left = t4file->len; 158 while (left > FWBUF_SIZE) { 159 if (t4file->user) { 160 if (copy_from_user(buf, dp, FWBUF_SIZE)) 161 return -EFAULT; 162 } else { 163 memcpy(buf, dp, FWBUF_SIZE); 164 } 165 for (i = 0; i < FWBUF_SIZE; i++) 166 if (b1_save_put_byte(base, buf[i]) < 0) { 167 printk(KERN_ERR "%s: corrupted firmware file ?\n", 168 card->name); 169 return -EIO; 170 } 171 left -= FWBUF_SIZE; 172 dp += FWBUF_SIZE; 173 } 174 if (left) { 175 if (t4file->user) { 176 if (copy_from_user(buf, dp, left)) 177 return -EFAULT; 178 } else { 179 memcpy(buf, dp, left); 180 } 181 for (i = 0; i < left; i++) 182 if (b1_save_put_byte(base, buf[i]) < 0) { 183 printk(KERN_ERR "%s: corrupted firmware file ?\n", 184 card->name); 185 return -EIO; 186 } 187 } 188 return 0; 189} 190 191int b1_load_config(avmcard *card, capiloaddatapart * config) 192{ 193 unsigned char buf[FWBUF_SIZE]; 194 unsigned char *dp; 195 unsigned int base = card->port; 196 int i, j, left; 197 198 dp = config->data; 199 left = config->len; 200 if (left) { 201 b1_put_byte(base, SEND_CONFIG); 202 b1_put_word(base, 1); 203 b1_put_byte(base, SEND_CONFIG); 204 b1_put_word(base, left); 205 } 206 while (left > FWBUF_SIZE) { 207 if (config->user) { 208 if (copy_from_user(buf, dp, FWBUF_SIZE)) 209 return -EFAULT; 210 } else { 211 memcpy(buf, dp, FWBUF_SIZE); 212 } 213 for (i = 0; i < FWBUF_SIZE; ) { 214 b1_put_byte(base, SEND_CONFIG); 215 for (j=0; j < 4; j++) { 216 b1_put_byte(base, buf[i++]); 217 } 218 } 219 left -= FWBUF_SIZE; 220 dp += FWBUF_SIZE; 221 } 222 if (left) { 223 if (config->user) { 224 if (copy_from_user(buf, dp, left)) 225 return -EFAULT; 226 } else { 227 memcpy(buf, dp, left); 228 } 229 for (i = 0; i < left; ) { 230 b1_put_byte(base, SEND_CONFIG); 231 for (j=0; j < 4; j++) { 232 if (i < left) 233 b1_put_byte(base, buf[i++]); 234 else 235 b1_put_byte(base, 0); 236 } 237 } 238 } 239 return 0; 240} 241 242int b1_loaded(avmcard *card) 243{ 244 unsigned int base = card->port; 245 unsigned long stop; 246 unsigned char ans; 247 unsigned long tout = 2; 248 249 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { 250 if (b1_tx_empty(base)) 251 break; 252 } 253 if (!b1_tx_empty(base)) { 254 printk(KERN_ERR "%s: b1_loaded: tx err, corrupted t4 file ?\n", 255 card->name); 256 return 0; 257 } 258 b1_put_byte(base, SEND_POLL); 259 for (stop = jiffies + tout * HZ; time_before(jiffies, stop);) { 260 if (b1_rx_full(base)) { 261 if ((ans = b1_get_byte(base)) == RECEIVE_POLL) { 262 return 1; 263 } 264 printk(KERN_ERR "%s: b1_loaded: got 0x%x, firmware not running\n", 265 card->name, ans); 266 return 0; 267 } 268 } 269 printk(KERN_ERR "%s: b1_loaded: firmware not running\n", card->name); 270 return 0; 271} 272 273/* ------------------------------------------------------------- */ 274 275int b1_load_firmware(struct capi_ctr *ctrl, capiloaddata *data) 276{ 277 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 278 avmcard *card = cinfo->card; 279 unsigned int port = card->port; 280 unsigned long flags; 281 int retval; 282 283 b1_reset(port); 284 285 if ((retval = b1_load_t4file(card, &data->firmware))) { 286 b1_reset(port); 287 printk(KERN_ERR "%s: failed to load t4file!!\n", 288 card->name); 289 return retval; 290 } 291 292 b1_disable_irq(port); 293 294 if (data->configuration.len > 0 && data->configuration.data) { 295 if ((retval = b1_load_config(card, &data->configuration))) { 296 b1_reset(port); 297 printk(KERN_ERR "%s: failed to load config!!\n", 298 card->name); 299 return retval; 300 } 301 } 302 303 if (!b1_loaded(card)) { 304 printk(KERN_ERR "%s: failed to load t4file.\n", card->name); 305 return -EIO; 306 } 307 308 spin_lock_irqsave(&card->lock, flags); 309 b1_setinterrupt(port, card->irq, card->cardtype); 310 b1_put_byte(port, SEND_INIT); 311 b1_put_word(port, CAPI_MAXAPPL); 312 b1_put_word(port, AVM_NCCI_PER_CHANNEL*2); 313 b1_put_word(port, ctrl->cnr - 1); 314 spin_unlock_irqrestore(&card->lock, flags); 315 316 return 0; 317} 318 319void b1_reset_ctr(struct capi_ctr *ctrl) 320{ 321 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 322 avmcard *card = cinfo->card; 323 unsigned int port = card->port; 324 325 b1_reset(port); 326 b1_reset(port); 327 328 memset(cinfo->version, 0, sizeof(cinfo->version)); 329 capilib_release(&cinfo->ncci_head); 330 capi_ctr_reseted(ctrl); 331} 332 333void b1_register_appl(struct capi_ctr *ctrl, 334 u16 appl, 335 capi_register_params *rp) 336{ 337 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 338 avmcard *card = cinfo->card; 339 unsigned int port = card->port; 340 unsigned long flags; 341 int nconn, want = rp->level3cnt; 342 343 if (want > 0) nconn = want; 344 else nconn = ctrl->profile.nbchannel * -want; 345 if (nconn == 0) nconn = ctrl->profile.nbchannel; 346 347 spin_lock_irqsave(&card->lock, flags); 348 b1_put_byte(port, SEND_REGISTER); 349 b1_put_word(port, appl); 350 b1_put_word(port, 1024 * (nconn+1)); 351 b1_put_word(port, nconn); 352 b1_put_word(port, rp->datablkcnt); 353 b1_put_word(port, rp->datablklen); 354 spin_unlock_irqrestore(&card->lock, flags); 355} 356 357void b1_release_appl(struct capi_ctr *ctrl, u16 appl) 358{ 359 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 360 avmcard *card = cinfo->card; 361 unsigned int port = card->port; 362 unsigned long flags; 363 364 capilib_release_appl(&cinfo->ncci_head, appl); 365 366 spin_lock_irqsave(&card->lock, flags); 367 b1_put_byte(port, SEND_RELEASE); 368 b1_put_word(port, appl); 369 spin_unlock_irqrestore(&card->lock, flags); 370} 371 372u16 b1_send_message(struct capi_ctr *ctrl, struct sk_buff *skb) 373{ 374 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 375 avmcard *card = cinfo->card; 376 unsigned int port = card->port; 377 unsigned long flags; 378 u16 len = CAPIMSG_LEN(skb->data); 379 u8 cmd = CAPIMSG_COMMAND(skb->data); 380 u8 subcmd = CAPIMSG_SUBCOMMAND(skb->data); 381 u16 dlen, retval; 382 383 if (CAPICMD(cmd, subcmd) == CAPI_DATA_B3_REQ) { 384 retval = capilib_data_b3_req(&cinfo->ncci_head, 385 CAPIMSG_APPID(skb->data), 386 CAPIMSG_NCCI(skb->data), 387 CAPIMSG_MSGID(skb->data)); 388 if (retval != CAPI_NOERROR) 389 return retval; 390 391 dlen = CAPIMSG_DATALEN(skb->data); 392 393 spin_lock_irqsave(&card->lock, flags); 394 b1_put_byte(port, SEND_DATA_B3_REQ); 395 b1_put_slice(port, skb->data, len); 396 b1_put_slice(port, skb->data + len, dlen); 397 spin_unlock_irqrestore(&card->lock, flags); 398 } else { 399 spin_lock_irqsave(&card->lock, flags); 400 b1_put_byte(port, SEND_MESSAGE); 401 b1_put_slice(port, skb->data, len); 402 spin_unlock_irqrestore(&card->lock, flags); 403 } 404 405 dev_kfree_skb_any(skb); 406 return CAPI_NOERROR; 407} 408 409/* ------------------------------------------------------------- */ 410 411void b1_parse_version(avmctrl_info *cinfo) 412{ 413 struct capi_ctr *ctrl = &cinfo->capi_ctrl; 414 avmcard *card = cinfo->card; 415 capi_profile *profp; 416 u8 *dversion; 417 u8 flag; 418 int i, j; 419 420 for (j = 0; j < AVM_MAXVERSION; j++) 421 cinfo->version[j] = "\0\0" + 1; 422 for (i = 0, j = 0; 423 j < AVM_MAXVERSION && i < cinfo->versionlen; 424 j++, i += cinfo->versionbuf[i] + 1) 425 cinfo->version[j] = &cinfo->versionbuf[i + 1]; 426 427 strlcpy(ctrl->serial, cinfo->version[VER_SERIAL], sizeof(ctrl->serial)); 428 memcpy(&ctrl->profile, cinfo->version[VER_PROFILE],sizeof(capi_profile)); 429 strlcpy(ctrl->manu, "AVM GmbH", sizeof(ctrl->manu)); 430 dversion = cinfo->version[VER_DRIVER]; 431 ctrl->version.majorversion = 2; 432 ctrl->version.minorversion = 0; 433 ctrl->version.majormanuversion = (((dversion[0] - '0') & 0xf) << 4); 434 ctrl->version.majormanuversion |= ((dversion[2] - '0') & 0xf); 435 ctrl->version.minormanuversion = (dversion[3] - '0') << 4; 436 ctrl->version.minormanuversion |= 437 (dversion[5] - '0') * 10 + ((dversion[6] - '0') & 0xf); 438 439 profp = &ctrl->profile; 440 441 flag = ((u8 *)(profp->manu))[1]; 442 switch (flag) { 443 case 0: if (cinfo->version[VER_CARDTYPE]) 444 strcpy(cinfo->cardname, cinfo->version[VER_CARDTYPE]); 445 else strcpy(cinfo->cardname, "B1"); 446 break; 447 case 3: strcpy(cinfo->cardname,"PCMCIA B"); break; 448 case 4: strcpy(cinfo->cardname,"PCMCIA M1"); break; 449 case 5: strcpy(cinfo->cardname,"PCMCIA M2"); break; 450 case 6: strcpy(cinfo->cardname,"B1 V3.0"); break; 451 case 7: strcpy(cinfo->cardname,"B1 PCI"); break; 452 default: sprintf(cinfo->cardname, "AVM?%u", (unsigned int)flag); break; 453 } 454 printk(KERN_NOTICE "%s: card %d \"%s\" ready.\n", 455 card->name, ctrl->cnr, cinfo->cardname); 456 457 flag = ((u8 *)(profp->manu))[3]; 458 if (flag) 459 printk(KERN_NOTICE "%s: card %d Protocol:%s%s%s%s%s%s%s\n", 460 card->name, 461 ctrl->cnr, 462 (flag & 0x01) ? " DSS1" : "", 463 (flag & 0x02) ? " CT1" : "", 464 (flag & 0x04) ? " VN3" : "", 465 (flag & 0x08) ? " NI1" : "", 466 (flag & 0x10) ? " AUSTEL" : "", 467 (flag & 0x20) ? " ESS" : "", 468 (flag & 0x40) ? " 1TR6" : "" 469 ); 470 471 flag = ((u8 *)(profp->manu))[5]; 472 if (flag) 473 printk(KERN_NOTICE "%s: card %d Linetype:%s%s%s%s\n", 474 card->name, 475 ctrl->cnr, 476 (flag & 0x01) ? " point to point" : "", 477 (flag & 0x02) ? " point to multipoint" : "", 478 (flag & 0x08) ? " leased line without D-channel" : "", 479 (flag & 0x04) ? " leased line with D-channel" : "" 480 ); 481} 482 483/* ------------------------------------------------------------- */ 484 485irqreturn_t b1_interrupt(int interrupt, void *devptr) 486{ 487 avmcard *card = devptr; 488 avmctrl_info *cinfo = &card->ctrlinfo[0]; 489 struct capi_ctr *ctrl = &cinfo->capi_ctrl; 490 unsigned char b1cmd; 491 struct sk_buff *skb; 492 493 unsigned ApplId; 494 unsigned MsgLen; 495 unsigned DataB3Len; 496 unsigned NCCI; 497 unsigned WindowSize; 498 unsigned long flags; 499 500 spin_lock_irqsave(&card->lock, flags); 501 502 if (!b1_rx_full(card->port)) { 503 spin_unlock_irqrestore(&card->lock, flags); 504 return IRQ_NONE; 505 } 506 507 b1cmd = b1_get_byte(card->port); 508 509 switch (b1cmd) { 510 511 case RECEIVE_DATA_B3_IND: 512 513 ApplId = (unsigned) b1_get_word(card->port); 514 MsgLen = b1_get_slice(card->port, card->msgbuf); 515 DataB3Len = b1_get_slice(card->port, card->databuf); 516 spin_unlock_irqrestore(&card->lock, flags); 517 518 if (MsgLen < 30) { /* not CAPI 64Bit */ 519 memset(card->msgbuf+MsgLen, 0, 30-MsgLen); 520 MsgLen = 30; 521 CAPIMSG_SETLEN(card->msgbuf, 30); 522 } 523 if (!(skb = alloc_skb(DataB3Len + MsgLen, GFP_ATOMIC))) { 524 printk(KERN_ERR "%s: incoming packet dropped\n", 525 card->name); 526 } else { 527 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); 528 memcpy(skb_put(skb, DataB3Len), card->databuf, DataB3Len); 529 capi_ctr_handle_message(ctrl, ApplId, skb); 530 } 531 break; 532 533 case RECEIVE_MESSAGE: 534 535 ApplId = (unsigned) b1_get_word(card->port); 536 MsgLen = b1_get_slice(card->port, card->msgbuf); 537 spin_unlock_irqrestore(&card->lock, flags); 538 if (!(skb = alloc_skb(MsgLen, GFP_ATOMIC))) { 539 printk(KERN_ERR "%s: incoming packet dropped\n", 540 card->name); 541 } else { 542 memcpy(skb_put(skb, MsgLen), card->msgbuf, MsgLen); 543 if (CAPIMSG_CMD(skb->data) == CAPI_DATA_B3_CONF) 544 capilib_data_b3_conf(&cinfo->ncci_head, ApplId, 545 CAPIMSG_NCCI(skb->data), 546 CAPIMSG_MSGID(skb->data)); 547 548 capi_ctr_handle_message(ctrl, ApplId, skb); 549 } 550 break; 551 552 case RECEIVE_NEW_NCCI: 553 554 ApplId = b1_get_word(card->port); 555 NCCI = b1_get_word(card->port); 556 WindowSize = b1_get_word(card->port); 557 spin_unlock_irqrestore(&card->lock, flags); 558 559 capilib_new_ncci(&cinfo->ncci_head, ApplId, NCCI, WindowSize); 560 561 break; 562 563 case RECEIVE_FREE_NCCI: 564 565 ApplId = b1_get_word(card->port); 566 NCCI = b1_get_word(card->port); 567 spin_unlock_irqrestore(&card->lock, flags); 568 569 if (NCCI != 0xffffffff) 570 capilib_free_ncci(&cinfo->ncci_head, ApplId, NCCI); 571 572 break; 573 574 case RECEIVE_START: 575 /* b1_put_byte(card->port, SEND_POLLACK); */ 576 spin_unlock_irqrestore(&card->lock, flags); 577 capi_ctr_resume_output(ctrl); 578 break; 579 580 case RECEIVE_STOP: 581 spin_unlock_irqrestore(&card->lock, flags); 582 capi_ctr_suspend_output(ctrl); 583 break; 584 585 case RECEIVE_INIT: 586 587 cinfo->versionlen = b1_get_slice(card->port, cinfo->versionbuf); 588 spin_unlock_irqrestore(&card->lock, flags); 589 b1_parse_version(cinfo); 590 printk(KERN_INFO "%s: %s-card (%s) now active\n", 591 card->name, 592 cinfo->version[VER_CARDTYPE], 593 cinfo->version[VER_DRIVER]); 594 capi_ctr_ready(ctrl); 595 break; 596 597 case RECEIVE_TASK_READY: 598 ApplId = (unsigned) b1_get_word(card->port); 599 MsgLen = b1_get_slice(card->port, card->msgbuf); 600 spin_unlock_irqrestore(&card->lock, flags); 601 card->msgbuf[MsgLen] = 0; 602 while ( MsgLen > 0 603 && ( card->msgbuf[MsgLen-1] == '\n' 604 || card->msgbuf[MsgLen-1] == '\r')) { 605 card->msgbuf[MsgLen-1] = 0; 606 MsgLen--; 607 } 608 printk(KERN_INFO "%s: task %d \"%s\" ready.\n", 609 card->name, ApplId, card->msgbuf); 610 break; 611 612 case RECEIVE_DEBUGMSG: 613 MsgLen = b1_get_slice(card->port, card->msgbuf); 614 spin_unlock_irqrestore(&card->lock, flags); 615 card->msgbuf[MsgLen] = 0; 616 while ( MsgLen > 0 617 && ( card->msgbuf[MsgLen-1] == '\n' 618 || card->msgbuf[MsgLen-1] == '\r')) { 619 card->msgbuf[MsgLen-1] = 0; 620 MsgLen--; 621 } 622 printk(KERN_INFO "%s: DEBUG: %s\n", card->name, card->msgbuf); 623 break; 624 625 case 0xff: 626 spin_unlock_irqrestore(&card->lock, flags); 627 printk(KERN_ERR "%s: card removed ?\n", card->name); 628 return IRQ_NONE; 629 default: 630 spin_unlock_irqrestore(&card->lock, flags); 631 printk(KERN_ERR "%s: b1_interrupt: 0x%x ???\n", 632 card->name, b1cmd); 633 return IRQ_HANDLED; 634 } 635 return IRQ_HANDLED; 636} 637 638/* ------------------------------------------------------------- */ 639int b1ctl_read_proc(char *page, char **start, off_t off, 640 int count, int *eof, struct capi_ctr *ctrl) 641{ 642 avmctrl_info *cinfo = (avmctrl_info *)(ctrl->driverdata); 643 avmcard *card = cinfo->card; 644 u8 flag; 645 int len = 0; 646 char *s; 647 648 len += sprintf(page+len, "%-16s %s\n", "name", card->name); 649 len += sprintf(page+len, "%-16s 0x%x\n", "io", card->port); 650 len += sprintf(page+len, "%-16s %d\n", "irq", card->irq); 651 switch (card->cardtype) { 652 case avm_b1isa: s = "B1 ISA"; break; 653 case avm_b1pci: s = "B1 PCI"; break; 654 case avm_b1pcmcia: s = "B1 PCMCIA"; break; 655 case avm_m1: s = "M1"; break; 656 case avm_m2: s = "M2"; break; 657 case avm_t1isa: s = "T1 ISA (HEMA)"; break; 658 case avm_t1pci: s = "T1 PCI"; break; 659 case avm_c4: s = "C4"; break; 660 case avm_c2: s = "C2"; break; 661 default: s = "???"; break; 662 } 663 len += sprintf(page+len, "%-16s %s\n", "type", s); 664 if (card->cardtype == avm_t1isa) 665 len += sprintf(page+len, "%-16s %d\n", "cardnr", card->cardnr); 666 if ((s = cinfo->version[VER_DRIVER]) != 0) 667 len += sprintf(page+len, "%-16s %s\n", "ver_driver", s); 668 if ((s = cinfo->version[VER_CARDTYPE]) != 0) 669 len += sprintf(page+len, "%-16s %s\n", "ver_cardtype", s); 670 if ((s = cinfo->version[VER_SERIAL]) != 0) 671 len += sprintf(page+len, "%-16s %s\n", "ver_serial", s); 672 673 if (card->cardtype != avm_m1) { 674 flag = ((u8 *)(ctrl->profile.manu))[3]; 675 if (flag) 676 len += sprintf(page+len, "%-16s%s%s%s%s%s%s%s\n", 677 "protocol", 678 (flag & 0x01) ? " DSS1" : "", 679 (flag & 0x02) ? " CT1" : "", 680 (flag & 0x04) ? " VN3" : "", 681 (flag & 0x08) ? " NI1" : "", 682 (flag & 0x10) ? " AUSTEL" : "", 683 (flag & 0x20) ? " ESS" : "", 684 (flag & 0x40) ? " 1TR6" : "" 685 ); 686 } 687 if (card->cardtype != avm_m1) { 688 flag = ((u8 *)(ctrl->profile.manu))[5]; 689 if (flag) 690 len += sprintf(page+len, "%-16s%s%s%s%s\n", 691 "linetype", 692 (flag & 0x01) ? " point to point" : "", 693 (flag & 0x02) ? " point to multipoint" : "", 694 (flag & 0x08) ? " leased line without D-channel" : "", 695 (flag & 0x04) ? " leased line with D-channel" : "" 696 ); 697 } 698 len += sprintf(page+len, "%-16s %s\n", "cardname", cinfo->cardname); 699 700 if (off+count >= len) 701 *eof = 1; 702 if (len < off) 703 return 0; 704 *start = page + off; 705 return ((count < len-off) ? count : len-off); 706} 707 708/* ------------------------------------------------------------- */ 709 710#ifdef CONFIG_PCI 711 712avmcard_dmainfo * 713avmcard_dma_alloc(char *name, struct pci_dev *pdev, long rsize, long ssize) 714{ 715 avmcard_dmainfo *p; 716 void *buf; 717 718 p = kzalloc(sizeof(avmcard_dmainfo), GFP_KERNEL); 719 if (!p) { 720 printk(KERN_WARNING "%s: no memory.\n", name); 721 goto err; 722 } 723 724 p->recvbuf.size = rsize; 725 buf = pci_alloc_consistent(pdev, rsize, &p->recvbuf.dmaaddr); 726 if (!buf) { 727 printk(KERN_WARNING "%s: allocation of receive dma buffer failed.\n", name); 728 goto err_kfree; 729 } 730 p->recvbuf.dmabuf = buf; 731 732 p->sendbuf.size = ssize; 733 buf = pci_alloc_consistent(pdev, ssize, &p->sendbuf.dmaaddr); 734 if (!buf) { 735 printk(KERN_WARNING "%s: allocation of send dma buffer failed.\n", name); 736 goto err_free_consistent; 737 } 738 739 p->sendbuf.dmabuf = buf; 740 skb_queue_head_init(&p->send_queue); 741 742 return p; 743 744 err_free_consistent: 745 pci_free_consistent(p->pcidev, p->recvbuf.size, 746 p->recvbuf.dmabuf, p->recvbuf.dmaaddr); 747 err_kfree: 748 kfree(p); 749 err: 750 return NULL; 751} 752 753void avmcard_dma_free(avmcard_dmainfo *p) 754{ 755 pci_free_consistent(p->pcidev, p->recvbuf.size, 756 p->recvbuf.dmabuf, p->recvbuf.dmaaddr); 757 pci_free_consistent(p->pcidev, p->sendbuf.size, 758 p->sendbuf.dmabuf, p->sendbuf.dmaaddr); 759 skb_queue_purge(&p->send_queue); 760 kfree(p); 761} 762 763EXPORT_SYMBOL(avmcard_dma_alloc); 764EXPORT_SYMBOL(avmcard_dma_free); 765 766#endif 767 768EXPORT_SYMBOL(b1_irq_table); 769 770EXPORT_SYMBOL(b1_alloc_card); 771EXPORT_SYMBOL(b1_free_card); 772EXPORT_SYMBOL(b1_detect); 773EXPORT_SYMBOL(b1_getrevision); 774EXPORT_SYMBOL(b1_load_t4file); 775EXPORT_SYMBOL(b1_load_config); 776EXPORT_SYMBOL(b1_loaded); 777EXPORT_SYMBOL(b1_load_firmware); 778EXPORT_SYMBOL(b1_reset_ctr); 779EXPORT_SYMBOL(b1_register_appl); 780EXPORT_SYMBOL(b1_release_appl); 781EXPORT_SYMBOL(b1_send_message); 782 783EXPORT_SYMBOL(b1_parse_version); 784EXPORT_SYMBOL(b1_interrupt); 785 786EXPORT_SYMBOL(b1ctl_read_proc); 787 788static int __init b1_init(void) 789{ 790 char *p; 791 char rev[32]; 792 793 if ((p = strchr(revision, ':')) != 0 && p[1]) { 794 strlcpy(rev, p + 2, 32); 795 if ((p = strchr(rev, '$')) != 0 && p > rev) 796 *(p-1) = 0; 797 } else 798 strcpy(rev, "1.0"); 799 800 printk(KERN_INFO "b1: revision %s\n", rev); 801 802 return 0; 803} 804 805static void __exit b1_exit(void) 806{ 807} 808 809module_init(b1_init); 810module_exit(b1_exit); 811