View | Details | Raw Unified | Return to bug 14990
Collapse All | Expand All

(-)channel.c (-70 / +128 lines)
Lines 37-42 Link Here
37
#define CANCHANGE(c) (!(c)->buffer.dl)
37
#define CANCHANGE(c) (!(c)->buffer.dl)
38
38
39
static void chn_stintr(pcm_channel *c);
39
static void chn_stintr(pcm_channel *c);
40
static void chn_clearbuf(pcm_channel *c, int length);
40
/*
41
/*
41
 * SOUND OUTPUT
42
 * SOUND OUTPUT
42
43
Lines 103-109 Link Here
103
{
104
{
104
	if (ISA_DMA(&c->buffer)) {
105
	if (ISA_DMA(&c->buffer)) {
105
		/* tell isa_dma to bounce data in/out */
106
		/* tell isa_dma to bounce data in/out */
106
    	} else panic("chn_isadmabounce called on invalid channel");
107
    	} else KASSERT(1, ("chn_isadmabounce called on invalid channel"));
107
}
108
}
108
109
109
static int
110
static int
Lines 153-179 Link Here
153
 * NOTE: when we are using auto dma in the device, rl might become
154
 * NOTE: when we are using auto dma in the device, rl might become
154
 * negative.
155
 * negative.
155
 */
156
 */
157
DEB (static int chn_updatecount=0);
158
156
void
159
void
157
chn_dmaupdate(pcm_channel *c)
160
chn_dmaupdate(pcm_channel *c)
158
{
161
{
159
	snd_dbuf *b = &c->buffer;
162
	snd_dbuf *b = &c->buffer;
160
	int delta, hwptr = chn_getptr(c);
163
	int delta, hwptr;
164
	DEB (int b_rl=b->rl; int b_fl=b->fl; int b_rp=b->rp; int b_fp=b->fp);
161
165
166
	hwptr = chn_getptr(c);
162
	if (c->direction == PCMDIR_PLAY) {
167
	if (c->direction == PCMDIR_PLAY) {
163
		delta = (b->bufsize + hwptr - b->rp) % b->bufsize;
168
		delta = (b->bufsize + hwptr - b->rp) % b->bufsize;
164
		b->rp = hwptr;
169
		b->rp = hwptr;
165
		b->rl -= delta;
170
		b->rl -= delta;
166
		b->fl += delta;
171
		b->fl += delta;
172
		DEB(if (b->rl<0) printf("OUCH!(%d) rl %d(%d) delta %d bufsize %d hwptr %d rp %d(%d)\n", chn_updatecount++, b->rl, b_rl, delta, b->bufsize, hwptr, b->rp, b_rp)); 
167
	} else {
173
	} else {
168
		delta = (b->bufsize + hwptr - b->fp) % b->bufsize;
174
		delta = (b->bufsize + hwptr - b->fp) % b->bufsize;
169
		b->fp = hwptr;
175
		b->fp = hwptr;
170
		b->rl += delta;
176
		b->rl += delta;
171
		b->fl -= delta;
177
		b->fl -= delta;
178
		DEB(if (b->fl<0) printf("OUCH!(%d) fl %d(%d) delta %d bufsize %d hwptr %d fp %d(%d)\n", chn_updatecount++, b->fl, b_fl, delta, b->bufsize, hwptr, b->fp, b_fp)); 
172
	}
179
	}
173
	b->total += delta;
180
	b->total += delta;
174
}
181
}
175
182
176
/*
183
/*
184
 * Check channel for underflow occured, reset DMA buffer in case of 
185
 * underflow. It must be called at spltty().
186
 */
187
static void
188
chn_checkunderflow(pcm_channel *c)
189
{
190
    	snd_dbuf *b = &c->buffer;
191
	
192
	if (b->underflow) {
193
		DEB(printf("Clear underflow condition\n"));
194
		b->rp = b->fp = chn_getptr(c);
195
		b->rl = 0;
196
		b->fl = b->bufsize;
197
	  	b->underflow=0;
198
	} else {
199
		chn_dmaupdate(c);
200
	}
201
}
202
203
/*
177
 * Write interrupt routine. Can be called from other places (e.g.
204
 * Write interrupt routine. Can be called from other places (e.g.
178
 * to start a paused transfer), but with interrupts disabled.
205
 * to start a paused transfer), but with interrupts disabled.
179
 */
