From owner-freebsd-multimedia Thu Aug 23 10:44: 2 2001 Delivered-To: freebsd-multimedia@freebsd.org Received: from mail.katsurajima.seya.yokohama.jp (mail.katsurajima.seya.yokohama.jp [210.164.211.67]) by hub.freebsd.org (Postfix) with ESMTP id D240E37B408 for ; Thu, 23 Aug 2001 10:43:44 -0700 (PDT) (envelope-from raven@katsurajima.seya.yokohama.jp) Received: from monster.katsurajima.seya.yokohama.jp (gw-global.katsurajima.seya.yokohama.jp [192.168.2.3]) by mail.katsurajima.seya.yokohama.jp (Postfix) with ESMTP id 8CEAA1D8C08; Fri, 24 Aug 2001 02:43:42 +0900 (JST) Received: from zenchan.katsurajima.seya.yokohama.jp (zenchan [192.168.1.3]) by monster.katsurajima.seya.yokohama.jp (8.9.3/3.7W05/05/99) with SMTP id CAA51898; Fri, 24 Aug 2001 02:43:42 +0900 (JST) Date: Fri, 24 Aug 2001 02:43:18 +0900 From: Katsurajima Naoto To: FreeBSD-multimedia@FreeBSD.ORG Cc: freebsd-users-jp@jp.FreeBSD.ORG Subject: 4.4-RC ich sound driver bug fix Message-Id: <20010824024318.13add558.raven@katsurajima.seya.yokohama.jp> X-Mailer: Sylpheed version 0.4.66 (GTK+ 1.2.10; i386--freebsd5.0) Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-2022-JP Content-Transfer-Encoding: 7bit Sender: owner-freebsd-multimedia@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org Hellow. I fixed sound driver for Intel ICH AC'97. Changed points are - FIFO buffer control method is now been strict. By this change, CPU and DMA are never conflict on same buffer block. Many troubles are occured by this conflict. - Not use ICH's PICB(Position In Current Buffer) function for getting hardware pointer. This function seems to be buggy, and not only untrused on the value, but also getting trouble. On the other hand, this driver cannot check playing position under block size. But many case, this is not so big problem. - and few little fixes I checked this driver with xmms, xine, rollemup and timidity++. Under first 3 programs, there is no problem and very stable on my notebook PC(Toshiba DynaBookSS3440). But timidity++ plays with crick noise.(I have not checked yet why) It may be better to reboot by power off/on than by reboot command, after attemp patch and rebuild kernel. It is because of clearing illeagal condition caused by old driver. This patch is tested only on 4.4-RC. But may work on -CURRENT. Please check it. -- Katsurajima "Raven" Naoto(桂島 直人) Family Emblem: Circle and Left 3 Clove-TOMOE(丸に左三つ丁子巴) e-mail: raven@katsurajima.seya.yokohama.jp --- cut here *** sys/dev/sound/pci/ich.c.orig Wed Aug 1 14:37:30 2001 --- sys/dev/sound/pci/ich.c Thu Aug 23 10:32:55 2001 *************** *** 53,58 **** --- 53,59 ---- u_int32_t num, run; u_int32_t blksz, blkcnt; u_int32_t regbase, spdreg; + u_int32_t civ; struct snd_dbuf *buffer; struct pcm_channel *channel; *************** *** 296,302 **** ch->blksz = blocksize; ich_filldtbl(ch); ! ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ICH_DTBL_LENGTH - 1, 1); return ch->blksz; } --- 297,303 ---- ch->blksz = blocksize; ich_filldtbl(ch); ! ich_wr(sc, ch->regbase + ICH_REG_X_LVI, ch->blkcnt - 1, 1); return ch->blksz; } *************** *** 306,311 **** --- 307,313 ---- { struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; + u_int32_t st; switch (go) { case PCMTRIG_START: *************** *** 314,319 **** --- 316,327 ---- ich_wr(sc, ch->regbase + ICH_REG_X_CR, ICH_X_CR_RPBM | ICH_X_CR_LVBIE | ICH_X_CR_IOCE | ICH_X_CR_FEIE, 1); break; + case PCMTRIG_STOP: + ch->run = 0; + st = ich_rd(sc, ch->regbase + ICH_REG_X_CR, 1); + ich_wr(sc, ch->regbase + ICH_REG_X_CR, st & ~ICH_X_CR_RPBM, 1); + break; + case PCMTRIG_ABORT: ich_resetchan(sc, ch->num); ch->run = 0; *************** *** 327,344 **** { struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; ! u_int32_t ci, ofs, pos; - ofs = 0; ci = 1234; ! while (ci != ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1)) { ci = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1); - ofs = ich_rd(sc, ch->regbase + ICH_REG_X_PICB, 2) * 2; - } ! ofs = ch->blksz - ofs; ci %= ch->blkcnt; ! pos = (ch->blksz * ci) + ofs; return pos; } --- 335,349 ---- { struct sc_chinfo *ch = data; struct sc_info *sc = ch->parent; ! u_int32_t ci, pos; ci = 1234; ! while (ci != ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1)) ci = ich_rd(sc, ch->regbase + ICH_REG_X_CIV, 1); ! ch->civ = ci; ci %= ch->blkcnt; ! pos = ch->blksz * ci; return pos; } *************** *** 371,377 **** { struct sc_info *sc = (struct sc_info *)p; struct sc_chinfo *ch; ! u_int32_t st, lvi; int i; for (i = 0; i < 3; i++) { --- 376,382 ---- { struct sc_info *sc = (struct sc_info *)p; struct sc_chinfo *ch; ! u_int32_t st, lvi, cbi, lbi; int i; for (i = 0; i < 3; i++) { *************** *** 385,391 **** if (ch->run) chn_intr(ch->channel); lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1); ! lvi++; lvi %= ICH_DTBL_LENGTH; ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1); } --- 390,405 ---- if (ch->run) chn_intr(ch->channel); lvi = ich_rd(sc, ch->regbase + ICH_REG_X_LVI, 1); ! cbi = ch->civ % ch->blkcnt; ! if (cbi == 0) ! cbi = ch->blkcnt - 1; ! else ! cbi--; ! lbi = lvi % ch->blkcnt; ! if (cbi >= lbi) ! lvi += cbi - lbi; ! else ! lvi += cbi + ch->blkcnt - lbi; lvi %= ICH_DTBL_LENGTH; ich_wr(sc, ch->regbase + ICH_REG_X_LVI, lvi, 1); } *************** *** 419,425 **** ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4); ! if (ich_resetchan(sc, 0) || ich_resetchan(sc, 0)) return ENXIO; if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap)) --- 433,439 ---- ich_wr(sc, ICH_REG_GLOB_CNT, ICH_GLOB_CTL_COLD | ICH_GLOB_CTL_PRES, 4); ! if (ich_resetchan(sc, 0) || ich_resetchan(sc, 1)) return ENXIO; if (bus_dmamem_alloc(sc->dmat, (void **)&sc->dtbl, BUS_DMA_NOWAIT, &sc->dtmap)) *************** *** 475,481 **** sc->dev = dev; data = pci_read_config(dev, PCIR_COMMAND, 2); ! data |= (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN | PCIM_CMD_BUSMASTEREN); pci_write_config(dev, PCIR_COMMAND, data, 2); data = pci_read_config(dev, PCIR_COMMAND, 2); --- 489,495 ---- sc->dev = dev; data = pci_read_config(dev, PCIR_COMMAND, 2); ! data |= (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN); pci_write_config(dev, PCIR_COMMAND, data, 2); data = pci_read_config(dev, PCIR_COMMAND, 2); *************** *** 494,500 **** sc->nabmbart = rman_get_bustag(sc->nabmbar); sc->nabmbarh = rman_get_bushandle(sc->nabmbar); ! if (bus_dma_tag_create(NULL, 4, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ICH_DEFAULT_BUFSZ, 1, 0x3ffff, 0, &sc->dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto bad; --- 508,514 ---- sc->nabmbart = rman_get_bustag(sc->nabmbar); sc->nabmbarh = rman_get_bushandle(sc->nabmbar); ! if (bus_dma_tag_create(NULL, 8, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ICH_DEFAULT_BUFSZ, 1, 0x3ffff, 0, &sc->dmat) != 0) { device_printf(dev, "unable to create dma tag\n"); goto bad; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-multimedia" in the body of the message