> + * Called when opening the input device. This will submit the URB to
> + * the usb system so we start getting reports
> + */
> +static int gtco_input_open(struct input_dev *inputdev)
> +{
> + struct gtco *device;
> + device = inputdev->private;
> +
> + /* Prevent us from submitting the one Urb more than once */
> + if (device->openCount++)
> + return 0;
> +
> + device->urbinfo->dev = device->usbdev;
> + if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) {
This is a race condition in the error case. A second open
may suceed while the first open is sleeping allocating memory
for URB submission. If submitting the first open's URB then fails,
no URB is submitted.
> + device->openCount--;
> + return -EIO;
> + }
> + return 0;
> +}
> +
> +/**
> + Called when closing the input device. This will unlink the URB
> +*/
> +static void gtco_input_close(struct input_dev *inputdev)
> +{
> + struct gtco *device = inputdev->private;
> +
> + /* Decrement the open count and release the urb */
> + device->openCount--;
> + if (device->openCount==0){
> + usb_unlink_urb(device->urbinfo);
Please use usb_kill_urb()
[..]
> + /* All reports have X and Y coords in the same place */
> + val = le16_to_cpu(*(__le16 *) &(device->buffer[1]));
unaligned access. Please use get_unaligned().
> + input_report_abs(inputdev, ABS_X, val);
> +
> + val = le16_to_cpu(*(__le16 *) &(device->buffer[3]));
unaligned
> + buttonbyte = (device->buffer[5])>>1;
> + }else{
> +
> + val = le16_to_cpu(*(__le16 *)
> (&(device->buffer[1])));
unaligned
> + input_report_abs(inputdev, ABS_X, val);
> +
> + val = le16_to_cpu(*(__le16 *)
> (&(device->buffer[3])));
unaligned
> + /* Allocate memory for device structure */
> + device = kzalloc(sizeof(struct gtco), GFP_KERNEL);
> + if (device == NULL) {
> + err("No more memory");
> + return -ENOMEM;
> + }
> +
> +
> + device->inputdevice = input_allocate_device();
> + if (!device->inputdevice){
> + kfree(device);
> + err("No more memory");
> + return -ENOMEM;
> + }
Please gather all the deallocations at the end and use goto for errors.
> +
> + /* Get pointer to the input device */
> + inputdev = device->inputdevice;
> +
> + /* Save interface information */
> + device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface));
> +
> +
> + /* Allocate some data for incoming reports */
> + device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE,
> + GFP_ATOMIC, &(device->buf_dma));
GFP_KERNEL is sufficient.
> +/*
> + * This function is a standard USB function called when the USB device
> + * is disconnected. We will get rid of the URV, de-register the input
> + * device, and free up allocated memory
> + */
> +static void gtco_disconnect(struct usb_interface *interface)
> +{
> +
> + /* Grab private device ptr */
> + struct gtco *device = usb_get_intfdata (interface);
> + struct input_dev *inputdev;
> +
> + inputdev = device->inputdevice;
> +
> + /* Now reverse all the registration stuff */
> + if (device) {
> + usb_unlink_urb(device->urbinfo);
usb_kill_urb()
HTH
Oliver
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
[email protected]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel