Example #1
0
static void hid_irq_in(struct urb *urb)
{
	struct hid_device	*hid = urb->context;
	struct usbhid_device 	*usbhid = hid->driver_data;
	int			status;

	switch (urb->status) {
	case 0:			/* success */
		usbhid_mark_busy(usbhid);
		usbhid->retry_delay = 0;
		hid_input_report(urb->context, HID_INPUT_REPORT,
				 urb->transfer_buffer,
				 urb->actual_length, 1);
		/*
		 * autosuspend refused while keys are pressed
		 * because most keyboards don't wake up when
		 * a key is released
		 */
		if (hid_check_keys_pressed(hid))
			set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
		else
			clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
		break;
	case -EOVERFLOW:
	case -EPIPE:		/* stall */
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		set_bit((urb->status == -EPIPE)? HID_CLEAR_HALT:HID_RESET_PENDING, &usbhid->iofl);
		schedule_work(&usbhid->reset_work);
		return;
	case -ECONNRESET:	/* unlink */
	case -ENOENT:
	case -ESHUTDOWN:	/* unplug */
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		return;
	case -EILSEQ:		/* protocol error or unplug */
	case -EPROTO:		/* protocol error or unplug */
	case -ETIME:		/* protocol error or unplug */
	case -ETIMEDOUT:	/* Should never happen, but... */
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		hid_io_error(hid);
		return;
	default:		/* error */
		dev_warn(&urb->dev->dev, "input irq status %d  "
				"received\n", urb->status);
	}

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		if (status != -EPERM) {
			err_hid("can't resubmit intr, %s-%s/input%d, status %d",
					hid_to_usb_dev(hid)->bus->bus_name,
					hid_to_usb_dev(hid)->devpath,
					usbhid->ifnum, status);
			hid_io_error(hid);
		}
	}
}
Example #2
0
static void hid_irq_in(struct urb *urb)
{
	struct hid_device	*hid = urb->context;
	struct usbhid_device 	*usbhid = hid->driver_data;
	int			status;

	switch (urb->status) {
	case 0:			
		usbhid_mark_busy(usbhid);
		usbhid->retry_delay = 0;
		hid_input_report(urb->context, HID_INPUT_REPORT,
				 urb->transfer_buffer,
				 urb->actual_length, 1);
		
		if (hid_check_keys_pressed(hid))
			set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
		else
			clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
		break;
	case -EPIPE:		
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		set_bit(HID_CLEAR_HALT, &usbhid->iofl);
		schedule_work(&usbhid->reset_work);
		return;
	case -ECONNRESET:	
	case -ENOENT:
	case -ESHUTDOWN:	
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		return;
	case -EILSEQ:		
	case -EPROTO:		
	case -ETIME:		
	case -ETIMEDOUT:	
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		hid_io_error(hid);
		return;
	default:		
		dev_warn(&urb->dev->dev, "input irq status %d  "
				"received\n", urb->status);
	}

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		if (status != -EPERM) {
			err_hid("can't resubmit intr, %s-%s/input%d, status %d",
					hid_to_usb_dev(hid)->bus->bus_name,
					hid_to_usb_dev(hid)->devpath,
					usbhid->ifnum, status);
			hid_io_error(hid);
		}
	}
}
Example #3
0
/* I/O retry timer routine */
static void hid_retry_timeout(unsigned long _hid)
{
	struct hid_device *hid = (struct hid_device *) _hid;
	struct usbhid_device *usbhid = hid->driver_data;

	dev_dbg(&usbhid->intf->dev, "retrying intr urb\n");
	if (hid_start_in(hid))
		hid_io_error(hid);
}
Example #4
0
/* Workqueue routine to reset the device or clear a halt */
static void hid_reset(struct work_struct *work)
{
	struct usbhid_device *usbhid =
		container_of(work, struct usbhid_device, reset_work);
	struct hid_device *hid = usbhid->hid;
	int rc = 0;

	if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) {
		dev_dbg(&usbhid->intf->dev, "clear halt\n");
		rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe);
		clear_bit(HID_CLEAR_HALT, &usbhid->iofl);
		hid_start_in(hid);
	}

	else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) {
		dev_dbg(&usbhid->intf->dev, "resetting device\n");
		rc = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf);
		if (rc == 0) {
			rc = usb_reset_device(hid_to_usb_dev(hid));
			usb_unlock_device(hid_to_usb_dev(hid));
		}
		clear_bit(HID_RESET_PENDING, &usbhid->iofl);
	}

	switch (rc) {
	case 0:
		if (!test_bit(HID_IN_RUNNING, &usbhid->iofl))
			hid_io_error(hid);
		break;
	default:
		hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n",
			hid_to_usb_dev(hid)->bus->bus_name,
			hid_to_usb_dev(hid)->devpath,
			usbhid->ifnum, rc);
		/* FALLTHROUGH */
	case -EHOSTUNREACH:
	case -ENODEV:
	case -EINTR:
		break;
	}
}
Example #5
0
static void hid_irq_in(struct urb *urb)
{
	struct hid_device	*hid = urb->context;
	struct usbhid_device 	*usbhid = hid->driver_data;
	int			status;

	switch (urb->status) {
	case 0:			/* success */
		usbhid_mark_busy(usbhid);
		usbhid->retry_delay = 0;
#if defined(CONFIG_TOUCHSCREEN_NEXIO_USB)
		if((hid->vendor == NEXIO_USB_TOUCH_VENDOR) && (hid->product == NEXIO_USB_TOUCH_PRODUCT))	{
			if(nexio_touch_driver_open)	{
				nexio_touch_report_data(urb->transfer_buffer, urb->actual_length);
			}
		}
		else	
#endif
#if defined(CONFIG_TOUCHSCREEN_EGALAX_USB)
		if((hid->vendor == EGALAX_USB_TOUCH_VENDOR) && (hid->product == EGALAX_USB_TOUCH_PRODUCT))	{
			if(egalax_touch_driver_open)	{
				egalax_touch_report_data(urb->transfer_buffer, urb->actual_length);
			}
		}
		else	
#endif
		{
			hid_input_report(urb->context, HID_INPUT_REPORT,
					 urb->transfer_buffer,
					 urb->actual_length, 1);
			/*
			 * autosuspend refused while keys are pressed
			 * because most keyboards don't wake up when
			 * a key is released
			 */
			if (hid_check_keys_pressed(hid))
				set_bit(HID_KEYS_PRESSED, &usbhid->iofl);
			else
				clear_bit(HID_KEYS_PRESSED, &usbhid->iofl);
		}
		break;
	case -EPIPE:		/* stall */
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		set_bit(HID_CLEAR_HALT, &usbhid->iofl);
		schedule_work(&usbhid->reset_work);
		return;
	case -ECONNRESET:	/* unlink */
	case -ENOENT:
	case -ESHUTDOWN:	/* unplug */
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		return;
	case -EILSEQ:		/* protocol error or unplug */
	case -EPROTO:		/* protocol error or unplug */
	case -ETIME:		/* protocol error or unplug */
	case -ETIMEDOUT:	/* Should never happen, but... */
		usbhid_mark_busy(usbhid);
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		hid_io_error(hid);
		return;
	default:		/* error */
		hid_warn(urb->dev, "input irq status %d received\n",
			 urb->status);
	}

	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		clear_bit(HID_IN_RUNNING, &usbhid->iofl);
		if (status != -EPERM) {
			hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n",
				hid_to_usb_dev(hid)->bus->bus_name,
				hid_to_usb_dev(hid)->devpath,
				usbhid->ifnum, status);
			hid_io_error(hid);
		}
	}
}