diff options
Diffstat (limited to 'drivers/char/ip2/ip2main.c')
-rw-r--r-- | drivers/char/ip2/ip2main.c | 111 |
1 files changed, 42 insertions, 69 deletions
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c index 70957acaa96..5dc74404058 100644 --- a/drivers/char/ip2/ip2main.c +++ b/drivers/char/ip2/ip2main.c @@ -98,6 +98,9 @@ #include <linux/major.h> #include <linux/wait.h> #include <linux/device.h> +#include <linux/smp_lock.h> +#include <linux/firmware.h> +#include <linux/platform_device.h> #include <linux/tty.h> #include <linux/tty_flip.h> @@ -155,9 +158,7 @@ static char *pcDriver_name = "ip2"; static char *pcIpl = "ip2ipl"; // cheezy kludge or genius - you decide? -int ip2_loadmain(int *, int *, unsigned char *, int); -static unsigned char *Fip_firmware; -static int Fip_firmware_size; +int ip2_loadmain(int *, int *); /***********************/ /* Function Prototypes */ @@ -208,7 +209,7 @@ static int ip2_ipl_open(struct inode *, struct file *); static int DumpTraceBuffer(char __user *, int); static int DumpFifoBuffer( char __user *, int); -static void ip2_init_board(int); +static void ip2_init_board(int, const struct firmware *); static unsigned short find_eisa_board(int); /***************/ @@ -346,27 +347,6 @@ have_requested_irq( char irq ) } /******************************************************************************/ -/* Function: init_module() */ -/* Parameters: None */ -/* Returns: Success (0) */ -/* */ -/* Description: */ -/* This is a required entry point for an installable module. It simply calls */ -/* the driver initialisation function and returns what it returns. */ -/******************************************************************************/ -#ifdef MODULE -static int __init -ip2_init_module(void) -{ -#ifdef IP2DEBUG_INIT - printk (KERN_DEBUG "Loading module ...\n" ); -#endif - return 0; -} -module_init(ip2_init_module); -#endif /* MODULE */ - -/******************************************************************************/ /* Function: cleanup_module() */ /* Parameters: None */ /* Returns: Nothing */ @@ -495,8 +475,27 @@ static const struct tty_operations ip2_ops = { /* SA_RANDOM - can be source for cert. random number generators */ #define IP2_SA_FLAGS 0 + +static const struct firmware *ip2_request_firmware(void) +{ + struct platform_device *pdev; + const struct firmware *fw; + + pdev = platform_device_register_simple("ip2", 0, NULL, 0); + if (IS_ERR(pdev)) { + printk(KERN_ERR "Failed to register platform device for ip2\n"); + return NULL; + } + if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) { + printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n"); + fw = NULL; + } + platform_device_unregister(pdev); + return fw; +} + int -ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) +ip2_loadmain(int *iop, int *irqp) { int i, j, box; int err = 0; @@ -504,6 +503,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) i2eBordStrPtr pB = NULL; int rc = -1; static struct pci_dev *pci_dev_i = NULL; + const struct firmware *fw = NULL; ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); @@ -537,9 +537,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } poll_only = !poll_only; - Fip_firmware = firmware; - Fip_firmware_size = firmsize; - /* Announce our presence */ printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); @@ -659,10 +656,18 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) } } for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { + /* We don't want to request the firmware unless we have at + least one board */ if ( i2BoardPtrTable[i] != NULL ) { - ip2_init_board( i ); + if (!fw) + fw = ip2_request_firmware(); + if (!fw) + break; + ip2_init_board(i, fw); } } + if (fw) + release_firmware(fw); ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); @@ -779,8 +784,6 @@ out: return err; } -EXPORT_SYMBOL(ip2_loadmain); - /******************************************************************************/ /* Function: ip2_init_board() */ /* Parameters: Index of board in configuration structure */ @@ -792,7 +795,7 @@ EXPORT_SYMBOL(ip2_loadmain); /* are reported on the console. */ /******************************************************************************/ static void -ip2_init_board( int boardnum ) +ip2_init_board(int boardnum, const struct firmware *fw) { int i; int nports = 0, nboxes = 0; @@ -812,7 +815,7 @@ ip2_init_board( int boardnum ) goto err_initialize; } - if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size ) + if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size ) != II_DOWN_GOOD ) { printk ( KERN_ERR "IP2: failed to download loadware\n" ); goto err_release_region; @@ -1286,11 +1289,12 @@ static void do_input(struct work_struct *work) // code duplicated from n_tty (ldisc) static inline void isig(int sig, struct tty_struct *tty, int flush) { + /* FIXME: This is completely bogus */ if (tty->pgrp) kill_pgrp(tty->pgrp, sig, 1); if (flush || !L_NOFLSH(tty)) { - if ( tty->ldisc.flush_buffer ) - tty->ldisc.flush_buffer(tty); + if ( tty->ldisc.ops->flush_buffer ) + tty->ldisc.ops->flush_buffer(tty); i2InputFlush( tty->driver_data ); } } @@ -1339,7 +1343,7 @@ static void do_status(struct work_struct *work) } tmp = pCh->pTTY->real_raw; pCh->pTTY->real_raw = 0; - pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); + pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); pCh->pTTY->real_raw = tmp; } #endif /* NEVER_HAPPENS_AS_SETUP_XXX */ @@ -2931,42 +2935,11 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg ) static int ip2_ipl_open( struct inode *pInode, struct file *pFile ) { - unsigned int iplminor = iminor(pInode); - i2eBordStrPtr pB; - i2ChanStrPtr pCh; #ifdef IP2DEBUG_IPL printk (KERN_DEBUG "IP2IPL: open\n" ); #endif - - switch(iplminor) { - // These are the IPL devices - case 0: - case 4: - case 8: - case 12: - break; - - // These are the status devices - case 1: - case 5: - case 9: - case 13: - break; - - // These are the debug devices - case 2: - case 6: - case 10: - case 14: - pB = i2BoardPtrTable[iplminor / 4]; - pCh = (i2ChanStrPtr) pB->i2eChannelPtr; - break; - - // This is the trace device - case 3: - break; - } + cycle_kernel_lock(); return 0; } |