patch-2.4.27 linux-2.4.27/drivers/sound/msnd_pinnacle.c
Next file: linux-2.4.27/drivers/sound/pss.c
Previous file: linux-2.4.27/drivers/sound/msnd.h
Back to the patch index
Back to the overall index
- Lines: 185
- Date:
2004-08-07 16:26:05.561384046 -0700
- Orig file:
linux-2.4.26/drivers/sound/msnd_pinnacle.c
- Orig date:
2002-08-02 17:39:44.000000000 -0700
diff -urN linux-2.4.26/drivers/sound/msnd_pinnacle.c linux-2.4.27/drivers/sound/msnd_pinnacle.c
@@ -804,7 +804,7 @@
static __inline__ int pack_DARQ_to_DARF(register int bank)
{
- register int size, n, timeout = 3;
+ register int size, timeout = 3;
register WORD wTmp;
LPDAQD DAQD;
@@ -825,13 +825,10 @@
/* Read data from the head (unprotected bank 1 access okay
since this is only called inside an interrupt) */
outb(HPBLKSEL_1, dev.io + HP_BLKS);
- if ((n = msnd_fifo_write(
+ msnd_fifo_write(
&dev.DARF,
(char *)(dev.base + bank * DAR_BUFF_SIZE),
- size, 0)) <= 0) {
- outb(HPBLKSEL_0, dev.io + HP_BLKS);
- return n;
- }
+ size);
outb(HPBLKSEL_0, dev.io + HP_BLKS);
return 1;
@@ -853,21 +850,16 @@
if (protect) {
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_read(
+ n = msnd_fifo_read(
&dev.DAPF,
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
- DAP_BUFF_SIZE, 0)) < 0) {
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ DAP_BUFF_SIZE);
spin_unlock_irqrestore(&dev.lock, flags);
} else {
- if ((n = msnd_fifo_read(
+ n = msnd_fifo_read(
&dev.DAPF,
(char *)(dev.base + bank_num * DAP_BUFF_SIZE),
- DAP_BUFF_SIZE, 0)) < 0) {
- return n;
- }
+ DAP_BUFF_SIZE);
}
if (!n)
break;
@@ -894,30 +886,43 @@
static int dsp_read(char *buf, size_t len)
{
int count = len;
+ char *page = (char *)__get_free_page(PAGE_SIZE);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
- int n;
+ int n, k;
unsigned long flags;
+ k = PAGE_SIZE;
+ if (k > count)
+ k = count;
+
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_read(&dev.DARF, buf, count, 1)) < 0) {
- printk(KERN_WARNING LOGNAME ": FIFO read error\n");
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ n = msnd_fifo_read(&dev.DARF, page, k);
spin_unlock_irqrestore(&dev.lock, flags);
+ if (copy_to_user(buf, page, n)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
buf += n;
count -= n;
+ if (n == k && count)
+ continue;
+
if (!test_bit(F_READING, &dev.flags) && dev.mode & FMODE_READ) {
dev.last_recbank = -1;
if (chk_send_dsp_cmd(&dev, HDEX_RECORD_START) == 0)
set_bit(F_READING, &dev.flags);
}
- if (dev.rec_ndelay)
+ if (dev.rec_ndelay) {
+ free_page((unsigned long)page);
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_READBLOCK, &dev.flags);
@@ -926,41 +931,57 @@
get_rec_delay_jiffies(DAR_BUFF_SIZE)))
clear_bit(F_READING, &dev.flags);
clear_bit(F_READBLOCK, &dev.flags);
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ free_page((unsigned long)page);
return -EINTR;
+ }
}
}
-
+ free_page((unsigned long)page);
return len - count;
}
static int dsp_write(const char *buf, size_t len)
{
int count = len;
+ char *page = (char *)__get_free_page(GFP_KERNEL);
+
+ if (!page)
+ return -ENOMEM;
while (count > 0) {
- int n;
+ int n, k;
unsigned long flags;
+ k = PAGE_SIZE;
+ if (k > count)
+ k = count;
+
+ if (copy_from_user(page, buf, k)) {
+ free_page((unsigned long)page);
+ return -EFAULT;
+ }
+
/* Critical section: protect fifo in non-interrupt */
spin_lock_irqsave(&dev.lock, flags);
- if ((n = msnd_fifo_write(&dev.DAPF, buf, count, 1)) < 0) {
- printk(KERN_WARNING LOGNAME ": FIFO write error\n");
- spin_unlock_irqrestore(&dev.lock, flags);
- return n;
- }
+ n = msnd_fifo_write(&dev.DAPF, page, k);
spin_unlock_irqrestore(&dev.lock, flags);
buf += n;
count -= n;
+ if (count && n == k)
+ continue;
+
if (!test_bit(F_WRITING, &dev.flags) && (dev.mode & FMODE_WRITE)) {
dev.last_playbank = -1;
if (pack_DAPF_to_DAPQ(1) > 0)
set_bit(F_WRITING, &dev.flags);
}
- if (dev.play_ndelay)
+ if (dev.play_ndelay) {
+ free_page((unsigned long)page);
return count == len ? -EAGAIN : len - count;
+ }
if (count > 0) {
set_bit(F_WRITEBLOCK, &dev.flags);
@@ -968,11 +989,14 @@
&dev.writeblock,
get_play_delay_jiffies(DAP_BUFF_SIZE));
clear_bit(F_WRITEBLOCK, &dev.flags);
- if (signal_pending(current))
+ if (signal_pending(current)) {
+ free_page((unsigned long)page);
return -EINTR;
+ }
}
}
+ free_page((unsigned long)page);
return len - count;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)