206
 */
Lines 183-189 Link Here
183
    	snd_dbuf *b = &c->buffer;
210
    	snd_dbuf *b = &c->buffer;
184
    	int start;
211
    	int start;
185
212
186
    	if (b->dl) chn_dmadone(c);
213
    	if (b->underflow) return; /* nothing new happened */
214
	if (b->dl) chn_dmadone(c);
187
215
188
    	/*
216
    	/*
189
     	* start another dma operation only if have ready data in the buffer,
217
     	* start another dma operation only if have ready data in the buffer,
Lines 198-237 Link Here
198
    	if (start) {
226
    	if (start) {
199
		int l;
227
		int l;
200
		chn_dmaupdate(c);
228
		chn_dmaupdate(c);
201
		l = min(b->rl, c->blocksize) & DMA_ALIGN_MASK;
202
		if (c->flags & CHN_F_MAPPED) l = c->blocksize;
229
		if (c->flags & CHN_F_MAPPED) l = c->blocksize;
230
		else l = min(b->rl, c->blocksize) & DMA_ALIGN_MASK;
203
		/*
231
		/*
204
	 	* check if we need to reprogram the DMA on the sound card.
232
	 	* check if we need to reprogram the DMA on the sound card.
205
	 	* This happens if the size has changed _and_ the new size
233
	 	* This happens if the size has changed from zero
206
	 	* is smaller, or it matches the blocksize.
207
	 	*
234
	 	*
208
	 	* 0 <= l <= blocksize
209
	 	* 0 <= dl <= blocksize
210
	 	* reprog if (dl == 0 || l != dl)
211
	 	* was:
212
		* l != b->dl && (b->dl == 0 || l < b->dl || l == c->blocksize)
213
	 	*/
235
	 	*/
214
		if (b->dl == 0 || l != b->dl) {
236
		if (b->dl == 0) {
215
	    		/* size has changed. Stop and restart */
237
			/* Start DMA operation */
216
	    		DEB(printf("wrintr: bsz %d -> %d, rp %d rl %d\n",
238
	    		b->dl = c->blocksize ; /* record new transfer size */
217
				   b->dl, l, b->rp, b->rl));
218
	    		if (b->dl) chn_trigger(c, PCMTRIG_STOP);
219
	    		b->dl = l; /* record new transfer size */
220
	    		chn_trigger(c, PCMTRIG_START);
239
	    		chn_trigger(c, PCMTRIG_START);
240
		} else if (b->dl != l) {
241
			/* 
242
			 * we are near to underflow condition, so to prevent
243
			 * audio 'clicks' clear next 1.5*dl bytes
244
			 */
245
			 chn_clearbuf(c, (b->dl*3)/2);
221
		}
246
		}
222
    	} else {
247
    	} else {
223
		/* cannot start a new dma transfer */
248
		/* cannot start a new dma transfer */
224
		DEB(printf("cannot start wr-dma flags 0x%08x rp %d rl %d\n",
249
		DEB(printf("cannot start wr-dma flags 0x%08x rp %d rl %d\n",
225
			   c->flags, b->rp, b->rl));
250
			   c->flags, b->rp, b->rl));
226
		if (b->dl) { /* was active */
251
		if (b->dl) { /* DMA was active */
227
	    		b->dl = 0;
252
			b->underflow = 1; /* set underflow flag */
228
	    		chn_trigger(c, PCMTRIG_STOP);
253
			chn_clearbuf(c, b->bufsize); /* and clear all DMA buffer */
229
#if 0
230
            		if (c->flags & CHN_F_WRITING)
231
				DEB(printf("got wrint while reloading\n"));
232
	    		else if (b->rl <= 0) /* XXX added 980110 lr */
233
				chn_resetbuf(c);
234
#endif
235
		}
254
		}
236
    	}
255
    	}
