All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: "Tais M. Hansen" <tais.hansen@osd.dk>
Cc: alsa-devel@lists.sourceforge.net
Subject: Re: Re: [Alsa-user] Upgrade problems -addendum
Date: Mon, 27 Jan 2003 16:15:45 +0100	[thread overview]
Message-ID: <s5h3cneoc7y.wl@alsa2.suse.de> (raw)
In-Reply-To: <200301271542.48663.tais.hansen@osd.dk>

[-- Attachment #1: Type: text/plain, Size: 891 bytes --]

At Mon, 27 Jan 2003 15:42:43 +0100,
Tais M. Hansen <tais.hansen@osd.dk> wrote:
> 
> [1  <text/plain; iso-8859-1 (quoted-printable)>]
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> On Monday 27 January 2003 11:42, Takashi Iwai wrote:
> > > I just gave it another try with aplay. Bad idea; froze the system.
> > > Something's really wrong with the test8-patch.
> > ok.  now, i rewrote the patch completely again.
> > the module options was removed again.
> > here we go...
> 
> Ok. Hope you had a great weekend. :)
> 
> - - Fresh cvs update. Recompiled & installed alsa-lib and alsa-util.
> - - POINTER_DEBUG enabled.
> 
> No sound from aplay but it had a lot of complaints for me. Two files attached.

ok, the patch was buggy.
but any sounds must come out.  please check your mixer configuration.


the fixed patch below:  same as test9 but more verbose with POINTER_DEBUG.


Takashi

[-- Attachment #2: via-pointer-test10.dif --]
[-- Type: application/octet-stream, Size: 10515 bytes --]

Index: alsa-kernel/pci/via82xx.c
===================================================================
RCS file: /suse/tiwai/cvs/alsa/alsa-kernel/pci/via82xx.c,v
retrieving revision 1.21
diff -u -r1.21 via82xx.c
--- alsa-kernel/pci/via82xx.c	22 Jan 2003 14:21:05 -0000	1.21
+++ alsa-kernel/pci/via82xx.c	27 Jan 2003 15:12:46 -0000
@@ -88,7 +88,7 @@
 MODULE_PARM(mpu_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
 MODULE_PARM_DESC(mpu_port, "MPU-401 port.");
 MODULE_PARM_SYNTAX(mpu_port, SNDRV_PORT_DESC);
-MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
+MODULE_PARM(ac97_clock, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
 MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (default 48000Hz).");
 MODULE_PARM_SYNTAX(ac97_clock, SNDRV_ENABLED ",default:48000");
 
@@ -230,10 +230,13 @@
 	u32 *table; /* physical address + flag */
 	dma_addr_t table_addr;
 	struct snd_via_sg_table *idx_table;
+	int *period_idx;
+	unsigned int periods;
 	/* for recovery from the unexpected pointer */
+	unsigned int intr_cnt;
 	unsigned int lastpos;
+	unsigned int lastidx;
 	unsigned int bufsize;
-	unsigned int bufsize2;
 };
 
 
@@ -262,11 +265,17 @@
 		if (! dev->idx_table)
 			return -ENOMEM;
 	}
+	if (! dev->period_idx) {
+		dev->period_idx = kmalloc(sizeof(int) * VIA_TABLE_SIZE, GFP_KERNEL);
+		if (! dev->period_idx)
+			return -ENOMEM;
+	}
 
 	/* fill the entries */
 	idx = 0;
 	ofs = 0;
 	for (i = 0; i < periods; i++) {
+		dev->period_idx[i] = idx;
 		rest = fragsize;
 		/* fill descriptors for a period.
 		 * a period can be split to several descriptors if it's
@@ -302,7 +311,7 @@
 	}
 	dev->tbl_entries = idx;
 	dev->bufsize = periods * fragsize;
-	dev->bufsize2 = dev->bufsize / 2;
+	dev->periods = periods;
 	return 0;
 }
 
@@ -318,13 +327,18 @@
 		kfree(dev->idx_table);
 		dev->idx_table = NULL;
 	}
+	if (dev->period_idx) {
+		kfree(dev->period_idx);
+		dev->period_idx = NULL;
+	}
 }
 
 
 /*
  */
 
-enum { TYPE_VIA686 = 1, TYPE_VIA8233 };
+enum { TYPE_CARD_VIA686 = 1, TYPE_CARD_VIA8233 };
+enum { TYPE_VIA686, TYPE_VIA8233, TYPE_VIA8233A };
 
 #define VIA_MAX_DEVS	7	/* 4 playback, 1 multi, 2 capture */
 
@@ -365,8 +379,8 @@
 };
 
 static struct pci_device_id snd_via82xx_ids[] __devinitdata = {
-	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA686, },	/* 686A */
-	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_VIA8233, },	/* VT8233 */
+	{ 0x1106, 0x3058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA686, },	/* 686A */
+	{ 0x1106, 0x3059, PCI_ANY_ID, PCI_ANY_ID, 0, 0, TYPE_CARD_VIA8233, },	/* VT8233 */
 	{ 0, }
 };
 
