The ir_input_dev gets filled in by __ir_input_register, the one allocated in mceusb_init_input_dev was being overwritten by the correct one shortly after it was initialized (ultimately resulting in a memory leak). This bug was inherited from imon.c, and was pointed out to me by Maxim Levitsky. v2: fix incorrect dev arg to dev_dbg
Unified · Split
| @@ -228,7 +228,6 @@ static struct usb_device_id std_tx_mask_list[] = { · 227 unmodified lines | |||
| 228 | /* data structure for each usb transceiver */ | 228 | /* data structure for each usb transceiver */ |
| 229 | struct mceusb_dev { | 229 | struct mceusb_dev { |
| 230 | /* ir-core bits */ | 230 | /* ir-core bits */ |
| 231 | struct ir_input_dev *irdev; | ||
| 232 | struct ir_dev_props *props; | 231 | struct ir_dev_props *props; |
| 233 | struct ir_raw_event rawir; | 232 | struct ir_raw_event rawir; |
| 234 | 233 | ||
| @@ -739,7 +738,7 @@ static void mceusb_dev_recv(struct urb *urb, struct pt_regs *regs) · 504 unmodified lines | |||
| 739 | 738 | ||
| 740 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { | 739 | if (ir->send_flags == RECV_FLAG_IN_PROGRESS) { |
| 741 | ir->send_flags = SEND_FLAG_COMPLETE; | 740 | ir->send_flags = SEND_FLAG_COMPLETE; |
| 742 | dev_dbg(&ir->irdev->dev, "setup answer received %d bytes\n", | 741 | dev_dbg(ir->dev, "setup answer received %d bytes\n", |
| 743 | buf_len); | 742 | buf_len); |
| 744 | } | 743 | } |
| 745 | 744 | ||
| @@ -861,7 +860,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) · 115 unmodified lines | |||
| 861 | { | 860 | { |
| 862 | struct input_dev *idev; | 861 | struct input_dev *idev; |
| 863 | struct ir_dev_props *props; | 862 | struct ir_dev_props *props; |
| 864 | struct ir_input_dev *irdev; | ||
| 865 | struct device *dev = ir->dev; | 863 | struct device *dev = ir->dev; |
| 866 | int ret = -ENODEV; | 864 | int ret = -ENODEV; |
| 867 | 865 | ||
| @@ -878,12 +876,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) · 10 unmodified lines | |||
| 878 | goto props_alloc_failed; | 876 | goto props_alloc_failed; |
| 879 | } | 877 | } |
| 880 | 878 | ||
| 881 | irdev = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL); | ||
| 882 | if (!irdev) { | ||
| 883 | dev_err(dev, "remote ir input dev allocation failed\n"); | ||
| 884 | goto ir_dev_alloc_failed; | ||
| 885 | } | ||
| 886 | |||
| 887 | snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome " | 879 | snprintf(ir->name, sizeof(ir->name), "Media Center Ed. eHome " |
| 888 | "Infrared Remote Transceiver (%04x:%04x)", | 880 | "Infrared Remote Transceiver (%04x:%04x)", |
| 889 | le16_to_cpu(ir->usbdev->descriptor.idVendor), | 881 | le16_to_cpu(ir->usbdev->descriptor.idVendor), |
| @@ -902,9 +894,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) · 12 unmodified lines | |||
| 902 | props->tx_ir = mceusb_tx_ir; | 894 | props->tx_ir = mceusb_tx_ir; |
| 903 | 895 | ||
| 904 | ir->props = props; | 896 | ir->props = props; |
| 905 | ir->irdev = irdev; | ||
| 906 | |||
| 907 | input_set_drvdata(idev, irdev); | ||
| 908 | 897 | ||
| 909 | ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME); | 898 | ret = ir_input_register(idev, RC_MAP_RC6_MCE, props, DRIVER_NAME); |
| 910 | if (ret < 0) { | 899 | if (ret < 0) { |
| @@ -915,8 +904,6 @@ static struct input_dev *mceusb_init_input_dev(struct mceusb_dev *ir) · 4 unmodified lines | |||
| 915 | return idev; | 904 | return idev; |
| 916 | 905 | ||
| 917 | irdev_failed: | 906 | irdev_failed: |
| 918 | kfree(irdev); | ||
| 919 | ir_dev_alloc_failed: | ||
| 920 | kfree(props); | 907 | kfree(props); |
| 921 | props_alloc_failed: | 908 | props_alloc_failed: |
| 922 | input_free_device(idev); | 909 | input_free_device(idev); |