237
}
256
}
Lines 255-263 Link Here
255
int
274
int
256
chn_write(pcm_channel *c, struct uio *buf)
275
chn_write(pcm_channel *c, struct uio *buf)
257
{
276
{
258
	int 		a, l, w, timeout, ret = 0;
277
	int 		a, l, w, timeout, ret = 0, rc;
259
	long		s;
278
	long		s;
260
	snd_dbuf       *b = &c->buffer;
279
	snd_dbuf       *b = &c->buffer;
280
	int		threshold, maxthreshold, minthreshold;
261
281
262
	if (c->flags & CHN_F_WRITING) {
282
	if (c->flags & CHN_F_WRITING) {
263
		/* This shouldn't happen and is actually silly
283
		/* This shouldn't happen and is actually silly
Lines 267-301 Link Here
267
		return EBUSY;
287
		return EBUSY;
268
	}
288
	}
269
	a = (1 << c->align) - 1;
289
	a = (1 << c->align) - 1;
290
	maxthreshold=(b->dl/4+a)&(~a);
291
	minthreshold=a;
270
	c->flags |= CHN_F_WRITING;
292
	c->flags |= CHN_F_WRITING;
271
	while ((c->smegcnt + buf->uio_resid) > a) {
293
	s = spltty();
272
		s = spltty();
294
	chn_checkunderflow(c);
273
		chn_dmaupdate(c);
295
	splx(s);
274
		splx(s);
296
	while ((buf->uio_resid+c->smegcnt) > minthreshold ) { /* Don't allow write unaligned data */
275
		if (b->fl < DMA_ALIGN_THRESHOLD) {
297
		threshold = min ((buf->uio_resid+c->smegcnt), maxthreshold);
298
		if (b->fl < threshold) {
276
			if (c->flags & CHN_F_NBIO) break;
299
			if (c->flags & CHN_F_NBIO) break;
277
			timeout = (buf->uio_resid >= b->dl)? hz : 1;
300
			timeout = (buf->uio_resid >= b->dl)? hz : 1;
278
			ret = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout);
301
			rc = tsleep(b, PRIBIO | PCATCH, "pcmwr", timeout);
279
			if (ret == EINTR) chn_abort(c);
302
			if (rc == 0 || rc == EWOULDBLOCK) {
280
			if (ret == EINTR || ret == ERESTART) break;
303
				s = spltty();
281
			ret = 0;
304
				chn_checkunderflow(c);
282
			continue;
305
				splx(s);				
283
		}
306
				if (b->fl < minthreshold) continue; /* write only alligned chunk of data */
307
			} else {
308
#if 0
309
			 	if (ret == EINTR) chn_abort(c);
310
#endif			
311
				ret=rc;
312
				break;
313
			}
314
		} 
284
		/* ensure we always have a whole number of samples */
315
		/* ensure we always have a whole number of samples */
285
		l = min(b->fl, b->bufsize - b->fp) & ~a;
316
		l = min(b->fl, b->bufsize - b->fp);
286
		if (l == 0) break;
317
		KASSERT(!(l & a),("unaligned write %d, %d fl %d fp %d bufsize %d", l, a + 1, b->fl, b->fp, b->bufsize));
287
		w = c->feeder->feed(c->feeder, c, b->buf + b->fp, l, buf);
318
		w = c->feeder->feed(c->feeder, c, b->buf + b->fp, l, buf);
288
		if (w == 0) panic("no feed");
319
		KASSERT(w, ("chn_write: no feed"));
289
		s = spltty();
320
		s = spltty();
290
		b->rl += w;
321
		b->rl += w;
291
		b->fl -= w;
322
		b->fl -= w;
292
		b->fp = (b->fp + w) % b->bufsize;
323
		b->fp = (b->fp + w) % b->bufsize;
293
	      	splx(s);
324
	      	splx(s);
294
		if (b->rl && !b->dl) chn_stintr(c);
325
		DEB(if(1) printf("write %d bytes fp %d rl %d\n",w ,b->fp, b->rl));
326
		if (!b->dl) chn_stintr(c);
295
	}
327
	}
296
	if ((ret == 0) && (buf->uio_resid > 0)) {
328
	if ((ret == 0) && (buf->uio_resid > 0)) {
297
		l = buf->uio_resid;
329
		l = buf->uio_resid;
298
		if ((c->smegcnt + l) >= SMEGBUFSZ) panic("resid overflow %d", l);
330
		KASSERT( (c->smegcnt + l) < SMEGBUFSZ, ("resid overflow %d", l));
299
		uiomove(c->smegbuf + c->smegcnt, l, buf);
331
		uiomove(c->smegbuf + c->smegcnt, l, buf);
300
		c->smegcnt += l;
332
		c->smegcnt += l;
301
	}
333
	}
Lines 472-515 Link Here
472
	return 0;
504
	return 0;
473
}
505
}
474
506
507
static void
508
chn_clearbuf(pcm_channel *c, int length)
509
{
510
int i;
511
u_int16_t data, *p;
512
513
	snd_dbuf *b = &c->buffer;
514
	/* rely on length & DMA_ALIGN_MASK == 0 */
515
	length&=DMA_ALIGN_MASK;
516
	if (c->hwfmt & AFMT_SIGNED)	data = 0x00; else data = 0x80;
517
	if (c->hwfmt & AFMT_16BIT)	data <<= 8; else data |= data << 8;
518
	if (c->hwfmt & AFMT_BIGENDIAN)
519
		data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00);