@@ -481,10 +495,13 @@
 	/* disable interrupts */
 	outb(0x00, port + VIA_REG_OFFSET_CONTROL);
 	/* clear interrupts */
-	outb(0x03, port + VIA_REG_OFFSET_STATUS);
-	outb(0x00, port + VIA_REG_OFFSET_TYPE); /* for via686 */
+	outb(0x07, port + VIA_REG_OFFSET_STATUS);
+	if (chip->chip_type == TYPE_VIA686)
+		outb(0x00, port + VIA_REG_OFFSET_TYPE);
 	outl(0, port + VIA_REG_OFFSET_CURR_PTR);
 	viadev->lastpos = 0;
+	viadev->lastidx = 0;
+	viadev->intr_cnt = 0;
 }
 
 
@@ -512,10 +529,20 @@
 	/* check status for each stream */
 	for (i = 0; i < chip->num_devs; i++) {
 		viadev_t *viadev = &chip->devs[i];
-		if (inb(chip->port + viadev->reg_offset) & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG)) {
-			outb(VIA_REG_STAT_FLAG | VIA_REG_STAT_EOL, VIAREG(chip, OFFSET_STATUS) + viadev->reg_offset);
+		unsigned long port = chip->port + viadev->reg_offset; /* STATUS */
+		unsigned char status = inb(port) & 0x07;
+		if (! status)
+			continue;
+		outb(status, port); /* ack */
+		if (status & (VIA_REG_STAT_EOL|VIA_REG_STAT_FLAG)) {
 			if (viadev->substream && viadev->running) {
+				viadev->intr_cnt++;
+				if (viadev->intr_cnt >= viadev->periods)
+					viadev->intr_cnt = 0;
 				spin_unlock(&chip->reg_lock);
+#ifdef POINTER_DEBUG
+				snd_printd("period elapsed\n");
+#endif
 				snd_pcm_period_elapsed(viadev->substream);
 				spin_lock(&chip->reg_lock);
 			}
@@ -538,7 +565,7 @@
 	unsigned char val;
 	unsigned long port = chip->port + viadev->reg_offset;
 
-	if (chip->chip_type == TYPE_VIA8233)
+	if (chip->chip_type != TYPE_VIA686)
 		val = VIA_REG_CTRL_INT;
 	else
 		val = 0;
@@ -573,35 +600,76 @@
  */
 
 /*
+ * check whether the given index is within the current area
+ */
+static inline int out_of_intr_idx(viadev_t *viadev, unsigned int idx)
+{
+	unsigned int cnt;
+
+	if (idx < viadev->period_idx[viadev->intr_cnt])
+		return 1;
+	cnt = viadev->intr_cnt + 1;
+	if (cnt != viadev->periods && idx >= viadev->period_idx[cnt])
+		return 1;
+	return 0;
+}
+
+/*
  * calculate the linear position at the given sg-buffer index and the rest count
  */
-static inline unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
+static unsigned int calc_linear_pos(viadev_t *viadev, unsigned int idx, unsigned int count)
 {
 	unsigned int size, res;
 
 	size = viadev->idx_table[idx].size;
 	res = viadev->idx_table[idx].offset + size - count;
-
-	/* check the validity of the calculated position */
-	if (size < count || (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2))) {
 #ifdef POINTER_DEBUG
-		printk("fail: idx = %i/%i, lastpos = 0x%x, bufsize2 = 0x%x, offsize = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, viadev->lastpos, viadev->bufsize2, viadev->idx_table[idx].offset, viadev->idx_table[idx].size, count);
+	snd_printd("calc_linear_pos: idx = %i/%i, ptr = 0x%x, lastpos = 0x%x, size = 0x%x, count = 0x%x\n", idx, viadev->tbl_entries, res, viadev->lastpos, size, count);
 #endif
-		/* count register returns full size when end of buffer is reached */
-		if (size != count) {
-			snd_printd(KERN_ERR "invalid via82xx_cur_ptr, using last valid pointer\n");
-			res = viadev->lastpos;
-		} else {
-			res = viadev->idx_table[idx].offset + size;
-			if (res < viadev->lastpos && (res >= viadev->bufsize2 || viadev->lastpos < viadev->bufsize2)) {
-				snd_printd(KERN_ERR "invalid via82xx_cur_ptr (2), using last valid pointer\n");
-				res = viadev->lastpos;
+	if (count == 0) {
+		/* fully processed, increase the index */
+		if (++idx >= viadev->tbl_entries)
+			idx = 0;
+	}
+
+	if (out_of_intr_idx(viadev, idx)) {
+		if (size == count) {
+			/* count register returns full size when end of buffer is reached */
+			if (++idx >= viadev->tbl_entries)
+				idx = 0;
+			if (! out_of_intr_idx(viadev, idx)) {
+				res = viadev->idx_table[idx].offset;
+				goto _ok;
 			}
 		}
+		if (! out_of_intr_idx(viadev, viadev->lastidx)) {
+#ifdef POINTER_DEBUG
+			snd_printd("recover from last\n");
+#endif
+			return viadev->lastpos;
+		}
+		/* recover from the interrupt pointer */
+		idx = viadev->period_idx[viadev->intr_cnt];
+		res = viadev->idx_table[idx].offset;
+#ifdef POINTER_DEBUG
+		snd_printd("recover from intr: idx = %i, ptr = 0x%x\n", idx, res);
+#endif
+	} else if (res < viadev->lastpos) {
+		if (! out_of_intr_idx(viadev, viadev->lastidx)) {
+#ifdef POINTER_DEBUG
+			snd_printd("recover from last #2\n");
+#endif
+			return viadev->lastpos;
+		}
 	}
-	viadev->lastpos = res; /* remember the last positiion */
+ _ok:
 	if (res >= viadev->bufsize)
 		res -= viadev->bufsize;
+	viadev->lastidx = idx;
+	viadev->lastpos = res;
+#ifdef POINTER_DEBUG
+	snd_printd("get position: 0x%x, idx = %d\n", res, idx);
+#endif
 	return res;
 }
 
@@ -648,7 +716,7 @@
 		return 0;
 	spin_lock(&chip->reg_lock);
 	count = inl(VIAREG(chip, OFFSET_CURR_COUNT) + viadev->reg_offset);
-	idx = count >> 24;
+	idx = (count >> 24) & viadev->tbl_entries;
 	count &= 0xffffff;
 	res = calc_linear_pos(viadev, idx, count);
 	spin_unlock(&chip->reg_lock);
@@ -950,7 +1018,7 @@
 	if ((err = snd_via82xx_pcm_open(chip, viadev, substream)) < 0)
 		return err;
 	substream->runtime->hw.channels_max = 6;
-	if (chip->revision == VIA_REV_8233A)
+	if (chip->chip_type == TYPE_VIA8233A)
 		snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, &hw_constraints_channels);
 	return 0;
 }
@@ -1365,7 +1433,7 @@
 	int i, err, caps;
 	unsigned char val;
 
-	caps = chip->revision == VIA_REV_8233A ? 1 : 2;
+	caps = chip->chip_type == TYPE_VIA8233A ? 1 : 2;
 	for (i = 0; i < caps; i++) {
 		snd_via8233_capture_source.index = i;
 		err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_via8233_capture_source, chip));
@@ -1651,6 +1719,19 @@
 	return 0;
 }
 
+struct via823x_info {
+	int revision;
+	char *name;
+	int type;
+};
+static struct via823x_info via823x_cards[] __devinitdata = {
+	{ VIA_REV_PRE_8233, "VIA 8233-Pre", TYPE_VIA8233 },
+	{ VIA_REV_8233C, "VIA 8233C", TYPE_VIA8233 },
+	{ VIA_REV_8233, "VIA 8233", TYPE_VIA8233 },
+	{ VIA_REV_8233A, "VIA 8233A", TYPE_VIA8233A },
+	{ VIA_REV_8233, "VIA 8235", TYPE_VIA8233 },
+};
+
 static int __devinit snd_via82xx_probe(struct pci_dev *pci,
 				       const struct pci_device_id *pci_id)
 {
@@ -1658,7 +1739,7 @@
 	snd_card_t *card;
 	via82xx_t *chip;
 	unsigned char revision;
-	int chip_type;
+	int chip_type = 0, card_type;
 	int i, err;
 
 	if (dev >= SNDRV_CARDS)
@@ -1672,24 +1753,31 @@
 	if (card == NULL)
 		return -ENOMEM;
 
-	chip_type = pci_id->driver_data;
+	card_type = pci_id->driver_data;
 	pci_read_config_byte(pci, PCI_REVISION_ID, &revision);
-	switch (chip_type) {
-	case TYPE_VIA686:
+	switch (card_type) {
+	case TYPE_CARD_VIA686:
 		strcpy(card->driver, "VIA686A");
 		strcpy(card->shortname, "VIA 82C686A/B");
+		chip_type = TYPE_VIA686;
 		break;
-	case TYPE_VIA8233:
-		if (revision == VIA_REV_8233A) {
+	case TYPE_CARD_VIA8233:
+		chip_type = TYPE_VIA8233;
+		sprintf(card->shortname, "VIA 823x rev%d", revision);
+		for (i = 0; i < ARRAY_SIZE(via823x_cards); i++) {
+			if (revision == via823x_cards[i].revision) {
+				chip_type = via823x_cards[i].type;
+				strcpy(card->shortname, via823x_cards[i].name);
+				break;
+			}
+		}
+		if (chip_type == VIA_REV_8233A)
 			strcpy(card->driver, "VIA8233A");
-			strcpy(card->shortname, "VIA 8233A");
-		} else {
+		else
 			strcpy(card->driver, "VIA8233");
-			strcpy(card->shortname, "VIA 8233/C");
-		}
 		break;
 	default:
-		snd_printk(KERN_ERR "invalid chip type %d\n", chip_type);
+		snd_printk(KERN_ERR "invalid card type %d\n", card_type);
 		err = -EINVAL;
 		goto __error;
 	}
@@ -1705,7 +1793,7 @@
 		    (err = snd_via686_init_misc(chip, dev)) < 0)
 			goto __error;
 	} else {
-		if (revision == VIA_REV_8233A) {
+		if (chip_type == VIA_REV_8233A) {
 			if ((err = snd_via8233a_pcm_new(chip)) < 0)
 				goto __error;
 		} else {
@@ -1792,4 +1880,3 @@
 __setup("snd-via82xx=", alsa_card_via82xx_setup);
 
 #endif /* ifndef MODULE */
- 

  reply	other threads:[~2003-01-27 15:15 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <200301221234.33054.tais.hansen@osd.dk>
     [not found] ` <200301221543.52285.tais.hansen@osd.dk>
     [not found]   ` <s5hznpt1bn2.wl@alsa2.suse.de>
     [not found]     ` <200301221647.05780.tais.hansen@osd.dk>
2003-01-22 16:23       ` [Alsa-user] Upgrade problems -addendum Takashi Iwai
2003-01-23  0:35         ` Tais M. Hansen
2003-01-23 10:03           ` Takashi Iwai
2003-01-23 11:15             ` Tais M. Hansen
2003-01-23 11:46               ` Takashi Iwai
2003-01-23 12:36                 ` Tais M. Hansen
2003-01-23 15:08                   ` Takashi Iwai
2003-01-23 17:50                     ` Tais M. Hansen
2003-01-23 18:07                       ` Takashi Iwai
2003-01-23 18:43                         ` Tais M. Hansen
2003-01-24  9:12                           ` Takashi Iwai
2003-01-24 12:41                             ` Tais M. Hansen
2003-01-24 13:30                               ` Takashi Iwai
2003-01-24 14:12                                 ` Tais M. Hansen
2003-01-24 15:45                                   ` Takashi Iwai
2003-01-24 16:40                                     ` Tais M. Hansen
2003-01-24 17:08                                       ` Takashi Iwai
2003-01-24 21:24                                         ` Tais M. Hansen
2003-01-27 10:42                                           ` Takashi Iwai
2003-01-27 14:42                                             ` Tais M. Hansen
2003-01-27 15:15                                               ` Takashi Iwai [this message]
2003-01-27 17:01                                                 ` Tais M. Hansen
2003-01-27 17:27                                                   ` Takashi Iwai
2003-01-28  0:43                                                     ` VIA823x testing Tais M. Hansen
2003-01-28  9:31                                                       ` Takashi Iwai
2003-01-28 13:25                                                         ` Tais M. Hansen
2003-01-28 16:21                                                           ` Takashi Iwai
2003-01-28 23:19                                                             ` Tais M. Hansen
2003-01-24 16:42                                     ` Re: [Alsa-user] Upgrade problems -addendum Tais M. Hansen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=s5h3cneoc7y.wl@alsa2.suse.de \
    --to=tiwai@suse.de \
    --cc=alsa-devel@lists.sourceforge.net \
    --cc=tais.hansen@osd.dk \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.