if(combbuf) kfree(combbuf); 
kfree(combbuf); 
ess_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos){	struct ess_state *s = (struct ess_state *)file->private_data;	ssize_t ret;	unsigned long flags;	unsigned swptr;	int cnt;	unsigned char *combbuf = NULL;		VALIDATE_STATE(s);	if (s->dma_adc.mapped)		return -ENXIO;	if (!s->dma_adc.ready && (ret = prog_dmabuf(s, 1)))		return ret;	if (!access_ok(VERIFY_WRITE, buffer, count))		return -EFAULT;	if(!(combbuf = kmalloc(count,GFP_KERNEL)))		return -ENOMEM;	ret = 0;	calc_bob_rate(s);	while (count > 0) {		spin_lock_irqsave(&s->lock, flags);		/* remember, all these things are expressed in bytes to be			sent to the user.. hence the evil / 2 down below */		swptr = s->dma_adc.swptr;		cnt = s->dma_adc.dmasize-swptr;		if (s->dma_adc.count < cnt)			cnt = s->dma_adc.count;		spin_unlock_irqrestore(&s->lock, flags);		if (cnt > count)			cnt = count;		if ( cnt > 0 ) cnt &= ~3;		if (cnt <= 0) {			start_adc(s);			if (file->f_flags & O_NONBLOCK) 			{				ret = ret ? ret : -EAGAIN;				goto rec_return_free;			}			if (!interruptible_sleep_on_timeout(&s->dma_adc.wait, HZ)) {				if(! s->card->in_suspend) printk(KERN_DEBUG "maestro: read: chip lockup? dmasz %u fragsz %u count %i hwptr %u swptr %u\n",				       s->dma_adc.dmasize, s->dma_adc.fragsize, s->dma_adc.count, 				       s->dma_adc.hwptr, s->dma_adc.swptr);				stop_adc(s);				spin_lock_irqsave(&s->lock, flags);				set_dmac(s, virt_to_bus(s->dma_adc.rawbuf), s->dma_adc.numfrag << s->dma_adc.fragshift);				/* program enhanced mode registers */				/* FILL ME *//*				wrindir(s, SV_CIDMACBASECOUNT1, (s->dma_adc.fragsamples-1) >> 8);				wrindir(s, SV_CIDMACBASECOUNT0, s->dma_adc.fragsamples-1); */				s->dma_adc.count = s->dma_adc.hwptr = s->dma_adc.swptr = 0;				spin_unlock_irqrestore(&s->lock, flags);			}			if (signal_pending(current)) 			{				ret = ret ? ret : -ERESTARTSYS;				goto rec_return_free;			}			continue;		}			if(s->fmt & (ESS_FMT_STEREO << ESS_ADC_SHIFT)) {			/* swptr/2 so that we know the real offset in each apu's buffer */			comb_stereo(s->dma_adc.rawbuf,combbuf,swptr/2,cnt,s->dma_adc.dmasize);			if (copy_to_user(buffer, combbuf, cnt)) {				ret = ret ? ret : -EFAULT;				goto rec_return_free;			}		} else  {			if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt)) {				ret = ret ? ret : -EFAULT;				goto rec_return_free;			}		}		swptr = (swptr + cnt) % s->dma_adc.dmasize;		spin_lock_irqsave(&s->lock, flags);		s->dma_adc.swptr = swptr;		s->dma_adc.count -= cnt;		spin_unlock_irqrestore(&s->lock, flags);		count -= cnt;		buffer += cnt;		ret += cnt;		start_adc(s);	}rec_return_free:	if(combbuf) kfree(combbuf);	return ret;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/09417379be9b126e10ae7dcd7afc20b666146266/maestro.c/buggy/sound/oss/maestro.c