520
	for (i = b->fp, p=(u_int16_t*)(b->buf+b->fp) ; i < b->bufsize && length; i += 2, length-=2)
521
		*p++ = data;
522
	for (i = 0, p=(u_int16_t*)b->buf; i < b->bufsize && length; i += 2, length-=2)
523
		*p++ = data;
524
525
	return;
526
}
527
475
void
528
void
476
chn_resetbuf(pcm_channel *c)
529
chn_resetbuf(pcm_channel *c)
477
{
530
{
478
	snd_dbuf *b = &c->buffer;
531
	snd_dbuf *b = &c->buffer;
479
	u_int16_t data, *p;
480
	u_int32_t i;
481
532
482
	c->smegcnt = 0;
533
	c->smegcnt = 0;
483
	c->buffer.sample_size = 1;
534
	c->buffer.sample_size = 1;
484
	c->buffer.sample_size <<= (c->hwfmt & AFMT_STEREO)? 1 : 0;
535
	c->buffer.sample_size <<= (c->hwfmt & AFMT_STEREO)? 1 : 0;
485
	c->buffer.sample_size <<= (c->hwfmt & AFMT_16BIT)? 1 : 0;
536
	c->buffer.sample_size <<= (c->hwfmt & AFMT_16BIT)? 1 : 0;
486
	/* rely on bufsize & 3 == 0 */
487
	if (c->hwfmt & AFMT_SIGNED)	data = 0x00; else data = 0x80;
488
	if (c->hwfmt & AFMT_16BIT)	data <<= 8; else data |= data << 8;
489
	if (c->hwfmt & AFMT_BIGENDIAN)
490
		data = ((data >> 8) & 0x00ff) | ((data << 8) & 0xff00);
491
	for (i = 0, p = (u_int16_t *)b->buf; i < b->bufsize; i += 2)
492
		*p++ = data;
493
	b->rp = b->fp = 0;
537
	b->rp = b->fp = 0;
494
	b->dl = b->rl = 0;
538
	b->dl = b->rl = 0;
539
	b->fl = b->bufsize;
540
	chn_clearbuf(c, b->bufsize);
495
	b->prev_total = b->total = 0;
541
	b->prev_total = b->total = 0;
496
	b->prev_int_count = b->int_count = 0;
542
	b->prev_int_count = b->int_count = 0;
497
	b->first_poll = 1;
543
	b->first_poll = 1;
498
	b->fl = b->bufsize;
544
	b->underflow=0;
499
}
545
}
500
546
501
void
547
void
502
buf_isadma(snd_dbuf *b, int go)
548
buf_isadma(snd_dbuf *b, int go)
503
{
549
{
504
	if (ISA_DMA(b)) {
550
	if (ISA_DMA(b)) {
505
        	if (go == PCMTRIG_START) isa_dmastart(b->dir | B_RAW, b->buf,
551
        	if (go == PCMTRIG_START) {
506
						      b->bufsize, b->chan);
552
			DEB(printf("buf 0x%p ISA DMA started\n", b));
507
		else {
553
			isa_dmastart(b->dir | B_RAW, b->buf,
554
					b->bufsize, b->chan);
555
		} else {
556
			DEB(printf("buf 0x%p ISA DMA stopped\n", b));
508
			isa_dmastop(b->chan);
557
			isa_dmastop(b->chan);
509
			isa_dmadone(b->dir | B_RAW, b->buf, b->bufsize,
558
			isa_dmadone(b->dir | B_RAW, b->buf, b->bufsize,
510
				    b->chan);
559
				    b->chan);
511
		}
560
		}
512
    	} else panic("buf_isadma called on invalid channel");
561
    	} else KASSERT(1, ("buf_isadma called on invalid channel"));
513
}
562
}
514
563
515
int
564
int
Lines 519-525 Link Here
519
		int i = b->dl? isa_dmastatus(b->chan) : b->bufsize;
