summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSean Young <sean@mess.org>2013-02-16 21:25:43 +0100
committerMauro Carvalho Chehab <mchehab@redhat.com>2013-03-19 19:14:00 +0100
commit801b69f2570e2556c6d5a060df85ce9bd0d38119 (patch)
tree31c5debaeceb7a0a7c1ac027ab96a710708dc3a0 /drivers
parent[media] em28xx: Add ISDB support for c3tech Digital duo (diff)
downloadlinux-801b69f2570e2556c6d5a060df85ce9bd0d38119.tar.xz
linux-801b69f2570e2556c6d5a060df85ce9bd0d38119.zip
[media] redrat3: limit periods to hardware limits
The redrat hardware cannot handle periods of larger than 32767us, limit appropriately. Also fix memory leak in redrat3_get_timeout. Signed-off-by: Sean Young <sean@mess.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/rc/redrat3.c53
1 files changed, 24 insertions, 29 deletions
diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c
index 1b37fe2779f8..842bdcded27c 100644
--- a/drivers/media/rc/redrat3.c
+++ b/drivers/media/rc/redrat3.c
@@ -209,9 +209,6 @@ struct redrat3_dev {
u16 pktlen;
u16 pkttype;
u16 bytes_read;
- /* indicate whether we are going to reprocess
- * the USB callback with a bigger buffer */
- int buftoosmall;
char *datap;
u32 carrier;
@@ -396,7 +393,6 @@ static u32 redrat3_us_to_len(u32 microsec)
/* don't allow zero lengths to go back, breaks lirc */
return result ? result : 1;
-
}
/* timer callback to send reset event */
@@ -515,8 +511,6 @@ static void redrat3_process_ir_data(struct redrat3_dev *rr3)
rr3_dbg(dev, "calling ir_raw_event_handle\n");
ir_raw_event_handle(rr3->rc);
-
- return;
}
/* Util fn to send rr3 cmds */
@@ -613,7 +607,7 @@ static inline void redrat3_delete(struct redrat3_dev *rr3,
static u32 redrat3_get_timeout(struct redrat3_dev *rr3)
{
- u32 *tmp;
+ __be32 *tmp;
u32 timeout = MS_TO_US(150); /* a sane default, if things go haywire */
int len, ret, pipe;
@@ -628,14 +622,16 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3)
ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5);
- if (ret != len) {
+ if (ret != len)
dev_warn(rr3->dev, "Failed to read timeout from hardware\n");
- return timeout;
+ else {
+ timeout = redrat3_len_to_us(be32_to_cpup(tmp));
+
+ rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000);
}
- timeout = redrat3_len_to_us(be32_to_cpu(*tmp));
+ kfree(tmp);
- rr3_dbg(rr3->dev, "Got timeout of %d ms\n", timeout / 1000);
return timeout;
}
@@ -755,7 +751,6 @@ static void redrat3_read_packet_start(struct redrat3_dev *rr3, int len)
static void redrat3_read_packet_continue(struct redrat3_dev *rr3, int len)
{
-
rr3_ftr(rr3->dev, "Entering %s\n", __func__);
memcpy(rr3->datap, (unsigned char *)rr3->bulk_in_buf, len);
@@ -815,7 +810,7 @@ out:
}
/* callback function from USB when async USB request has completed */
-static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
+static void redrat3_handle_async(struct urb *urb)
{
struct redrat3_dev *rr3;
int ret;
@@ -857,7 +852,7 @@ static void redrat3_handle_async(struct urb *urb, struct pt_regs *regs)
}
}
-static void redrat3_write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+static void redrat3_write_bulk_callback(struct urb *urb)
{
struct redrat3_dev *rr3;
int len;
@@ -901,7 +896,7 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
struct redrat3_dev *rr3 = rcdev->priv;
struct device *dev = rr3->dev;
struct redrat3_signal_header header;
- int i, j, ret, ret_len, offset;
+ int i, ret, ret_len, offset;
int lencheck, cur_sample_len, pipe;
char *buffer = NULL, *sigdata = NULL;
int *sample_lens = NULL;
@@ -931,8 +926,19 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
goto out;
}
+ sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL);
+ if (!sigdata) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
for (i = 0; i < count; i++) {
cur_sample_len = redrat3_us_to_len(txbuf[i]);
+ if (cur_sample_len > 0xffff) {
+ dev_warn(dev, "transmit period of %uus truncated to %uus\n",
+ txbuf[i], redrat3_len_to_us(0xffff));
+ cur_sample_len = 0xffff;
+ }
for (lencheck = 0; lencheck < curlencheck; lencheck++) {
if (sample_lens[lencheck] == cur_sample_len)
break;
@@ -950,22 +956,11 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf,
break;
}
}
- }
-
- sigdata = kzalloc((count + RR3_TX_TRAILER_LEN), GFP_KERNEL);
- if (!sigdata) {
- ret = -ENOMEM;
- goto out;
+ sigdata[i] = lencheck;
}
sigdata[count] = RR3_END_OF_SIGNAL;
sigdata[count + 1] = RR3_END_OF_SIGNAL;
- for (i = 0; i < count; i++) {
- for (j = 0; j < curlencheck; j++) {
- if (sample_lens[j] == redrat3_us_to_len(txbuf[i]))
- sigdata[i] = j;
- }
- }
offset = RR3_TX_HEADER_OFFSET;
sendbuf_len = RR3_HEADER_LENGTH + (sizeof(u16) * RR3_DRIVER_MAXLENS)
@@ -1175,7 +1170,7 @@ static int redrat3_dev_probe(struct usb_interface *intf,
pipe = usb_rcvbulkpipe(udev, ep_in->bEndpointAddress);
usb_fill_bulk_urb(rr3->read_urb, udev, pipe,
rr3->bulk_in_buf, ep_in->wMaxPacketSize,
- (usb_complete_t)redrat3_handle_async, rr3);
+ redrat3_handle_async, rr3);
/* set up bulk-out endpoint*/
rr3->write_urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -1195,7 +1190,7 @@ static int redrat3_dev_probe(struct usb_interface *intf,
pipe = usb_sndbulkpipe(udev, ep_out->bEndpointAddress);
usb_fill_bulk_urb(rr3->write_urb, udev, pipe,
rr3->bulk_out_buf, ep_out->wMaxPacketSize,
- (usb_complete_t)redrat3_write_bulk_callback, rr3);
+ redrat3_write_bulk_callback, rr3);
rr3->udev = udev;