Add support for /very/ experimental -e (exposure) option.
Add support for LKM operation. Change M_NOWAIT on buffer memory allocation to M_WAIT in hopes we'll be able to get ourselves a nice fat buffer from the kernel if we suspend. Note: The LKM support looks kinda screwy in two areas, where I found problems with the kernel proper. First, calling dev_attach() at module load time will cause a panic. I haven't investigated. Secondly, I had to manually call qcam_drvinit() to register the device softc structure by hand at module load time. This seems bogus, it should be called as a core part of the module load process for character/block device drivers.
This commit is contained in:
parent
4374dd874b
commit
f3a4ca94cd
@ -118,7 +118,10 @@ qcam_registerdev (struct isa_device *id)
|
||||
kdc->kdc_unit = id->id_unit;
|
||||
kdc->kdc_parentdata = id;
|
||||
|
||||
#ifndef ACTUALLY_LKM_NOT_KERNEL /* there's a bug in dev_attach
|
||||
when running from an LKM */
|
||||
dev_attach(kdc);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
@ -186,7 +189,7 @@ qcam_attach (struct isa_device *devp)
|
||||
static int
|
||||
qcam_open (dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct qcam_softc *qs = (struct qcam_softc *)&qcam_softc[UNIT(dev)];
|
||||
struct qcam_softc *qs = &qcam_softc[UNIT(dev)];
|
||||
|
||||
if (!(qs->flags & QC_ALIVE))
|
||||
return ENXIO;
|
||||
@ -195,7 +198,7 @@ qcam_open (dev_t dev, int flags, int fmt, struct proc *p)
|
||||
return EBUSY;
|
||||
|
||||
qs->buffer_end = qs->buffer = malloc(QC_MAXFRAMEBUFSIZE, M_DEVBUF,
|
||||
M_NOWAIT);
|
||||
M_WAITOK);
|
||||
if (!qs->buffer)
|
||||
return ENOMEM;
|
||||
|
||||
@ -212,7 +215,7 @@ qcam_open (dev_t dev, int flags, int fmt, struct proc *p)
|
||||
static int
|
||||
qcam_close (dev_t dev, int flags, int fmt, struct proc *p)
|
||||
{
|
||||
struct qcam_softc *qs = (struct qcam_softc *)&qcam_softc[UNIT(dev)];
|
||||
struct qcam_softc *qs = &qcam_softc[UNIT(dev)];
|
||||
|
||||
if (qs->buffer) {
|
||||
free(qs->buffer, M_DEVBUF);
|
||||
@ -228,7 +231,7 @@ qcam_close (dev_t dev, int flags, int fmt, struct proc *p)
|
||||
static int
|
||||
qcam_read (dev_t dev, struct uio *uio, int ioflag)
|
||||
{
|
||||
struct qcam_softc *qs = (struct qcam_softc *)&qcam_softc[UNIT(dev)];
|
||||
struct qcam_softc *qs = &qcam_softc[UNIT(dev)];
|
||||
int bytes, bufsize;
|
||||
int error;
|
||||
|
||||
@ -252,7 +255,7 @@ qcam_read (dev_t dev, struct uio *uio, int ioflag)
|
||||
static int
|
||||
qcam_ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
{
|
||||
struct qcam_softc *qs = (struct qcam_softc *)&qcam_softc[UNIT(dev)];
|
||||
struct qcam_softc *qs = &qcam_softc[UNIT(dev)];
|
||||
struct qcam *info = (struct qcam *)data;
|
||||
|
||||
if (!data)
|
||||
@ -268,6 +271,7 @@ qcam_ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
info->qc_yorigin = qs->y_origin;
|
||||
info->qc_bpp = qs->bpp;
|
||||
info->qc_zoom = qs->zoom;
|
||||
info->qc_exposure = qs->exposure;
|
||||
info->qc_brightness = qs->brightness;
|
||||
info->qc_whitebalance = qs->whitebalance;
|
||||
info->qc_contrast = qs->contrast;
|
||||
@ -300,6 +304,7 @@ qcam_ioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
|
||||
qs->y_origin = info->qc_yorigin;
|
||||
qs->bpp = info->qc_bpp;
|
||||
qs->zoom = info->qc_zoom;
|
||||
qs->exposure = info->qc_exposure;
|
||||
qs->brightness = info->qc_brightness;
|
||||
qs->whitebalance = info->qc_whitebalance;
|
||||
qs->contrast = info->qc_contrast;
|
||||
@ -333,4 +338,68 @@ qcam_drvinit (void *unused)
|
||||
|
||||
SYSINIT(qcamdev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR,qcam_drvinit,NULL)
|
||||
|
||||
#ifdef QCAM_MODULE
|
||||
|
||||
#include <sys/exec.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <sys/sysproto.h>
|
||||
#include <sys/lkm.h>
|
||||
|
||||
static struct isa_device qcam_mod_dev =
|
||||
{0, &qcamdriver, IO_LPT1, 0, -1, (caddr_t) 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 0, 0};
|
||||
|
||||
MOD_DEV(qcam, LM_DT_CHAR, CDEV_MAJOR, &qcam_cdevsw);
|
||||
|
||||
static int
|
||||
qcam_load (struct lkm_table *lkmtp, int cmd)
|
||||
{
|
||||
if (qcam_probe(&qcam_mod_dev)) {
|
||||
qcam_attach(&qcam_mod_dev);
|
||||
|
||||
qcam_drvinit(NULL); /* XXX this shouldn't NEED to be here
|
||||
* the LKM code should be doing this
|
||||
* for us! */
|
||||
|
||||
uprintf("qcam: driver loaded\n");
|
||||
return 0;
|
||||
} else {
|
||||
uprintf("qcam: probe failed\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
qcam_unload (struct lkm_table *lkmtp, int cmd)
|
||||
{
|
||||
struct qcam_softc *qs;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NQCAM; i++) {
|
||||
qs = &qcam_softc[i];
|
||||
if (qs->flags & QC_OPEN) {
|
||||
uprintf("qcam%d: cannot unload, device busy", qs->unit);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
uprintf("qcam: driver unloaded\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
qcam_stat (struct lkm_table *lkmtp, int cmd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
qcam_mod (struct lkm_table *lkmtp, int cmd, int ver)
|
||||
{
|
||||
#define _module qcam_module
|
||||
DISPATCH(lkmtp, cmd, ver,
|
||||
qcam_load, qcam_unload, qcam_stat);
|
||||
}
|
||||
|
||||
#endif /* QCAM_MODULE */
|
||||
#endif /* NQCAM */
|
||||
|
@ -56,6 +56,7 @@ struct qcam_softc {
|
||||
int y_origin; /* ?? units */
|
||||
int zoom; /* 0=none, 1=1.5x, 2=2x */
|
||||
int bpp; /* 4 or 6 */
|
||||
int exposure; /* time to open shutter */
|
||||
u_char xferparms; /* calcualted transfer params */
|
||||
u_char contrast;
|
||||
u_char brightness;
|
||||
@ -104,6 +105,10 @@ struct qcam_softc {
|
||||
#define QC_TIMEOUT_CMD 5000 /* timeout for control cmds */
|
||||
#define QC_TIMEOUT 400 /* timeout on scan reads */
|
||||
|
||||
/* This value could be OS
|
||||
dependant */
|
||||
#define QC_DEF_EXPOSURE 200 /* default exposure */
|
||||
|
||||
extern int qcam_detect __P((u_int port));
|
||||
extern void qcam_reset __P((struct qcam_softc *qs));
|
||||
extern int qcam_scan __P((struct qcam_softc *qs));
|
||||
|
@ -115,16 +115,16 @@ static u_short *qcam_rsblow_end = &qcam_rsblow[STATBUFSIZE];
|
||||
} while (((V) & 0x01) && --timeout); STATLOW(T) \
|
||||
}
|
||||
|
||||
static int
|
||||
sendbyte (u_int port, int value)
|
||||
inline static int
|
||||
sendbyte (u_int port, int value, int delay)
|
||||
{
|
||||
u_char s1, s2;
|
||||
|
||||
write_data(port, value);
|
||||
DELAY(100);
|
||||
write_data(port, value);
|
||||
DELAY(100);
|
||||
write_data(port, value);
|
||||
if (delay) {
|
||||
DELAY(delay);
|
||||
write_data(port, value);
|
||||
}
|
||||
|
||||
write_control(port, QC_CTL_HIGHNIB);
|
||||
READ_STATUS_BYTE_HIGH(port, s1, QC_TIMEOUT_CMD);
|
||||
@ -138,15 +138,27 @@ sendbyte (u_int port, int value)
|
||||
static int
|
||||
send_command (struct qcam_softc *qs, int cmd, int value)
|
||||
{
|
||||
if (sendbyte(qs->iobase, cmd) != cmd)
|
||||
if (sendbyte(qs->iobase, cmd, qs->exposure) != cmd)
|
||||
return 1;
|
||||
|
||||
if (sendbyte(qs->iobase, value) != value)
|
||||
if (sendbyte(qs->iobase, value, qs->exposure) != value)
|
||||
return 1;
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
static int
|
||||
send_xfermode (struct qcam_softc *qs, int value)
|
||||
{
|
||||
if (sendbyte(qs->iobase, QC_XFERMODE, qs->exposure) != QC_XFERMODE)
|
||||
return 1;
|
||||
|
||||
if (sendbyte(qs->iobase, value, qs->exposure) != value)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
qcam_reset (struct qcam_softc *qs)
|
||||
{
|
||||
@ -447,7 +459,7 @@ qcam_scan (struct qcam_softc *qs)
|
||||
if (qs->init_req)
|
||||
qcam_init(qs);
|
||||
|
||||
if (send_command(qs, QC_XFERMODE, qs->xferparms))
|
||||
if (send_xfermode(qs, qs->xferparms))
|
||||
return 1;
|
||||
|
||||
if (qcam_debug && (timeouts != qcam_timeouts))
|
||||
@ -481,6 +493,7 @@ qcam_default (struct qcam_softc *qs) {
|
||||
qs->y_origin = QC_DEF_YORG;
|
||||
qs->bpp = QC_DEF_BPP;
|
||||
qs->zoom = QC_DEF_ZOOM;
|
||||
qs->exposure = QC_DEF_EXPOSURE;
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user