568
		int i = b->dl? isa_dmastatus(b->chan) : b->bufsize;
520
		if (i < 0) i = 0;
569
		if (i < 0) i = 0;
521
		return b->bufsize - i;
570
		return b->bufsize - i;
522
    	} else panic("buf_isadmaptr called on invalid channel");
571
    	} else KASSERT(1, ("buf_isadmaptr called on invalid channel"));
523
	return -1;
572
	return -1;
524
}
573
}
525
574
Lines 543-549 Link Here
543
	    		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1);
592
	    		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmsyn", 1);
544
	    		splx(s);
593
	    		splx(s);
545
	    		if (ret == ERESTART || ret == EINTR) {
594
	    		if (ret == ERESTART || ret == EINTR) {
546
				printf("tsleep returns %d\n", ret);
595
				DEB(printf("chn_sync: tsleep returns %d\n", ret));
547
				return -1;
596
				return -1;
548
	    		}
597
	    		}
549
		} else break;
598
		} else break;
Lines 605-622 Link Here
605
    	DEB(printf("snd_flush c->flags 0x%08x\n", c->flags));
654
    	DEB(printf("snd_flush c->flags 0x%08x\n", c->flags));
606
    	c->flags |= CHN_F_CLOSING;
655
    	c->flags |= CHN_F_CLOSING;
607
    	if (c->direction != PCMDIR_PLAY) chn_abort(c);
656
    	if (c->direction != PCMDIR_PLAY) chn_abort(c);
608
    	else while (b->dl) {
657
    	else if (b->dl) while (!b->underflow) {
609
		/* still pending output data. */
658
		/* still pending output data. */
610
		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz);
659
		ret = tsleep((caddr_t)b, PRIBIO | PCATCH, "pcmflu", hz);
611
		chn_dmaupdate(c);
660
		DEB(chn_dmaupdate(c));
612
		DEB(printf("snd_sync: now rl : fl  %d : %d\n", b->rl, b->fl));
661
		DEB(printf("snd_sync: now rl : fl  %d : %d\n", b->rl, b->fl));
613
		if (ret == EINTR) {
662
		if (ret == EINTR || ret == ERESTART) {
614
	    		printf("tsleep returns %d\n", ret);
663
	    		DEB(printf("chn_flush: tsleep returns %d\n", ret));
615
	    		return -1;
664
	    		return -1;
616
		}
665
		}
617
		if (ret && --count == 0) {
666
		if (ret && --count == 0) {
618
	    		printf("timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n",
667
	    		DEB(printf("chn_flush: timeout flushing dbuf_out, cnt 0x%x flags 0x%x\n",\
619
			       b->rl, c->flags);
668
			       b->rl, c->flags));
620
	    		break;
669
	    		break;
621
		}
670
		}
622
    	}
671
    	}
Lines 641-651 Link Here
641
	if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) {
690
	if ((c->flags & CHN_F_INIT) && CANCHANGE(c)) {
642
		chn_setformat(c, c->format);
691
		chn_setformat(c, c->format);
643
		chn_setspeed(c, c->speed);
692
		chn_setspeed(c, c->speed);
644
		chn_setblocksize(c, c->blocksize);
693
		chn_setblocksize(c, (c->flags & CHN_F_HAS_SIZE) ? c->blocksize : 0);
645
		chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff);
694
		chn_setvolume(c, (c->volume >> 8) & 0xff, c->volume & 0xff);
646
		c->flags &= ~CHN_F_INIT;
695
		c->flags &= ~CHN_F_INIT;
647
		return 1;
696
		return 1;
648
	}
