diff options
Diffstat (limited to 'drivers/usb/input/ati_remote.c')
-rw-r--r-- | drivers/usb/input/ati_remote.c | 173 |
1 files changed, 89 insertions, 84 deletions
diff --git a/drivers/usb/input/ati_remote.c b/drivers/usb/input/ati_remote.c index fd99681ee483..9a2a47db9494 100644 --- a/drivers/usb/input/ati_remote.c +++ b/drivers/usb/input/ati_remote.c | |||
@@ -112,7 +112,6 @@ | |||
112 | 112 | ||
113 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ | 113 | #define NAME_BUFSIZE 80 /* size of product name, path buffers */ |
114 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ | 114 | #define DATA_BUFSIZE 63 /* size of URB data buffers */ |
115 | #define ATI_INPUTNUM 1 /* Which input device to register as */ | ||
116 | 115 | ||
117 | static unsigned long channel_mask; | 116 | static unsigned long channel_mask; |
118 | module_param(channel_mask, ulong, 0444); | 117 | module_param(channel_mask, ulong, 0444); |
@@ -162,7 +161,7 @@ static char accel[] = { 1, 2, 4, 6, 9, 13, 20 }; | |||
162 | static DECLARE_MUTEX(disconnect_sem); | 161 | static DECLARE_MUTEX(disconnect_sem); |
163 | 162 | ||
164 | struct ati_remote { | 163 | struct ati_remote { |
165 | struct input_dev idev; | 164 | struct input_dev *idev; |
166 | struct usb_device *udev; | 165 | struct usb_device *udev; |
167 | struct usb_interface *interface; | 166 | struct usb_interface *interface; |
168 | 167 | ||
@@ -198,15 +197,13 @@ struct ati_remote { | |||
198 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ | 197 | #define KIND_ACCEL 7 /* Directional keypad - left, right, up, down.*/ |
199 | 198 | ||
200 | /* Translation table from hardware messages to input events. */ | 199 | /* Translation table from hardware messages to input events. */ |
201 | static struct | 200 | static struct { |
202 | { | ||
203 | short kind; | 201 | short kind; |
204 | unsigned char data1, data2; | 202 | unsigned char data1, data2; |
205 | int type; | 203 | int type; |
206 | unsigned int code; | 204 | unsigned int code; |
207 | int value; | 205 | int value; |
208 | } ati_remote_tbl[] = | 206 | } ati_remote_tbl[] = { |
209 | { | ||
210 | /* Directional control pad axes */ | 207 | /* Directional control pad axes */ |
211 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ | 208 | {KIND_ACCEL, 0x35, 0x70, EV_REL, REL_X, -1}, /* left */ |
212 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ | 209 | {KIND_ACCEL, 0x36, 0x71, EV_REL, REL_X, 1}, /* right */ |
@@ -286,7 +283,6 @@ static struct | |||
286 | 283 | ||
287 | /* Local function prototypes */ | 284 | /* Local function prototypes */ |
288 | static void ati_remote_dump (unsigned char *data, unsigned int actual_length); | 285 | static void ati_remote_dump (unsigned char *data, unsigned int actual_length); |
289 | static void ati_remote_delete (struct ati_remote *dev); | ||
290 | static int ati_remote_open (struct input_dev *inputdev); | 286 | static int ati_remote_open (struct input_dev *inputdev); |
291 | static void ati_remote_close (struct input_dev *inputdev); | 287 | static void ati_remote_close (struct input_dev *inputdev); |
292 | static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); | 288 | static int ati_remote_sendpacket (struct ati_remote *ati_remote, u16 cmd, unsigned char *data); |
@@ -428,7 +424,7 @@ static void ati_remote_input_report(struct urb *urb, struct pt_regs *regs) | |||
428 | { | 424 | { |
429 | struct ati_remote *ati_remote = urb->context; | 425 | struct ati_remote *ati_remote = urb->context; |
430 | unsigned char *data= ati_remote->inbuf; | 426 | unsigned char *data= ati_remote->inbuf; |
431 | struct input_dev *dev = &ati_remote->idev; | 427 | struct input_dev *dev = ati_remote->idev; |
432 | int index, acc; | 428 | int index, acc; |
433 | int remote_num; | 429 | int remote_num; |
434 | 430 | ||
@@ -587,38 +583,55 @@ static void ati_remote_irq_in(struct urb *urb, struct pt_regs *regs) | |||
587 | } | 583 | } |
588 | 584 | ||
589 | /* | 585 | /* |
590 | * ati_remote_delete | 586 | * ati_remote_alloc_buffers |
591 | */ | 587 | */ |
592 | static void ati_remote_delete(struct ati_remote *ati_remote) | 588 | static int ati_remote_alloc_buffers(struct usb_device *udev, |
589 | struct ati_remote *ati_remote) | ||
593 | { | 590 | { |
594 | if (ati_remote->irq_urb) | 591 | ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, |
595 | usb_kill_urb(ati_remote->irq_urb); | 592 | &ati_remote->inbuf_dma); |
593 | if (!ati_remote->inbuf) | ||
594 | return -1; | ||
596 | 595 | ||
597 | if (ati_remote->out_urb) | 596 | ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, |
598 | usb_kill_urb(ati_remote->out_urb); | 597 | &ati_remote->outbuf_dma); |
598 | if (!ati_remote->outbuf) | ||
599 | return -1; | ||
599 | 600 | ||
600 | input_unregister_device(&ati_remote->idev); | 601 | ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); |
602 | if (!ati_remote->irq_urb) | ||
603 | return -1; | ||
601 | 604 | ||
602 | if (ati_remote->inbuf) | 605 | ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); |
603 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 606 | if (!ati_remote->out_urb) |
604 | ati_remote->inbuf, ati_remote->inbuf_dma); | 607 | return -1; |
605 | 608 | ||
606 | if (ati_remote->outbuf) | 609 | return 0; |
607 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | 610 | } |
608 | ati_remote->outbuf, ati_remote->outbuf_dma); | ||
609 | 611 | ||
612 | /* | ||
613 | * ati_remote_free_buffers | ||
614 | */ | ||
615 | static void ati_remote_free_buffers(struct ati_remote *ati_remote) | ||
616 | { | ||
610 | if (ati_remote->irq_urb) | 617 | if (ati_remote->irq_urb) |
611 | usb_free_urb(ati_remote->irq_urb); | 618 | usb_free_urb(ati_remote->irq_urb); |
612 | 619 | ||
613 | if (ati_remote->out_urb) | 620 | if (ati_remote->out_urb) |
614 | usb_free_urb(ati_remote->out_urb); | 621 | usb_free_urb(ati_remote->out_urb); |
615 | 622 | ||
616 | kfree(ati_remote); | 623 | if (ati_remote->inbuf) |
624 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | ||
625 | ati_remote->inbuf, ati_remote->inbuf_dma); | ||
626 | |||
627 | if (ati_remote->outbuf) | ||
628 | usb_buffer_free(ati_remote->udev, DATA_BUFSIZE, | ||
629 | ati_remote->inbuf, ati_remote->outbuf_dma); | ||
617 | } | 630 | } |
618 | 631 | ||
619 | static void ati_remote_input_init(struct ati_remote *ati_remote) | 632 | static void ati_remote_input_init(struct ati_remote *ati_remote) |
620 | { | 633 | { |
621 | struct input_dev *idev = &(ati_remote->idev); | 634 | struct input_dev *idev = ati_remote->idev; |
622 | int i; | 635 | int i; |
623 | 636 | ||
624 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); | 637 | idev->evbit[0] = BIT(EV_KEY) | BIT(EV_REL); |
@@ -637,7 +650,7 @@ static void ati_remote_input_init(struct ati_remote *ati_remote) | |||
637 | idev->phys = ati_remote->phys; | 650 | idev->phys = ati_remote->phys; |
638 | 651 | ||
639 | usb_to_input_id(ati_remote->udev, &idev->id); | 652 | usb_to_input_id(ati_remote->udev, &idev->id); |
640 | idev->dev = &ati_remote->udev->dev; | 653 | idev->cdev.dev = &ati_remote->udev->dev; |
641 | } | 654 | } |
642 | 655 | ||
643 | static int ati_remote_initialize(struct ati_remote *ati_remote) | 656 | static int ati_remote_initialize(struct ati_remote *ati_remote) |
@@ -674,7 +687,7 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) | |||
674 | (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { | 687 | (ati_remote_sendpacket(ati_remote, 0x8007, init2))) { |
675 | dev_err(&ati_remote->interface->dev, | 688 | dev_err(&ati_remote->interface->dev, |
676 | "Initializing ati_remote hardware failed.\n"); | 689 | "Initializing ati_remote hardware failed.\n"); |
677 | return 1; | 690 | return -EIO; |
678 | } | 691 | } |
679 | 692 | ||
680 | return 0; | 693 | return 0; |
@@ -686,95 +699,83 @@ static int ati_remote_initialize(struct ati_remote *ati_remote) | |||
686 | static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id) | 699 | static int ati_remote_probe(struct usb_interface *interface, const struct usb_device_id *id) |
687 | { | 700 | { |
688 | struct usb_device *udev = interface_to_usbdev(interface); | 701 | struct usb_device *udev = interface_to_usbdev(interface); |
689 | struct ati_remote *ati_remote = NULL; | 702 | struct usb_host_interface *iface_host = interface->cur_altsetting; |
690 | struct usb_host_interface *iface_host; | 703 | struct usb_endpoint_descriptor *endpoint_in, *endpoint_out; |
691 | int retval = -ENOMEM; | 704 | struct ati_remote *ati_remote; |
692 | char path[64]; | 705 | struct input_dev *input_dev; |
693 | 706 | int err = -ENOMEM; | |
694 | /* Allocate and clear an ati_remote struct */ | ||
695 | if (!(ati_remote = kmalloc(sizeof (struct ati_remote), GFP_KERNEL))) | ||
696 | return -ENOMEM; | ||
697 | memset(ati_remote, 0x00, sizeof (struct ati_remote)); | ||
698 | 707 | ||
699 | iface_host = interface->cur_altsetting; | ||
700 | if (iface_host->desc.bNumEndpoints != 2) { | 708 | if (iface_host->desc.bNumEndpoints != 2) { |
701 | err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); | 709 | err("%s: Unexpected desc.bNumEndpoints\n", __FUNCTION__); |
702 | retval = -ENODEV; | 710 | return -ENODEV; |
703 | goto error; | ||
704 | } | 711 | } |
705 | 712 | ||
706 | ati_remote->endpoint_in = &(iface_host->endpoint[0].desc); | 713 | endpoint_in = &iface_host->endpoint[0].desc; |
707 | ati_remote->endpoint_out = &(iface_host->endpoint[1].desc); | 714 | endpoint_out = &iface_host->endpoint[1].desc; |
708 | ati_remote->udev = udev; | ||
709 | ati_remote->interface = interface; | ||
710 | 715 | ||
711 | if (!(ati_remote->endpoint_in->bEndpointAddress & 0x80)) { | 716 | if (!(endpoint_in->bEndpointAddress & USB_DIR_IN)) { |
712 | err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__); | 717 | err("%s: Unexpected endpoint_in->bEndpointAddress\n", __FUNCTION__); |
713 | retval = -ENODEV; | 718 | return -ENODEV; |
714 | goto error; | ||
715 | } | 719 | } |
716 | if ((ati_remote->endpoint_in->bmAttributes & 3) != 3) { | 720 | if ((endpoint_in->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) { |
717 | err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__); | 721 | err("%s: Unexpected endpoint_in->bmAttributes\n", __FUNCTION__); |
718 | retval = -ENODEV; | 722 | return -ENODEV; |
719 | goto error; | ||
720 | } | 723 | } |
721 | if (le16_to_cpu(ati_remote->endpoint_in->wMaxPacketSize) == 0) { | 724 | if (le16_to_cpu(endpoint_in->wMaxPacketSize) == 0) { |
722 | err("%s: endpoint_in message size==0? \n", __FUNCTION__); | 725 | err("%s: endpoint_in message size==0? \n", __FUNCTION__); |
723 | retval = -ENODEV; | 726 | return -ENODEV; |
724 | goto error; | ||
725 | } | 727 | } |
726 | 728 | ||
727 | /* Allocate URB buffers, URBs */ | 729 | ati_remote = kzalloc(sizeof (struct ati_remote), GFP_KERNEL); |
728 | ati_remote->inbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, | 730 | input_dev = input_allocate_device(); |
729 | &ati_remote->inbuf_dma); | 731 | if (!ati_remote || !input_dev) |
730 | if (!ati_remote->inbuf) | 732 | goto fail1; |
731 | goto error; | ||
732 | 733 | ||
733 | ati_remote->outbuf = usb_buffer_alloc(udev, DATA_BUFSIZE, SLAB_ATOMIC, | 734 | /* Allocate URB buffers, URBs */ |
734 | &ati_remote->outbuf_dma); | 735 | if (ati_remote_alloc_buffers(udev, ati_remote)) |
735 | if (!ati_remote->outbuf) | 736 | goto fail2; |
736 | goto error; | ||
737 | 737 | ||
738 | ati_remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); | 738 | ati_remote->endpoint_in = endpoint_in; |
739 | if (!ati_remote->irq_urb) | 739 | ati_remote->endpoint_out = endpoint_out; |
740 | goto error; | 740 | ati_remote->udev = udev; |
741 | ati_remote->idev = input_dev; | ||
742 | ati_remote->interface = interface; | ||
741 | 743 | ||
742 | ati_remote->out_urb = usb_alloc_urb(0, GFP_KERNEL); | 744 | usb_make_path(udev, ati_remote->phys, sizeof(ati_remote->phys)); |
743 | if (!ati_remote->out_urb) | 745 | strlcpy(ati_remote->phys, "/input0", sizeof(ati_remote->phys)); |
744 | goto error; | ||
745 | 746 | ||
746 | usb_make_path(udev, path, NAME_BUFSIZE); | ||
747 | sprintf(ati_remote->phys, "%s/input%d", path, ATI_INPUTNUM); | ||
748 | if (udev->manufacturer) | 747 | if (udev->manufacturer) |
749 | strcat(ati_remote->name, udev->manufacturer); | 748 | strlcpy(ati_remote->name, udev->manufacturer, sizeof(ati_remote->name)); |
750 | 749 | ||
751 | if (udev->product) | 750 | if (udev->product) |
752 | sprintf(ati_remote->name, "%s %s", ati_remote->name, udev->product); | 751 | snprintf(ati_remote->name, sizeof(ati_remote->name), |
752 | "%s %s", ati_remote->name, udev->product); | ||
753 | 753 | ||
754 | if (!strlen(ati_remote->name)) | 754 | if (!strlen(ati_remote->name)) |
755 | sprintf(ati_remote->name, DRIVER_DESC "(%04x,%04x)", | 755 | snprintf(ati_remote->name, sizeof(ati_remote->name), |
756 | DRIVER_DESC "(%04x,%04x)", | ||
756 | le16_to_cpu(ati_remote->udev->descriptor.idVendor), | 757 | le16_to_cpu(ati_remote->udev->descriptor.idVendor), |
757 | le16_to_cpu(ati_remote->udev->descriptor.idProduct)); | 758 | le16_to_cpu(ati_remote->udev->descriptor.idProduct)); |
758 | 759 | ||
760 | ati_remote_input_init(ati_remote); | ||
761 | |||
759 | /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ | 762 | /* Device Hardware Initialization - fills in ati_remote->idev from udev. */ |
760 | retval = ati_remote_initialize(ati_remote); | 763 | err = ati_remote_initialize(ati_remote); |
761 | if (retval) | 764 | if (err) |
762 | goto error; | 765 | goto fail3; |
763 | 766 | ||
764 | /* Set up and register input device */ | 767 | /* Set up and register input device */ |
765 | ati_remote_input_init(ati_remote); | 768 | input_register_device(ati_remote->idev); |
766 | input_register_device(&ati_remote->idev); | ||
767 | |||
768 | dev_info(&ati_remote->interface->dev, "Input registered: %s on %s\n", | ||
769 | ati_remote->name, path); | ||
770 | 769 | ||
771 | usb_set_intfdata(interface, ati_remote); | 770 | usb_set_intfdata(interface, ati_remote); |
771 | return 0; | ||
772 | 772 | ||
773 | error: | 773 | fail3: usb_kill_urb(ati_remote->irq_urb); |
774 | if (retval) | 774 | usb_kill_urb(ati_remote->out_urb); |
775 | ati_remote_delete(ati_remote); | 775 | fail2: ati_remote_free_buffers(ati_remote); |
776 | 776 | fail1: input_free_device(input_dev); | |
777 | return retval; | 777 | kfree(ati_remote); |
778 | return err; | ||
778 | } | 779 | } |
779 | 780 | ||
780 | /* | 781 | /* |
@@ -791,7 +792,11 @@ static void ati_remote_disconnect(struct usb_interface *interface) | |||
791 | return; | 792 | return; |
792 | } | 793 | } |
793 | 794 | ||
794 | ati_remote_delete(ati_remote); | 795 | usb_kill_urb(ati_remote->irq_urb); |
796 | usb_kill_urb(ati_remote->out_urb); | ||
797 | input_unregister_device(ati_remote->idev); | ||
798 | ati_remote_free_buffers(ati_remote); | ||
799 | kfree(ati_remote); | ||
795 | } | 800 | } |
796 | 801 | ||
797 | /* | 802 | /* |