Commit d37734b2 authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Eicon driver fixes

o Return correct error codes
o New-style named initializers
o Don't define dummy fops operations where not needed
o Race-free open()

(Armin Schindler)
parent a226cc99
......@@ -974,6 +974,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl, diva_os_message_buffer_s *dm
__u32 length = DIVA_MESSAGE_BUFFER_LEN(dmb);
word clength = READ_WORD(&msg->header.length);
word command = READ_WORD(&msg->header.command);
u16 retval = CAPI_NOERROR;
if(diva_os_in_irq()) {
DBG_ERR(("CAPI_SEND_MSG - in irq context !"))
......@@ -1008,6 +1009,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl, diva_os_message_buffer_s *dm
READ_WORD(&msg->info.data_b3_req.Data_Length) > (length - clength))
{
DBG_ERR(("Write - invalid message size"))
retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
goto write_end;
}
......@@ -1015,6 +1017,7 @@ static u16 diva_send_message(struct capi_ctr *ctrl, diva_os_message_buffer_s *dm
if (i == (MAX_DATA_B3 * this->MaxNCCI))
{
DBG_ERR(("Write - too many data pending"))
retval = CAPI_SENDQUEUEFULL;
goto write_end;
}
msg->info.data_b3_req.Data = i;
......@@ -1052,19 +1055,22 @@ static u16 diva_send_message(struct capi_ctr *ctrl, diva_os_message_buffer_s *dm
break;
case _BAD_MSG:
DBG_ERR(("Write - bad message"))
retval = CAPI_ILLCMDORSUBCMDORMSGTOSMALL;
break;
case _QUEUE_FULL:
DBG_ERR(("Write - queue full"))
retval = CAPI_SENDQUEUEFULL;
break;
default:
DBG_ERR(("Write - api_put returned unknown error"))
retval = CAPI_UNKNOWNNOTPAR;
break;
}
write_end:
diva_os_leave_spin_lock (&api_lock, &old_irql, "send message");
diva_os_free_message_buffer(dmb);
return CAPI_NOERROR;
return retval;
}
......
......@@ -30,7 +30,7 @@
EXPORT_NO_SYMBOLS;
static char *main_revision = "$Revision: 1.1.2.2 $";
static char *main_revision = "$Revision: 1.1.2.4 $";
static int major = 241;
......@@ -53,7 +53,8 @@ char *DRIVERRELEASE = "2.0";
static devfs_handle_t devfs_handle;
static wait_queue_head_t msgwaitq;
static atomic_t opened;
static DECLARE_MUTEX(opened_sem);
static int opened;
static struct timeval start_time;
extern int mntfunc_init(int *, void **, unsigned long);
......@@ -308,10 +309,14 @@ maint_poll(struct file *file, poll_table * wait)
static int
maint_open(struct inode *ino, struct file *filep)
{
if (atomic_read(&opened))
down(&opened_sem);
if (opened)
{
up(&opened_sem);
return(-EBUSY);
else
atomic_inc(&opened);
}
opened++;
up(&opened_sem);
filep->private_data = 0;
......@@ -326,34 +331,24 @@ maint_close(struct inode *ino, struct file *filep)
filep->private_data = 0;
}
atomic_dec(&opened);
down(&opened_sem);
opened--;
up(&opened_sem);
return(0);
}
static int maint_ioctl (struct inode *inode, struct file *file, uint cmd, ulong arg)
{
return(-EINVAL);
}
static loff_t
maint_lseek(struct file *file, loff_t offset, int orig)
{
return(-ESPIPE);
}
/*
* fops
*/
static struct file_operations maint_fops =
{
owner: THIS_MODULE,
llseek: maint_lseek,
read: maint_read,
write: maint_write,
poll: maint_poll,
ioctl: maint_ioctl,
open: maint_open,
release: maint_close,
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = maint_read,
.write = maint_write,
.poll = maint_poll,
.open = maint_open,
.release = maint_close
};
static int DIVA_INIT_FUNCTION
......@@ -395,14 +390,13 @@ static ssize_t divas_maint_read(struct file * file, char * buf,
static struct file_operations divas_maint_fops =
{
owner: THIS_MODULE,
llseek: maint_lseek,
read: divas_maint_read,
write: divas_maint_write,
poll: maint_poll,
ioctl: maint_ioctl,
open: maint_open,
release: maint_close,
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_maint_read,
.write = divas_maint_write,
.poll = maint_poll,
.open = maint_open,
.release = maint_close
};
static void divas_maint_unregister_chrdev(void)
......
/* $Id: divasi.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
/* $Id: divasi.c,v 1.1.2.7 2001/05/01 15:48:05 armin Exp $
*
* Driver for Eicon DIVA Server ISDN cards.
* User Mode IDI Interface
......@@ -30,7 +30,7 @@
EXPORT_NO_SYMBOLS;
static char *main_revision = "$Revision: 1.1.2.2 $";
static char *main_revision = "$Revision: 1.1.2.7 $";
static int major = 242;
......@@ -76,11 +76,9 @@ getrev(const char *revision)
/*
* LOCALS
*/
static loff_t um_idi_lseek (struct file *file, loff_t offset, int orig);
static ssize_t um_idi_read (struct file *file, char *buf, size_t count, loff_t *offset);
static ssize_t um_idi_write (struct file *file, const char *buf, size_t count, loff_t *offset);
static unsigned int um_idi_poll (struct file *file, poll_table *wait);
static int um_idi_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
static int um_idi_open (struct inode *inode, struct file *file);
static int um_idi_release (struct inode *inode, struct file *file);
static int remove_entity (void* entity);
......@@ -161,14 +159,13 @@ remove_um_idi_proc(void)
static struct file_operations divas_idi_fops =
{
owner: THIS_MODULE,
llseek: um_idi_lseek,
read: um_idi_read,
write: um_idi_write,
poll: um_idi_poll,
ioctl: um_idi_ioctl,
open: um_idi_open,
release: um_idi_release,
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = um_idi_read,
.write = um_idi_write,
.poll = um_idi_poll,
.open = um_idi_open,
.release = um_idi_release
};
static void divas_idi_unregister_chrdev(void)
......@@ -255,12 +252,6 @@ module_exit(divasi_exit);
* FILE OPERATIONS
*/
static loff_t
um_idi_lseek(struct file *file, loff_t offset, int orig)
{
return (-ESPIPE);
}
static int
divas_um_idi_copy_to_user (void* os_handle, void* dst, const void* src, int length)
{
......@@ -428,12 +419,6 @@ um_idi_poll (struct file *file, poll_table *wait)
return (POLLIN | POLLRDNORM);
}
static int
um_idi_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
return (-EINVAL);
}
static int
um_idi_open (struct inode *inode, struct file *file)
{
......
/* $Id: divasmain.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
/* $Id: divasmain.c,v 1.1.2.8 2001/05/01 15:48:05 armin Exp $
*
* Low level driver for Eicon DIVA Server ISDN cards.
*
......@@ -46,7 +46,7 @@
#include "diva_dma.h"
EXPORT_NO_SYMBOLS;
static char *main_revision = "$Revision: 1.1.2.2 $";
static char *main_revision = "$Revision: 1.1.2.8 $";
int errno = 0;
static int major = 240;
......@@ -72,8 +72,8 @@ static devfs_handle_t devfs_handle;
typedef struct _diva_os_thread_dpc {
struct tasklet_struct divas_task;
diva_os_soft_isr_t* psoft_isr;
struct work_struct trap_script_task;
diva_os_soft_isr_t* psoft_isr;
int card_failed;
} diva_os_thread_dpc_t;
......@@ -685,12 +685,6 @@ static int divas_release(struct inode * inode, struct file * file)
return(0);
}
static int divas_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{
return(-EINVAL);
}
static ssize_t divas_write(struct file * file, const char * buf,
size_t count, loff_t *ppos)
{
......@@ -759,22 +753,15 @@ static unsigned int divas_poll(struct file *file, poll_table * wait)
return (POLLIN | POLLRDNORM);
}
static loff_t divas_lseek(struct file *file, loff_t offset, int orig)
{
return(-ESPIPE);
}
static struct file_operations divas_fops =
{
owner: THIS_MODULE,
llseek: divas_lseek,
read: divas_read,
write: divas_write,
poll: divas_poll,
ioctl: divas_ioctl,
open: divas_open,
release: divas_release,
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_read,
.write = divas_write,
.poll = divas_poll,
.open = divas_open,
.release = divas_release
};
static void divas_unregister_chrdev(void)
......
/* $Id: divasproc.c,v 1.1.2.2 2002/10/02 14:38:37 armin Exp $
/* $Id: divasproc.c,v 1.1.2.4 2001/02/16 08:40:36 armin Exp $
*
* Low level driver for Eicon DIVA Server ISDN cards.
* /proc functions
......@@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/poll.h>
#include <linux/proc_fs.h>
#include <linux/interrupt.h>
#include "platform.h"
#include "debuglib.h"
......@@ -117,28 +118,15 @@ divas_close(struct inode *inode, struct file *file)
return(0);
}
static int
divas_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
{
return(-EINVAL);
}
static loff_t
divas_lseek(struct file *file, loff_t offset, int orig)
{
return(-ESPIPE);
}
static struct file_operations divas_fops =
{
owner: THIS_MODULE,
llseek: divas_lseek,
read: divas_read,
write: divas_write,
poll: divas_poll,
ioctl: divas_ioctl,
open: divas_open,
release: divas_close,
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = divas_read,
.write = divas_write,
.poll = divas_poll,
.open = divas_open,
.release = divas_close
};
int
......@@ -355,6 +343,11 @@ int create_adapter_proc (diva_os_xdi_adapter_t* a) {
struct proc_dir_entry *de, *pe;
char tmp[16];
if(in_interrupt()) { /* FIXME */
printk(KERN_ERR "divasproc: create_proc in_interrupt, not creating\n");
return(1);
}
sprintf(tmp, "%s%d", adapter_dir_name, a->controller);
if(!(de = create_proc_entry(tmp, S_IFDIR, proc_net_isdn_eicon)))
return(0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment