[cpia] USB anyone?

Jochen Scharrlach Jochen.Scharrlach@schwaben.de
Thu, 20 Jan 2000 19:38:31 +0100


sbertin@mindspring.com writes:
 > That should be enough.  It will delay the call to
 > video_unregister_device until the device is closed.  Ioctls and mmap
 > will fail (oops, there's a bug.  They should return -ENODEV if cam->ops
 > is NULL). /proc/cpia/videox will go away. cpia_read will return
 > -ENODEV.  No need to go through the gymnastics you describe below.

If you'd ever met me in real life, you'd know that I won't do any
gymnastics if I can avoid it :)

Ok, let's get back to the array-problem: my suggestion was to trigger
the unregister-stuff from the lowlevel driver with the follwing
function:


unregister_driver(cam_data *drv)
{
  struct cam_lowlevel *mystuff = drv->cam_lowlevel; // getting the lowlevel-stuff
  cam_list_remove(drv);           // removing the camera from the list
  cpia_unregister(drv);           // telling the highlevel-driver to clean up
  /* cleaning up mystuff */       // cleaning up the lowlevel-stuff
}


The only thing cpia_unregister() has to do is to make sure that it
won't try to access the lowlevel-driver for this camera anymore. 

The cpia_close() function in cpia.c would simply look like this:


static void cpia_close(struct video_device *dev)
{
	struct cam_data *cam;

	DBG("cpia_close\n");
	cam = dev->priv;

	if (cam->ops != NULL) {
	        /* Return ownership of /proc/cpia/videoX to root */
		cam->proc_entry->uid = 0;
	
		/* save camera state for later open (developers guide ch 3.5.3) */
		save_camera_state(cam);

		/* GotoLoPower */
		goto_low_power(cam);

		/* Update the camera ststus */
		do_command(cam, CPIA_COMMAND_GetCameraStatus, 0, 0, 0, 0);

		/* cleanup internal state stuff */
		free_frames(cam->frame);

		/* close cpia */
		cam->ops->close(cam->lowlevel_data);
	}
        if(--cam->open_count == 0) {
		/* clean up capture-buffers */
		if(cam->raw_image) {
			rvfree(cam->raw_image, CPIA_MAX_IMAGE_SIZE);
			cam->raw_image = 0;
		}
		if(cam->decompressed_frame.data) {
			rvfree(cam->decompressed_frame.data, CPIA_MAX_FRAME_SIZE);
			cam->decompressed_frame.data = 0;
		}
		if(cam->frame_buf) {
			free_frame_buf(cam);
		}
                if(cam->ops == NULL) {
			video_unregister_device(dev);
			kfree(cam);
		}
	}
	

#ifdef MODULE
	MOD_DEC_USE_COUNT;
#endif
	return;
}


Yes, the kernel_(un)lock is missing - did you use it only to protect
the array operations or are there other critical parts? 

Bye,
Jochen

-- 
new signature coming RSN (tm)