ChangeSet 1.1608.84.18, 2004/03/10 12:21:20-08:00, oliver@neukum.org [PATCH] USB: fixes for aiptek driver - don't pass buffers allocated on stack to the sync helpers - check errors in probe - fix count in open - proper macros drivers/usb/input/aiptek.c | 57 +++++++++++++++++++++++++++++++-------------- 1 files changed, 40 insertions(+), 17 deletions(-) diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c --- a/drivers/usb/input/aiptek.c Tue Mar 16 15:02:44 2004 +++ b/drivers/usb/input/aiptek.c Tue Mar 16 15:02:44 2004 @@ -43,7 +43,8 @@ #include #include #include - +#include +#include /* * Version Information */ @@ -160,9 +161,9 @@ proximity = data[5] & 0x01; input_report_key(dev, BTN_TOOL_PEN, proximity); - x = ((__u32) data[1]) | ((__u32) data[2] << 8); - y = ((__u32) data[3]) | ((__u32) data[4] << 8); - pressure = ((__u32) data[6]) | ((__u32) data[7] << 8); + x = le16_to_cpu(get_unaligned((u16 *) &data[1])); + y = le16_to_cpu(get_unaligned((u16 *) &data[3])); + pressure = le16_to_cpu(*(u16 *) &data[6]); pressure -= aiptek->features->pressure_min; if (pressure < 0) { @@ -209,8 +210,10 @@ return 0; aiptek->irq->dev = aiptek->usbdev; - if (usb_submit_urb(aiptek->irq, GFP_KERNEL)) + if (usb_submit_urb(aiptek->irq, GFP_KERNEL)) { + aiptek->open--; return -EIO; + } return 0; } @@ -234,19 +237,27 @@ (type << 8) + id, inter->desc.bInterfaceNumber, buf, size, HZ); } -static void +static int aiptek_command(struct usb_device *dev, struct usb_host_interface *inter, unsigned char command, unsigned char data) { - __u8 buf[3]; + u8 *buf; + int err; + + buf = kmalloc(3, GFP_KERNEL); + if (!buf) + return -ENOMEM; buf[0] = 4; buf[1] = command; buf[2] = data; - if (usb_set_report(dev, inter, 3, 2, buf, 3) != 3) { + if ((err = usb_set_report(dev, inter, 3, 2, buf, 3)) != 3) { dbg("aiptek_command: 0x%x 0x%x\n", command, data); } + + kfree(buf); + return err < 0 ? err : 0; } static int @@ -257,30 +268,32 @@ struct usb_host_interface *interface = intf->altsetting + 0; struct usb_endpoint_descriptor *endpoint; struct aiptek *aiptek; + int err = -ENOMEM; if (!(aiptek = kmalloc(sizeof (struct aiptek), GFP_KERNEL))) - return -ENOMEM; + goto error_out_noalloc; memset(aiptek, 0, sizeof (struct aiptek)); - aiptek->data = usb_buffer_alloc(dev, 10, SLAB_ATOMIC, &aiptek->data_dma); + aiptek->data = usb_buffer_alloc(dev, 10, GFP_KERNEL, &aiptek->data_dma); if (!aiptek->data) { - kfree(aiptek); - return -ENOMEM; + goto error_out_nobuf; } aiptek->irq = usb_alloc_urb(0, GFP_KERNEL); if (!aiptek->irq) { - usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma); - kfree(aiptek); - return -ENOMEM; + goto error_out_nourb; } /* Resolution500LPI */ - aiptek_command(dev, interface, 0x18, 0x04); + err = aiptek_command(dev, interface, 0x18, 0x04); + if (err) + goto error_out; /* SwitchToTablet */ - aiptek_command(dev, interface, 0x10, 0x01); + err = aiptek_command(dev, interface, 0x10, 0x01); + if (err) + goto error_out; aiptek->features = aiptek_features + id->driver_info; @@ -340,6 +353,16 @@ usb_set_intfdata(intf, aiptek); return 0; + +error_out: + usb_free_urb(aiptek->irq); +error_out_nourb: + usb_buffer_free(dev, 10, aiptek->data, aiptek->data_dma); +error_out_nobuf: + kfree(aiptek); +error_out_noalloc: + return err; + } static void