Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 801b69f2 authored by Sean Young's avatar Sean Young Committed by Mauro Carvalho Chehab
Browse files

[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: default avatarSean Young <sean@mess.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 4159d01b
Loading
Loading
Loading
Loading
+24 −29
Original line number Diff line number Diff line
@@ -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 @@ 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;
@@ -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;