patch-2.4.22 linux-2.4.22/drivers/sound/cs46xx.c

Next file: linux-2.4.22/drivers/sound/emu10k1/efxmgr.c
Previous file: linux-2.4.22/drivers/sound/cmpci.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/drivers/sound/cs46xx.c linux-2.4.22/drivers/sound/cs46xx.c
@@ -312,6 +312,9 @@
 	/* The cs461x has a certain amount of cross channel interaction
 	   so we use a single per card lock */
 	spinlock_t lock;
+	
+	/* Keep AC97 sane */
+	spinlock_t ac97_lock;
 
 	/* mixer use count */
 	atomic_t mixer_use_cnt;
@@ -947,8 +950,8 @@
 
 struct InitStruct
 {
-    u32 long off;
-    u32 long val;
+    u32 off;
+    u32 val;
 } InitArray[] = { {0x00000040, 0x3fc0000f},
                   {0x0000004c, 0x04800000},
 
@@ -3823,11 +3826,12 @@
 /* Write AC97 codec registers */
 
 
-static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg)
+static u16 _cs_ac97_get(struct ac97_codec *dev, u8 reg)
 {
 	struct cs_card *card = dev->private_data;
 	int count,loopcnt;
 	unsigned int tmp;
+	u16 ret;
 	
 	/*
 	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
@@ -3838,7 +3842,6 @@
 	 *  6. Read ACSTS = Status Register = 464h, check VSTS bit
 	 */
 
-
 	cs461x_peekBA0(card, BA0_ACSDA);
 
 	/*
@@ -3929,7 +3932,19 @@
 		"cs46xx: cs_ac97_get() reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", 
 			reg, cs461x_peekBA0(card, BA0_ACSDA),
 			cs461x_peekBA0(card, BA0_ACCAD)));
-	return(cs461x_peekBA0(card, BA0_ACSDA));
+	ret = cs461x_peekBA0(card, BA0_ACSDA);
+	return ret;
+}
+
+static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg)
+{
+	u16 ret;
+	struct cs_card *card = dev->private_data;
+	
+	spin_lock(&card->ac97_lock);
+	ret = _cs_ac97_get(dev, reg);
+	spin_unlock(&card->ac97_lock);
+	return ret;
 }
 
 static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
@@ -3938,11 +3953,14 @@
 	int count;
 	int val2 = 0;
 	
+	spin_lock(&card->ac97_lock);
+	
 	if(reg == AC97_CD_VOL)
 	{
-		val2 = cs_ac97_get(dev, AC97_CD_VOL);
+		val2 = _cs_ac97_get(dev, AC97_CD_VOL);
 	}
 	
+	
 	/*
 	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
 	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
@@ -3990,6 +4008,8 @@
 			"cs46xx: AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val));
 	}
 
+	spin_unlock(&card->ac97_lock);
+
 	/*
 	 *	Adjust power if the mixer is selected/deselected according
 	 *	to the CD.
@@ -4235,9 +4255,8 @@
 		"cs46xx: cs_ac97_init()+\n") );
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
-		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+		if ((codec = ac97_alloc_codec()) == NULL)
 			return -ENOMEM;
-		memset(codec, 0, sizeof(struct ac97_codec));
 
 		/* initialize some basic codec information, other fields will be filled
 		   in ac97_probe_codec */
@@ -4260,10 +4279,10 @@
 
 		eid = cs_ac97_get(codec, AC97_EXTENDED_ID);
 		
-		if(eid==0xFFFFFF)
+		if(eid==0xFFFF)
 		{
 			printk(KERN_WARNING "cs46xx: codec %d not present\n",num_ac97);
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 		
@@ -4271,7 +4290,7 @@
 			
 		if ((codec->dev_mixer = register_sound_mixer(&cs_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "cs46xx: couldn't register mixer!\n");
-			kfree(codec);
+			ac97_release_codec(codec);
 			break;
 		}
 		card->ac97_codec[num_ac97] = codec;
@@ -5311,6 +5330,7 @@
 	card->irq = pci_dev->irq;
 	card->magic = CS_CARD_MAGIC;
 	spin_lock_init(&card->lock);
+	spin_lock_init(&card->ac97_lock);
 
 	pci_set_master(pci_dev);
 
@@ -5438,7 +5458,7 @@
 			for (j = 0; j < NR_AC97; j++)
 				if (card->ac97_codec[j] != NULL) {
 					unregister_sound_mixer(card->ac97_codec[j]->dev_mixer);
-					kfree (card->ac97_codec[j]);
+					ac97_release_codec(card->ac97_codec[j]);
 				}
 			mdelay(10 * cs_laptop_wait);
 			continue;
@@ -5595,7 +5615,7 @@
 	for (i = 0; i < NR_AC97; i++)
 		if (card->ac97_codec[i] != NULL) {
 			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
-			kfree (card->ac97_codec[i]);
+			ac97_release_codec(card->ac97_codec[i]);
 		}
 	unregister_sound_dsp(card->dev_audio);
         if(card->dev_midi)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)