diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index c12cf8fc4be0..e19df02ec860 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -98,6 +98,8 @@ | |||
98 | #include <linux/major.h> | 98 | #include <linux/major.h> |
99 | #include <linux/wait.h> | 99 | #include <linux/wait.h> |
100 | #include <linux/device.h> | 100 | #include <linux/device.h> |
101 | #include <linux/firmware.h> | ||
102 | #include <linux/platform_device.h> | ||
101 | 103 | ||
102 | #include <linux/tty.h> | 104 | #include <linux/tty.h> |
103 | #include <linux/tty_flip.h> | 105 | #include <linux/tty_flip.h> |
@@ -155,9 +157,7 @@ static char *pcDriver_name = "ip2"; | |||
155 | static char *pcIpl = "ip2ipl"; | 157 | static char *pcIpl = "ip2ipl"; |
156 | 158 | ||
157 | // cheezy kludge or genius - you decide? | 159 | // cheezy kludge or genius - you decide? |
158 | int ip2_loadmain(int *, int *, unsigned char *, int); | 160 | int ip2_loadmain(int *, int *); |
159 | static unsigned char *Fip_firmware; | ||
160 | static int Fip_firmware_size; | ||
161 | 161 | ||
162 | /***********************/ | 162 | /***********************/ |
163 | /* Function Prototypes */ | 163 | /* Function Prototypes */ |
@@ -208,7 +208,7 @@ static int ip2_ipl_open(struct inode *, struct file *); | |||
208 | static int DumpTraceBuffer(char __user *, int); | 208 | static int DumpTraceBuffer(char __user *, int); |
209 | static int DumpFifoBuffer( char __user *, int); | 209 | static int DumpFifoBuffer( char __user *, int); |
210 | 210 | ||
211 | static void ip2_init_board(int); | 211 | static void ip2_init_board(int, const struct firmware *); |
212 | static unsigned short find_eisa_board(int); | 212 | static unsigned short find_eisa_board(int); |
213 | 213 | ||
214 | /***************/ | 214 | /***************/ |
@@ -474,8 +474,27 @@ static const struct tty_operations ip2_ops = { | |||
474 | /* SA_RANDOM - can be source for cert. random number generators */ | 474 | /* SA_RANDOM - can be source for cert. random number generators */ |
475 | #define IP2_SA_FLAGS 0 | 475 | #define IP2_SA_FLAGS 0 |
476 | 476 | ||
477 | |||
478 | static const struct firmware *ip2_request_firmware(void) | ||
479 | { | ||
480 | struct platform_device *pdev; | ||
481 | const struct firmware *fw; | ||
482 | |||
483 | pdev = platform_device_register_simple("ip2", 0, NULL, 0); | ||
484 | if (IS_ERR(pdev)) { | ||
485 | printk(KERN_ERR "Failed to register platform device for ip2\n"); | ||
486 | return NULL; | ||
487 | } | ||
488 | if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { | ||
489 | printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); | ||
490 | fw = NULL; | ||
491 | } | ||
492 | platform_device_unregister(pdev); | ||
493 | return fw; | ||
494 | } | ||
495 | |||
477 | int | 496 | int |
478 | ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | 497 | ip2_loadmain(int *iop, int *irqp) |
479 | { | 498 | { |
480 | int i, j, box; | 499 | int i, j, box; |
481 | int err = 0; | 500 | int err = 0; |
@@ -483,6 +502,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
483 | i2eBordStrPtr pB = NULL; | 502 | i2eBordStrPtr pB = NULL; |
484 | int rc = -1; | 503 | int rc = -1; |
485 | static struct pci_dev *pci_dev_i = NULL; | 504 | static struct pci_dev *pci_dev_i = NULL; |
505 | const struct firmware *fw = NULL; | ||
486 | 506 | ||
487 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); | 507 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); |
488 | 508 | ||
@@ -516,9 +536,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
516 | } | 536 | } |
517 | poll_only = !poll_only; | 537 | poll_only = !poll_only; |
518 | 538 | ||
519 | Fip_firmware = firmware; | ||
520 | Fip_firmware_size = firmsize; | ||
521 | |||
522 | /* Announce our presence */ | 539 | /* Announce our presence */ |
523 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); | 540 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); |
524 | 541 | ||
@@ -638,10 +655,18 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
638 | } | 655 | } |
639 | } | 656 | } |
640 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 657 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { |
658 | /* We don't want to request the firmware unless we have at | ||
659 | least one board */ | ||
641 | if ( i2BoardPtrTable[i] != NULL ) { | 660 | if ( i2BoardPtrTable[i] != NULL ) { |
642 | ip2_init_board( i ); | 661 | if (!fw) |
662 | fw = ip2_request_firmware(); | ||
663 | if (!fw) | ||
664 | break; | ||
665 | ip2_init_board(i, fw); | ||
643 | } | 666 | } |
644 | } | 667 | } |
668 | if (fw) | ||
669 | release_firmware(fw); | ||
645 | 670 | ||
646 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); | 671 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); |
647 | 672 | ||
@@ -769,7 +794,7 @@ out: | |||
769 | /* are reported on the console. */ | 794 | /* are reported on the console. */ |
770 | /******************************************************************************/ | 795 | /******************************************************************************/ |
771 | static void | 796 | static void |
772 | ip2_init_board( int boardnum ) | 797 | ip2_init_board(int boardnum, const struct firmware *fw) |
773 | { | 798 | { |
774 | int i; | 799 | int i; |
775 | int nports = 0, nboxes = 0; | 800 | int nports = 0, nboxes = 0; |
@@ -789,7 +814,7 @@ ip2_init_board( int boardnum ) | |||
789 | goto err_initialize; | 814 | goto err_initialize; |
790 | } | 815 | } |
791 | 816 | ||
792 | if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size ) | 817 | if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) |
793 | != II_DOWN_GOOD ) { | 818 | != II_DOWN_GOOD ) { |
794 | printk ( KERN_ERR "IP2: failed to download loadware\n" ); | 819 | printk ( KERN_ERR "IP2: failed to download loadware\n" ); |
795 | goto err_release_region; | 820 | goto err_release_region; |