[cpia] USB anyone?
Jochen Scharrlach
Jochen.Scharrlach@schwaben.de
Mon, 17 Jan 2000 20:55:16 +0100 (CET)
Peter Pregler writes:
> Hmmm, I don't understand that. There is a cpia_unregister_camera in the current
ok, I must have been dreaming about this one. I just patched my cpia.c
and found that the patch needed a small fix before it could be
applied, at least "patch -p2 < ..." didn't like it :)
There is one thing I still don't understand: video_register_device()
is called in cpia_register_camera(), while video_unregister_device()
is called by cpia_close() - doesn't this make the device a one-way
street, i.e. after closing your app you'll have to reload the module
to start it again? If I am wrong again, the stuff below won't make
much sense :*)
> not much of a destinction between cleanup_module and hot-plugging. It is just a
It seems to take some time until I understand the driver. Sorry, it
*is* be possible to use your scheme, but I have to admit that I don't
like it: there are two more or less redundant fixed-size arrays to keep
track of the cameras. So I'll take this problem in two steps: first
I'll make a driver that works with the current cpia.c and then I'll
try to convince you to change the array-stuff...
The theory: the highlevel cpia.c either gets called by the
lowlevel-driver to (un)register a camera or it is called by the
v4l-API to do something with an existing driver - I don't think it's
ever needed that the cpia.c tells the lowlevel-driver to (un)register a
camera, assuming that it is not possible to unload cpia.o *before*
cpia_*.o (which wouldn't make sense IMHO). So only the
lowlevel-drivers have to keep track of the cameras and no camera[] and
camnr's are needed by cpia.c. The lowlevel-drivers could use a linked
list for this. The following could be in cpia.h (keep in mind that my
C is a bit rusty):
struct cam_lowlevel; /* defined in the lowlevel driver */
struct cam_data {
struct cam_data **previous;
struct cam_data *next;
struct cam_lowlevel *lowlevel;
[...]
};
//
// adding a highlevel-struct to the list
//
#define cam_list_add(drv) \
{\
(drv)->previous = &cam_list;\
(drv)->next = cam_list;\
if (cam_list != NULL)\
cam_list->previous = &(drv)->next;\
cam_data = drv;\
} while (0)
//
// removing a highlevel-struct from the list
//
#define cam_list_remove(drv) \
{\
*(drv)->previous=(drv)->next;\
if ((drv)->next != NULL)\
(drv)->next->previous = (drv)->previous;\
} while (0)
//
// searching the highlevel-struct for the given camera object
// and calling unregister_driver() with it
//
#define cam_unregister(cam) \
{\
struct cam_data *drv = cam_list;\
while (drv != NULL && drv->cam_lowlevel->camera != cam)\
drv = drv->next;\
if (drv != NULL)\
unregister_driver(drv);\
} while(0)
The following would be in the lowlevel driver:
static struct cam_data *cam_list = NULL;
struct cam_lowlevel{
struct myTypeOfCamera *camera;
[...]
};
unregister_driver(cam_data *drv)
{
struct cam_lowlevel *mystuff = drv->cam_lowlevel;
cam_list_remove(drv);
cpia_unregister(drv);
/* cleaning up mystuff */
}
cpia_xyz_register(struct myTypeOfCamera *camera)
{
struct cam_data *drv = NULL;
struct cam_lowlevel *cam;
/* Initializing cam */
drv = cpia_register(cam);
cam_list_add(drv);
}
cpia_xyz_unregister(struct myTypeOfCamera *camera)
{
cam_unregister(camera);
}
cpia_xyz_cleanup()
{
while (cam_list != NULL)
unregister_driver(cam_list);
/* and so on */
}
It's certainly not in the best possible form, but I really think that
*one* *linked list* could reduce the complexity and would make it
mouch easier to write new lowlevel-drivers and maintain the existing
ones.
Just my $0.02,
Jochen
--
new signature coming RSN (tm)