697
	}
698
	if (CANCHANGE(c) && !(c->flags & CHN_F_HAS_SIZE) )  
699
		chn_setblocksize(c, 0); /* Apply new block size */
649
	return 0;
700
	return 0;
650
}
701
}
651
702
Lines 716-725 Link Here
716
		c->flags &= ~CHN_F_HAS_SIZE;
767
		c->flags &= ~CHN_F_HAS_SIZE;
717
		if (blksz >= 2) c->flags |= CHN_F_HAS_SIZE;
768
		if (blksz >= 2) c->flags |= CHN_F_HAS_SIZE;
718
		blksz = abs(blksz);
769
		blksz = abs(blksz);
719
		if (blksz < 2) blksz = (c->buffer.sample_size * c->speed) >> 2;
770
		if (blksz < 2) blksz = c->buffer.sample_size * (c->speed / 4); /* 1/4 sec */
720
		RANGE(blksz, 1024, c->buffer.bufsize / 4);
771
		RANGE(blksz, 1024, c->buffer.bufsize / 4);
721
		blksz &= ~3;
772
		blksz &= DMA_ALIGN_MASK;
722
		c->blocksize = c->setblocksize(c->devinfo, blksz);
773
		c->blocksize = c->setblocksize(c->devinfo, blksz)&DMA_ALIGN_MASK;
723
		return c->blocksize;
774
		return c->blocksize;
724
	}
775
	}
725
	c->blocksize = blksz;
776
	c->blocksize = blksz;
Lines 736-742 Link Here
736
int
787
int
737
chn_getptr(pcm_channel *c)
788
chn_getptr(pcm_channel *c)
738
{
789
{
739
	return c->getptr(c->devinfo);
790
	int hwptr;
791
	int a = (1 << c->align) - 1;
792
793
	hwptr=c->getptr(c->devinfo);
794
	/* don't allow unaligned values in the hwa ptr */
795
	hwptr &= ~a ; /* Apply channel align mask */
796
	hwptr &= DMA_ALIGN_MASK; /* Apply DMA align mask */
797
	return hwptr;
740
}
798
}
741
799
742
pcmchan_caps *
800
pcmchan_caps *
(-)datatypes.h (+1 lines)
Lines 71-76 Link Here
71
	u_long prev_total; /* copy of the above when GETxPTR called */
71
	u_long prev_total; /* copy of the above when GETxPTR called */
72
	int first_poll;
72
	int first_poll;
73
	bus_dmamap_t dmamap;
73
	bus_dmamap_t dmamap;
74
	int underflow;
