Hi,
Please consider applying.
- Arnaldo
--- linux-2.4.0-test7/drivers/telephony/ixj.c Thu Jul 13 01:58:43 2000
+++ linux-2.4.0-test7.acme/drivers/telephony/ixj.c Sun Aug 27 19:17:42 2000
@@ -17,10 +17,16 @@
* David W. Erhart, <derhart@quicknet.net>
* John Sellers, <jsellers@quicknet.net>
* Mike Preston, <mpreston@quicknet.net>
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
*
* Fixes:
*
* 2.3.x port : Alan Cox
+ * check put_user return,
+ * resource release on failure in
+ * ixj_build_cadence, get rid of
+ * check_region (race in 2.4),
+ * some cleanups : Arnaldo Carvalho de Melo
*
* More information about the hardware related to this driver can be found
* at our website: http://www.quicknet.net
@@ -1306,10 +1312,7 @@
/* Don't ever copy more than the user asks */
i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
j->read_buffer_ready = 0;
- if (i)
- return -EFAULT;
- else
- return min(length, j->read_buffer_size);
+ return i ? -EFAULT : min(length, j->read_buffer_size);
}
ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
@@ -1373,10 +1376,7 @@
if (j->write_buffer_wp + count >= j->write_buffer_end)
j->write_buffer_wp = j->write_buffer;
i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
- if (i)
- return -EFAULT;
-
- return min(count, j->write_buffer_size);
+ return i ? -EFAULT : min(count, j->write_buffer_size);
}
ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count,
@@ -3391,21 +3391,22 @@
IXJ_CADENCE_ELEMENT *lcep;
IXJ_TONE ti;
IXJ *j = &ixj[board];
+ int ret = -EFAULT;
lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
if (lcp == NULL)
return -ENOMEM;
if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)))
- return -EFAULT;
+ goto cleanup_lcp;
lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
if (lcep == NULL) {
- kfree(lcp);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto cleanup_lcp;
}
if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
- return -EFAULT;
+ goto cleanup_lcep;
if(j->cadence_t)
{
@@ -3429,6 +3430,9 @@
ixj_play_tone(board, lcp->ce[0].index);
return 1;
+cleanup_lcep: kfree(lcep);
+cleanup_lcp: kfree(lcp);
+ return ret;
}
static void add_caps(int board)
@@ -3668,22 +3672,22 @@
samplerate = arg;
break;
case IXJCTL_DRYBUFFER_READ:
- put_user(j->drybuffer, (unsigned long *) arg);
+ retval = put_user(j->drybuffer, (unsigned long *) arg);
break;
case IXJCTL_DRYBUFFER_CLEAR:
j->drybuffer = 0;
break;
case IXJCTL_FRAMES_READ:
- put_user(j->framesread, (unsigned long *) arg);
+ retval = put_user(j->framesread, (unsigned long *) arg);
break;
case IXJCTL_FRAMES_WRITTEN:
- put_user(j->frameswritten, (unsigned long *) arg);
+ retval = put_user(j->frameswritten, (unsigned long *) arg);
break;
case IXJCTL_READ_WAIT:
- put_user(j->read_wait, (unsigned long *) arg);
+ retval = put_user(j->read_wait, (unsigned long *) arg);
break;
case IXJCTL_WRITE_WAIT:
- put_user(j->write_wait, (unsigned long *) arg);
+ retval = put_user(j->write_wait, (unsigned long *) arg);
break;
case PHONE_MAXRINGS:
j->maxrings = arg;
@@ -3814,9 +3818,7 @@
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)))
- return -EFAULT;
- return 0;
+ return copy_to_user((void *)arg, &pd, sizeof(pd)) ? -EFAULT : 0;
}
case IXJCTL_DSP_IDLE:
idle(board);
@@ -3904,7 +3906,8 @@
retval = j->filter_hist[arg];
break;
case IXJCTL_INIT_TONE:
- copy_from_user(&ti, (char *) arg, sizeof(ti));
+ if (copy_from_user(&ti, (char *) arg, sizeof(ti)))
+ return -EFAULT;
retval = ixj_init_tone(board, &ti);
break;
case IXJCTL_TONE_CADENCE:
@@ -4101,26 +4104,27 @@
{
j->cardtype = 400; // Internet PhoneJACK Lite
- if (check_region(j->XILINXbase, 4)) {
+ if (!request_region(j->XILINXbase, 4, "ixj control")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
return -1;
}
- request_region(j->XILINXbase, 4, "ixj control");
j->pld_slicw.pcib.e1 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase);
} else {
j->cardtype = 300; // Internet LineJACK
- if (check_region(j->XILINXbase, 8)) {
+ if (!request_region(j->XILINXbase, 8, "ixj control")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
return -1;
}
- request_region(j->XILINXbase, 8, "ixj control");
}
} else if (j->dsp.low == 0x22) {
j->cardtype = 500; // Internet PhoneJACK PCI
- request_region(j->XILINXbase, 4, "ixj control");
+ if (!request_region(j->XILINXbase, 4, "ixj control")) {
+ printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
+ return -1;
+ }
j->pld_slicw.pcib.e1 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase);
} else
@@ -4140,21 +4144,18 @@
break;
case 300: // Internet LineJACK
- if (check_region(j->XILINXbase, 8)) {
+ if (!request_region(j->XILINXbase, 8, "ixj control")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
return -1;
}
- request_region(j->XILINXbase, 8, "ixj control");
break;
case 400: //Internet PhoneJACK Lite
case 500: //Internet PhoneJACK PCI
-
- if (check_region(j->XILINXbase, 4)) {
+ if (!request_region(j->XILINXbase, 4, "ixj control")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", j->XILINXbase);
return -1;
}
- request_region(j->XILINXbase, 4, "ixj control");
j->pld_slicw.pcib.e1 = 1;
outb_p(j->pld_slicw.byte, j->XILINXbase);
break;
@@ -4549,13 +4550,11 @@
if (func != 0x110)
ixj[cnt].XILINXbase = dev->resource[1].start; /* get real port */
- result = check_region(ixj[cnt].DSPbase, 16);
- if (result) {
+ if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
cleanup();
- return result;
+ return -EBUSY;
}
- request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
switch (func) {
case (0x110):
ixj[cnt].cardtype = 100;
@@ -4591,13 +4590,11 @@
ixj[cnt].DSPbase = dspio[cnt];
ixj[cnt].XILINXbase = xio[cnt];
ixj[cnt].cardtype = 0;
- result = check_region(ixj[cnt].DSPbase, 16);
- if (result) {
+ if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
cleanup();
- return result;
+ return -EBUSY;
}
- request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
probe = ixj_selfprobe(cnt);
ixj[cnt].dev = NULL;
}
@@ -4616,13 +4613,11 @@
ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10;
ixj[cnt].serial = (PCIEE_GetSerialNumber)pci_resource_start(pci, 2);
- result = check_region(ixj[cnt].DSPbase, 16);
- if (result) {
+ if (!request_region(ixj[cnt].DSPbase, 16, "ixj DSP")) {
printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
cleanup();
- return result;
+ return -EBUSY;
}
- request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
ixj[cnt].cardtype = 500;
probe = ixj_selfprobe(cnt);
cnt++;
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/
This archive was generated by hypermail 2b29 : Thu Aug 31 2000 - 21:00:20 EST