#include <linux/mm.h>
#include <linux/init.h>
#include <linux/device.h>
+#include <linux/smp_lock.h>
+ #include <linux/firmware.h>
+ #include <linux/platform_device.h>
#include <asm/atarihw.h>
#include <asm/traps.h>
} \
}
- /* DSP56001 bootstrap code */
- static char bootstrap[] = {
- 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4,
- 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47,
- 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00,
- 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe,
- 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0,
- 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a,
- 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4,
- 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01,
- 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08,
- 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46,
- 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa,
- 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00,
- 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9,
- 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80,
- 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a,
- 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0,
- 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4,
- 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a,
- 0xf0, 0x80, 0x00, 0x7e, 0xad};
- static int sizeof_bootstrap = 375;
-
-
static struct dsp56k_device {
unsigned long in_use;
long maxio, timeout;
static int dsp56k_upload(u_char __user *bin, int len)
{
+ struct platform_device *pdev;
+ const struct firmware *fw;
+ const char fw_name[] = "dsp56k/bootstrap.bin";
+ int err;
int i;
- u_char *p;
-
+
dsp56k_reset();
-
- p = bootstrap;
- for (i = 0; i < sizeof_bootstrap/3; i++) {
+
+ pdev = platform_device_register_simple("dsp56k", 0, NULL, 0);
+ if (IS_ERR(pdev)) {
+ printk(KERN_ERR "Failed to register device for \"%s\"\n",
+ fw_name);
+ return -EINVAL;
+ }
+ err = request_firmware(&fw, fw_name, &pdev->dev);
+ platform_device_unregister(pdev);
+ if (err) {
+ printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+ fw_name, err);
+ return err;
+ }
+ if (fw->size % 3) {
+ printk(KERN_ERR "Bogus length %d in image \"%s\"\n",
+ fw->size, fw_name);
+ release_firmware(fw);
+ return -EINVAL;
+ }
+ for (i = 0; i < fw->size; i = i + 3) {
/* tx_wait(10); */
- dsp56k_host_interface.data.b[1] = *p++;
- dsp56k_host_interface.data.b[2] = *p++;
- dsp56k_host_interface.data.b[3] = *p++;
+ dsp56k_host_interface.data.b[1] = fw->data[i];
+ dsp56k_host_interface.data.b[2] = fw->data[i + 1];
+ dsp56k_host_interface.data.b[3] = fw->data[i + 2];
}
+ release_firmware(fw);
for (; i < 512; i++) {
/* tx_wait(10); */
dsp56k_host_interface.data.b[1] = 0;
static int dsp56k_open(struct inode *inode, struct file *file)
{
int dev = iminor(inode) & 0x0f;
+ int ret = 0;
+ lock_kernel();
switch(dev)
{
case DSP56K_DEV_56001:
- if (test_and_set_bit(0, &dsp56k.in_use))
- return -EBUSY;
+ if (test_and_set_bit(0, &dsp56k.in_use)) {
+ ret = -EBUSY;
+ goto out;
+ }
dsp56k.timeout = TIMEOUT;
dsp56k.maxio = MAXIO;
break;
default:
- return -ENODEV;
+ ret = -ENODEV;
}
-
- return 0;
+out:
+ unlock_kernel();
+ return ret;
}
static int dsp56k_release(struct inode *inode, struct file *file)
module_exit(dsp56k_cleanup_driver);
MODULE_LICENSE("GPL");
+ MODULE_FIRMWARE("dsp56k/bootstrap.bin");
#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 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);
/***************/
/* 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 );
/* 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;
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;
}