The ir_input_dev gets filled in by __ir_input_register, the one allocated in imon_init_idev was being overwritten by the correct one shortly after it was initialized (ultimately resulting in a memory leak). Additionally, there was an ill-advised memcpy into that extraneous ir_input_dev which gets fixed by this. Ill-advised memcpy pointed out by Dmitry Torokhov, bad usage of ir_input_dev pointed out by Maxim Levitsky.
Unified · Split
| @@ -87,7 +87,6 @@ static ssize_t lcd_write(struct file *file, const char *buf, · 86 unmodified lines | ||
| 87 | 87 | struct imon_context { |
| 88 | 88 | struct device *dev; |
| 89 | 89 | struct ir_dev_props *props; |
| 90 | − struct ir_input_dev *ir; | |
| 91 | 90 | /* Newer devices have two interfaces */ |
| 92 | 91 | struct usb_device *usbdev_intf0; |
| 93 | 92 | struct usb_device *usbdev_intf1; |
| @@ -1656,7 +1655,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) · 1562 unmodified lines | ||
| 1656 | 1655 | { |
| 1657 | 1656 | struct input_dev *idev; |
| 1658 | 1657 | struct ir_dev_props *props; |
| 1659 | − struct ir_input_dev *ir; | |
| 1660 | 1658 | int ret, i; |
| 1661 | 1659 | |
| 1662 | 1660 | idev = input_allocate_device(); |
| @@ -1671,12 +1669,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) · 8 unmodified lines | ||
| 1671 | 1669 | goto props_alloc_failed; |
| 1672 | 1670 | } |
| 1673 | 1671 | |
| 1674 | − ir = kzalloc(sizeof(struct ir_input_dev), GFP_KERNEL); | |
| 1675 | − if (!ir) { | |
| 1676 | − dev_err(ictx->dev, "remote ir input dev allocation failed\n"); | |
| 1677 | − goto ir_dev_alloc_failed; | |
| 1678 | − } | |
| 1679 | − | |
| 1680 | 1672 | snprintf(ictx->name_idev, sizeof(ictx->name_idev), |
| 1681 | 1673 | "iMON Remote (%04x:%04x)", ictx->vendor, ictx->product); |
| 1682 | 1674 | idev->name = ictx->name_idev; |
| @@ -1706,14 +1698,9 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) · 23 unmodified lines | ||
| 1706 | 1698 | props->change_protocol = imon_ir_change_protocol; |
| 1707 | 1699 | ictx->props = props; |
| 1708 | 1700 | |
| 1709 | − ictx->ir = ir; | |
| 1710 | − memcpy(&ir->dev, ictx->dev, sizeof(struct device)); | |
| 1711 | − | |
| 1712 | 1701 | usb_to_input_id(ictx->usbdev_intf0, &idev->id); |
| 1713 | 1702 | idev->dev.parent = ictx->dev; |
| 1714 | 1703 | |
| 1715 | − input_set_drvdata(idev, ir); | |
| 1716 | − | |
| 1717 | 1704 | ret = ir_input_register(idev, RC_MAP_IMON_PAD, props, MOD_NAME); |
| 1718 | 1705 | if (ret < 0) { |
| 1719 | 1706 | dev_err(ictx->dev, "remote input dev register failed\n"); |
| @@ -1723,8 +1710,6 @@ static struct input_dev *imon_init_idev(struct imon_context *ictx) · 3 unmodified lines | ||
| 1723 | 1710 | return idev; |
| 1724 | 1711 | |
| 1725 | 1712 | idev_register_failed: |
| 1726 | − kfree(ir); | |
| 1727 | −ir_dev_alloc_failed: | |
| 1728 | 1713 | kfree(props); |
| 1729 | 1714 | props_alloc_failed: |
| 1730 | 1715 | input_free_device(idev); |