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