diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 415 |
1 files changed, 198 insertions, 217 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 098c9de3022d..39269d19a02d 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -314,31 +314,27 @@ MODULE_PARM_DESC(poll_only, "Do not use card interrupts"); | |||
314 | /* for sysfs class support */ | 314 | /* for sysfs class support */ |
315 | static struct class *ip2_class; | 315 | static struct class *ip2_class; |
316 | 316 | ||
317 | // Some functions to keep track of what irq's we have | 317 | /* Some functions to keep track of what irqs we have */ |
318 | 318 | ||
319 | static int | 319 | static int __init is_valid_irq(int irq) |
320 | is_valid_irq(int irq) | ||
321 | { | 320 | { |
322 | int *i = Valid_Irqs; | 321 | int *i = Valid_Irqs; |
323 | 322 | ||
324 | while ((*i != 0) && (*i != irq)) { | 323 | while (*i != 0 && *i != irq) |
325 | i++; | 324 | i++; |
326 | } | 325 | |
327 | return (*i); | 326 | return *i; |
328 | } | 327 | } |
329 | 328 | ||
330 | static void | 329 | static void __init mark_requested_irq(char irq) |
331 | mark_requested_irq( char irq ) | ||
332 | { | 330 | { |
333 | rirqs[iindx++] = irq; | 331 | rirqs[iindx++] = irq; |
334 | } | 332 | } |
335 | 333 | ||
336 | #ifdef MODULE | 334 | static int __exit clear_requested_irq(char irq) |
337 | static int | ||
338 | clear_requested_irq( char irq ) | ||
339 | { | 335 | { |
340 | int i; | 336 | int i; |
341 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 337 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
342 | if (rirqs[i] == irq) { | 338 | if (rirqs[i] == irq) { |
343 | rirqs[i] = 0; | 339 | rirqs[i] = 0; |
344 | return 1; | 340 | return 1; |
@@ -346,17 +342,15 @@ clear_requested_irq( char irq ) | |||
346 | } | 342 | } |
347 | return 0; | 343 | return 0; |
348 | } | 344 | } |
349 | #endif | ||
350 | 345 | ||
351 | static int | 346 | static int have_requested_irq(char irq) |
352 | have_requested_irq( char irq ) | ||
353 | { | 347 | { |
354 | // array init to zeros so 0 irq will not be requested as a side effect | 348 | /* array init to zeros so 0 irq will not be requested as a side |
349 | * effect */ | ||
355 | int i; | 350 | int i; |
356 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 351 | for (i = 0; i < IP2_MAX_BOARDS; ++i) |
357 | if (rirqs[i] == irq) | 352 | if (rirqs[i] == irq) |
358 | return 1; | 353 | return 1; |
359 | } | ||
360 | return 0; | 354 | return 0; |
361 | } | 355 | } |
362 | 356 | ||
@@ -380,46 +374,44 @@ static void __exit ip2_cleanup_module(void) | |||
380 | int err; | 374 | int err; |
381 | int i; | 375 | int i; |
382 | 376 | ||
383 | #ifdef IP2DEBUG_INIT | ||
384 | printk (KERN_DEBUG "Unloading %s: version %s\n", pcName, pcVersion ); | ||
385 | #endif | ||
386 | /* Stop poll timer if we had one. */ | 377 | /* Stop poll timer if we had one. */ |
387 | if ( TimerOn ) { | 378 | if (TimerOn) { |
388 | del_timer ( &PollTimer ); | 379 | del_timer(&PollTimer); |
389 | TimerOn = 0; | 380 | TimerOn = 0; |
390 | } | 381 | } |
391 | 382 | ||
392 | /* Reset the boards we have. */ | 383 | /* Reset the boards we have. */ |
393 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 384 | for (i = 0; i < IP2_MAX_BOARDS; i++) |
394 | if ( i2BoardPtrTable[i] ) { | 385 | if (i2BoardPtrTable[i]) |
395 | iiReset( i2BoardPtrTable[i] ); | 386 | iiReset(i2BoardPtrTable[i]); |
396 | } | ||
397 | } | ||
398 | 387 | ||
399 | /* The following is done at most once, if any boards were installed. */ | 388 | /* The following is done at most once, if any boards were installed. */ |
400 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 389 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
401 | if ( i2BoardPtrTable[i] ) { | 390 | if (i2BoardPtrTable[i]) { |
402 | iiResetDelay( i2BoardPtrTable[i] ); | 391 | iiResetDelay(i2BoardPtrTable[i]); |
403 | /* free io addresses and Tibet */ | 392 | /* free io addresses and Tibet */ |
404 | release_region( ip2config.addr[i], 8 ); | 393 | release_region(ip2config.addr[i], 8); |
405 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); | 394 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i)); |
406 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, 4 * i + 1)); | 395 | device_destroy(ip2_class, MKDEV(IP2_IPL_MAJOR, |
396 | 4 * i + 1)); | ||
407 | } | 397 | } |
408 | /* Disable and remove interrupt handler. */ | 398 | /* Disable and remove interrupt handler. */ |
409 | if ( (ip2config.irq[i] > 0) && have_requested_irq(ip2config.irq[i]) ) { | 399 | if (ip2config.irq[i] > 0 && |
410 | free_irq ( ip2config.irq[i], (void *)&pcName); | 400 | have_requested_irq(ip2config.irq[i])) { |
411 | clear_requested_irq( ip2config.irq[i]); | 401 | free_irq(ip2config.irq[i], (void *)&pcName); |
402 | clear_requested_irq(ip2config.irq[i]); | ||
412 | } | 403 | } |
413 | } | 404 | } |
414 | class_destroy(ip2_class); | 405 | class_destroy(ip2_class); |
415 | if ( ( err = tty_unregister_driver ( ip2_tty_driver ) ) ) { | 406 | err = tty_unregister_driver(ip2_tty_driver); |
416 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", err); | 407 | if (err) |
417 | } | 408 | printk(KERN_ERR "IP2: failed to unregister tty driver (%d)\n", |
409 | err); | ||
418 | put_tty_driver(ip2_tty_driver); | 410 | put_tty_driver(ip2_tty_driver); |
419 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); | 411 | unregister_chrdev(IP2_IPL_MAJOR, pcIpl); |
420 | remove_proc_entry("ip2mem", NULL); | 412 | remove_proc_entry("ip2mem", NULL); |
421 | 413 | ||
422 | // free memory | 414 | /* free memory */ |
423 | for (i = 0; i < IP2_MAX_BOARDS; i++) { | 415 | for (i = 0; i < IP2_MAX_BOARDS; i++) { |
424 | void *pB; | 416 | void *pB; |
425 | #ifdef CONFIG_PCI | 417 | #ifdef CONFIG_PCI |
@@ -431,20 +423,14 @@ static void __exit ip2_cleanup_module(void) | |||
431 | #endif | 423 | #endif |
432 | pB = i2BoardPtrTable[i]; | 424 | pB = i2BoardPtrTable[i]; |
433 | if (pB != NULL) { | 425 | if (pB != NULL) { |
434 | kfree ( pB ); | 426 | kfree(pB); |
435 | i2BoardPtrTable[i] = NULL; | 427 | i2BoardPtrTable[i] = NULL; |
436 | } | 428 | } |
437 | if ((DevTableMem[i]) != NULL ) { | 429 | if (DevTableMem[i] != NULL) { |
438 | kfree ( DevTableMem[i] ); | 430 | kfree(DevTableMem[i]); |
439 | DevTableMem[i] = NULL; | 431 | DevTableMem[i] = NULL; |
440 | } | 432 | } |
441 | } | 433 | } |
442 | |||
443 | /* Cleanup the iiEllis subsystem. */ | ||
444 | iiEllisCleanup(); | ||
445 | #ifdef IP2DEBUG_INIT | ||
446 | printk (KERN_DEBUG "IP2 Unloaded\n" ); | ||
447 | #endif | ||
448 | } | 434 | } |
449 | module_exit(ip2_cleanup_module); | 435 | module_exit(ip2_cleanup_module); |
450 | 436 | ||
@@ -552,14 +538,13 @@ static int __init ip2_setup(char *str) | |||
552 | __setup("ip2=", ip2_setup); | 538 | __setup("ip2=", ip2_setup); |
553 | #endif /* !MODULE */ | 539 | #endif /* !MODULE */ |
554 | 540 | ||
555 | static int ip2_loadmain(void) | 541 | static int __init ip2_loadmain(void) |
556 | { | 542 | { |
557 | int i, j, box; | 543 | int i, j, box; |
558 | int err = 0; | 544 | int err = 0; |
559 | static int loaded; | ||
560 | i2eBordStrPtr pB = NULL; | 545 | i2eBordStrPtr pB = NULL; |
561 | int rc = -1; | 546 | int rc = -1; |
562 | static struct pci_dev *pci_dev_i = NULL; | 547 | struct pci_dev *pdev = NULL; |
563 | const struct firmware *fw = NULL; | 548 | const struct firmware *fw = NULL; |
564 | 549 | ||
565 | if (poll_only) { | 550 | if (poll_only) { |
@@ -567,119 +552,108 @@ static int ip2_loadmain(void) | |||
567 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; | 552 | irq[0] = irq[1] = irq[2] = irq[3] = poll_only = 0; |
568 | } | 553 | } |
569 | 554 | ||
570 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); | 555 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0); |
571 | 556 | ||
572 | /* process command line arguments to modprobe or | 557 | /* process command line arguments to modprobe or |
573 | insmod i.e. iop & irqp */ | 558 | insmod i.e. iop & irqp */ |
574 | /* irqp and iop should ALWAYS be specified now... But we check | 559 | /* irqp and iop should ALWAYS be specified now... But we check |
575 | them individually just to be sure, anyways... */ | 560 | them individually just to be sure, anyways... */ |
576 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 561 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
577 | ip2config.addr[i] = io[i]; | 562 | ip2config.addr[i] = io[i]; |
578 | if (irq[i] >= 0) | 563 | if (irq[i] >= 0) |
579 | ip2config.irq[i] = irq[i]; | 564 | ip2config.irq[i] = irq[i]; |
580 | else | 565 | else |
581 | ip2config.irq[i] = 0; | 566 | ip2config.irq[i] = 0; |
582 | // This is a little bit of a hack. If poll_only=1 on command | 567 | /* This is a little bit of a hack. If poll_only=1 on command |
583 | // line back in ip2.c OR all IRQs on all specified boards are | 568 | line back in ip2.c OR all IRQs on all specified boards are |
584 | // explicitly set to 0, then drop to poll only mode and override | 569 | explicitly set to 0, then drop to poll only mode and override |
585 | // PCI or EISA interrupts. This superceeds the old hack of | 570 | PCI or EISA interrupts. This superceeds the old hack of |
586 | // triggering if all interrupts were zero (like da default). | 571 | triggering if all interrupts were zero (like da default). |
587 | // Still a hack but less prone to random acts of terrorism. | 572 | Still a hack but less prone to random acts of terrorism. |
588 | // | 573 | |
589 | // What we really should do, now that the IRQ default is set | 574 | What we really should do, now that the IRQ default is set |
590 | // to -1, is to use 0 as a hard coded, do not probe. | 575 | to -1, is to use 0 as a hard coded, do not probe. |
591 | // | 576 | |
592 | // /\/\|=mhw=|\/\/ | 577 | /\/\|=mhw=|\/\/ |
578 | */ | ||
593 | poll_only |= irq[i]; | 579 | poll_only |= irq[i]; |
594 | } | 580 | } |
595 | poll_only = !poll_only; | 581 | poll_only = !poll_only; |
596 | 582 | ||
597 | /* Announce our presence */ | 583 | /* Announce our presence */ |
598 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); | 584 | printk(KERN_INFO "%s version %s\n", pcName, pcVersion); |
599 | |||
600 | // ip2 can be unloaded and reloaded for no good reason | ||
601 | // we can't let that happen here or bad things happen | ||
602 | // second load hoses board but not system - fixme later | ||
603 | if (loaded) { | ||
604 | printk( KERN_INFO "Still loaded\n" ); | ||
605 | return 0; | ||
606 | } | ||
607 | loaded++; | ||
608 | 585 | ||
609 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); | 586 | ip2_tty_driver = alloc_tty_driver(IP2_MAX_PORTS); |
610 | if (!ip2_tty_driver) | 587 | if (!ip2_tty_driver) |
611 | return -ENOMEM; | 588 | return -ENOMEM; |
612 | 589 | ||
613 | /* Initialise the iiEllis subsystem. */ | ||
614 | iiEllisInit(); | ||
615 | |||
616 | /* Initialise all the boards we can find (up to the maximum). */ | 590 | /* Initialise all the boards we can find (up to the maximum). */ |
617 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 591 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
618 | switch ( ip2config.addr[i] ) { | 592 | switch (ip2config.addr[i]) { |
619 | case 0: /* skip this slot even if card is present */ | 593 | case 0: /* skip this slot even if card is present */ |
620 | break; | 594 | break; |
621 | default: /* ISA */ | 595 | default: /* ISA */ |
622 | /* ISA address must be specified */ | 596 | /* ISA address must be specified */ |
623 | if ( (ip2config.addr[i] < 0x100) || (ip2config.addr[i] > 0x3f8) ) { | 597 | if (ip2config.addr[i] < 0x100 || |
624 | printk ( KERN_ERR "IP2: Bad ISA board %d address %x\n", | 598 | ip2config.addr[i] > 0x3f8) { |
625 | i, ip2config.addr[i] ); | 599 | printk(KERN_ERR "IP2: Bad ISA board %d " |
600 | "address %x\n", i, | ||
601 | ip2config.addr[i]); | ||
626 | ip2config.addr[i] = 0; | 602 | ip2config.addr[i] = 0; |
627 | } else { | 603 | break; |
628 | ip2config.type[i] = ISA; | 604 | } |
629 | 605 | ip2config.type[i] = ISA; | |
630 | /* Check for valid irq argument, set for polling if invalid */ | 606 | |
631 | if (ip2config.irq[i] && !is_valid_irq(ip2config.irq[i])) { | 607 | /* Check for valid irq argument, set for polling if |
632 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n",ip2config.irq[i]); | 608 | * invalid */ |
633 | ip2config.irq[i] = 0;// 0 is polling and is valid in that sense | 609 | if (ip2config.irq[i] && |
634 | } | 610 | !is_valid_irq(ip2config.irq[i])) { |
611 | printk(KERN_ERR "IP2: Bad IRQ(%d) specified\n", | ||
612 | ip2config.irq[i]); | ||
613 | /* 0 is polling and is valid in that sense */ | ||
614 | ip2config.irq[i] = 0; | ||
635 | } | 615 | } |
636 | break; | 616 | break; |
637 | case PCI: | 617 | case PCI: |
638 | #ifdef CONFIG_PCI | 618 | #ifdef CONFIG_PCI |
639 | { | 619 | { |
640 | int status; | 620 | u32 addr; |
621 | int status; | ||
641 | 622 | ||
642 | pci_dev_i = pci_get_device(PCI_VENDOR_ID_COMPUTONE, | 623 | pdev = pci_get_device(PCI_VENDOR_ID_COMPUTONE, |
643 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pci_dev_i); | 624 | PCI_DEVICE_ID_COMPUTONE_IP2EX, pdev); |
644 | if (pci_dev_i != NULL) { | 625 | if (pdev == NULL) { |
645 | unsigned int addr; | 626 | ip2config.addr[i] = 0; |
646 | 627 | printk(KERN_ERR "IP2: PCI board %d not " | |
647 | if (pci_enable_device(pci_dev_i)) { | 628 | "found\n", i); |
648 | printk( KERN_ERR "IP2: can't enable PCI device at %s\n", | 629 | break; |
649 | pci_name(pci_dev_i)); | 630 | } |
650 | break; | ||
651 | } | ||
652 | ip2config.type[i] = PCI; | ||
653 | ip2config.pci_dev[i] = pci_dev_get(pci_dev_i); | ||
654 | status = | ||
655 | pci_read_config_dword(pci_dev_i, PCI_BASE_ADDRESS_1, &addr); | ||
656 | if ( addr & 1 ) { | ||
657 | ip2config.addr[i]=(USHORT)(addr&0xfffe); | ||
658 | } else { | ||
659 | printk( KERN_ERR "IP2: PCI I/O address error\n"); | ||
660 | } | ||
661 | 631 | ||
662 | // If the PCI BIOS assigned it, lets try and use it. If we | 632 | if (pci_enable_device(pdev)) { |
663 | // can't acquire it or it screws up, deal with it then. | 633 | dev_err(&pdev->dev, "can't enable device\n"); |
664 | 634 | break; | |
665 | // if (!is_valid_irq(pci_irq)) { | ||
666 | // printk( KERN_ERR "IP2: Bad PCI BIOS IRQ(%d)\n",pci_irq); | ||
667 | // pci_irq = 0; | ||
668 | // } | ||
669 | ip2config.irq[i] = pci_dev_i->irq; | ||
670 | } else { // ann error | ||
671 | ip2config.addr[i] = 0; | ||
672 | printk(KERN_ERR "IP2: PCI board %d not found\n", i); | ||
673 | } | ||
674 | } | 635 | } |
636 | ip2config.type[i] = PCI; | ||
637 | ip2config.pci_dev[i] = pci_dev_get(pdev); | ||
638 | status = pci_read_config_dword(pdev, PCI_BASE_ADDRESS_1, | ||
639 | &addr); | ||
640 | if (addr & 1) | ||
641 | ip2config.addr[i] = (USHORT)(addr & 0xfffe); | ||
642 | else | ||
643 | dev_err(&pdev->dev, "I/O address error\n"); | ||
644 | |||
645 | ip2config.irq[i] = pdev->irq; | ||
646 | } | ||
675 | #else | 647 | #else |
676 | printk( KERN_ERR "IP2: PCI card specified but PCI support not\n"); | 648 | printk(KERN_ERR "IP2: PCI card specified but PCI " |
677 | printk( KERN_ERR "IP2: configured in this kernel.\n"); | 649 | "support not enabled.\n"); |
678 | printk( KERN_ERR "IP2: Recompile kernel with CONFIG_PCI defined!\n"); | 650 | printk(KERN_ERR "IP2: Recompile kernel with CONFIG_PCI " |
651 | "defined!\n"); | ||
679 | #endif /* CONFIG_PCI */ | 652 | #endif /* CONFIG_PCI */ |
680 | break; | 653 | break; |
681 | case EISA: | 654 | case EISA: |
682 | if ( (ip2config.addr[i] = find_eisa_board( Eisa_slot + 1 )) != 0) { | 655 | ip2config.addr[i] = find_eisa_board(Eisa_slot + 1); |
656 | if (ip2config.addr[i] != 0) { | ||
683 | /* Eisa_irq set as side effect, boo */ | 657 | /* Eisa_irq set as side effect, boo */ |
684 | ip2config.type[i] = EISA; | 658 | ip2config.type[i] = EISA; |
685 | } | 659 | } |
@@ -687,31 +661,32 @@ static int ip2_loadmain(void) | |||
687 | break; | 661 | break; |
688 | } /* switch */ | 662 | } /* switch */ |
689 | } /* for */ | 663 | } /* for */ |
690 | if (pci_dev_i) | 664 | pci_dev_put(pdev); |
691 | pci_dev_put(pci_dev_i); | ||
692 | 665 | ||
693 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 666 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
694 | if ( ip2config.addr[i] ) { | 667 | if (ip2config.addr[i]) { |
695 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); | 668 | pB = kzalloc(sizeof(i2eBordStr), GFP_KERNEL); |
696 | if (pB) { | 669 | if (pB) { |
697 | i2BoardPtrTable[i] = pB; | 670 | i2BoardPtrTable[i] = pB; |
698 | iiSetAddress( pB, ip2config.addr[i], ii2DelayTimer ); | 671 | iiSetAddress(pB, ip2config.addr[i], |
699 | iiReset( pB ); | 672 | ii2DelayTimer); |
700 | } else { | 673 | iiReset(pB); |
701 | printk(KERN_ERR "IP2: board memory allocation error\n"); | 674 | } else |
702 | } | 675 | printk(KERN_ERR "IP2: board memory allocation " |
676 | "error\n"); | ||
703 | } | 677 | } |
704 | } | 678 | } |
705 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 679 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
706 | if ( ( pB = i2BoardPtrTable[i] ) != NULL ) { | 680 | pB = i2BoardPtrTable[i]; |
707 | iiResetDelay( pB ); | 681 | if (pB != NULL) { |
682 | iiResetDelay(pB); | ||
708 | break; | 683 | break; |
709 | } | 684 | } |
710 | } | 685 | } |
711 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 686 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
712 | /* We don't want to request the firmware unless we have at | 687 | /* We don't want to request the firmware unless we have at |
713 | least one board */ | 688 | least one board */ |
714 | if ( i2BoardPtrTable[i] != NULL ) { | 689 | if (i2BoardPtrTable[i] != NULL) { |
715 | if (!fw) | 690 | if (!fw) |
716 | fw = ip2_request_firmware(); | 691 | fw = ip2_request_firmware(); |
717 | if (!fw) | 692 | if (!fw) |
@@ -722,7 +697,7 @@ static int ip2_loadmain(void) | |||
722 | if (fw) | 697 | if (fw) |
723 | release_firmware(fw); | 698 | release_firmware(fw); |
724 | 699 | ||
725 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); | 700 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 2, 0); |
726 | 701 | ||
727 | ip2_tty_driver->owner = THIS_MODULE; | 702 | ip2_tty_driver->owner = THIS_MODULE; |
728 | ip2_tty_driver->name = "ttyF"; | 703 | ip2_tty_driver->name = "ttyF"; |
@@ -733,20 +708,23 @@ static int ip2_loadmain(void) | |||
733 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; | 708 | ip2_tty_driver->subtype = SERIAL_TYPE_NORMAL; |
734 | ip2_tty_driver->init_termios = tty_std_termios; | 709 | ip2_tty_driver->init_termios = tty_std_termios; |
735 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; | 710 | ip2_tty_driver->init_termios.c_cflag = B9600|CS8|CREAD|HUPCL|CLOCAL; |
736 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; | 711 | ip2_tty_driver->flags = TTY_DRIVER_REAL_RAW | |
712 | TTY_DRIVER_DYNAMIC_DEV; | ||
737 | tty_set_operations(ip2_tty_driver, &ip2_ops); | 713 | tty_set_operations(ip2_tty_driver, &ip2_ops); |
738 | 714 | ||
739 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 3, 0 ); | 715 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 3, 0); |
740 | 716 | ||
741 | /* Register the tty devices. */ | 717 | err = tty_register_driver(ip2_tty_driver); |
742 | if ( ( err = tty_register_driver ( ip2_tty_driver ) ) ) { | 718 | if (err) { |
743 | printk(KERN_ERR "IP2: failed to register tty driver (%d)\n", err); | 719 | printk(KERN_ERR "IP2: failed to register tty driver\n"); |
744 | put_tty_driver(ip2_tty_driver); | 720 | put_tty_driver(ip2_tty_driver); |
745 | return -EINVAL; | 721 | return err; /* leaking resources */ |
746 | } else | 722 | } |
747 | /* Register the IPL driver. */ | 723 | |
748 | if ( ( err = register_chrdev ( IP2_IPL_MAJOR, pcIpl, &ip2_ipl ) ) ) { | 724 | err = register_chrdev(IP2_IPL_MAJOR, pcIpl, &ip2_ipl); |
749 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", err ); | 725 | if (err) { |
726 | printk(KERN_ERR "IP2: failed to register IPL device (%d)\n", | ||
727 | err); | ||
750 | } else { | 728 | } else { |
751 | /* create the sysfs class */ | 729 | /* create the sysfs class */ |
752 | ip2_class = class_create(THIS_MODULE, "ip2"); | 730 | ip2_class = class_create(THIS_MODULE, "ip2"); |
@@ -758,82 +736,85 @@ static int ip2_loadmain(void) | |||
758 | /* Register the read_procmem thing */ | 736 | /* Register the read_procmem thing */ |
759 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { | 737 | if (!proc_create("ip2mem",0,NULL,&ip2mem_proc_fops)) { |
760 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); | 738 | printk(KERN_ERR "IP2: failed to register read_procmem\n"); |
761 | } else { | 739 | return -EIO; /* leaking resources */ |
740 | } | ||
762 | 741 | ||
763 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 4, 0 ); | 742 | ip2trace(ITRC_NO_PORT, ITRC_INIT, 4, 0); |
764 | /* Register the interrupt handler or poll handler, depending upon the | 743 | /* Register the interrupt handler or poll handler, depending upon the |
765 | * specified interrupt. | 744 | * specified interrupt. |
766 | */ | 745 | */ |
767 | 746 | ||
768 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 747 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
769 | if ( 0 == ip2config.addr[i] ) { | 748 | if (ip2config.addr[i] == 0) |
770 | continue; | 749 | continue; |
771 | } | ||
772 | 750 | ||
773 | if ( NULL != ( pB = i2BoardPtrTable[i] ) ) { | 751 | pB = i2BoardPtrTable[i]; |
774 | device_create_drvdata(ip2_class, NULL, | 752 | if (pB != NULL) { |
775 | MKDEV(IP2_IPL_MAJOR, 4 * i), | 753 | device_create_drvdata(ip2_class, NULL, |
776 | NULL, "ipl%d", i); | 754 | MKDEV(IP2_IPL_MAJOR, 4 * i), |
777 | device_create_drvdata(ip2_class, NULL, | 755 | NULL, "ipl%d", i); |
778 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), | 756 | device_create_drvdata(ip2_class, NULL, |
779 | NULL, "stat%d", i); | 757 | MKDEV(IP2_IPL_MAJOR, 4 * i + 1), |
780 | 758 | NULL, "stat%d", i); | |
781 | for ( box = 0; box < ABS_MAX_BOXES; ++box ) | 759 | |
782 | { | 760 | for (box = 0; box < ABS_MAX_BOXES; box++) |
783 | for ( j = 0; j < ABS_BIGGEST_BOX; ++j ) | 761 | for (j = 0; j < ABS_BIGGEST_BOX; j++) |
784 | { | 762 | if (pB->i2eChannelMap[box] & (1 << j)) |
785 | if ( pB->i2eChannelMap[box] & (1 << j) ) | 763 | tty_register_device( |
786 | { | 764 | ip2_tty_driver, |
787 | tty_register_device(ip2_tty_driver, | 765 | j + ABS_BIGGEST_BOX * |
788 | j + ABS_BIGGEST_BOX * | 766 | (box+i*ABS_MAX_BOXES), |
789 | (box+i*ABS_MAX_BOXES), NULL); | 767 | NULL); |
790 | } | 768 | } |
791 | } | ||
792 | } | ||
793 | } | ||
794 | 769 | ||
795 | if (poll_only) { | 770 | if (poll_only) { |
796 | // Poll only forces driver to only use polling and | 771 | /* Poll only forces driver to only use polling and |
797 | // to ignore the probed PCI or EISA interrupts. | 772 | to ignore the probed PCI or EISA interrupts. */ |
798 | ip2config.irq[i] = CIR_POLL; | 773 | ip2config.irq[i] = CIR_POLL; |
799 | } | 774 | } |
800 | if ( ip2config.irq[i] == CIR_POLL ) { | 775 | if (ip2config.irq[i] == CIR_POLL) { |
801 | retry: | 776 | retry: |
802 | if (!TimerOn) { | 777 | if (!TimerOn) { |
803 | PollTimer.expires = POLL_TIMEOUT; | 778 | PollTimer.expires = POLL_TIMEOUT; |
804 | add_timer ( &PollTimer ); | 779 | add_timer(&PollTimer); |
805 | TimerOn = 1; | 780 | TimerOn = 1; |
806 | printk( KERN_INFO "IP2: polling\n"); | 781 | printk(KERN_INFO "IP2: polling\n"); |
807 | } | ||
808 | } else { | ||
809 | if (have_requested_irq(ip2config.irq[i])) | ||
810 | continue; | ||
811 | rc = request_irq( ip2config.irq[i], ip2_interrupt, | ||
812 | IP2_SA_FLAGS | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
813 | pcName, i2BoardPtrTable[i]); | ||
814 | if (rc) { | ||
815 | printk(KERN_ERR "IP2: an request_irq failed: error %d\n",rc); | ||
816 | ip2config.irq[i] = CIR_POLL; | ||
817 | printk( KERN_INFO "IP2: Polling %ld/sec.\n", | ||
818 | (POLL_TIMEOUT - jiffies)); | ||
819 | goto retry; | ||
820 | } | ||
821 | mark_requested_irq(ip2config.irq[i]); | ||
822 | /* Initialise the interrupt handler bottom half (aka slih). */ | ||
823 | } | 782 | } |
824 | } | 783 | } else { |
825 | for( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 784 | if (have_requested_irq(ip2config.irq[i])) |
826 | if ( i2BoardPtrTable[i] ) { | 785 | continue; |
827 | set_irq( i, ip2config.irq[i] ); /* set and enable board interrupt */ | 786 | rc = request_irq(ip2config.irq[i], ip2_interrupt, |
787 | IP2_SA_FLAGS | | ||
788 | (ip2config.type[i] == PCI ? IRQF_SHARED : 0), | ||
789 | pcName, i2BoardPtrTable[i]); | ||
790 | if (rc) { | ||
791 | printk(KERN_ERR "IP2: request_irq failed: " | ||
792 | "error %d\n", rc); | ||
793 | ip2config.irq[i] = CIR_POLL; | ||
794 | printk(KERN_INFO "IP2: Polling %ld/sec.\n", | ||
795 | (POLL_TIMEOUT - jiffies)); | ||
796 | goto retry; | ||
828 | } | 797 | } |
798 | mark_requested_irq(ip2config.irq[i]); | ||
799 | /* Initialise the interrupt handler bottom half | ||
800 | * (aka slih). */ | ||
829 | } | 801 | } |
830 | } | 802 | } |
831 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0 ); | 803 | |
832 | goto out; | 804 | for (i = 0; i < IP2_MAX_BOARDS; ++i) { |
805 | if (i2BoardPtrTable[i]) { | ||
806 | /* set and enable board interrupt */ | ||
807 | set_irq(i, ip2config.irq[i]); | ||
808 | } | ||
809 | } | ||
810 | |||
811 | ip2trace(ITRC_NO_PORT, ITRC_INIT, ITRC_RETURN, 0); | ||
812 | |||
813 | return 0; | ||
833 | 814 | ||
834 | out_chrdev: | 815 | out_chrdev: |
835 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); | 816 | unregister_chrdev(IP2_IPL_MAJOR, "ip2"); |
836 | out: | 817 | /* unregister and put tty here */ |
837 | return err; | 818 | return err; |
838 | } | 819 | } |
839 | module_init(ip2_loadmain); | 820 | module_init(ip2_loadmain); |