[linux-dvb] Re: Kernel Oops with Hauppauge WinTV NOVA T USB2 & Remote Control

Mario Rossi mariofutire at googlemail.com
Sat Oct 7 15:06:36 CEST 2006


I've found where is the problem in the Kernel oops while using the
remote control with WinTV NOVA T USB2.

In the following function
(linux/drivers/media/dvb/dvb-usb/nova-t-usb2.c) I added a debug print
for all pointers involved and the one that is NULL is "st" meaning
that d->priv is NULL.

I've tried and the error occurs both while playing TV and while not playing.
The rest of the function works properly. Here is the output when I
block the null pointer dereference (with debug enabled).

Oct  7 14:02:33 thinkpad kernel: raw key code 0xfc, 0x1f, 0x00 to c:
1e d: 03 toggle: 1
Oct  7 14:02:33 thinkpad kernel: c: 0, d: 1e
Oct  7 14:02:33 thinkpad kernel: c: 1, d: 1e
Oct  7 14:02:33 thinkpad kernel: c: 2, d: 1e
Oct  7 14:02:33 thinkpad kernel: c: 3, d: 1e
Oct  7 14:02:33 thinkpad kernel: ERROR 2 3

"ERROR 2" is something I added to find where the null pointer occurs,
afterwards the function is forced to "return 0".

Does anybody know how this thing works? Who and when initialises d->priv?

static int nova_t_rc_query(struct dvb_usb_device *d, u32 *event, int *state)
{
	u8 key[5],cmd[2] = { DIBUSB_REQ_POLL_REMOTE, 0x35 }, data,toggle,custom;
	u16 raw;
	int i = 0;
	struct dibusb_state *st = d->priv;

// st is NULL!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

	dvb_usb_generic_rw(d,cmd,2,key,5,0);

	*state = REMOTE_NO_KEY_PRESSED;
	switch (key[0]) {
		case DIBUSB_RC_HAUPPAUGE_KEY_PRESSED:
			raw = ((key[1] << 8) | key[2]) >> 3;
			toggle = !!(raw & 0x800);
			data = raw & 0x3f;
			custom = (raw >> 6) & 0x1f;

			deb_rc("raw key code 0x%02x, 0x%02x, 0x%02x to c: %02x d: %02x
toggle: %d\n",key[1],key[2],key[3],custom,data,toggle);

			for (i = 0; i < ARRAY_SIZE(haupp_rc_keys); i++) {
				deb_rc("c: %x, d: %x\n",haupp_rc_keys[i].data,haupp_rc_keys[i].custom);
				if (haupp_rc_keys[i].data == data &&
					haupp_rc_keys[i].custom == custom) {

					*event = haupp_rc_keys[i].event;
					*state = REMOTE_KEY_PRESSED;
					if (st->old_toggle == toggle) {
						if (st->last_repeat_count++ < 2)
							*state = REMOTE_NO_KEY_PRESSED;
					} else {
						st->last_repeat_count = 0;
						st->old_toggle = toggle;
					}
					break;
				}
			}

			break;
		case DIBUSB_RC_HAUPPAUGE_KEY_EMPTY:
		default:
			break;
	}

	return 0;
}

Thanks

Mario



More information about the linux-dvb mailing list