[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)