#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>
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 */
static int ip2_open(PTTY, struct file *);
static void ip2_close(PTTY, struct file *);
static int ip2_write(PTTY, const unsigned char *, int);
-static void ip2_putchar(PTTY, unsigned char);
+static int ip2_putchar(PTTY, unsigned char);
static void ip2_flush_chars(PTTY);
static int ip2_write_room(PTTY);
static int ip2_chars_in_buf(PTTY);
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);
/***************/
return 0;
}
-/******************************************************************************/
-/* 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
-int
-init_module(void)
-{
-#ifdef IP2DEBUG_INIT
- printk (KERN_DEBUG "Loading module ...\n" );
-#endif
- return 0;
-}
-#endif /* MODULE */
-
/******************************************************************************/
/* Function: cleanup_module() */
/* Parameters: None */
/* driver should be returned since it may be unloaded from memory. */
/******************************************************************************/
#ifdef MODULE
-void
-cleanup_module(void)
+void __exit
+ip2_cleanup_module(void)
{
int err;
int i;
printk (KERN_DEBUG "IP2 Unloaded\n" );
#endif
}
+module_exit(ip2_cleanup_module);
#endif /* MODULE */
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;
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 );
}
poll_only = !poll_only;
- Fip_firmware = firmware;
- Fip_firmware_size = firmsize;
-
/* Announce our presence */
printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
}
}
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 );
return err;
}
-EXPORT_SYMBOL(ip2_loadmain);
-
/******************************************************************************/
/* Function: ip2_init_board() */
/* Parameters: Index of board in configuration structure */
/* 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;
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;
* Write to FIFO; don't bother to adjust fifo capacity for this, since
* board will respond almost immediately after SendMail hit.
*/
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 4);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
pB->i2eUsingIrq = boardIrq;
pB->i2eOutMailWaiting |= MB_OUT_STUFFED;
(CMD_OF(tempCommand))[4] = 64; // chars
(CMD_OF(tempCommand))[5] = 87; // HW_TEST
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 8);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
CHANNEL_OF(tempCommand) = 0;
PTYPE_OF(tempCommand) = PTYPE_BYPASS;
CMD_COUNT_OF(tempCommand) = 2;
(CMD_OF(tempCommand))[0] = 44; /* get ping */
(CMD_OF(tempCommand))[1] = 200; /* 200 ms */
- WRITE_LOCK_IRQSAVE(&pB->write_fifo_spinlock,flags);
+ write_lock_irqsave(&pB->write_fifo_spinlock, flags);
iiWriteBuf(pB, tempCommand, 4);
- WRITE_UNLOCK_IRQRESTORE(&pB->write_fifo_spinlock,flags);
+ write_unlock_irqrestore(&pB->write_fifo_spinlock, flags);
#endif
iiEnableMailIrq(pB);
// Data input
if ( pCh->pTTY != NULL ) {
- READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+ read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
if (!pCh->throttled && (pCh->Ibuf_stuff != pCh->Ibuf_strip)) {
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
i2Input( pCh );
} else
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
} else {
ip2trace(CHANN, ITRC_INPUT, 22, 0 );
serviceOutgoingFifo ( pCh->pMyBord );
- if ( tty->driver->flush_buffer )
- tty->driver->flush_buffer(tty);
- if ( tty->ldisc.flush_buffer )
- tty->ldisc.flush_buffer(tty);
+ tty_ldisc_flush(tty);
+ tty_driver_flush_buffer(tty);
tty->closing = 0;
pCh->pTTY = NULL;
ip2_flush_chars( tty );
/* This is the actual move bit. Make sure it does what we need!!!!! */
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
bytesSent = i2Output( pCh, pData, count);
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2trace (CHANN, ITRC_WRITE, ITRC_RETURN, 1, bytesSent );
/* */
/* */
/******************************************************************************/
-static void
+static int
ip2_putchar( PTTY tty, unsigned char ch )
{
i2ChanStrPtr pCh = tty->driver_data;
// ip2trace (CHANN, ITRC_PUTC, ITRC_ENTER, 1, ch );
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
pCh->Pbuf[pCh->Pbuf_stuff++] = ch;
if ( pCh->Pbuf_stuff == sizeof pCh->Pbuf ) {
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2_flush_chars( tty );
} else
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
+ return 1;
// ip2trace (CHANN, ITRC_PUTC, ITRC_RETURN, 1, ch );
}
i2ChanStrPtr pCh = tty->driver_data;
unsigned long flags;
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
if ( pCh->Pbuf_stuff ) {
// ip2trace (CHANN, ITRC_PUTC, 10, 1, strip );
}
pCh->Pbuf_stuff -= strip;
}
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
}
/******************************************************************************/
i2ChanStrPtr pCh = tty->driver_data;
unsigned long flags;
- READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
bytesFree = i2OutputFree( pCh ) - pCh->Pbuf_stuff;
- READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
ip2trace (CHANN, ITRC_WRITE, 11, 1, bytesFree );
pCh->Obuf_char_count + pCh->Pbuf_stuff,
pCh->Obuf_char_count, pCh->Pbuf_stuff );
#endif
- READ_LOCK_IRQSAVE(&pCh->Obuf_spinlock,flags);
+ read_lock_irqsave(&pCh->Obuf_spinlock, flags);
rc = pCh->Obuf_char_count;
- READ_UNLOCK_IRQRESTORE(&pCh->Obuf_spinlock,flags);
- READ_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Obuf_spinlock, flags);
+ read_lock_irqsave(&pCh->Pbuf_spinlock, flags);
rc += pCh->Pbuf_stuff;
- READ_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ read_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
return rc;
}
#ifdef IP2DEBUG_WRITE
printk (KERN_DEBUG "IP2: flush buffer\n" );
#endif
- WRITE_LOCK_IRQSAVE(&pCh->Pbuf_spinlock,flags);
+ write_lock_irqsave(&pCh->Pbuf_spinlock, flags);
pCh->Pbuf_stuff = 0;
- WRITE_UNLOCK_IRQRESTORE(&pCh->Pbuf_spinlock,flags);
+ write_unlock_irqrestore(&pCh->Pbuf_spinlock, flags);
i2FlushOutput( pCh );
ip2_owake(tty);
pCh->throttled = 0;
i2QueueCommands(PTYPE_BYPASS, pCh, 0, 1, CMD_RESUME);
serviceOutgoingFifo( pCh->pMyBord );
- READ_LOCK_IRQSAVE(&pCh->Ibuf_spinlock,flags)
+ read_lock_irqsave(&pCh->Ibuf_spinlock, flags);
if ( pCh->Ibuf_stuff != pCh->Ibuf_strip ) {
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
#ifdef IP2DEBUG_READ
printk (KERN_DEBUG "i2Input called from unthrottle\n" );
#endif
i2Input( pCh );
} else
- READ_UNLOCK_IRQRESTORE(&pCh->Ibuf_spinlock,flags)
+ read_unlock_irqrestore(&pCh->Ibuf_spinlock, flags);
}
static void
* for masking). Caller should use TIOCGICOUNT to see which one it was
*/
case TIOCMIWAIT:
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cprev = pCh->icount; /* note the counters on entry */
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
i2QueueCommands(PTYPE_BYPASS, pCh, 100, 4,
CMD_DCD_REP, CMD_CTS_REP, CMD_DSR_REP, CMD_RI_REP);
init_waitqueue_entry(&wait, current);
rc = -ERESTARTSYS;
break;
}
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cnow = pCh->icount; /* atomic copy */
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
if (cnow.rng == cprev.rng && cnow.dsr == cprev.dsr &&
cnow.dcd == cprev.dcd && cnow.cts == cprev.cts) {
rc = -EIO; /* no change => rc */
case TIOCGICOUNT:
ip2trace (CHANN, ITRC_IOCTL, 11, 1, rc );
- WRITE_LOCK_IRQSAVE(&pB->read_fifo_spinlock, flags);
+ write_lock_irqsave(&pB->read_fifo_spinlock, flags);
cnow = pCh->icount;
- WRITE_UNLOCK_IRQRESTORE(&pB->read_fifo_spinlock, flags);
+ write_unlock_irqrestore(&pB->read_fifo_spinlock, flags);
p_cuser = argp;
rc = put_user(cnow.cts, &p_cuser->cts);
rc = put_user(cnow.dsr, &p_cuser->dsr);
case 65: /* Board - ip2stat */
if ( pB ) {
rc = copy_to_user(argp, pB, sizeof(i2eBordStr));
- rc = put_user(INB(pB->i2eStatus),
+ rc = put_user(inb(pB->i2eStatus),
(ULONG __user *)(arg + (ULONG)(&pB->i2eStatus) - (ULONG)pB ) );
} else {
rc = -ENODEV;
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;
}