Skip to content

Commit

Permalink
[media] redrat3: limit periods to hardware limits
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Sean Young authored and Mauro Carvalho Chehab committed Mar 19, 2013
1 parent 4159d01 commit 801b69f
Showing 1 changed file with 24 additions and 29 deletions.
53 changes: 24 additions & 29 deletions drivers/media/rc/redrat3.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;

Expand All @@ -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;
}

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -815,7 +810,7 @@ static int redrat3_get_ir_data(struct redrat3_dev *rr3, int len)
}

/* 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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand All @@ -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)
Expand Down Expand Up @@ -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);
Expand All @@ -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;

Expand Down

0 comments on commit 801b69f

Please sign in to comment.