/*! * mxc_hrt_start_timer() - start a timer for otg state machine * Set or reset timer to interrupt in number of uS (micro-seconds). * * XXX There may be a floor or minimum that can be effectively set. * XXX We have seen an occasional problem with US(25) for discharge for example. * * @param otg * @param usec */ int mxc_hrt_start_timer(struct otg_instance *otg, int usec) { TRACE_MSG1(OCD, "usec: %d", usec); mxc_hr_usec_set = usec; //TRACE_MSG1 (OCD, "usec: %d", usec); mxc_hr_active = FALSE; TRACE_MSG1(OCD, "resetting active: %d", mxc_hr_active); del_timer(&hr_timer); RETURN_ZERO_UNLESS(usec); mxc_hr_active = TRUE; TRACE_MSG1(OCD, "setting active: %d", mxc_hr_active); if (mxc_hr_usec_set >= 1000000) { hr_timer.expires = jiffies + ((mxc_hr_usec_set/1000000)*mxc_hr_jiffy_per_sec); hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); TRACE_MSG4 (OCD, "usec: %u jiffies: %8u expires: %8u arch_cycle_expires: %8u LONG", usec, jiffies, hr_timer.expires, hr_timer.arch_cycle_expires); } else { hr_timer.expires = jiffies; hr_timer.arch_cycle_expires = get_arch_cycles(jiffies); if (mxc_hr_usec_set < 100) { TRACE_MSG1(OCD, "usec: %d set to minimum 100", mxc_hr_usec_set); mxc_hr_usec_set = 100; } hr_timer.arch_cycle_expires += nsec_to_arch_cycle(mxc_hr_usec_set * 1000); TRACE_MSG2(OCD, "arch_cycle_expires: %d arch_cycles_per_jiffy: %d", hr_timer.arch_cycle_expires, arch_cycles_per_jiffy); while (hr_timer.arch_cycle_expires >= arch_cycles_per_jiffy) { hr_timer.expires++; hr_timer.arch_cycle_expires -= arch_cycles_per_jiffy; } TRACE_MSG4 (OCD, "usec: %u jiffies: %8u expires: %8u arch_cycle_expires: %8u SHORT", usec, jiffies, hr_timer.expires, hr_timer.arch_cycle_expires); } add_timer(&hr_timer); return 0; }
/*! * inteltest_cl_device_request - called to process a request to endpoint or interface * @param function * @param request * @return non-zero for failure, will cause endpoint zero stall */ static int inteltest_cl_device_request (struct usbd_function_instance *function, struct usbd_device_request *request) { struct usbd_urb *urb; u16 wLength = le16_to_cpu(request->wLength); TRACE_MSG5(GCLASS, "bmRequestType: %02x bRequest: %02x wValue: %04x wIndex: %04x wLength: %04x", request->bmRequestType, request->bRequest, request->wValue, request->wIndex, request->wLength); /* XXX it should be this, need to verify */ RETURN_EINVAL_UNLESS(USB_REQ_RECIPIENT_DEVICE == (request->bmRequestType & USB_REQ_RECIPIENT_MASK)); switch (ctrl->bRequest) { switch (request->bmRequestType & USB_REQ_DIRECTION_MASK) { case USB_REQ_DEVICE2HOST: switch (request->bRequest) { case 0x5c: /* read test */ RETURN_EINVAL_UNLESS((urb = usbd_alloc_urb_ep0 (function, wLength, NULL))); RETURN_ZERO_UNLESS(rc || usbd_start_in_urb(urb)); break; } break; case USB_REQ_HOST2DEVICE: switch (request->bRequest) { case 0x5b: /* write test */ RETURN_EINVAL_UNLESS((urb = usbd_alloc_urb_ep0 (function, wLength, NULL))); RETURN_ZERO_UNLESS(rc || usbd_start_out_urb(urb)); break; } break; } return -EINVAL; } /* ********************************************************************************************* */ #if !defined(OTG_C99) /*! function_ops - operations table for the USB Device Core */ static struct usbd_function_operations inteltest_function_ops; /*! inteltest_class_driver - USB Device Core function driver definition */ struct usbd_class_driver inteltest_class_driver; #else /* defined(OTG_C99) */ /*! function_ops - operations table for the USB Device Core */ static struct usbd_function_operations inteltest_function_ops = { .device_request = inteltest_cl_device_request, /*!< called for each received device request */ }; /*! inteltest_class_driver - USB Device Core function driver definition */ struct usbd_class_driver inteltest_class_driver = { .driver.name = "inteltest-class", /*!< driver name */ .driver.fops = &inteltest_function_ops, /*!< operations table */ }; #endif /* defined(OTG_C99) */ /* USB Module init/exit ***************************************************** */ //#if OTG_EPILOGUE /*! * inteltest_cl_modexit() - module init * * This is called by the Linux kernel; when the module is being unloaded * if compiled as a module. This function is never called if the * driver is linked into the kernel. * @return none */ static void inteltest_cl_modexit (void) { usbd_deregister_class_function (&inteltest_class_driver); otg_trace_invalidate_tag(GCLASS); } module_exit (inteltest_cl_modexit); //#endif /*! * inteltest_cl_modinit() - module init * * This is called by the Linux kernel; either when the module is loaded * if compiled as a module, or during the system intialization if the * driver is linked into the kernel. * * This function will parse module parameters if required and then register * the inteltest driver with the USB Device software. * */ static int inteltest_cl_modinit (void) { #if !defined(OTG_C99) /*! function_ops - operations table for the USB Device Core */ ZERO(inteltest_function_ops); inteltest_function_ops.device_request=inteltest_cl_device_request; /*! called for each received device request */ /*! class_driver - USB Device Core function driver definition */ ZERO(inteltest_class_driver); inteltest_class_driver.driver.name = "inteltest-class"; /*! driver name */ inteltest_class_driver.driver.fops = &inteltest_function_ops; /*! operations table */ #endif /* defined(OTG_C99) */ GCLASS = otg_trace_obtain_tag(NULL, "inteltest-cf"); // register as usb function driver TRACE_MSG0(GCLASS, "REGISTER CLASS"); THROW_IF (usbd_register_class_function (&inteltest_class_driver, "inteltest-class", NULL), error); TRACE_MSG0(GCLASS, "REGISTER FINISHED"); CATCH(error) { inteltest_cl_modexit(); return -EINVAL; } return 0; }