Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id ; Wed, 30 Oct 2002 09:04:03 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id ; Wed, 30 Oct 2002 09:04:03 -0500 Received: from ns.suse.de ([213.95.15.193]:21771 "EHLO Cantor.suse.de") by vger.kernel.org with ESMTP id ; Wed, 30 Oct 2002 09:03:59 -0500 Date: Wed, 30 Oct 2002 15:09:35 +0100 Message-ID: From: Takashi Iwai To: Josh Myer Cc: Subject: Re: [PATCH] sound/pci/via82xx.c "sleeping function called..." In-Reply-To: References: User-Agent: Wanderlust/2.6.1 (Upside Down) SEMI/1.14.4 (Hosorogi) FLIM/1.14.4 (=?ISO-8859-4?Q?Kashiharajing=FE-mae?=) APEL/10.2 MULE XEmacs/21.4 (patch 8) (Honest Recruiter) (i386-suse-linux) MIME-Version: 1.0 (generated by SEMI 1.14.4 - "Hosorogi") Content-Type: multipart/mixed; boundary="Multipart_Wed_Oct_30_15:09:35_2002-1" Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5155 Lines: 166 --Multipart_Wed_Oct_30_15:09:35_2002-1 Content-Type: text/plain; charset=US-ASCII Hi, At Tue, 29 Oct 2002 22:23:15 -0600 (CST), Josh Myer wrote: > > Attached is a patch which seems to cure these, but no promises that it's > Correct (!): thanks for spotting this bug. yes, the patch cures, but it may fail the allocation because of ATOMIC. could you try the attached patch? Takashi --Multipart_Wed_Oct_30_15:09:35_2002-1 Content-Type: application/octet-stream Content-Disposition: attachment; filename="via82xx-fix.dif" Content-Transfer-Encoding: 7bit --- linux/sound/pci/via82xx.c 22 Oct 2002 09:37:30 -0000 1.12 +++ linux/sound/pci/via82xx.c 30 Oct 2002 14:06:18 -0000 @@ -201,11 +201,16 @@ } viadev_t; +/* + * allocate and initialize the descriptor buffers + * periods = number of periods + * fragsize = period size in bytes + */ static int build_via_table(viadev_t *dev, snd_pcm_substream_t *substream, - struct pci_dev *pci) + struct pci_dev *pci, + int periods, int fragsize) { - int i, idx, ofs, rest, fragsize; - snd_pcm_runtime_t *runtime = substream->runtime; + int i, idx, ofs, rest; struct snd_sg_buf *sgbuf = snd_magic_cast(snd_pcm_sgbuf_t, substream->dma_private, return -EINVAL); if (! dev->table) { @@ -223,10 +228,9 @@ } /* fill the entries */ - fragsize = snd_pcm_lib_period_bytes(substream); idx = 0; ofs = 0; - for (i = 0; i < runtime->periods; i++) { + for (i = 0; i < periods; i++) { rest = fragsize; /* fill descriptors for a period. * a period can be split to several descriptors if it's @@ -241,7 +245,7 @@ r = rest; rest -= r; if (! rest) { - if (i == runtime->periods - 1) + if (i == periods - 1) flag = VIA_TBL_BIT_EOL; /* buffer boundary */ else flag = VIA_TBL_BIT_FLAG; /* period boundary */ @@ -472,19 +476,14 @@ } -static int snd_via82xx_setup_periods(via82xx_t *chip, viadev_t *viadev, - snd_pcm_substream_t *substream) +static int snd_via82xx_set_format(via82xx_t *chip, viadev_t *viadev, + snd_pcm_substream_t *substream) { snd_pcm_runtime_t *runtime = substream->runtime; unsigned long port = chip->port + viadev->reg_offset; - int err; snd_via82xx_channel_reset(chip, viadev); - err = build_via_table(viadev, substream, chip->pci); - if (err < 0) - return err; - outl((u32)viadev->table_addr, port + VIA_REG_OFFSET_TABLE_PTR); switch (chip->chip_type) { case TYPE_VIA686: @@ -583,11 +582,28 @@ static int snd_via82xx_hw_params(snd_pcm_substream_t * substream, snd_pcm_hw_params_t * hw_params) { - return snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params)); + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture; + int err; + + err = snd_pcm_sgbuf_alloc(substream, params_buffer_bytes(hw_params)); + if (err < 0) + return err; + err = build_via_table(viadev, substream, chip->pci, + params_periods(hw_params), + params_period_bytes(hw_params)); + if (err < 0) + return err; + return err; } static int snd_via82xx_hw_free(snd_pcm_substream_t * substream) { + via82xx_t *chip = snd_pcm_substream_chip(substream); + viadev_t *viadev = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? &chip->playback : &chip->capture; + + clean_via_table(viadev, substream, chip->pci); + snd_pcm_sgbuf_free(substream); return 0; } @@ -606,7 +622,7 @@ tmp = inl(VIAREG(chip, PLAYBACK_STOP_IDX)) & ~0xfffff; outl(tmp | (0xffff * runtime->rate)/(48000/16), VIAREG(chip, PLAYBACK_STOP_IDX)); } - return snd_via82xx_setup_periods(chip, &chip->playback, substream); + return snd_via82xx_set_format(chip, &chip->playback, substream); } static int snd_via82xx_capture_prepare(snd_pcm_substream_t * substream) @@ -617,7 +633,7 @@ snd_ac97_set_rate(chip->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate); if (chip->chip_type == TYPE_VIA8233) outb(VIA_REG_CAPTURE_FIFO_ENABLE, VIAREG(chip, CAPTURE_FIFO)); - return snd_via82xx_setup_periods(chip, &chip->capture, substream); + return snd_via82xx_set_format(chip, &chip->capture, substream); } static inline unsigned int snd_via82xx_cur_ptr(via82xx_t *chip, viadev_t *viadev) @@ -761,20 +777,16 @@ static int snd_via82xx_playback_close(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - - clean_via_table(&chip->playback, substream, chip->pci); - snd_pcm_sgbuf_delete(substream); chip->playback.substream = NULL; + snd_pcm_sgbuf_delete(substream); return 0; } static int snd_via82xx_capture_close(snd_pcm_substream_t * substream) { via82xx_t *chip = snd_pcm_substream_chip(substream); - - clean_via_table(&chip->capture, substream, chip->pci); - snd_pcm_sgbuf_delete(substream); chip->capture.substream = NULL; + snd_pcm_sgbuf_delete(substream); return 0; } --Multipart_Wed_Oct_30_15:09:35_2002-1-- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/