Hi Greg, Today's linux-next merge of the usb tree got a conflict in drivers/staging/media/easycap/easycap_main.c between various commits from the v4l-dvb tree and commit 5df773120477 ("USB: Staging: media: easycap: remove err() usage") from the usb tree. I fixed it up (I think - see below) and can carry the fix as necessary. -- Cheers, Stephen Rothwell sfr@xxxxxxxxxxxxxxxx diff --cc drivers/staging/media/easycap/easycap_main.c index aed9537,6f83d36..0000000 --- a/drivers/staging/media/easycap/easycap_main.c +++ b/drivers/staging/media/easycap/easycap_main.c @@@ -3401,176 -3126,6 +3401,175 @@@ static void config_easycap(struct easyc } } } +} + +/* + * This function is called from within easycap_usb_disconnect() and is + * protected by semaphores set and cleared by easycap_usb_disconnect(). + * By this stage the device has already been physically unplugged, + * so peasycap->pusb_device is no longer valid. + */ +static void easycap_delete(struct kref *pkref) +{ + struct easycap *peasycap; + + peasycap = container_of(pkref, struct easycap, kref); + if (!peasycap) { + SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); + return; + } + + /* Free video urbs */ + free_video_urbs(peasycap); + + /* Free video isoc buffers */ + free_isocbuffers(peasycap); + + /* Free video field buffers */ + free_fieldbuffers(peasycap); + + /* Free video frame buffers */ + free_framebuffers(peasycap); + + /* Free audio urbs */ + free_audio_urbs(peasycap); + + /* Free audio isoc buffers */ + free_audio_buffers(peasycap); + + free_easycap(peasycap); + + JOT(4, "ending.\n"); +} + +static const struct v4l2_file_operations v4l2_fops = { + .owner = THIS_MODULE, + .open = easycap_open_noinode, + .unlocked_ioctl = easycap_unlocked_ioctl, + .poll = easycap_poll, + .mmap = easycap_mmap, +}; + +static int easycap_register_video(struct easycap *peasycap) +{ + /* + * FIXME: This is believed to be harmless, + * but may well be unnecessary or wrong. + */ + peasycap->video_device.v4l2_dev = NULL; + + strcpy(&peasycap->video_device.name[0], "easycapdc60"); + peasycap->video_device.fops = &v4l2_fops; + peasycap->video_device.minor = -1; + peasycap->video_device.release = (void *)(&videodev_release); + + video_set_drvdata(&(peasycap->video_device), (void *)peasycap); + + if (0 != (video_register_device(&(peasycap->video_device), + VFL_TYPE_GRABBER, -1))) { - err("Not able to register with videodev"); + videodev_release(&(peasycap->video_device)); + return -ENODEV; + } + + peasycap->registered_video++; + + SAM("registered with videodev: %i=minor\n", + peasycap->video_device.minor); + peasycap->minor = peasycap->video_device.minor; + + return 0; +} + +/* + * When the device is plugged, this function is called three times, + * one for each interface. + */ +static int easycap_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *usbdev; + struct usb_host_interface *alt; + struct usb_endpoint_descriptor *ep; + struct usb_interface_descriptor *interface; + struct easycap *peasycap; + int i, j, rc; + u8 bInterfaceNumber; + u8 bInterfaceClass; + u8 bInterfaceSubClass; + int okalt[8], isokalt; + int okepn[8]; + int okmps[8]; + int maxpacketsize; + + usbdev = interface_to_usbdev(intf); + + alt = usb_altnum_to_altsetting(intf, 0); + if (!alt) { + SAY("ERROR: usb_host_interface not found\n"); + return -EFAULT; + } + + interface = &alt->desc; + if (!interface) { + SAY("ERROR: intf_descriptor is NULL\n"); + return -EFAULT; + } + + /* Get properties of probed interface */ + bInterfaceNumber = interface->bInterfaceNumber; + bInterfaceClass = interface->bInterfaceClass; + bInterfaceSubClass = interface->bInterfaceSubClass; + + JOT(4, "intf[%i]: num_altsetting=%i\n", + bInterfaceNumber, intf->num_altsetting); + JOT(4, "intf[%i]: cur_altsetting - altsetting=%li\n", + bInterfaceNumber, + (long int)(intf->cur_altsetting - intf->altsetting)); + JOT(4, "intf[%i]: bInterfaceClass=0x%02X bInterfaceSubClass=0x%02X\n", + bInterfaceNumber, bInterfaceClass, bInterfaceSubClass); + + /* + * A new struct easycap is always allocated when interface 0 is probed. + * It is not possible here to free any existing struct easycap. + * This should have been done by easycap_delete() when the device was + * physically unplugged. + * The allocated struct easycap is saved for later usage when + * interfaces 1 and 2 are probed. + */ + if (0 == bInterfaceNumber) { + /* + * Alloc structure and save it in a free slot in + * easycapdc60_dongle array + */ + peasycap = alloc_easycap(bInterfaceNumber); + if (!peasycap) + return -ENOMEM; + + /* Perform basic struct initialization */ + init_easycap(peasycap, usbdev, intf, bInterfaceNumber); + + /* Dynamically fill in the available formats */ + rc = easycap_video_fillin_formats(); + if (0 > rc) { + SAM("ERROR: fillin_formats() rc = %i\n", rc); + return -EFAULT; + } + JOM(4, "%i formats available\n", rc); + + /* Populate easycap.inputset[] */ + rc = populate_inputset(peasycap); + if (rc < 0) + return rc; + JOM(4, "finished initialization\n"); + } else { + peasycap = get_easycap(usbdev, bInterfaceNumber); + if (!peasycap) + return -ENODEV; + } + + config_easycap(peasycap, bInterfaceNumber, + bInterfaceClass, + bInterfaceSubClass); /* * Investigate all altsettings. This is done in detail @@@ -3854,9 -3562,33 +3853,12 @@@ JOM(4, "registered device instance: %s\n", peasycap->v4l2_device.name); - /* - * FIXME: This is believed to be harmless, - * but may well be unnecessary or wrong. - */ - peasycap->video_device.v4l2_dev = NULL; - - - strcpy(&peasycap->video_device.name[0], "easycapdc60"); - peasycap->video_device.fops = &v4l2_fops; - peasycap->video_device.minor = -1; - peasycap->video_device.release = (void *)(&videodev_release); - - video_set_drvdata(&(peasycap->video_device), (void *)peasycap); - - if (0 != (video_register_device(&(peasycap->video_device), - VFL_TYPE_GRABBER, -1))) { + rc = easycap_register_video(peasycap); - if (rc < 0) ++ if (rc < 0) { + dev_err(&intf->dev, + "Not able to register with videodev\n"); - videodev_release(&(peasycap->video_device)); return -ENODEV; + } - - peasycap->registered_video++; - SAM("registered with videodev: %i=minor\n", - peasycap->video_device.minor); - peasycap->minor = peasycap->video_device.minor; - break; } /* 1: Audio control */
Attachment:
pgpBliOWtzlpQ.pgp
Description: PGP signature