Date: Sun, 16 Nov 2003 14:11:27 -0500 From: Mathew Kanner <mat@cnd.mcgill.ca> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/59349: patch to including locking for es137x sound driver Message-ID: <20031116191127.GJ68875@cnd.mcgill.ca> Resent-Message-ID: <200311161920.hAGJKGbL049246@freefall.freebsd.org>
index | next in thread | raw e-mail
>Number: 59349
>Category: kern
>Synopsis: patch to including locking for es137x sound driver
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Sun Nov 16 11:20:16 PST 2003
>Closed-Date:
>Last-Modified:
>Originator: Mathew Kanner
>Release: FreeBSD 5.x
>Organization:
>Environment:
System: FreeBSD tube.mine.nu 5.1-CURRENT-20031021-JPSNAP FreeBSD 5.1-CURRENT-20031021-JPSNAP #0: Tue Oct 21 01:07:08 GMT 2003 root@ushi.jp.freebsd.org:/usr/obj/usr/src/sys/GENERIC i386
>Description:
While working with pav@freebsd to solve the poping and craking
problem, we experimented with adding locking to the driver. Although
it didn't help, I think it belongs in the driver anyway because it
moves it to being MPSAFE. I'm filing this here for safe keeping.
Note the missing mtx_destroy.
>How-To-Repeat:
>Fix:
--5gxpn/Q6ypwruk0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="es137xlock.patch"
--- es137x.c.old Sat Nov 15 02:02:10 2003
+++ es137x.c Sat Nov 15 14:18:35 2003
@@ -118,6 +118,7 @@
u_long ctrl;
u_long sctrl;
struct es_chinfo pch, rch;
+ struct mtx *lock;
};
/* -------------------------------------------------------------------- */
@@ -284,6 +285,7 @@
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
+ snd_mtxlock(es->lock);
if (dir == PCMDIR_PLAY) {
bus_space_write_1(es->st, es->sh, ES1370_REG_MEMPAGE, ES1370_REG_DAC2_FRAMEADR >> 8);
bus_space_write_4(es->st, es->sh, ES1370_REG_DAC2_FRAMEADR & 0xff, sndbuf_getbufaddr(ch->buffer));
@@ -294,6 +296,7 @@
bus_space_write_4(es->st, es->sh, ES1370_REG_ADC_FRAMECNT & 0xff, (ch->bufsz >> 2) - 1);
}
ch->dir = dir;
+ snd_mtxunlock(es->lock);
return 0;
}
@@ -303,6 +306,7 @@
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
+ snd_mtxlock(es->lock);
if (ch->dir == PCMDIR_PLAY) {
es->sctrl &= ~SCTRL_P2FMT;
if (format & AFMT_S16_LE) es->sctrl |= SCTRL_P2SEB;
@@ -314,6 +318,7 @@
}
bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
ch->fmt = format;
+ snd_mtxunlock(es->lock);
return 0;
}
@@ -323,10 +328,12 @@
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
+ snd_mtxlock(es->lock);
es->ctrl &= ~CTRL_PCLKDIV;
es->ctrl |= DAC2_SRTODIV(speed) << CTRL_SH_PCLKDIV;
bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
/* rec/play speeds locked together - should indicate in flags */
+ snd_mtxunlock(es->lock);
return speed; /* XXX calc real speed */
}
@@ -335,12 +342,16 @@
{
struct es_chinfo *ch = data;
struct es_info *es = ch->parent;
+ int i;
+ snd_mtxlock(es->lock);
if (ch->dir == PCMDIR_PLAY) {
- return es1371_dac_rate(es, speed, 3 - ch->num); /* play */
+ i = es1371_dac_rate(es, speed, 3 - ch->num); /* play */
} else {
- return es1371_adc_rate(es, speed, 1); /* record */
+ i = es1371_adc_rate(es, speed, 1); /* record */
}
+ snd_mtxunlock(es->lock);
+ return i;
}
static int
@@ -365,6 +376,7 @@
if (go == PCMTRIG_EMLDMAWR || go == PCMTRIG_EMLDMARD)
return 0;
+ snd_mtxlock(es->lock);
cnt = (ch->blksz / sndbuf_getbps(ch->buffer)) - 1;
if (ch->dir == PCMDIR_PLAY) {
@@ -391,6 +403,7 @@
}
bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
bus_space_write_4(es->st, es->sh, ES1370_REG_CONTROL, es->ctrl);
+ snd_mtxunlock(es->lock);
return 0;
}
@@ -406,8 +419,10 @@
else
reg = ES1370_REG_ADC_FRAMECNT;
+ snd_mtxlock(es->lock);
bus_space_write_4(es->st, es->sh, ES1370_REG_MEMPAGE, reg >> 8);
cnt = bus_space_read_4(es->st, es->sh, reg & 0x000000ff) >> 16;
+ snd_mtxunlock(es->lock);
/* cnt is longwords */
return cnt << 2;
}
@@ -453,8 +468,12 @@
struct es_info *es = p;
unsigned intsrc, sctrl;
+ snd_mtxlock(es->lock);
intsrc = bus_space_read_4(es->st, es->sh, ES1370_REG_STATUS);
- if ((intsrc & STAT_INTR) == 0) return;
+ if ((intsrc & STAT_INTR) == 0) {
+ snd_mtxunlock(es->lock);
+ return;
+ }
sctrl = es->sctrl;
if (intsrc & STAT_ADC) sctrl &= ~SCTRL_R1INTEN;
@@ -463,6 +482,7 @@
bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, sctrl);
bus_space_write_4(es->st, es->sh, ES1370_REG_SERIAL_CONTROL, es->sctrl);
+ snd_mtxunlock(es->lock);
if (intsrc & STAT_ADC) chn_intr(es->rch.channel);
if (intsrc & STAT_DAC1);
@@ -845,7 +865,7 @@
device_printf(dev, "cannot allocate softc\n");
return ENXIO;
}
-
+ es->lock = snd_mtxcreate(device_get_nameunit(dev), "sound softc");
es->dev = dev;
mapped = 0;
data = pci_read_config(dev, PCIR_COMMAND, 2);
@@ -908,7 +928,7 @@
es->irqid = 0;
es->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &es->irqid,
0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
- if (!es->irq || snd_setup_intr(dev, es->irq, 0, es_intr, es, &es->ih)) {
+ if (!es->irq || snd_setup_intr(dev, es->irq, INTR_MPSAFE, es_intr, es, &es->ih)) {
device_printf(dev, "unable to map interrupt\n");
goto bad;
}
--5gxpn/Q6ypwruk0T--
>Release-Note:
>Audit-Trail:
>Unformatted:
--5gxpn/Q6ypwruk0T
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20031116191127.GJ68875>
