Example #1
0
/*!
 * 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;
}