diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 81 |
1 files changed, 38 insertions, 43 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index c12cf8fc4be0..9a2394cda943 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c | |||
@@ -98,6 +98,9 @@ | |||
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/smp_lock.h> | ||
102 | #include <linux/firmware.h> | ||
103 | #include <linux/platform_device.h> | ||
101 | 104 | ||
102 | #include <linux/tty.h> | 105 | #include <linux/tty.h> |
103 | #include <linux/tty_flip.h> | 106 | #include <linux/tty_flip.h> |
@@ -155,9 +158,7 @@ static char *pcDriver_name = "ip2"; | |||
155 | static char *pcIpl = "ip2ipl"; | 158 | static char *pcIpl = "ip2ipl"; |
156 | 159 | ||
157 | // cheezy kludge or genius - you decide? | 160 | // cheezy kludge or genius - you decide? |
158 | int ip2_loadmain(int *, int *, unsigned char *, int); | 161 | int ip2_loadmain(int *, int *); |
159 | static unsigned char *Fip_firmware; | ||
160 | static int Fip_firmware_size; | ||
161 | 162 | ||
162 | /***********************/ | 163 | /***********************/ |
163 | /* Function Prototypes */ | 164 | /* Function Prototypes */ |
@@ -208,7 +209,7 @@ static int ip2_ipl_open(struct inode *, struct file *); | |||
208 | static int DumpTraceBuffer(char __user *, int); | 209 | static int DumpTraceBuffer(char __user *, int); |
209 | static int DumpFifoBuffer( char __user *, int); | 210 | static int DumpFifoBuffer( char __user *, int); |
210 | 211 | ||
211 | static void ip2_init_board(int); | 212 | static void ip2_init_board(int, const struct firmware *); |
212 | static unsigned short find_eisa_board(int); | 213 | static unsigned short find_eisa_board(int); |
213 | 214 | ||
214 | /***************/ | 215 | /***************/ |
@@ -474,8 +475,27 @@ static const struct tty_operations ip2_ops = { | |||
474 | /* SA_RANDOM - can be source for cert. random number generators */ | 475 | /* SA_RANDOM - can be source for cert. random number generators */ |
475 | #define IP2_SA_FLAGS 0 | 476 | #define IP2_SA_FLAGS 0 |
476 | 477 | ||
478 | |||
479 | static const struct firmware *ip2_request_firmware(void) | ||
480 | { | ||
481 | struct platform_device *pdev; | ||
482 | const struct firmware *fw; | ||
483 | |||
484 | pdev = platform_device_register_simple("ip2", 0, NULL, 0); | ||
485 | if (IS_ERR(pdev)) { | ||
486 | printk(KERN_ERR "Failed to register platform device for ip2\n"); | ||
487 | return NULL; | ||
488 | } | ||
489 | if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { | ||
490 | printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); | ||
491 | fw = NULL; | ||
492 | } | ||
493 | platform_device_unregister(pdev); | ||
494 | return fw; | ||
495 | } | ||
496 | |||
477 | int | 497 | int |
478 | ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | 498 | ip2_loadmain(int *iop, int *irqp) |
479 | { | 499 | { |
480 | int i, j, box; | 500 | int i, j, box; |
481 | int err = 0; | 501 | int err = 0; |
@@ -483,6 +503,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
483 | i2eBordStrPtr pB = NULL; | 503 | i2eBordStrPtr pB = NULL; |
484 | int rc = -1; | 504 | int rc = -1; |
485 | static struct pci_dev *pci_dev_i = NULL; | 505 | static struct pci_dev *pci_dev_i = NULL; |
506 | const struct firmware *fw = NULL; | ||
486 | 507 | ||
487 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); | 508 | ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); |
488 | 509 | ||
@@ -516,9 +537,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
516 | } | 537 | } |
517 | poll_only = !poll_only; | 538 | poll_only = !poll_only; |
518 | 539 | ||
519 | Fip_firmware = firmware; | ||
520 | Fip_firmware_size = firmsize; | ||
521 | |||
522 | /* Announce our presence */ | 540 | /* Announce our presence */ |
523 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); | 541 | printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); |
524 | 542 | ||
@@ -638,10 +656,18 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) | |||
638 | } | 656 | } |
639 | } | 657 | } |
640 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { | 658 | for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { |
659 | /* We don't want to request the firmware unless we have at | ||
660 | least one board */ | ||
641 | if ( i2BoardPtrTable[i] != NULL ) { | 661 | if ( i2BoardPtrTable[i] != NULL ) { |
642 | ip2_init_board( i ); | 662 | if (!fw) |
663 | fw = ip2_request_firmware(); | ||
664 | if (!fw) | ||
665 | break; | ||
666 | ip2_init_board(i, fw); | ||
643 | } | 667 | } |
644 | } | 668 | } |
669 | if (fw) | ||
670 | release_firmware(fw); | ||
645 | 671 | ||
646 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); | 672 | ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); |
647 | 673 | ||
@@ -769,7 +795,7 @@ out: | |||
769 | /* are reported on the console. */ | 795 | /* are reported on the console. */ |
770 | /******************************************************************************/ | 796 | /******************************************************************************/ |
771 | static void | 797 | static void |
772 | ip2_init_board( int boardnum ) | 798 | ip2_init_board(int boardnum, const struct firmware *fw) |
773 | { | 799 | { |
774 | int i; | 800 | int i; |
775 | int nports = 0, nboxes = 0; | 801 | int nports = 0, nboxes = 0; |
@@ -789,7 +815,7 @@ ip2_init_board( int boardnum ) | |||
789 | goto err_initialize; | 815 | goto err_initialize; |
790 | } | 816 | } |
791 | 817 | ||
792 | if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size ) | 818 | if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) |
793 | != II_DOWN_GOOD ) { | 819 | != II_DOWN_GOOD ) { |
794 | printk ( KERN_ERR "IP2: failed to download loadware\n" ); | 820 | printk ( KERN_ERR "IP2: failed to download loadware\n" ); |
795 | goto err_release_region; | 821 | goto err_release_region; |
@@ -2908,42 +2934,11 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) | |||
2908 | static int | 2934 | static int |
2909 | ip2_ipl_open( struct inode *pInode, struct file *pFile ) | 2935 | ip2_ipl_open( struct inode *pInode, struct file *pFile ) |
2910 | { | 2936 | { |
2911 | unsigned int iplminor = iminor(pInode); | ||
2912 | i2eBordStrPtr pB; | ||
2913 | i2ChanStrPtr pCh; | ||
2914 | 2937 | ||
2915 | #ifdef IP2DEBUG_IPL | 2938 | #ifdef IP2DEBUG_IPL |
2916 | printk (KERN_DEBUG "IP2IPL: open\n" ); | 2939 | printk (KERN_DEBUG "IP2IPL: open\n" ); |
2917 | #endif | 2940 | #endif |
2918 | 2941 | cycle_kernel_lock(); | |
2919 | switch(iplminor) { | ||
2920 | // These are the IPL devices | ||
2921 | case 0: | ||
2922 | case 4: | ||
2923 | case 8: | ||
2924 | case 12: | ||
2925 | break; | ||
2926 | |||
2927 | // These are the status devices | ||
2928 | case 1: | ||
2929 | case 5: | ||
2930 | case 9: | ||
2931 | case 13: | ||
2932 | break; | ||
2933 | |||
2934 | // These are the debug devices | ||
2935 | case 2: | ||
2936 | case 6: | ||
2937 | case 10: | ||
2938 | case 14: | ||
2939 | pB = i2BoardPtrTable[iplminor / 4]; | ||
2940 | pCh = (i2ChanStrPtr) pB->i2eChannelPtr; | ||
2941 | break; | ||
2942 | |||
2943 | // This is the trace device | ||
2944 | case 3: | ||
2945 | break; | ||
2946 | } | ||
2947 | return 0; | 2942 | return 0; |
2948 | } | 2943 | } |
2949 | 2944 | ||