static int hertz = HZ;
static int samplerate = 100;
-MODULE_PARM(ixjdebug, "i");
+module_param(ixjdebug, int, 0);
/************************************************************************
*
return 0;
}
-static IXJ_REGFUNC ixj_DownloadG729 = &Stub;
-static IXJ_REGFUNC ixj_DownloadTS85 = &Stub;
static IXJ_REGFUNC ixj_PreRead = &Stub;
static IXJ_REGFUNC ixj_PostRead = &Stub;
static IXJ_REGFUNC ixj_PreWrite = &Stub;
static IXJ_REGFUNC ixj_PostWrite = &Stub;
-static IXJ_REGFUNC ixj_PreIoctl = &Stub;
-static IXJ_REGFUNC ixj_PostIoctl = &Stub;
static void ixj_read_frame(IXJ *j);
static void ixj_write_frame(IXJ *j);
static int ixj_init_filter(IXJ *j, IXJ_FILTER * jf);
static int ixj_init_filter_raw(IXJ *j, IXJ_FILTER_RAW * jfr);
static int ixj_init_tone(IXJ *j, IXJ_TONE * ti);
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp);
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp);
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp);
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp);
/* Serial Control Interface funtions */
static int SCI_Control(IXJ *j, int control);
static int SCI_Prepare(IXJ *j);
return 0;
}
-static int ixj_register(int index, IXJ_REGFUNC regfunc)
-{
- int cnt;
- int retval = 0;
- switch (index) {
- case G729LOADER:
- ixj_DownloadG729 = regfunc;
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- IXJ *j = get_ixj(cnt);
- while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- ixj_DownloadG729(j, 0L);
- clear_bit(cnt, &j->busyflags);
- }
- break;
- case TS85LOADER:
- ixj_DownloadTS85 = regfunc;
- for (cnt = 0; cnt < IXJMAX; cnt++) {
- IXJ *j = get_ixj(cnt);
- while(test_and_set_bit(cnt, (void *)&j->busyflags) != 0) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(1);
- }
- ixj_DownloadTS85(j, 0L);
- clear_bit(cnt, &j->busyflags);
- }
- break;
- case PRE_READ:
- ixj_PreRead = regfunc;
- break;
- case POST_READ:
- ixj_PostRead = regfunc;
- break;
- case PRE_WRITE:
- ixj_PreWrite = regfunc;
- break;
- case POST_WRITE:
- ixj_PostWrite = regfunc;
- break;
- case PRE_IOCTL:
- ixj_PreIoctl = regfunc;
- break;
- case POST_IOCTL:
- ixj_PostIoctl = regfunc;
- break;
- default:
- retval = 1;
- }
- return retval;
-}
-
-EXPORT_SYMBOL(ixj_register);
-
-static int ixj_unregister(int index)
-{
- int retval = 0;
- switch (index) {
- case G729LOADER:
- ixj_DownloadG729 = &Stub;
- break;
- case TS85LOADER:
- ixj_DownloadTS85 = &Stub;
- break;
- case PRE_READ:
- ixj_PreRead = &Stub;
- break;
- case POST_READ:
- ixj_PostRead = &Stub;
- break;
- case PRE_WRITE:
- ixj_PreWrite = &Stub;
- break;
- case POST_WRITE:
- ixj_PostWrite = &Stub;
- break;
- case PRE_IOCTL:
- ixj_PreIoctl = &Stub;
- break;
- case POST_IOCTL:
- ixj_PostIoctl = &Stub;
- break;
- default:
- retval = 1;
- }
- return retval;
-}
-
-EXPORT_SYMBOL(ixj_unregister);
-
static void ixj_init_timer(IXJ *j)
{
init_timer(&j->timer);
return 0;
}
-int ixj_release(struct inode *inode, struct file *file_p)
+static int ixj_release(struct inode *inode, struct file *file_p)
{
IXJ_TONE ti;
int cnt;
}
}
-static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * ppos)
+static ssize_t ixj_read(struct file * file_p, char __user *buf, size_t length, loff_t * ppos)
{
unsigned long i = *ppos;
IXJ * j = get_ixj(NUM(file_p->f_dentry->d_inode));
}
}
-static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
+static ssize_t ixj_enhanced_read(struct file * file_p, char __user *buf, size_t length,
loff_t * ppos)
{
int pre_retval;
return read_retval;
}
-static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_write(struct file *file_p, const char __user *buf, size_t count, loff_t * ppos)
{
unsigned long i = *ppos;
IXJ *j = file_p->private_data;
return min(count, j->write_buffer_size);
}
-static ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+static ssize_t ixj_enhanced_write(struct file * file_p, const char __user *buf, size_t count, loff_t * ppos)
{
int pre_retval;
ssize_t write_retval = 0;
ixj_WriteDSPCommand(0x3001, j); /* Test External SRAM */
}
-static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp)
+static int ixj_build_cadence(IXJ *j, IXJ_CADENCE __user * cp)
{
- IXJ_CADENCE *lcp;
+ ixj_cadence *lcp;
+ IXJ_CADENCE_ELEMENT __user *cep;
IXJ_CADENCE_ELEMENT *lcep;
IXJ_TONE ti;
+ int err;
- lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
+ lcp = kmalloc(sizeof(ixj_cadence), GFP_KERNEL);
if (lcp == NULL)
return -ENOMEM;
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)) || (unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT) )
- {
- kfree(lcp);
- return -EFAULT;
- }
+
+ err = -EFAULT;
+ if (copy_from_user(&lcp->elements_used,
+ &cp->elements_used, sizeof(int)))
+ goto out;
+ if (copy_from_user(&lcp->termination,
+ &cp->termination, sizeof(IXJ_CADENCE_TERM)))
+ goto out;
+ if (get_user(cep, &cp->ce))
+ goto out;
+
+ err = -EINVAL;
+ if ((unsigned)lcp->elements_used >= ~0U/sizeof(IXJ_CADENCE_ELEMENT))
+ goto out;
+
+ err = -ENOMEM;
lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
- if (lcep == NULL) {
- kfree(lcp);
- return -ENOMEM;
- }
- if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
- {
- kfree(lcep);
- kfree(lcp);
- return -EFAULT;
- }
+ if (!lcep)
+ goto out;
+
+ err = -EFAULT;
+ if (copy_from_user(lcep, cep, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
+ goto out1;
+
if (j->cadence_t) {
kfree(j->cadence_t->ce);
kfree(j->cadence_t);
}
ixj_play_tone(j, lcp->ce[0].index);
return 1;
+out1:
+ kfree(lcep);
+out:
+ kfree(lcp);
+ return err;
}
-static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp)
+static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE __user * cp)
{
IXJ_FILTER_CADENCE *lcp;
lcp = kmalloc(sizeof(IXJ_FILTER_CADENCE), GFP_KERNEL);
}
return -ENOMEM;
}
- if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE))) {
+ if (copy_from_user(lcp, cp, sizeof(IXJ_FILTER_CADENCE))) {
if(ixjdebug & 0x0001) {
printk(KERN_INFO "Could not copy cadence to kernel\n");
}
IXJ_TONE ti;
IXJ_FILTER jf;
IXJ_FILTER_RAW jfr;
+ void __user *argp = (void __user *)arg;
unsigned int raise, mant;
unsigned int minor = iminor(inode);
retval = j->serial;
break;
case IXJCTL_VERSION:
- if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
+ if (copy_to_user(argp, ixj_c_revision, strlen(ixj_c_revision)))
retval = -EFAULT;
break;
case PHONE_RING_CADENCE:
break;
case IXJCTL_CIDCW:
if(arg) {
- if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+ if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
retval = -EFAULT;
break;
}
/* Fall through */
case PHONE_RING_START:
if(arg) {
- if (copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID))) {
+ if (copy_from_user(&j->cid_send, argp, sizeof(PHONE_CID))) {
retval = -EFAULT;
break;
}
samplerate = arg;
break;
case IXJCTL_DRYBUFFER_READ:
- put_user(j->drybuffer, (unsigned long *) arg);
+ put_user(j->drybuffer, (unsigned long __user *) argp);
break;
case IXJCTL_DRYBUFFER_CLEAR:
j->drybuffer = 0;
break;
case IXJCTL_FRAMES_READ:
- put_user(j->framesread, (unsigned long *) arg);
+ put_user(j->framesread, (unsigned long __user *) argp);
break;
case IXJCTL_FRAMES_WRITTEN:
- put_user(j->frameswritten, (unsigned long *) arg);
+ put_user(j->frameswritten, (unsigned long __user *) argp);
break;
case IXJCTL_READ_WAIT:
- put_user(j->read_wait, (unsigned long *) arg);
+ put_user(j->read_wait, (unsigned long __user *) argp);
break;
case IXJCTL_WRITE_WAIT:
- put_user(j->write_wait, (unsigned long *) arg);
+ put_user(j->write_wait, (unsigned long __user *) argp);
break;
case PHONE_MAXRINGS:
j->maxrings = arg;
12, 10, 16, 9, 8, 48, 5,
40, 40, 80, 40, 40, 6
};
- if(copy_from_user(&pd, (void *)arg, sizeof(pd))) {
+ if(copy_from_user(&pd, argp, sizeof(pd))) {
retval = -EFAULT;
break;
}
default:val=proto_size[pd.type]*3;break;
}
pd.buf_min=pd.buf_max=pd.buf_opt=val;
- if(copy_to_user((void *)arg, &pd, sizeof(pd)))
+ if(copy_to_user(argp, &pd, sizeof(pd)))
retval = -EFAULT;
break;
}
ixj_write_vmwi(j, arg);
break;
case IXJCTL_CID:
- if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
+ if (copy_to_user(argp, &j->cid, sizeof(PHONE_CID)))
retval = -EFAULT;
j->ex.bits.caller_id = 0;
break;
break;
case PHONE_CAPABILITIES_LIST:
add_caps(j);
- if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
+ if (copy_to_user(argp, j->caplist, sizeof(struct phone_capability) * j->caps))
retval = -EFAULT;
break;
case PHONE_CAPABILITIES_CHECK:
{
struct phone_capability cap;
- if (copy_from_user(&cap, (char *) arg, sizeof(cap)))
+ if (copy_from_user(&cap, argp, sizeof(cap)))
retval = -EFAULT;
else {
add_caps(j);
j->ex.bits.pstn_ring = 0;
break;
case IXJCTL_SET_FILTER:
- if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
+ if (copy_from_user(&jf, argp, sizeof(jf)))
retval = -EFAULT;
retval = ixj_init_filter(j, &jf);
break;
case IXJCTL_SET_FILTER_RAW:
- if (copy_from_user(&jfr, (char *) arg, sizeof(jfr)))
+ if (copy_from_user(&jfr, argp, sizeof(jfr)))
retval = -EFAULT;
else
retval = ixj_init_filter_raw(j, &jfr);
retval = j->filter_hist[arg];
break;
case IXJCTL_INIT_TONE:
- if (copy_from_user(&ti, (char *) arg, sizeof(ti)))
+ if (copy_from_user(&ti, argp, sizeof(ti)))
retval = -EFAULT;
else
retval = ixj_init_tone(j, &ti);
break;
case IXJCTL_TONE_CADENCE:
- retval = ixj_build_cadence(j, (IXJ_CADENCE *) arg);
+ retval = ixj_build_cadence(j, argp);
break;
case IXJCTL_FILTER_CADENCE:
- retval = ixj_build_filter_cadence(j, (IXJ_FILTER_CADENCE *) arg);
+ retval = ixj_build_filter_cadence(j, argp);
break;
case IXJCTL_SIGCTL:
- if (copy_from_user(&j->sigdef, (char *)arg, sizeof(IXJ_SIGDEF))) {
+ if (copy_from_user(&j->sigdef, argp, sizeof(IXJ_SIGDEF))) {
retval = -EFAULT;
break;
}
return fasync_helper(fd, file_p, mode, &j->async_queue);
}
-struct file_operations ixj_fops =
+static struct file_operations ixj_fops =
{
.owner = THIS_MODULE,
.read = ixj_enhanced_read,
0,
};
-MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
-MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
+module_param_array(dspio, int, NULL, 0);
+module_param_array(xio, int, NULL, 0);
MODULE_DESCRIPTION("Quicknet VoIP Telephony card module - www.quicknet.net");
MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
MODULE_LICENSE("GPL");
cleanup();
}
-int __init ixj_probe_isapnp(int *cnt)
+static IXJ *new_ixj(unsigned long port)
+{
+ IXJ *res;
+ if (!request_region(port, 16, "ixj DSP")) {
+ printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", port);
+ return NULL;
+ }
+ res = ixj_alloc();
+ if (!res) {
+ release_region(port, 16);
+ printk(KERN_INFO "ixj: out of memory\n");
+ return NULL;
+ }
+ res->DSPbase = port;
+ return res;
+}
+
+static int __init ixj_probe_isapnp(int *cnt)
{
int probe = 0;
int func = 0x110;
return -ENODEV;
}
- result = check_region(pnp_port_start(dev, 0), 16);
- if (result) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%lx\n", pnp_port_start(dev, 0));
+ j = new_ixj(pnp_port_start(dev, 0));
+ if (!j)
break;
- }
-
- j = ixj_alloc();
- request_region(j->DSPbase, 16, "ixj DSP");
if (func != 0x110)
j->XILINXbase = pnp_port_start(dev, 1); /* get real port */
return probe;
}
-int __init ixj_probe_isa(int *cnt)
+static int __init ixj_probe_isa(int *cnt)
{
- int i, result, probe;
+ int i, probe;
/* Use passed parameters for older kernels without PnP */
for (i = 0; i < IXJMAX; i++) {
if (dspio[i]) {
- IXJ *j;
+ IXJ *j = new_ixj(dspio[i]);
- if ((result = check_region(ixj[*cnt].DSPbase, 16)) < 0) {
- printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[*cnt].DSPbase);
+ if (!j)
break;
- }
-
- j = ixj_alloc();
-
- j->DSPbase = dspio[i];
- request_region(j->DSPbase, 16, "ixj DSP");
j->XILINXbase = xio[i];
j->cardtype = 0;
return 0;
}
-int __init ixj_probe_pci(int *cnt)
+static int __init ixj_probe_pci(int *cnt)
{
struct pci_dev *pci = NULL;
int i, probe = 0;
IXJ *j = NULL;
- int result;
for (i = 0; i < IXJMAX - *cnt; i++) {
pci = pci_find_device(0x15E2, 0x0500, pci);
if (pci_enable_device(pci))
break;
- if ((result = check_region(pci_resource_start(pci, 0), 16)) < 0) {
- printk(KERN_INFO "ixj: can't get I/O address\n");
+ j = new_ixj(pci_resource_start(pci, 0));
+ if (!j)
break;
- }
- /* Grab a device slot */
- j = ixj_alloc();
- if(j == NULL)
- break;
-
- j->DSPbase = pci_resource_start(pci, 0);
j->serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
j->XILINXbase = j->DSPbase + 0x10;
- request_region(j->DSPbase, 16, "ixj DSP");
j->cardtype = QTI_PHONEJACK_PCI;
j->board = *cnt;
probe = ixj_selfprobe(j);