X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Ftelephony%2Fixj.c;h=210b0b16345ef8152f33b412438219f2443a9443;hb=6a77f38946aaee1cd85eeec6cf4229b204c15071;hp=5778788a2020b726ebab6c6491cee025700b11b1;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 5778788a2..210b0b163 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -285,7 +285,7 @@ static int ixjdebug; static int hertz = HZ; static int samplerate = 100; -MODULE_PARM(ixjdebug, "i"); +module_param(ixjdebug, int, 0); /************************************************************************ * @@ -406,14 +406,10 @@ static int Stub(IXJ * J, unsigned long arg) 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); @@ -461,8 +457,8 @@ static void DAA_Coeff_Japan(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); @@ -792,97 +788,6 @@ static int ixj_wink(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); @@ -2257,7 +2162,7 @@ static int ixj_open(struct phone_device *p, struct file *file_p) 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; @@ -2855,7 +2760,7 @@ static void alaw2ulaw(unsigned char *buff, unsigned long len) } } -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)); @@ -2910,7 +2815,7 @@ static ssize_t ixj_read(struct file * file_p, char *buf, size_t length, loff_t * } } -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; @@ -2935,7 +2840,7 @@ static ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length, 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; @@ -2989,7 +2894,7 @@ static ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, lof 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; @@ -5938,31 +5843,41 @@ static void ixj_testram(IXJ *j) 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); @@ -5982,9 +5897,14 @@ static int ixj_build_cadence(IXJ *j, IXJ_CADENCE * cp) } 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); @@ -5994,7 +5914,7 @@ static int ixj_build_filter_cadence(IXJ *j, IXJ_FILTER_CADENCE * cp) } 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"); } @@ -6206,6 +6126,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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); @@ -6251,7 +6172,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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: @@ -6259,7 +6180,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; } @@ -6274,7 +6195,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, /* 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; } @@ -6432,22 +6353,22 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; @@ -6573,7 +6494,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; } @@ -6590,7 +6511,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; } @@ -6644,7 +6565,7 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; @@ -6666,13 +6587,13 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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); @@ -6688,12 +6609,12 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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); @@ -6705,19 +6626,19 @@ static int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, 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; } @@ -6769,7 +6690,7 @@ static int ixj_fasync(int fd, struct file *file_p, int mode) 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, @@ -7691,8 +7612,8 @@ static int xio[IXJMAX + 1] = 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 "); MODULE_LICENSE("GPL"); @@ -7702,7 +7623,24 @@ static void __exit ixj_exit(void) 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; @@ -7734,14 +7672,9 @@ int __init ixj_probe_isapnp(int *cnt) 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 */ @@ -7787,24 +7720,17 @@ int __init ixj_probe_isapnp(int *cnt) 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; @@ -7818,12 +7744,11 @@ int __init ixj_probe_isa(int *cnt) 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); @@ -7832,20 +7757,12 @@ int __init ixj_probe_pci(int *cnt) 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);