/* Offset of the Telemetry configuration register
   within the on-card register space */
#define TELEMETRY_CONFIG_REG_OFFSET 0x0A


/* Value to program in the configuration register */
#define TELEMETRY_CONFIG_REG_VALUE 0xBC


/* The vendor-defined bRequest for programming the
   configuration register */
#define TELEMETRY_REQUEST_WRITE 0x0D


/* The vendor-defined bRequestType */
#define TELEMETRY_REQUEST_WRITE_REGISTER 0x0E


/* Open method */
static int
tele_open(struct inode *inode, struct file *file)
{
    struct completion tele_config_done;
    tele_device_t *tele_device;
    void *tele_ctrl_context;
    char *tmp;
    __le16 tele_config_index = TELEMETRY_CONFIG_REG_OFFSET;    
    unsigned int tele_ctrl_pipe;
    struct usb_interface *interface;

    /* Obtain the pointer to the device-specific structure.
       We saved it using usb_set_intfdata() in tele_probe() */
    interface = usb_find_interface(&tele_driver, iminor(inode));
    tele_device = usb_get_intfdata(interface);

    /* Allocate a URB for the control transfer */
    tele_device->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
    if (!tele_device->ctrl_urb) {
        return -EIO;
    }

    /* Populate the Control Request */
    tele_device->ctrl_req.bRequestType = TELEMETRY_REQUEST_WRITE;
    tele_device->ctrl_req.bRequest =
        TELEMETRY_REQUEST_WRITE_REGISTER;
    tele_device->ctrl_req.wValue =
        cpu_to_le16(TELEMETRY_CONFIG_REG_VALUE);
    tele_device->ctrl_req.wIndex =
        cpu_to_le16p(&tele_config_index);
    tele_device->ctrl_req.wLength = cpu_to_le16(1);
    tele_device->ctrl_urb->transfer_buffer_length = 1;
    tmp = kmalloc(1, GFP_KERNEL);
    *tmp = TELEMETRY_CONFIG_REG_VALUE;

    /* Create a control pipe attached to endpoint 0 */
    tele_ctrl_pipe = usb_sndctrlpipe(tele_device->usbdev, 0);

    /* Initialize the completion mechanism */
    init_completion(&tele_config_done);

    /* Set URB context. The context is part of the URB that is passed
       to the callback function as an argument. In this case, the
       context is the completion structure, tele_config_done */
    tele_ctrl_context = (void *)&tele_config_done;

    /* Initialize the fields in the control URB */
    usb_fill_control_urb(tele_device->ctrl_urb, tele_device->usbdev,
                         tele_ctrl_pipe,
                         (char *) &tele_device->ctrl_req,
                         tmp, 1, tele_ctrl_callback,
                         tele_ctrl_context);
    

    /* Submit the URB */
    usb_submit_urb(tele_device->ctrl_urb, GFP_ATOMIC);

    /* Wait until the callback returns indicating that the telemetry
       configuration register has been successfully initialized */
    wait_for_completion(&tele_config_done);

    /* Release our reference to the URB */
    usb_free_urb(urb);
    kfree(tmp);

    /* Save the device-specific object to the file’s private_data
       so that you can directly retrieve it from other entry points
       such as tele_read() and tele_write() */
    file->private_data = tele_device;

    /* Return the URB transfer status */
    return(tele_device->ctrl_urb->status);
}

/* Callback function */
static void
tele_ctrl_callback(struct urb *urb)
{
    complete((struct completion *)urb->context);
}


syntax highlighted by Code2HTML, v. 0.9.1