1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Use a mutex to synchronize the driver top and bottom halves instead of

using critcal_enter() and critical_exit() to attempt to replace spl*()
calls.  The critical section was calling selrecord(), which locks an
MTX_DEF mutex, which is not legal in a critical section.

Tested by: Stefan Ehmann <shoesoft@gmx.net> and "make universe"
Approved by: re (scottl)
This commit is contained in:
Don Lewis 2003-12-01 19:03:50 +00:00
parent 9d5880f42b
commit da6f8233bc
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=123088
4 changed files with 63 additions and 10 deletions

View File

@ -526,6 +526,9 @@ common_bktr_attach( bktr_ptr_t bktr, int unit, u_long pci_id, u_int rev )
}
#endif /* FreeBSD or BSDi */
#ifdef USE_VBIMUTEX
mtx_init(&bktr->vbimutex, "bktr vbi lock", NULL, MTX_DEF);
#endif
/* If this is a module, save the current contiguous memory */
#if defined(BKTR_FREEBSD_MODULE)
@ -807,6 +810,7 @@ common_bktr_intr( void *arg )
* both Odd and Even VBI data is captured. Therefore we do this
* in the Even field interrupt handler.
*/
LOCK_VBI(bktr);
if ( (bktr->vbiflags & VBI_CAPTURE)
&&(bktr->vbiflags & VBI_OPEN)
&&(field==EVEN_F)) {
@ -826,6 +830,7 @@ common_bktr_intr( void *arg )
}
UNLOCK_VBI(bktr);
/*
* Register the completed field
@ -1066,8 +1071,13 @@ video_open( bktr_ptr_t bktr )
int
vbi_open( bktr_ptr_t bktr )
{
if (bktr->vbiflags & VBI_OPEN) /* device is busy */
LOCK_VBI(bktr);
if (bktr->vbiflags & VBI_OPEN) { /* device is busy */
UNLOCK_VBI(bktr);
return( EBUSY );
}
bktr->vbiflags |= VBI_OPEN;
@ -1081,6 +1091,8 @@ vbi_open( bktr_ptr_t bktr )
bzero((caddr_t) bktr->vbibuffer, VBI_BUFFER_SIZE);
bzero((caddr_t) bktr->vbidata, VBI_DATA_SIZE);
UNLOCK_VBI(bktr);
return( 0 );
}
@ -1166,8 +1178,12 @@ int
vbi_close( bktr_ptr_t bktr )
{
LOCK_VBI(bktr);
bktr->vbiflags &= ~VBI_OPEN;
UNLOCK_VBI(bktr);
return( 0 );
}
@ -1232,19 +1248,32 @@ video_read(bktr_ptr_t bktr, int unit, dev_t dev, struct uio *uio)
int
vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
{
int readsize, readsize2;
int readsize, readsize2, start;
int status;
/*
* XXX - vbi_read() should be protected against being re-entered
* while it is unlocked for the uiomove.
*/
LOCK_VBI(bktr);
while(bktr->vbisize == 0) {
if (ioflag & IO_NDELAY) {
return EWOULDBLOCK;
status = EWOULDBLOCK;
goto out;
}
bktr->vbi_read_blocked = TRUE;
if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
return status;
#ifdef USE_VBIMUTEX
if ((status = msleep(VBI_SLEEP, &bktr->vbimutex, VBIPRI, "vbi",
0))) {
goto out;
}
#else
if ((status = tsleep(VBI_SLEEP, VBIPRI, "vbi", 0))) {
goto out;
}
#endif
}
/* Now we have some data to give to the user */
@ -1262,13 +1291,19 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
/* We need to wrap around */
readsize2 = VBI_BUFFER_SIZE - bktr->vbistart;
status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize2, uio);
status += uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
start = bktr->vbistart;
UNLOCK_VBI(bktr);
status = uiomove((caddr_t)bktr->vbibuffer + start, readsize2, uio);
if (status == 0)
status = uiomove((caddr_t)bktr->vbibuffer, (readsize - readsize2), uio);
} else {
UNLOCK_VBI(bktr);
/* We do not need to wrap around */
status = uiomove((caddr_t)bktr->vbibuffer + bktr->vbistart, readsize, uio);
}
LOCK_VBI(bktr);
/* Update the number of bytes left to read */
bktr->vbisize -= readsize;
@ -1276,6 +1311,9 @@ vbi_read(bktr_ptr_t bktr, struct uio *uio, int ioflag)
bktr->vbistart += readsize;
bktr->vbistart = bktr->vbistart % VBI_BUFFER_SIZE; /* wrap around if needed */
out:
UNLOCK_VBI(bktr);
return( status );
}

View File

@ -499,6 +499,9 @@ bktr_detach( device_t dev )
printf("bktr%d: i2c_attach: can't attach\n",
device_get_unit(dev));
#endif
#ifdef USE_VBIMUTEX
mtx_destroy(&bktr->vbimutex);
#endif
/* Note: We do not free memory for RISC programs, grab buffer, vbi buffers */
/* The memory is retained by the bktr_mem module so we can unload and */
@ -830,6 +833,7 @@ bktr_poll( dev_t dev, int events, struct thread *td)
return (ENXIO);
}
LOCK_VBI(bktr);
DISABLE_INTR(s);
if (events & (POLLIN | POLLRDNORM)) {
@ -845,6 +849,7 @@ bktr_poll( dev_t dev, int events, struct thread *td)
}
ENABLE_INTR(s);
UNLOCK_VBI(bktr);
return (revents);
}

View File

@ -61,9 +61,10 @@ void free_bktr_mem(bktr_ptr_t, bus_dmamap_t, vm_offset_t);
/************************************/
#if defined(__FreeBSD__)
#if (__FreeBSD_version >=500000)
#define USE_VBIMUTEX
#define DECLARE_INTR_MASK(s) /* no need to declare 's' */
#define DISABLE_INTR(s) critical_enter()
#define ENABLE_INTR(s) critical_exit()
#define DISABLE_INTR(s)
#define ENABLE_INTR(s)
#else
#define DECLARE_INTR_MASK(s) intrmask_t s
#define DISABLE_INTR(s) s=spltty()
@ -75,4 +76,10 @@ void free_bktr_mem(bktr_ptr_t, bus_dmamap_t, vm_offset_t);
#define ENABLE_INTR(s) enable_intr()
#endif
#ifdef USE_VBIMUTEX
#define LOCK_VBI(bktr) mtx_lock(&bktr->vbimutex)
#define UNLOCK_VBI(bktr) mtx_unlock(&bktr->vbimutex)
#else
#define LOCK_VBI(bktr)
#define UNLOCK_VBI(bktr)
#endif

View File

@ -542,6 +542,9 @@ struct bktr_softc {
dev_t tunerdev_alias; /* alias /dev/tuner to /dev/tuner0 */
dev_t vbidev_alias; /* alias /dev/vbi to /dev/vbi0 */
#endif
#if (__FreeBSD_version >= 500000)
struct mtx vbimutex; /* Mutex protecting vbi buffer */
#endif
#if (__FreeBSD_version >= 310000)
bus_space_tag_t memt; /* Bus space register access functions */
bus_space_handle_t memh; /* Bus space register access functions */