74
};
75
};
75
76
76
typedef int (pcmfeed_init_t)(pcm_feeder *feeder);
77
typedef int (pcmfeed_init_t)(pcm_feeder *feeder);
(-)dsp.c (-8 / +11 lines)
Lines 66-73 Link Here
66
static void
66
static void
67
setchns(snddev_info *d, int chan)
67
setchns(snddev_info *d, int chan)
68
{
68
{
69
	if ((d->flags & SD_F_PRIO_SET) == SD_F_PRIO_SET)
69
	KASSERT((d->flags & SD_F_PRIO_SET) != SD_F_PRIO_SET, \
70
		panic("read and write both prioritised");
70
		("getchns: read and write both prioritised"));
71
	d->flags |= SD_F_DIR_SET;
71
	d->flags |= SD_F_DIR_SET;
72
	if (d->flags & SD_F_EVILSB16) {
72
	if (d->flags & SD_F_EVILSB16) {
73
		if ((d->flags & SD_F_PRIO_RD) && (d->aplay[chan])) {
73
		if ((d->flags & SD_F_PRIO_RD) && (d->aplay[chan])) {
Lines 159-165 Link Here
159
		chn_abort(rdch);
159
		chn_abort(rdch);
160
		rdch->flags &= ~(CHN_F_BUSY | CHN_F_RUNNING | CHN_F_MAPPED);
160
		rdch->flags &= ~(CHN_F_BUSY | CHN_F_RUNNING | CHN_F_MAPPED);
161
	}
161
	}
162
	if (wrch) wrch->flags &= ~(CHN_F_BUSY | CHN_F_RUNNING | CHN_F_MAPPED);
162
	if (wrch) {
163
		chn_flush(wrch);
164
		wrch->flags &= ~(CHN_F_BUSY | CHN_F_RUNNING | CHN_F_MAPPED);
165
	}
163
	d->aplay[chan] = NULL;
166
	d->aplay[chan] = NULL;
164
	d->arec[chan] = NULL;
167
	d->arec[chan] = NULL;
165
	return 0;
168
	return 0;
Lines 173-180 Link Here
173
	if (!(d->flags & SD_F_PRIO_SET)) d->flags |= SD_F_PRIO_RD;
176
	if (!(d->flags & SD_F_PRIO_SET)) d->flags |= SD_F_PRIO_RD;
174
	if (!(d->flags & SD_F_DIR_SET)) setchns(d, chan);
177
	if (!(d->flags & SD_F_DIR_SET)) setchns(d, chan);
175
	getchns(d, chan, &rdch, &wrch);
178
	getchns(d, chan, &rdch, &wrch);
176
	if (!rdch || !(rdch->flags & CHN_F_BUSY))
179
	KASSERT(wrch, ("dsp_read: nonexistant channel"));
177
		panic("dsp_read: non%s channel", rdch? "busy" : "existant");
180
	KASSERT(wrch->flags & CHN_F_BUSY, ("dsp_read: nonbusy channel"));
178
	if (rdch->flags & CHN_F_MAPPED) return EINVAL;
181
	if (rdch->flags & CHN_F_MAPPED) return EINVAL;
179
	if (!(rdch->flags & CHN_F_RUNNING)) {
182
	if (!(rdch->flags & CHN_F_RUNNING)) {
180
		rdch->flags |= CHN_F_RUNNING;
183
		rdch->flags |= CHN_F_RUNNING;
Lines 191-198 Link Here
191
	if (!(d->flags & SD_F_PRIO_SET)) d->flags |= SD_F_PRIO_WR;
194
	if (!(d->flags & SD_F_PRIO_SET)) d->flags |= SD_F_PRIO_WR;
192
	if (!(d->flags & SD_F_DIR_SET)) setchns(d, chan);
195
	if (!(d->flags & SD_F_DIR_SET)) setchns(d, chan);
193
	getchns(d, chan, &rdch, &wrch);
196
	getchns(d, chan, &rdch, &wrch);
194
	if (!wrch || !(wrch->flags & CHN_F_BUSY))
197
	KASSERT(wrch, ("dsp_write: nonexistant channel"));
195
		panic("dsp_write: non%s channel", wrch? "busy" : "existant");
198
	KASSERT(wrch->flags & CHN_F_BUSY, ("dsp_write: nonbusy channel"));
196
	if (wrch->flags & CHN_F_MAPPED) return EINVAL;
199
	if (wrch->flags & CHN_F_MAPPED) return EINVAL;
197
	if (!(wrch->flags & CHN_F_RUNNING)) {
200
	if (!(wrch->flags & CHN_F_RUNNING)) {
198
		wrch->flags |= CHN_F_RUNNING;
201
		wrch->flags |= CHN_F_RUNNING;
Lines 519-525 Link Here
519
    	case SOUND_PCM_READ_FILTER:
522
    	case SOUND_PCM_READ_FILTER:
520
		/* dunno what these do, don't sound important */
523
		/* dunno what these do, don't sound important */
521
    	default:
524
    	default:
522
		DEB(printf("default ioctl snd%d fn 0x%08x fail\n", unit, cmd));
525
		DEB(printf("default ioctl chan%d fn 0x%08lx fail\n", chan, cmd));
523
		ret = EINVAL;
526
		ret = EINVAL;
524
		break;
527
		break;
525
    	}
528
    	}
(-)mss.c (-10 / +11 lines)
Lines 933-941 Link Here
933
		if (FULL_DUPLEX(mss)) ad_write(mss, 24, ~c); /* ack selectively */
933
		if (FULL_DUPLEX(mss)) ad_write(mss, 24, ~c); /* ack selectively */
934
		else io_wr(mss, MSS_STATUS, 0);	/* Clear interrupt status */
934
		else io_wr(mss, MSS_STATUS, 0);	/* Clear interrupt status */
935
    	}
935
    	}
936
    	if (i == 10) printf("mss_intr: irq, but not from mss\n");
936
    	if (i == 10) {
937
    	else if (served == 0) {
937
		BVDDB(printf("mss_intr: irq, but not from mss\n"));
938
		printf("mss_intr: unexpected irq with reason %x\n", c);
938
	} else if (served == 0) {
939
		BVDDB(printf("mss_intr: unexpected irq with reason %x\n", c));
939
		/*
940
		/*
940
	 	* this should not happen... I have no idea what to do now.
941
	 	* this should not happen... I have no idea what to do now.
941
	 	* maybe should do a sanity check and restart dmas ?
942
	 	* maybe should do a sanity check and restart dmas ?
Lines 1043-1049 Link Here
1043
    	u_char   prev;
1044
    	u_char   prev;
1044
1045
1045
    	if ((mss->bd_flags & BD_F_MCE_BIT) == 0) {
1046
    	if ((mss->bd_flags & BD_F_MCE_BIT) == 0) {
1046
		printf("--- hey, leave_MCE: MCE bit was not set!\n");
1047
		DEB(printf("--- hey, leave_MCE: MCE bit was not set!\n"));
1047
		return;
1048
		return;
1048
    	}
1049
    	}
1049
1050
Lines 1245-1252 Link Here
1245
        	ad_write(mss, 9, m);
1246
        	ad_write(mss, 9, m);
1246
        	if (ad_read(mss, 9) == m) break;
1247
        	if (ad_read(mss, 9) == m) break;
1247
    	}
1248
    	}
1248
    	if (retry == 0) printf("start dma, failed to set bit 0x%02x 0x%02x\n",
1249
    	if (retry == 0) BVDDB(printf("stop dma, failed to set bit 0x%02x 0x%02x\n", \
1249
			       m, ad_read(mss, 9));
1250
			       m, ad_read(mss, 9)));
1250
    	return 0;
1251
    	return 0;
1251
}
1252
}
1252
1253
Lines 1407-1413 Link Here
1407
#if 0
1408
#if 0
1408
    	reason = io_rd(mss, MSS_STATUS);
1409
    	reason = io_rd(mss, MSS_STATUS);
1409
    	if (!(reason & 1)) {/* no int, maybe a shared line ? */
1410
    	if (!(reason & 1)) {/* no int, maybe a shared line ? */
1410
		printf("intr: flag 0, mcir11 0x%02x\n", ad_read(mss, 11));
1411
		DEB(printf("intr: flag 0, mcir11 0x%02x\n", ad_read(mss, 11)));
1411
		return;
1412
		return;
1412
    	}
1413
    	}
1413
#endif
1414
#endif
Lines 1424-1431 Link Here
1424
		DEB(printf("Warning: MPU interrupt\n");)
1425
		DEB(printf("Warning: MPU interrupt\n");)
1425
		mc11 |= 0x20;
1426
		mc11 |= 0x20;
1426
    	}
1427
    	}
1427
    	if (mc11 & masked) printf("irq reset failed, mc11 0x%02x, 0x%02x\n",
1428
    	if (mc11 & masked) BVDDB(printf("irq reset failed, mc11 0x%02x, 0x%02x\n",\
1428
                              	  mc11, masked);
1429
                              	  mc11, masked));
1429
    	masked |= mc11;
1430
    	masked |= mc11;
1430
    	/*
1431
    	/*
1431
     	* the nice OPTi931 sets the IRQ line before setting the bits in
1432
     	* the nice OPTi931 sets the IRQ line before setting the bits in
Lines 1438-1444 Link Here
1438
	    		if (--loops) goto again;
1439
	    		if (--loops) goto again;
1439
	    		else DDB(printf("intr, but mc11 not set\n");)
1440
	    		else DDB(printf("intr, but mc11 not set\n");)
1440
		}
1441
		}
1441
		if (loops == 0) printf("intr, nothing in mcir11 0x%02x\n", mc11);
1442
		if (loops == 0) BVDDB(printf("intr, nothing in mcir11 0x%02x\n", mc11));
1442
		return;
1443
		return;
1443
    	}
1444
    	}

Return to bug 14990