summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1997-06-17 13:20:30 +0000
committerRalf Baechle <ralf@linux-mips.org>1997-06-17 13:20:30 +0000
commit7acb77a6e7bddd4c4c5aa975bbf976927c013798 (patch)
tree4139829ec6edb85f73774bb95cdec376758bfc73 /drivers
parent64d58d4c8cd6a89ee218301ec0dc0ebfec91a4db (diff)
Merge with 2.1.43.
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ap1000/ringbuf.c1
-rw-r--r--drivers/block/genhd.c141
-rw-r--r--drivers/block/ide.c40
-rw-r--r--drivers/block/ide.h2
-rw-r--r--drivers/block/loop.c2
-rw-r--r--drivers/block/md.c5
-rw-r--r--drivers/char/Makefile3
-rw-r--r--drivers/char/atarimouse.c2
-rw-r--r--drivers/char/console.c10
-rw-r--r--drivers/char/console_struct.h141
-rw-r--r--drivers/char/consolemap.c2
-rw-r--r--drivers/char/consolemap.h14
-rw-r--r--drivers/char/diacr.h8
-rw-r--r--drivers/char/dsp56k.c7
-rw-r--r--drivers/char/fbmem.c2
-rw-r--r--drivers/char/kbd_kern.h141
-rw-r--r--drivers/char/keyboard.c37
-rw-r--r--drivers/char/lp_m68k.c1
-rw-r--r--drivers/char/mem.c97
-rw-r--r--drivers/char/misc.c4
-rw-r--r--drivers/char/pc_keyb.c448
-rw-r--r--drivers/char/pc_keyb.h107
-rw-r--r--drivers/char/rtc.c62
-rw-r--r--drivers/char/selection.c14
-rw-r--r--drivers/char/selection.h283
-rw-r--r--drivers/char/softdog.c4
-rw-r--r--drivers/char/sysrq.c248
-rw-r--r--drivers/char/tga.c10
-rw-r--r--drivers/char/tty_io.c6
-rw-r--r--drivers/char/vc_screen.c4
-rw-r--r--drivers/char/vga.c10
-rw-r--r--drivers/char/vt.c8
-rw-r--r--drivers/char/vt_kern.h39
-rw-r--r--drivers/isdn/hisax/callc.c8
-rw-r--r--drivers/net/Config.in9
-rw-r--r--drivers/net/arcnet.c4
-rw-r--r--drivers/net/baycom.c12
-rw-r--r--drivers/net/defxx.c50
-rw-r--r--drivers/net/hdlcdrv.c22
-rw-r--r--drivers/net/net_init.c2
-rw-r--r--drivers/net/soundmodem/Makefile9
-rw-r--r--drivers/net/soundmodem/gentbl.c291
-rw-r--r--drivers/net/soundmodem/sm.c92
-rw-r--r--drivers/net/soundmodem/sm.h63
-rw-r--r--drivers/net/soundmodem/sm_afsk1200.c249
-rw-r--r--drivers/net/soundmodem/sm_afsk2400_7.c297
-rw-r--r--drivers/net/soundmodem/sm_afsk2400_8.c297
-rw-r--r--drivers/net/soundmodem/sm_fsk9600.c236
-rw-r--r--drivers/net/soundmodem/sm_hapn4800.c443
-rw-r--r--drivers/net/soundmodem/sm_sbc.c326
-rw-r--r--drivers/net/soundmodem/sm_wss.c399
-rw-r--r--drivers/net/soundmodem/smdma.h210
-rw-r--r--drivers/pci/pci.c48
-rw-r--r--drivers/sbus/char/bwtwo.c12
-rw-r--r--drivers/sbus/char/cgfourteen.c11
-rw-r--r--drivers/sbus/char/cgsix.c11
-rw-r--r--drivers/sbus/char/cgthree.c11
-rw-r--r--drivers/sbus/char/creator.c7
-rw-r--r--drivers/sbus/char/leo.c11
-rw-r--r--drivers/sbus/char/suncons.c12
-rw-r--r--drivers/sbus/char/sunfb.c12
-rw-r--r--drivers/sbus/char/sunkbd.c6
-rw-r--r--drivers/sbus/char/tcx.c11
-rw-r--r--drivers/sbus/char/vfc_dev.c2
-rw-r--r--drivers/sbus/char/weitek.c11
-rw-r--r--drivers/scsi/amiga7xx.c16
-rw-r--r--drivers/scsi/g_NCR5380.c5
-rw-r--r--drivers/scsi/script_asm.pl70
-rw-r--r--drivers/sound/dmabuf.c2
-rw-r--r--drivers/sound/soundcard.c2
70 files changed, 3269 insertions, 1913 deletions
diff --git a/drivers/ap1000/ringbuf.c b/drivers/ap1000/ringbuf.c
index b8bcbb541..ee33a03d4 100644
--- a/drivers/ap1000/ringbuf.c
+++ b/drivers/ap1000/ringbuf.c
@@ -318,7 +318,6 @@ struct inode_operations proc_ringbuf_inode_operations = {
NULL, /* mknod */
NULL, /* rename */
NULL, /* readlink */
- NULL, /* follow_link */
NULL, /* readpage */
NULL, /* writepage */
NULL, /* bmap */
diff --git a/drivers/block/genhd.c b/drivers/block/genhd.c
index ad0e79b1b..0217dcb52 100644
--- a/drivers/block/genhd.c
+++ b/drivers/block/genhd.c
@@ -380,7 +380,7 @@ check_table:
&& (q->sector & 63) == 1
&& (q->end_sector & 63) == 63) {
unsigned int heads = q->end_head + 1;
- if (heads == 32 || heads == 64 || heads == 128) {
+ if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {
(void) ide_xlate_1024(dev, heads, " [PTBL]");
break;
@@ -740,6 +740,141 @@ rdb_done:
}
#endif /* CONFIG_AMIGA_PARTITION */
+#ifdef CONFIG_ATARI_PARTITION
+#include <asm/atari_rootsec.h>
+
+/* ++guenther: this should be settable by the user ("make config")?.
+ */
+#define ICD_PARTS
+
+static int atari_partition (struct gendisk *hd, kdev_t dev,
+ unsigned long first_sector)
+{
+ int minor = current_minor, m_lim = current_minor + hd->max_p;
+ struct buffer_head *bh;
+ struct rootsector *rs;
+ struct partition_info *pi;
+ ulong extensect;
+#ifdef ICD_PARTS
+ int part_fmt = 0; /* 0:unknown, 1:AHDI, 2:ICD/Supra */
+#endif
+
+ bh = bread (dev, 0, get_ptable_blocksize(dev));
+ if (!bh)
+ {
+ printk (" unable to read block 0\n");
+ return -1;
+ }
+
+ rs = (struct rootsector *) bh->b_data;
+ pi = &rs->part[0];
+ printk (" AHDI");
+ for (; pi < &rs->part[4] && minor < m_lim; minor++, pi++)
+ {
+ if (pi->flg & 1)
+ /* active partition */
+ {
+ if (memcmp (pi->id, "XGM", 3) == 0)
+ /* extension partition */
+ {
+ struct rootsector *xrs;
+ struct buffer_head *xbh;
+ ulong partsect;
+
+#ifdef ICD_PARTS
+ part_fmt = 1;
+#endif
+ printk(" XGM<");
+ partsect = extensect = pi->st;
+ while (1)
+ {
+ xbh = bread (dev, partsect / 2, 1024);
+ if (!xbh)
+ {
+ printk (" block %ld read failed\n", partsect);
+ brelse(bh);
+ return 0;
+ }
+ if (partsect & 1)
+ xrs = (struct rootsector *) &xbh->b_data[512];
+ else
+ xrs = (struct rootsector *) &xbh->b_data[0];
+
+ /* ++roman: sanity check: bit 0 of flg field must be set */
+ if (!(xrs->part[0].flg & 1)) {
+ printk( "\nFirst sub-partition in extended partition is not valid!\n" );
+ break;
+ }
+
+ add_partition(hd, minor, partsect + xrs->part[0].st,
+ xrs->part[0].siz);
+
+ if (!(xrs->part[1].flg & 1)) {
+ /* end of linked partition list */
+ brelse( xbh );
+ break;
+ }
+ if (memcmp( xrs->part[1].id, "XGM", 3 ) != 0) {
+ printk( "\nID of extended partition is not XGM!\n" );
+ brelse( xbh );
+ break;
+ }
+
+ partsect = xrs->part[1].st + extensect;
+ brelse (xbh);
+ minor++;
+ if (minor >= m_lim) {
+ printk( "\nMaximum number of partitions reached!\n" );
+ break;
+ }
+ }
+ printk(" >");
+ }
+ else
+ {
+ /* we don't care about other id's */
+ add_partition (hd, minor, pi->st, pi->siz);
+ }
+ }
+ }
+#ifdef ICD_PARTS
+ if ( part_fmt!=1 ) /* no extended partitions -> test ICD-format */
+ {
+ pi = &rs->icdpart[0];
+ /* sanity check: no ICD format if first partition invalid */
+ if (memcmp (pi->id, "GEM", 3) == 0 ||
+ memcmp (pi->id, "BGM", 3) == 0 ||
+ memcmp (pi->id, "LNX", 3) == 0 ||
+ memcmp (pi->id, "SWP", 3) == 0 ||
+ memcmp (pi->id, "RAW", 3) == 0 )
+ {
+ printk(" ICD<");
+ for (; pi < &rs->icdpart[8] && minor < m_lim; minor++, pi++)
+ {
+ /* accept only GEM,BGM,RAW,LNX,SWP partitions */
+ if (pi->flg & 1 &&
+ (memcmp (pi->id, "GEM", 3) == 0 ||
+ memcmp (pi->id, "BGM", 3) == 0 ||
+ memcmp (pi->id, "LNX", 3) == 0 ||
+ memcmp (pi->id, "SWP", 3) == 0 ||
+ memcmp (pi->id, "RAW", 3) == 0) )
+ {
+ part_fmt = 2;
+ add_partition (hd, minor, pi->st, pi->siz);
+ }
+ }
+ printk(" >");
+ }
+ }
+#endif
+ brelse (bh);
+
+ printk ("\n");
+
+ return 1;
+}
+#endif /* CONFIG_ATARI_PARTITION */
+
static void check_partition(struct gendisk *hd, kdev_t dev)
{
static int first_time = 1;
@@ -777,6 +912,10 @@ static void check_partition(struct gendisk *hd, kdev_t dev)
if(amiga_partition(hd, dev, first_sector))
return;
#endif
+#ifdef CONFIG_ATARI_PARTITION
+ if(atari_partition(hd, dev, first_sector))
+ return;
+#endif
#ifdef CONFIG_SGI_PARTITION
if(sgi_partition(hd, dev, first_sector))
return;
diff --git a/drivers/block/ide.c b/drivers/block/ide.c
index 89759dd32..1b293c539 100644
--- a/drivers/block/ide.c
+++ b/drivers/block/ide.c
@@ -1,5 +1,5 @@
/*
- * linux/drivers/block/ide.c Version 6.02 Mar 11, 1997
+ * linux/drivers/block/ide.c Version 6.03 June 4, 1997
*
* Copyright (C) 1994-1997 Linus Torvalds & authors (see below)
*/
@@ -280,6 +280,7 @@
* support HDIO_GETGEO for floppies
* Version 6.02 fix ide_ack_intr() call
* check partition table on floppies
+ * Version 6.03 handle bad status bit sequencing in ide_wait_stat()
*
* Some additional driver compile-time options are in ide.h
*
@@ -1044,27 +1045,24 @@ int ide_wait_stat (ide_drive_t *drive, byte good, byte bad, unsigned long timeou
byte stat;
unsigned long flags;
-test:
- udelay(1); /* spec allows drive 400ns to change "BUSY" */
- if (OK_STAT((stat = GET_STAT()), good, bad))
- return 0; /* fast exit for most frequent case */
- if (!(stat & BUSY_STAT)) {
- ide_error(drive, "status error", stat);
- return 1;
- }
-
- save_flags(flags);
- ide_sti();
- timeout += jiffies;
- do {
- if (!((stat = GET_STAT()) & BUSY_STAT)) {
- restore_flags(flags);
- goto test;
+ udelay(1); /* spec allows drive 400ns to assert "BUSY" */
+ if ((stat = GET_STAT()) & BUSY_STAT) {
+ save_flags(flags);
+ ide_sti();
+ timeout += jiffies;
+ while ((stat = GET_STAT()) & BUSY_STAT) {
+ if (jiffies > timeout) {
+ restore_flags(flags);
+ ide_error(drive, "status timeout", stat);
+ return 1;
+ }
}
- } while (jiffies <= timeout);
-
- restore_flags(flags);
- ide_error(drive, "status timeout", GET_STAT());
+ restore_flags(flags);
+ }
+ udelay(1); /* allow status to settle, then read it again */
+ if (OK_STAT((stat = GET_STAT()), good, bad))
+ return 0;
+ ide_error(drive, "status error", stat);
return 1;
}
diff --git a/drivers/block/ide.h b/drivers/block/ide.h
index 241a571ca..95724e6e9 100644
--- a/drivers/block/ide.h
+++ b/drivers/block/ide.h
@@ -134,7 +134,7 @@ typedef unsigned char byte; /* used everywhere */
#define BAD_W_STAT (BAD_R_STAT | WRERR_STAT)
#define BAD_STAT (BAD_R_STAT | DRQ_STAT)
#define DRIVE_READY (READY_STAT | SEEK_STAT)
-#define DATA_READY (DRIVE_READY | DRQ_STAT)
+#define DATA_READY (DRQ_STAT)
/*
* Some more useful definitions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 212efece2..53fef9b74 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -318,7 +318,7 @@ static int loop_set_fd(struct loop_device *lo, kdev_t dev, unsigned int arg)
}
lo->lo_inode = inode;
- lo->lo_inode->i_count++;
+ atomic_inc(&lo->lo_inode->i_count);
lo->transfer = NULL;
figure_loop_size(lo);
MOD_INC_USE_COUNT;
diff --git a/drivers/block/md.c b/drivers/block/md.c
index 078e1e1ee..12cb6dcf0 100644
--- a/drivers/block/md.c
+++ b/drivers/block/md.c
@@ -202,9 +202,10 @@ static int do_md_stop (int minor, struct inode *inode)
{
int i;
- if (inode->i_count>1 || md_dev[minor].busy>1) /* ioctl : one open channel */
+ if (atomic_read(&inode->i_count)>1 || md_dev[minor].busy>1) /* ioctl : one open channel */
{
- printk ("STOP_MD md%x failed : i_count=%d, busy=%d\n", minor, inode->i_count, md_dev[minor].busy);
+ printk ("STOP_MD md%x failed : i_count=%d, busy=%d\n", minor,
+ atomic_read(&inode->i_count), md_dev[minor].busy);
return -EBUSY;
}
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index d5a19d343..900cb935f 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -46,6 +46,9 @@ endif
ifneq ($(ARCH),m68k)
L_OBJS += pc_keyb.o defkeymap.o
endif
+ifdef CONFIG_MAGIC_SYSRQ
+L_OBJS += sysrq.o
+endif
endif
ifeq ($(CONFIG_ATARI_DSP56K),y)
diff --git a/drivers/char/atarimouse.c b/drivers/char/atarimouse.c
index 18debb66b..950cb1546 100644
--- a/drivers/char/atarimouse.c
+++ b/drivers/char/atarimouse.c
@@ -176,7 +176,7 @@ __initfunc(int atari_mouse_init(void))
#define MIN_THRESHOLD 1
#define MAX_THRESHOLD 20 /* more seems not reasonable... */
-void atari_mouse_setup( char *str, int *ints )
+__initfunc(void atari_mouse_setup( char *str, int *ints ))
{
if (ints[0] < 1) {
printk( "atari_mouse_setup: no arguments!\n" );
diff --git a/drivers/char/console.c b/drivers/char/console.c
index 56748c068..61ab64aac 100644
--- a/drivers/char/console.c
+++ b/drivers/char/console.c
@@ -125,11 +125,11 @@ unsigned long video_port_base;
#include <asm/uaccess.h>
#include <asm/bitops.h>
-#include "kbd_kern.h"
-#include "vt_kern.h"
-#include "consolemap.h"
-#include "selection.h"
-#include "console_struct.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
diff --git a/drivers/char/console_struct.h b/drivers/char/console_struct.h
deleted file mode 100644
index a73836ad4..000000000
--- a/drivers/char/console_struct.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * console_struct.h
- *
- * Data structure and defines shared between console.c, vga.c and tga.c
- */
-
-#define NPAR 16
-
-struct vc_data {
- unsigned long vc_screenbuf_size;
- unsigned short vc_video_erase_char; /* Background erase character */
- unsigned char vc_attr; /* Current attributes */
- unsigned char vc_def_color; /* Default colors */
- unsigned char vc_color; /* Foreground & background */
- unsigned char vc_s_color; /* Saved foreground & background */
- unsigned char vc_ulcolor; /* Colour for underline mode */
- unsigned char vc_halfcolor; /* Colour for half intensity mode */
- unsigned long vc_origin; /* Used for EGA/VGA fast scroll */
- unsigned long vc_scr_end; /* Used for EGA/VGA fast scroll */
- unsigned long vc_pos;
- unsigned long vc_x,vc_y;
- unsigned long vc_top,vc_bottom;
- unsigned long vc_state;
- unsigned long vc_npar,vc_par[NPAR];
- unsigned long vc_video_mem_start; /* Start of video RAM */
- unsigned long vc_video_mem_end; /* End of video RAM (sort of) */
- unsigned long vc_saved_x;
- unsigned long vc_saved_y;
- /* mode flags */
- unsigned long vc_charset : 1; /* Character set G0 / G1 */
- unsigned long vc_s_charset : 1; /* Saved character set */
- unsigned long vc_disp_ctrl : 1; /* Display chars < 32? */
- unsigned long vc_toggle_meta : 1; /* Toggle high bit? */
- unsigned long vc_decscnm : 1; /* Screen Mode */
- unsigned long vc_decom : 1; /* Origin Mode */
- unsigned long vc_decawm : 1; /* Autowrap Mode */
- unsigned long vc_deccm : 1; /* Cursor Visible */
- unsigned long vc_decim : 1; /* Insert Mode */
- unsigned long vc_deccolm : 1; /* 80/132 Column Mode */
- /* attribute flags */
- unsigned long vc_intensity : 2; /* 0=half-bright, 1=normal, 2=bold */
- unsigned long vc_underline : 1;
- unsigned long vc_blink : 1;
- unsigned long vc_reverse : 1;
- unsigned long vc_s_intensity : 2; /* saved rendition */
- unsigned long vc_s_underline : 1;
- unsigned long vc_s_blink : 1;
- unsigned long vc_s_reverse : 1;
- /* misc */
- unsigned long vc_ques : 1;
- unsigned long vc_need_wrap : 1;
- unsigned long vc_has_scrolled : 1; /* Info for unblank_screen */
- unsigned long vc_kmalloced : 1; /* kfree_s() needed */
- unsigned long vc_report_mouse : 2;
- unsigned char vc_utf : 1; /* Unicode UTF-8 encoding */
- unsigned char vc_utf_count;
- long vc_utf_char;
- unsigned long vc_tab_stop[5]; /* Tab stops. 160 columns. */
- unsigned char vc_palette[16*3]; /* Colour palette for VGA+ */
- unsigned short * vc_translate;
- unsigned char vc_G0_charset;
- unsigned char vc_G1_charset;
- unsigned char vc_saved_G0;
- unsigned char vc_saved_G1;
- unsigned int vc_bell_pitch; /* Console bell pitch */
- unsigned int vc_bell_duration; /* Console bell duration */
- /* additional information is in vt_kern.h */
-};
-
-struct vc {
- struct vc_data *d;
-
- /* might add scrmem, vt_struct, kbd at some time,
- to have everything in one place - the disadvantage
- would be that vc_cons etc can no longer be static */
-};
-
-extern struct vc vc_cons [MAX_NR_CONSOLES];
-
-#define screenbuf_size (vc_cons[currcons].d->vc_screenbuf_size)
-#define origin (vc_cons[currcons].d->vc_origin)
-#define scr_end (vc_cons[currcons].d->vc_scr_end)
-#define pos (vc_cons[currcons].d->vc_pos)
-#define top (vc_cons[currcons].d->vc_top)
-#define bottom (vc_cons[currcons].d->vc_bottom)
-#define x (vc_cons[currcons].d->vc_x)
-#define y (vc_cons[currcons].d->vc_y)
-#define vc_state (vc_cons[currcons].d->vc_state)
-#define npar (vc_cons[currcons].d->vc_npar)
-#define par (vc_cons[currcons].d->vc_par)
-#define ques (vc_cons[currcons].d->vc_ques)
-#define attr (vc_cons[currcons].d->vc_attr)
-#define saved_x (vc_cons[currcons].d->vc_saved_x)
-#define saved_y (vc_cons[currcons].d->vc_saved_y)
-#define translate (vc_cons[currcons].d->vc_translate)
-#define G0_charset (vc_cons[currcons].d->vc_G0_charset)
-#define G1_charset (vc_cons[currcons].d->vc_G1_charset)
-#define saved_G0 (vc_cons[currcons].d->vc_saved_G0)
-#define saved_G1 (vc_cons[currcons].d->vc_saved_G1)
-#define utf (vc_cons[currcons].d->vc_utf)
-#define utf_count (vc_cons[currcons].d->vc_utf_count)
-#define utf_char (vc_cons[currcons].d->vc_utf_char)
-#define video_mem_start (vc_cons[currcons].d->vc_video_mem_start)
-#define video_mem_end (vc_cons[currcons].d->vc_video_mem_end)
-#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
-#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
-#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
-#define decscnm (vc_cons[currcons].d->vc_decscnm)
-#define decom (vc_cons[currcons].d->vc_decom)
-#define decawm (vc_cons[currcons].d->vc_decawm)
-#define deccm (vc_cons[currcons].d->vc_deccm)
-#define decim (vc_cons[currcons].d->vc_decim)
-#define deccolm (vc_cons[currcons].d->vc_deccolm)
-#define need_wrap (vc_cons[currcons].d->vc_need_wrap)
-#define has_scrolled (vc_cons[currcons].d->vc_has_scrolled)
-#define kmalloced (vc_cons[currcons].d->vc_kmalloced)
-#define report_mouse (vc_cons[currcons].d->vc_report_mouse)
-#define color (vc_cons[currcons].d->vc_color)
-#define s_color (vc_cons[currcons].d->vc_s_color)
-#define def_color (vc_cons[currcons].d->vc_def_color)
-#define foreground (color & 0x0f)
-#define background (color & 0xf0)
-#define charset (vc_cons[currcons].d->vc_charset)
-#define s_charset (vc_cons[currcons].d->vc_s_charset)
-#define intensity (vc_cons[currcons].d->vc_intensity)
-#define underline (vc_cons[currcons].d->vc_underline)
-#define blink (vc_cons[currcons].d->vc_blink)
-#define reverse (vc_cons[currcons].d->vc_reverse)
-#define s_intensity (vc_cons[currcons].d->vc_s_intensity)
-#define s_underline (vc_cons[currcons].d->vc_s_underline)
-#define s_blink (vc_cons[currcons].d->vc_s_blink)
-#define s_reverse (vc_cons[currcons].d->vc_s_reverse)
-#define ulcolor (vc_cons[currcons].d->vc_ulcolor)
-#define halfcolor (vc_cons[currcons].d->vc_halfcolor)
-#define tab_stop (vc_cons[currcons].d->vc_tab_stop)
-#define palette (vc_cons[currcons].d->vc_palette)
-#define bell_pitch (vc_cons[currcons].d->vc_bell_pitch)
-#define bell_duration (vc_cons[currcons].d->vc_bell_duration)
-
-#define vcmode (vt_cons[currcons]->vc_mode)
-#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct))
diff --git a/drivers/char/consolemap.c b/drivers/char/consolemap.c
index 878ac0d72..5b0e61fea 100644
--- a/drivers/char/consolemap.c
+++ b/drivers/char/consolemap.c
@@ -13,7 +13,7 @@
#include <linux/malloc.h>
#include <linux/init.h>
#include <asm/uaccess.h>
-#include "consolemap.h"
+#include <linux/consolemap.h>
static unsigned short translations[][256] = {
/* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
diff --git a/drivers/char/consolemap.h b/drivers/char/consolemap.h
deleted file mode 100644
index 9aba19db3..000000000
--- a/drivers/char/consolemap.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/*
- * consolemap.h
- *
- * Interface between console.c, selection.c and consolemap.c
- */
-#define LAT1_MAP 0
-#define GRAF_MAP 1
-#define IBMPC_MAP 2
-#define USER_MAP 3
-
-extern int hashtable_contents_valid;
-extern unsigned char inverse_translate(int glyph);
-extern unsigned short *set_translate(int m);
-extern int conv_uni_to_pc(long ucs);
diff --git a/drivers/char/diacr.h b/drivers/char/diacr.h
deleted file mode 100644
index 1c1a3ff05..000000000
--- a/drivers/char/diacr.h
+++ /dev/null
@@ -1,8 +0,0 @@
-#ifndef _DIACR_H
-#define _DIACR_H
-#include <linux/kd.h>
-
-extern struct kbdiacr accent_table[];
-extern unsigned int accent_table_size;
-
-#endif /* _DIACR_H */
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index ef97f7255..5928869e9 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -488,7 +488,7 @@ static int dsp56k_open(struct inode *inode, struct file *file)
return 0;
}
-static void dsp56k_release(struct inode *inode, struct file *file)
+static int dsp56k_release(struct inode *inode, struct file *file)
{
int dev = MINOR(inode->i_rdev) & 0x0f;
@@ -501,12 +501,13 @@ static void dsp56k_release(struct inode *inode, struct file *file)
break;
default:
printk("DSP56k driver: Unknown minor device: %d\n", dev);
- return;
+ return -ENXIO;
}
#ifdef MODULE
MOD_DEC_USE_COUNT;
-#endif /* MODULE */
+#endif
+ return 0;
}
static struct file_operations dsp56k_fops = {
diff --git a/drivers/char/fbmem.c b/drivers/char/fbmem.c
index b267f84d3..7db3b5dba 100644
--- a/drivers/char/fbmem.c
+++ b/drivers/char/fbmem.c
@@ -222,7 +222,7 @@ fb_mmap(struct inode *inode, struct file *file, struct vm_area_struct * vma)
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/char/kbd_kern.h b/drivers/char/kbd_kern.h
deleted file mode 100644
index 2d7dc1b7e..000000000
--- a/drivers/char/kbd_kern.h
+++ /dev/null
@@ -1,141 +0,0 @@
-#ifndef _KBD_KERN_H
-#define _KBD_KERN_H
-
-#include <linux/interrupt.h>
-#include <linux/keyboard.h>
-
-extern int shift_state;
-
-extern char *func_table[MAX_NR_FUNC];
-extern char func_buf[];
-extern char *funcbufptr;
-extern int funcbufsize, funcbufleft;
-
-/*
- * kbd->xxx contains the VC-local things (flag settings etc..)
- *
- * Note: externally visible are LED_SCR, LED_NUM, LED_CAP defined in kd.h
- * The code in KDGETLED / KDSETLED depends on the internal and
- * external order being the same.
- *
- * Note: lockstate is used as index in the array key_map.
- */
-struct kbd_struct {
-
- unsigned char lockstate;
-/* 8 modifiers - the names do not have any meaning at all;
- they can be associated to arbitrarily chosen keys */
-#define VC_SHIFTLOCK KG_SHIFT /* shift lock mode */
-#define VC_ALTGRLOCK KG_ALTGR /* altgr lock mode */
-#define VC_CTRLLOCK KG_CTRL /* control lock mode */
-#define VC_ALTLOCK KG_ALT /* alt lock mode */
-#define VC_SHIFTLLOCK KG_SHIFTL /* shiftl lock mode */
-#define VC_SHIFTRLOCK KG_SHIFTR /* shiftr lock mode */
-#define VC_CTRLLLOCK KG_CTRLL /* ctrll lock mode */
-#define VC_CTRLRLOCK KG_CTRLR /* ctrlr lock mode */
- unsigned char slockstate; /* for `sticky' Shift, Ctrl, etc. */
-
- unsigned char ledmode:2; /* one 2-bit value */
-#define LED_SHOW_FLAGS 0 /* traditional state */
-#define LED_SHOW_IOCTL 1 /* only change leds upon ioctl */
-#define LED_SHOW_MEM 2 /* `heartbeat': peek into memory */
-
- unsigned char ledflagstate:3; /* flags, not lights */
- unsigned char default_ledflagstate:3;
-#define VC_SCROLLOCK 0 /* scroll-lock mode */
-#define VC_NUMLOCK 1 /* numeric lock mode */
-#define VC_CAPSLOCK 2 /* capslock mode */
-
- unsigned char kbdmode:2; /* one 2-bit value */
-#define VC_XLATE 0 /* translate keycodes using keymap */
-#define VC_MEDIUMRAW 1 /* medium raw (keycode) mode */
-#define VC_RAW 2 /* raw (scancode) mode */
-#define VC_UNICODE 3 /* Unicode mode */
-
- unsigned char modeflags:5;
-#define VC_APPLIC 0 /* application key mode */
-#define VC_CKMODE 1 /* cursor key mode */
-#define VC_REPEAT 2 /* keyboard repeat */
-#define VC_CRLF 3 /* 0 - enter sends CR, 1 - enter sends CRLF */
-#define VC_META 4 /* 0 - meta, 1 - meta=prefix with ESC */
-};
-
-extern struct kbd_struct kbd_table[];
-
-extern int kbd_init(void);
-
-extern unsigned char getledstate(void);
-extern void setledstate(struct kbd_struct *kbd, unsigned int led);
-
-extern int do_poke_blanked_console;
-
-extern inline void show_console(void)
-{
- do_poke_blanked_console = 1;
- mark_bh(CONSOLE_BH);
-}
-
-extern inline void set_console(int nr)
-{
- want_console = nr;
- mark_bh(CONSOLE_BH);
-}
-
-extern inline void set_leds(void)
-{
- mark_bh(KEYBOARD_BH);
-}
-
-extern inline int vc_kbd_mode(struct kbd_struct * kbd, int flag)
-{
- return ((kbd->modeflags >> flag) & 1);
-}
-
-extern inline int vc_kbd_led(struct kbd_struct * kbd, int flag)
-{
- return ((kbd->ledflagstate >> flag) & 1);
-}
-
-extern inline void set_vc_kbd_mode(struct kbd_struct * kbd, int flag)
-{
- kbd->modeflags |= 1 << flag;
-}
-
-extern inline void set_vc_kbd_led(struct kbd_struct * kbd, int flag)
-{
- kbd->ledflagstate |= 1 << flag;
-}
-
-extern inline void clr_vc_kbd_mode(struct kbd_struct * kbd, int flag)
-{
- kbd->modeflags &= ~(1 << flag);
-}
-
-extern inline void clr_vc_kbd_led(struct kbd_struct * kbd, int flag)
-{
- kbd->ledflagstate &= ~(1 << flag);
-}
-
-extern inline void chg_vc_kbd_lock(struct kbd_struct * kbd, int flag)
-{
- kbd->lockstate ^= 1 << flag;
-}
-
-extern inline void chg_vc_kbd_slock(struct kbd_struct * kbd, int flag)
-{
- kbd->slockstate ^= 1 << flag;
-}
-
-extern inline void chg_vc_kbd_mode(struct kbd_struct * kbd, int flag)
-{
- kbd->modeflags ^= 1 << flag;
-}
-
-extern inline void chg_vc_kbd_led(struct kbd_struct * kbd, int flag)
-{
- kbd->ledflagstate ^= 1 << flag;
-}
-
-#define U(x) ((x) ^ 0xf000)
-
-#endif
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index 0185c2bda..66523964a 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -17,8 +17,11 @@
* Modified to provide 'generic' keyboard support by Hamish Macdonald
* Merge with the m68k keyboard driver and split-off of the PC low-level
* parts by Geert Uytterhoeven, May 1997
+ *
+ * 27-05-97: Added support for the Magic SysRq Key (Martin Mares)
*/
+#include <linux/config.h>
#include <linux/sched.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
@@ -30,9 +33,10 @@
#include <asm/keyboard.h>
#include <asm/bitops.h>
-#include "kbd_kern.h"
-#include "diacr.h"
-#include "vt_kern.h"
+#include <linux/kbd_kern.h>
+#include <linux/kbd_diacr.h>
+#include <linux/vt_kern.h>
+#include <linux/kbd_ll.h>
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
@@ -82,7 +86,7 @@ static int dead_key_next = 0;
* the variable must be global, or a new procedure must be created to
* return the value. I chose the former way.
*/
-/*static*/ int shift_state = 0;
+int shift_state = 0;
static int npadch = -1; /* -1 or number assembled on pad */
static unsigned char diacr = 0;
static char rep = 0; /* flag telling character repeat */
@@ -140,8 +144,14 @@ const int NR_TYPES = SIZE(max_vals);
static void put_queue(int);
static unsigned char handle_diacr(unsigned char);
-/* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
-struct pt_regs * pt_regs;
+/* kbd_pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
+struct pt_regs * kbd_pt_regs;
+
+#ifdef CONFIG_MAGIC_SYSRQ
+#define SYSRQ_KEY 0x54
+extern void handle_sysrq(int, struct pt_regs *, struct kbd_struct *, struct tty_struct *);
+static int sysrq_pressed;
+#endif
/*
* Many other routines do put_queue, but I think either
@@ -223,6 +233,17 @@ void handle_scancode(unsigned char scancode)
} else
rep = test_and_set_bit(keycode, key_down);
+#ifdef CONFIG_MAGIC_SYSRQ /* Handle the SysRq Hack */
+ if (keycode == SYSRQ_KEY) {
+ sysrq_pressed = !up_flag;
+ return;
+ } else if (sysrq_pressed) {
+ if (!up_flag)
+ handle_sysrq(keycode, kbd_pt_regs, kbd, tty);
+ return;
+ }
+#endif
+
if (kbd->kbdmode == VC_MEDIUMRAW) {
/* soon keycodes will require more than one byte */
put_queue(keycode + up_flag);
@@ -346,8 +367,8 @@ static void caps_on(void)
static void show_ptregs(void)
{
- if (pt_regs)
- show_regs(pt_regs);
+ if (kbd_pt_regs)
+ show_regs(kbd_pt_regs);
}
static void hold(void)
diff --git a/drivers/char/lp_m68k.c b/drivers/char/lp_m68k.c
index 17405c191..117dc3fe7 100644
--- a/drivers/char/lp_m68k.c
+++ b/drivers/char/lp_m68k.c
@@ -462,7 +462,6 @@ static struct file_operations lp_fops = {
EXPORT_SYMBOL(lp_table);
EXPORT_SYMBOL(lp_irq);
EXPORT_SYMBOL(lp_interrupt);
-EXPORT_SYMBOL(lp_init);
EXPORT_SYMBOL(register_parallel);
EXPORT_SYMBOL(unregister_parallel);
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 56d537fb3..499132bf8 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -35,6 +35,33 @@ void isdn_init(void);
void pcwatchdog_init(void);
#endif
+static long do_write_mem(struct file * file,
+ void *p, unsigned long realp,
+ const char * buf, unsigned long count)
+{
+ unsigned long written;
+
+ written = 0;
+#if defined(__sparc__) || defined(__mc68000__)
+ /* we don't have page 0 mapped on sparc and m68k.. */
+ if (realp < PAGE_SIZE) {
+ unsigned long sz = PAGE_SIZE-realp;
+ if (sz > count) sz = count;
+ /* Hmm. Do something? */
+ buf+=sz;
+ p+=sz;
+ count-=sz;
+ written+=sz;
+ }
+#endif
+ if (copy_from_user(p, buf, count) < 0)
+ return -EFAULT;
+ written += count;
+ file->f_pos += written;
+ return count;
+}
+
+
/*
* This funcion reads the *physical* memory. The f_pos points directly to the
* memory location.
@@ -45,7 +72,7 @@ static long read_mem(struct inode * inode, struct file * file,
unsigned long p = file->f_pos;
unsigned long end_mem;
unsigned long read;
-
+
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
@@ -54,15 +81,22 @@ static long read_mem(struct inode * inode, struct file * file,
read = 0;
#if defined(__sparc__) || defined(__mc68000__)
/* we don't have page 0 mapped on sparc and m68k.. */
- while (p < PAGE_SIZE && count > 0) {
- put_user(0,buf);
- buf++;
- p++;
- count--;
- read++;
+ if (p < PAGE_SIZE) {
+ unsigned long sz = PAGE_SIZE-p;
+ if (sz > count)
+ sz = count;
+ if (sz > 0) {
+ if (clear_user(buf, sz))
+ return -EFAULT;
+ buf += sz;
+ p += sz;
+ count -= sz;
+ read += sz;
+ }
}
#endif
- copy_to_user(buf, __va(p), count);
+ if (copy_to_user(buf, __va(p), count) < 0)
+ return -EFAULT;
read += count;
file->f_pos += read;
return read;
@@ -73,35 +107,19 @@ static long write_mem(struct inode * inode, struct file * file,
{
unsigned long p = file->f_pos;
unsigned long end_mem;
- unsigned long written;
end_mem = __pa(high_memory);
if (p >= end_mem)
return 0;
if (count > end_mem - p)
count = end_mem - p;
- written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
- /* we don't have page 0 mapped on sparc and m68k.. */
- while (p < PAGE_SIZE && count > 0) {
- /* Hmm. Do something? */
- buf++;
- p++;
- count--;
- written++;
- }
-#endif
- copy_from_user(__va(p), buf, count);
- written += count;
- file->f_pos += written;
- return count;
+ return do_write_mem(file,__va(p),p,buf,count);
}
static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_struct * vma)
{
unsigned long offset = vma->vm_offset;
-
if (offset & ~PAGE_MASK)
return -ENXIO;
#if defined(__i386__)
@@ -117,7 +135,7 @@ static int mmap_mem(struct inode * inode, struct file * file, struct vm_area_str
if (remap_page_range(vma->vm_start, offset, vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
@@ -166,27 +184,12 @@ static long write_kmem(struct inode * inode, struct file * file,
const char * buf, unsigned long count)
{
unsigned long p = file->f_pos;
- unsigned long written;
if (p >= (unsigned long) high_memory)
return 0;
if (count > (unsigned long) high_memory - p)
count = (unsigned long) high_memory - p;
- written = 0;
-#if defined(__sparc__) || defined(__mc68000__)
- /* we don't have page 0 mapped on sparc and m68k.. */
- while (p < PAGE_SIZE && count > 0) {
- /* Hmm. Do something? */
- buf++;
- p++;
- count--;
- written++;
- }
-#endif
- copy_from_user((char *) p, buf, count);
- written += count;
- file->f_pos += written;
- return count;
+ return do_write_mem(file,(void*)p,p,buf,count);
}
static long read_port(struct inode * inode, struct file * file,
@@ -195,8 +198,11 @@ static long read_port(struct inode * inode, struct file * file,
unsigned int i = file->f_pos;
char * tmp = buf;
+ if (verify_area(VERIFY_WRITE,buf,count))
+ return -EFAULT;
while (count-- > 0 && i < 65536) {
- put_user(inb(i),tmp);
+ if (__put_user(inb(i),tmp) < 0)
+ return -EFAULT;
i++;
tmp++;
}
@@ -210,9 +216,12 @@ static long write_port(struct inode * inode, struct file * file,
unsigned int i = file->f_pos;
const char * tmp = buf;
+ if (verify_area(VERIFY_READ,buf,count))
+ return -EFAULT;
while (count-- > 0 && i < 65536) {
char c;
- get_user(c, tmp);
+ if (__get_user(c, tmp))
+ return -EFAULT;
outb(c,i);
i++;
tmp++;
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index d632e4788..ed06f6314 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -44,8 +44,8 @@
#include <linux/apm_bios.h>
#endif
-#include <linux/tty.h> /* needed by selection.h */
-#include "selection.h" /* export its symbols */
+#include <linux/tty.h>
+#include <linux/selection.h>
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
#endif
diff --git a/drivers/char/pc_keyb.c b/drivers/char/pc_keyb.c
index 2d075636f..9e3267aaf 100644
--- a/drivers/char/pc_keyb.c
+++ b/drivers/char/pc_keyb.c
@@ -1,20 +1,10 @@
/*
* linux/drivers/char/pc_keyb.c
*
- * Written for linux by Johan Myreen as a translation from
- * the assembly version by Linus (with diacriticals added)
- *
- * Some additional features added by Christoph Niemann (ChN), March 1993
- *
- * Loadable keymaps by Risto Kankkunen, May 1993
- *
- * Diacriticals redone & other small changes, aeb@cwi.nl, June 1993
- * Added decr/incr_console, dynamic keymaps, Unicode support,
- * dynamic function/string keys, led setting, Sept 1994
- * `Sticky' modifier keys, 951006.
- * 11-11-96: SAK should now work in the raw mode (Martin Mares)
- *
* Separation of the PC low-level part by Geert Uytterhoeven, May 1997
+ * See keyboard.c for the whole history.
+ *
+ * Major cleanup by Martin Mares, May 1997
*/
#include <linux/sched.h>
@@ -24,89 +14,181 @@
#include <linux/signal.h>
#include <linux/ioport.h>
#include <linux/init.h>
+#include <linux/kbd_ll.h>
-#include <asm/bitops.h>
+/* Some configuration switches are present in the include file... */
-/*
- * Define these here, include/asm-mips/keyboard.h depends on them.
- *
- * keyboard controller registers
- */
-#define KBD_STATUS_REG (unsigned int) 0x64
-#define KBD_CNTL_REG (unsigned int) 0x64
-#define KBD_DATA_REG (unsigned int) 0x60
-/*
- * controller commands
- */
-#define KBD_READ_MODE (unsigned int) 0x20
-#define KBD_WRITE_MODE (unsigned int) 0x60
-#define KBD_SELF_TEST (unsigned int) 0xAA
-#define KBD_SELF_TEST2 (unsigned int) 0xAB
-#define KBD_CNTL_ENABLE (unsigned int) 0xAE
-/*
- * keyboard commands
- */
-#define KBD_ENABLE (unsigned int) 0xF4
-#define KBD_DISABLE (unsigned int) 0xF5
-#define KBD_RESET (unsigned int) 0xFF
-/*
- * keyboard replies
- */
-#define KBD_ACK (unsigned int) 0xFA
-#define KBD_POR (unsigned int) 0xAA
-/*
- * status register bits
- */
-#define KBD_OBF (unsigned int) 0x01
-#define KBD_IBF (unsigned int) 0x02
-#define KBD_GTO (unsigned int) 0x40
-#define KBD_PERR (unsigned int) 0x80
-/*
- * keyboard controller mode register bits
- */
-#define KBD_EKI (unsigned int) 0x01
-#define KBD_SYS (unsigned int) 0x04
-#define KBD_DMS (unsigned int) 0x20
-#define KBD_KCC (unsigned int) 0x40
+#include "pc_keyb.h"
#include <asm/keyboard.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/system.h>
/*
- * On non-x86 hardware we do a full keyboard controller
- * initialization, in case the bootup software hasn't done
- * it. On a x86, the BIOS will already have initialized the
- * keyboard.
+ * In case we run on a non-x86 hardware we need to initialize both the keyboard
+ * controller and the keyboard. On a x86, the BIOS will already have initialized
+ * them.
*/
+
#ifdef INIT_KBD
-int initialize_kbd(void);
-#endif
-#include <asm/io.h>
-#include <asm/system.h>
+__initfunc(static int kbd_wait_for_input(void))
+{
+ int n;
+ int status, data;
+
+ n = KBD_TIMEOUT;
+ do {
+ status = kbd_inb(KBD_STATUS_REG);
+ /*
+ * Wait for input data to become available. This bit will
+ * then be cleared by the following read of the DATA
+ * register.
+ */
+
+ if (!(status & KBD_STAT_OBF))
+ continue;
+
+ data = kbd_inb(KBD_DATA_REG);
+
+ /*
+ * Check to see if a timeout error has occurred. This means
+ * that transmission was started but did not complete in the
+ * normal time cycle. PERR is set when a parity error occurred
+ * in the last transmission.
+ */
+ if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) {
+ continue;
+ }
+ return (data & 0xff);
+ } while (--n);
+ return -1; /* timed-out if fell through to here... */
+}
+
+__initfunc(static void kbd_write(int address, int data))
+{
+ int status;
+
+ do {
+ status = kbd_inb(KBD_STATUS_REG);
+ } while (status & KBD_STAT_IBF);
+ kbd_outb(data, address);
+}
+
+__initfunc(static char *initialize_kbd2(void))
+{
+ /* Flush any pending input. */
+
+ while (kbd_wait_for_input() != -1)
+ ;
+
+ /*
+ * Test the keyboard interface.
+ * This seems to be the only way to get it going.
+ * If the test is successful a x55 is placed in the input buffer.
+ */
+
+ kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST);
+ if (kbd_wait_for_input() != 0x55)
+ return "Keyboard failed self test";
+
+ /*
+ * Perform a keyboard interface test. This causes the controller
+ * to test the keyboard clock and data lines. The results of the
+ * test are placed in the input buffer.
+ */
+
+ kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST);
+ if (kbd_wait_for_input() != 0x00)
+ return "Keyboard interface failed self test";
+
+ /* Enable the keyboard by allowing the keyboard clock to run. */
+
+ kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE);
+
+ /*
+ * Reset keyboard. If the read times out
+ * then the assumption is that no keyboard is
+ * plugged into the machine.
+ * This defaults the keyboard to scan-code set 2.
+ */
+
+ kbd_write(KBD_DATA_REG, KBD_CMD_RESET);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Keyboard reset failed, no ACK";
+ if (kbd_wait_for_input() != KBD_REPLY_POR)
+ return "Keyboard reset failed, no POR";
+
+ /*
+ * Set keyboard controller mode. During this, the keyboard should be
+ * in the disabled state.
+ */
+
+ kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Disable keyboard: no ACK";
+
+ kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE);
+ kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT
+ | KBD_MODE_SYS
+ | KBD_MODE_DISABLE_MOUSE
+ | KBD_MODE_KCC);
+
+ kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Enable keyboard: no ACK";
+
+ /*
+ * Finally, set the typematic rate to maximum.
+ */
+
+ kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Set rate: no ACK";
+ kbd_write(KBD_DATA_REG, 0x00);
+ if (kbd_wait_for_input() != KBD_REPLY_ACK)
+ return "Set rate: no ACK";
+
+ return NULL;
+}
+
+__initfunc(void initialize_kbd(void))
+{
+ unsigned long flags;
+ char *msg;
+
+ save_flags(flags); cli();
+ msg = initialize_kbd2();
+ restore_flags(flags);
+
+ if (msg)
+ printk(KERN_WARNING "initialize_kbd: %s\n", msg);
+}
-unsigned char kbd_read_mask = 0x01; /* modified by psaux.c */
+#endif /* INIT_KBD */
+
+unsigned char kbd_read_mask = KBD_STAT_OBF; /* Modified by psaux.c */
/* used only by send_data - set by keyboard_interrupt */
static volatile unsigned char reply_expected = 0;
static volatile unsigned char acknowledge = 0;
static volatile unsigned char resend = 0;
-/* pt_regs - set by keyboard_interrupt(), used by show_ptregs() */
+/*
+ * Wait for keyboard controller input buffer is empty.
+ */
+
static inline void kb_wait(void)
{
int i;
- for (i=0; i<0x100000; i++)
- if ((kbd_inb_p(0x64) & 0x02) == 0)
+ for (i=0; i<KBD_TIMEOUT; i++)
+ if (! (kbd_inb_p(KBD_STATUS_REG) & KBD_STAT_IBF))
return;
printk(KERN_WARNING "Keyboard timed out\n");
}
-extern struct pt_regs *pt_regs;
-
-extern void handle_scancode(unsigned char scancode);
-
-
/*
* Translation of escaped scancodes to keycodes.
* This is now user-settable.
@@ -247,11 +329,11 @@ int pckbd_getkeycode(unsigned int scancode)
static inline void send_cmd(unsigned char c)
{
kb_wait();
- kbd_outb(c,0x64);
+ kbd_outb(c, KBD_CNTL_REG);
}
-#define disable_keyboard() do { send_cmd(0xAD); kb_wait(); } while (0)
-#define enable_keyboard() send_cmd(0xAE)
+#define disable_keyboard() do { send_cmd(KBD_CCMD_KBD_DISABLE); kb_wait(); } while (0)
+#define enable_keyboard() send_cmd(KBD_CCMD_KBD_ENABLE)
#else
#define disable_keyboard() /* nothing */
#define enable_keyboard() /* nothing */
@@ -260,18 +342,21 @@ static inline void send_cmd(unsigned char c)
static int do_acknowledge(unsigned char scancode)
{
if (reply_expected) {
- /* 0xfa, 0xfe only mean "acknowledge", "resend" for most keyboards */
- /* but they are the key-up scancodes for PF6, PF10 on a FOCUS 9000 */
- reply_expected = 0;
- if (scancode == 0xfa) {
+ /* Unfortunately, we must recognise these codes only if we know they
+ * are known to be valid (i.e., after sending a command), because there
+ * are some brain-damaged keyboards (yes, FOCUS 9000 again) which have
+ * keys with such codes :(
+ */
+ if (scancode == KBD_REPLY_ACK) {
acknowledge = 1;
+ reply_expected = 0;
return 0;
- } else if (scancode == 0xfe) {
+ } else if (scancode == KBD_REPLY_RESEND) {
resend = 1;
+ reply_expected = 0;
return 0;
}
- /* strange ... */
- reply_expected = 1;
+ /* Should not happen... */
#if 0
printk(KERN_DEBUG "keyboard reply expected - got %02x\n",
scancode);
@@ -402,23 +487,23 @@ static void keyboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
unsigned char status;
- pt_regs = regs;
+ kbd_pt_regs = regs;
disable_keyboard();
- status = kbd_inb_p(0x64);
+ status = kbd_inb_p(KBD_STATUS_REG);
do {
unsigned char scancode;
/* mouse data? */
- if (status & kbd_read_mask & 0x20)
+ if (status & kbd_read_mask & KBD_STAT_MOUSE_OBF)
break;
- scancode = kbd_inb(0x60);
- if ((status & 0x01) && do_acknowledge(scancode))
+ scancode = kbd_inb(KBD_DATA_REG);
+ if ((status & KBD_STAT_OBF) && do_acknowledge(scancode))
handle_scancode(scancode);
- status = kbd_inb(0x64);
- } while (status & 0x01);
+ status = kbd_inb(KBD_STATUS_REG);
+ } while (status & (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF));
mark_bh(KEYBOARD_BH);
enable_keyboard();
@@ -439,9 +524,9 @@ static int send_data(unsigned char data)
acknowledge = 0;
resend = 0;
reply_expected = 1;
- kbd_outb_p(data, 0x60);
+ kbd_outb_p(data, KBD_DATA_REG);
for(i=0; i<0x200000; i++) {
- kbd_inb_p(0x64); /* just as a delay */
+ kbd_inb_p(KBD_STATUS_REG); /* just as a delay */
if (acknowledge)
return 1;
if (resend)
@@ -455,8 +540,8 @@ static int send_data(unsigned char data)
void pckbd_leds(unsigned char leds)
{
- if (!send_data(0xed) || !send_data(leds))
- send_data(0xf4); /* re-enable kbd if any errors */
+ if (!send_data(KBD_CMD_SET_LEDS) || !send_data(leds))
+ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */
}
__initfunc(void pckbd_init_hw(void))
@@ -467,180 +552,3 @@ __initfunc(void pckbd_init_hw(void))
initialize_kbd();
#endif
}
-
-#ifdef INIT_KBD
-
-/*
- * controller commands
- */
-#define KBD_READ_MODE (unsigned int) 0x20
-#define KBD_WRITE_MODE (unsigned int) 0x60
-#define KBD_SELF_TEST (unsigned int) 0xAA
-#define KBD_SELF_TEST2 (unsigned int) 0xAB
-#define KBD_CNTL_ENABLE (unsigned int) 0xAE
-/*
- * keyboard commands
- */
-#define KBD_ENABLE (unsigned int) 0xF4
-#define KBD_DISABLE (unsigned int) 0xF5
-#define KBD_RESET (unsigned int) 0xFF
-/*
- * keyboard replies
- */
-#define KBD_ACK (unsigned int) 0xFA
-#define KBD_POR (unsigned int) 0xAA
-/*
- * status register bits
- */
-#define KBD_OBF (unsigned int) 0x01
-#define KBD_IBF (unsigned int) 0x02
-#define KBD_GTO (unsigned int) 0x40
-#define KBD_PERR (unsigned int) 0x80
-/*
- * keyboard controller mode register bits
- */
-#define KBD_EKI (unsigned int) 0x01
-#define KBD_SYS (unsigned int) 0x04
-#define KBD_DMS (unsigned int) 0x20
-#define KBD_KCC (unsigned int) 0x40
-
-#define TIMEOUT_CONST 500000
-
-static int kbd_wait_for_input(void)
-{
- int n;
- int status, data;
-
- n = TIMEOUT_CONST;
- do {
- status = kbd_inb(KBD_STATUS_REG);
- /*
- * Wait for input data to become available. This bit will
- * then be cleared by the following read of the DATA
- * register.
- */
-
- if (!(status & KBD_OBF))
- continue;
-
- data = kbd_inb(KBD_DATA_REG);
-
- /*
- * Check to see if a timeout error has occurred. This means
- * that transmission was started but did not complete in the
- * normal time cycle. PERR is set when a parity error occurred
- * in the last transmission.
- */
- if (status & (KBD_GTO | KBD_PERR)) {
- continue;
- }
- return (data & 0xff);
- } while (--n);
- return (-1); /* timed-out if fell through to here... */
-}
-
-static void kbd_write(int address, int data)
-{
- int status;
-
- do {
- status = kbd_inb(KBD_STATUS_REG); /* spin until input buffer empty*/
- } while (status & KBD_IBF);
- kbd_outb(data, address); /* write out the data*/
-}
-
-__initfunc(int initialize_kbd(void))
-{
- unsigned long flags;
-
- save_flags(flags); cli();
-
- /* Flush any pending input. */
- while (kbd_wait_for_input() != -1)
- continue;
-
- /*
- * Test the keyboard interface.
- * This seems to be the only way to get it going.
- * If the test is successful a x55 is placed in the input buffer.
- */
- kbd_write(KBD_CNTL_REG, KBD_SELF_TEST);
- if (kbd_wait_for_input() != 0x55) {
- printk(KERN_WARNING "initialize_kbd: "
- "keyboard failed self test.\n");
- restore_flags(flags);
- return(-1);
- }
-
- /*
- * Perform a keyboard interface test. This causes the controller
- * to test the keyboard clock and data lines. The results of the
- * test are placed in the input buffer.
- */
- kbd_write(KBD_CNTL_REG, KBD_SELF_TEST2);
- if (kbd_wait_for_input() != 0x00) {
- printk(KERN_WARNING "initialize_kbd: "
- "keyboard failed self test 2.\n");
- restore_flags(flags);
- return(-1);
- }
-
- /* Enable the keyboard by allowing the keyboard clock to run. */
- kbd_write(KBD_CNTL_REG, KBD_CNTL_ENABLE);
-
- /*
- * Reset keyboard. If the read times out
- * then the assumption is that no keyboard is
- * plugged into the machine.
- * This defaults the keyboard to scan-code set 2.
- */
- kbd_write(KBD_DATA_REG, KBD_RESET);
- if (kbd_wait_for_input() != KBD_ACK) {
- printk(KERN_WARNING "initialize_kbd: "
- "reset kbd failed, no ACK.\n");
- restore_flags(flags);
- return(-1);
- }
-
- if (kbd_wait_for_input() != KBD_POR) {
- printk(KERN_WARNING "initialize_kbd: "
- "reset kbd failed, not POR.\n");
- restore_flags(flags);
- return(-1);
- }
-
- /*
- * now do a DEFAULTS_DISABLE always
- */
- kbd_write(KBD_DATA_REG, KBD_DISABLE);
- if (kbd_wait_for_input() != KBD_ACK) {
- printk(KERN_WARNING "initialize_kbd: "
- "disable kbd failed, no ACK.\n");
- restore_flags(flags);
- return(-1);
- }
-
- /*
- * Enable keyboard interrupt, operate in "sys" mode,
- * enable keyboard (by clearing the disable keyboard bit),
- * disable mouse, do conversion of keycodes.
- */
- kbd_write(KBD_CNTL_REG, KBD_WRITE_MODE);
- kbd_write(KBD_DATA_REG, KBD_EKI|KBD_SYS|KBD_DMS|KBD_KCC);
-
- /*
- * now ENABLE the keyboard to set it scanning...
- */
- kbd_write(KBD_DATA_REG, KBD_ENABLE);
- if (kbd_wait_for_input() != KBD_ACK) {
- printk(KERN_WARNING "initialize_kbd: "
- "keyboard enable failed.\n");
- restore_flags(flags);
- return(-1);
- }
-
- restore_flags(flags);
-
- return (1);
-}
-#endif /* INIT_KBD */
diff --git a/drivers/char/pc_keyb.h b/drivers/char/pc_keyb.h
new file mode 100644
index 000000000..f12ddab08
--- /dev/null
+++ b/drivers/char/pc_keyb.h
@@ -0,0 +1,107 @@
+/*
+ * linux/drivers/char/pc_keyb.h
+ *
+ * PC Keyboard And Keyboard Controller
+ *
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ */
+
+/*
+ * Configuration Switches
+ */
+
+#define KBD_REPORT_ERR /* Report keyboard errors */
+#define KBD_REPORT_UNKN /* Report unknown scan codes */
+#undef KBD_IS_FOCUS_9000 /* We have the brain-damaged FOCUS-9000 keyboard */
+#define KBD_TIMEOUT 0x100000 /* Timeout for sending of commands */
+
+/*
+ * Internal variables of the driver
+ */
+
+extern unsigned char kbd_read_mask;
+extern unsigned char aux_device_present;
+
+/*
+ * Keyboard Controller Registers
+ */
+
+#define KBD_STATUS_REG 0x64 /* Status register (R) */
+#define KBD_CNTL_REG 0x64 /* Controller command register (W) */
+#define KBD_DATA_REG 0x60 /* Keyboard data register (R/W) */
+
+/*
+ * Keyboard Controller Commands
+ */
+
+#define KBD_CCMD_READ_MODE 0x20 /* Read mode bits */
+#define KBD_CCMD_WRITE_MODE 0x60 /* Write mode bits */
+#define KBD_CCMD_GET_VERSION 0xA1 /* Get controller version */
+#define KBD_CCMD_MOUSE_DISABLE 0xA7 /* Disable mouse interface */
+#define KBD_CCMD_MOUSE_ENABLE 0xA8 /* Enable mouse interface */
+#define KBD_CCMD_TEST_MOUSE 0xA9 /* Mouse interface test */
+#define KBD_CCMD_SELF_TEST 0xAA /* Controller self test */
+#define KBD_CCMD_KBD_TEST 0xAB /* Keyboard interface test */
+#define KBD_CCMD_KBD_DISABLE 0xAD /* Keyboard interface disable */
+#define KBD_CCMD_KBD_ENABLE 0xAE /* Keyboard interface enable */
+#define KBD_CCMD_WRITE_MOUSE 0xD4 /* Write the following byte to the mouse */
+
+/*
+ * Keyboard Commands
+ */
+
+#define KBD_CMD_SET_LEDS 0xED /* Set keyboard leds */
+#define KBD_CMD_SET_RATE 0xF3 /* Set typematic rate */
+#define KBD_CMD_ENABLE 0xF4 /* Enable scanning */
+#define KBD_CMD_DISABLE 0xF5 /* Disable scanning */
+#define KBD_CMD_RESET 0xFF /* Reset */
+
+/*
+ * Keyboard Replies
+ */
+
+#define KBD_REPLY_POR 0xAA /* Power on reset */
+#define KBD_REPLY_ACK 0xFA /* Command ACK */
+#define KBD_REPLY_RESEND 0xFE /* Command NACK, send the cmd again */
+
+/*
+ * Status Register Bits
+ */
+
+#define KBD_STAT_OBF 0x01 /* Keyboard output buffer full */
+#define KBD_STAT_IBF 0x02 /* Keyboard input buffer full */
+#define KBD_STAT_SELFTEST 0x04 /* Self test successful */
+#define KBD_STAT_CMD 0x08 /* Last write was a command write (0=data) */
+#define KBD_STAT_UNLOCKED 0x10 /* Zero if keyboard locked */
+#define KBD_STAT_MOUSE_OBF 0x20 /* Mouse output buffer full */
+#define KBD_STAT_GTO 0x40 /* General receive/xmit timeout */
+#define KBD_STAT_PERR 0x80 /* Parity error */
+
+#define AUX_STAT_OBF (KBD_STAT_OBF | KBD_STAT_MOUSE_OBF)
+
+/*
+ * Controller Mode Register Bits
+ */
+
+#define KBD_MODE_KBD_INT 0x01 /* Keyboard data generage IRQ1 */
+#define KBD_MODE_MOUSE_INT 0x02 /* Mouse data generate IRQ12 */
+#define KBD_MODE_SYS 0x04 /* The system flag (?) */
+#define KBD_MODE_NO_KEYLOCK 0x08 /* The keylock doesn't affect the keyboard if set */
+#define KBD_MODE_DISABLE_KBD 0x10 /* Disable keyboard interface */
+#define KBD_MODE_DISABLE_MOUSE 0x20 /* Disable mouse interface */
+#define KBD_MODE_KCC 0x40 /* Scan code conversion to PC format */
+#define KBD_MODE_RFU 0x80
+
+/*
+ * Mouse Commands
+ */
+
+#define AUX_SET_RES 0xE8 /* Set resolution */
+#define AUX_SET_SCALE11 0xE6 /* Set 1:1 scaling */
+#define AUX_SET_SCALE21 0xE7 /* Set 2:1 scaling */
+#define AUX_GET_SCALE 0xE9 /* Get scaling factor */
+#define AUX_SET_STREAM 0xEA /* Set stream mode */
+#define AUX_SET_SAMPLE 0xF3 /* Set sample rate */
+#define AUX_ENABLE_DEV 0xF4 /* Enable aux device */
+#define AUX_DISABLE_DEV 0xF5 /* Disable aux device */
+#define AUX_RESET 0xFF /* Reset aux device */
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 3235ebeaa..a8614999d 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -43,6 +43,7 @@
* this driver.)
*/
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
@@ -156,10 +157,6 @@ static long rtc_read(struct inode *inode, struct file *file, char *buf,
if (count < sizeof(unsigned long))
return -EINVAL;
- retval = verify_area(VERIFY_WRITE, buf, sizeof(unsigned long));
- if (retval)
- return retval;
-
add_wait_queue(&rtc_wait, &wait);
current->state = TASK_INTERRUPTIBLE;
@@ -183,8 +180,7 @@ static long rtc_read(struct inode *inode, struct file *file, char *buf,
data = rtc_irq_data;
rtc_irq_data = 0;
restore_flags(flags);
- copy_to_user(buf, &data, sizeof(unsigned long));
- retval = sizeof(unsigned long);
+ retval = put_user(data, (unsigned long *)buf)) ?: sizeof(unsigned long);
}
current->state = TASK_RUNNING;
@@ -198,6 +194,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
{
unsigned long flags;
+ struct rtc_time wtime;
switch (cmd) {
case RTC_AIE_OFF: /* Mask alarm int. enab. bit */
@@ -254,18 +251,9 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
* means "don't care" or "match all". Only the tm_hour,
* tm_min, and tm_sec values are filled in.
*/
- int retval;
- struct rtc_time alm_tm;
-
- retval = verify_area(VERIFY_WRITE, (struct rtc_time*)arg, sizeof(struct rtc_time));
- if (retval != 0 )
- return retval;
-
- get_rtc_alm_time(&alm_tm);
- copy_to_user((struct rtc_time*)arg, &alm_tm, sizeof(struct rtc_time));
-
- return 0;
+ get_rtc_alm_time(&wtime);
+ break;
}
case RTC_ALM_SET: /* Store a time into the alarm */
{
@@ -278,11 +266,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned char hrs, min, sec;
struct rtc_time alm_tm;
- retval = verify_area(VERIFY_READ, (struct rtc_time*)arg, sizeof(struct rtc_time));
- if (retval != 0 )
- return retval;
-
- copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time));
+ if (copy_from_user(&alm_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+ return -EFAULT;
hrs = alm_tm.tm_hour;
min = alm_tm.tm_min;
@@ -315,16 +300,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
case RTC_RD_TIME: /* Read the time/date from RTC */
{
- int retval;
- struct rtc_time rtc_tm;
-
- retval = verify_area(VERIFY_WRITE, (struct rtc_time*)arg, sizeof(struct rtc_time));
- if (retval !=0 )
- return retval;
-
- get_rtc_time(&rtc_tm);
- copy_to_user((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time));
- return 0;
+ get_rtc_time(&wtime);
+ break;
}
case RTC_SET_TIME: /* Set the RTC */
{
@@ -338,11 +315,8 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
if (!suser())
return -EACCES;
- retval = verify_area(VERIFY_READ, (struct rtc_time*)arg, sizeof(struct rtc_time));
- if (retval !=0 )
- return retval;
-
- copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time));
+ if (copy_from_user(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time)))
+ return -EFAULT;
yrs = rtc_tm.tm_year + 1900 + ARCFUDGE;
mon = rtc_tm.tm_mon + 1; /* tm_mon starts at zero */
@@ -403,14 +377,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
}
case RTC_IRQP_READ: /* Read the periodic IRQ rate. */
{
- int retval;
-
- retval = verify_area(VERIFY_WRITE, (unsigned long*)arg, sizeof(unsigned long));
- if (retval != 0)
- return retval;
-
- copy_to_user((unsigned long*)arg, &rtc_freq, sizeof(unsigned long));
- return 0;
+ return put_user(rtc_freq, (unsigned long *)arg);
}
case RTC_IRQP_SET: /* Set periodic IRQ rate. */
{
@@ -451,6 +418,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
default:
return -EINVAL;
}
+ return copy_to_user(arg, &wtime, sizeof wtime) ? -EFAULT : 0;
}
/*
@@ -536,11 +504,11 @@ __initfunc(int rtc_init(void))
{
unsigned long flags;
- printk("Real Time Clock Driver v%s\n", RTC_VERSION);
+ printk(KERN_INFO "Real Time Clock Driver v%s\n", RTC_VERSION);
if(request_irq(RTC_IRQ, rtc_interrupt, SA_INTERRUPT, "rtc", NULL))
{
/* Yeah right, seeing as irq 8 doesn't even hit the bus. */
- printk("rtc: IRQ %d is not free.\n", RTC_IRQ);
+ printk(KERN_ERR "rtc: IRQ %d is not free.\n", RTC_IRQ);
return -EIO;
}
misc_register(&rtc_dev);
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index b3f6d1570..b34d73665 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -21,9 +21,9 @@
#include <asm/uaccess.h>
-#include "vt_kern.h"
-#include "consolemap.h"
-#include "selection.h"
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -101,9 +101,9 @@ int sel_loadlut(const unsigned long arg)
}
/* does screen address p correspond to character at LH/RH edge of screen? */
-static inline int atedge(const int p)
+static inline int atedge(const int p, int size_row)
{
- return (!(p % video_size_row) || !((p + 2) % video_size_row));
+ return (!(p % size_row) || !((p + 2) % size_row));
}
/* constrain v such that v <= u */
@@ -227,9 +227,9 @@ int set_selection(const unsigned long arg, struct tty_struct *tty, int user)
/* select to end of line if on trailing space */
if (new_sel_end > new_sel_start &&
- !atedge(new_sel_end) && isspace(sel_pos(new_sel_end))) {
+ !atedge(new_sel_end, size_row) && isspace(sel_pos(new_sel_end))) {
for (pe = new_sel_end + 2; ; pe += 2)
- if (!isspace(sel_pos(pe)) || atedge(pe))
+ if (!isspace(sel_pos(pe)) || atedge(pe, size_row))
break;
if (isspace(sel_pos(pe)))
new_sel_end = pe;
diff --git a/drivers/char/selection.h b/drivers/char/selection.h
deleted file mode 100644
index 4ed656ff9..000000000
--- a/drivers/char/selection.h
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * selection.h
- *
- * Interface between console.c, tty_io.c, vt.c, vc_screen.c and selection.c
- */
-
-#include <linux/config.h>
-
-extern int sel_cons;
-
-extern void clear_selection(void);
-extern int set_selection(const unsigned long arg, struct tty_struct *tty, int user);
-extern int paste_selection(struct tty_struct *tty);
-extern int sel_loadlut(const unsigned long arg);
-extern int mouse_reporting(void);
-extern void mouse_report(struct tty_struct * tty, int butt, int mrx, int mry);
-
-#ifdef CONFIG_FB_CONSOLE
-extern unsigned long get_video_num_columns(unsigned int console);
-extern unsigned long get_video_num_lines(unsigned int console);
-extern unsigned long get_video_size_row(unsigned int console);
-#else
-#define get_video_num_columns(dummy) video_num_columns
-#define get_video_num_lines(dummy) video_num_lines
-#define get_video_size_row(dummy) video_size_row
-#endif
-
-extern unsigned long video_num_columns;
-extern unsigned long video_num_lines;
-extern unsigned long video_size_row;
-extern unsigned char video_type;
-extern unsigned long video_mem_base;
-extern unsigned long video_mem_term;
-extern unsigned long video_screen_size;
-extern unsigned short video_port_reg;
-extern unsigned short video_port_val;
-
-extern int console_blanked;
-extern int can_do_color;
-
-extern unsigned long video_font_height;
-extern unsigned long video_scan_lines;
-extern unsigned long default_font_height;
-extern int video_font_is_default;
-
-extern unsigned char color_table[];
-extern int default_red[];
-extern int default_grn[];
-extern int default_blu[];
-
-extern unsigned short __real_origin;
-extern unsigned short __origin;
-extern unsigned char has_wrapped;
-
-extern unsigned short *vc_scrbuf[MAX_NR_CONSOLES];
-
-extern void do_unblank_screen(void);
-extern unsigned short *screen_pos(int currcons, int w_offset, int viewed);
-extern unsigned short screen_word(int currcons, int offset, int viewed);
-extern int scrw2glyph(unsigned short scr_word);
-extern void complement_pos(int currcons, int offset);
-extern void invert_screen(int currcons, int offset, int count, int shift);
-
-#define reverse_video_char(a) (((a) & 0x88) | ((((a) >> 4) | ((a) << 4)) & 0x77))
-#define reverse_video_short(a) (((a) & 0x88ff) | \
- (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4))
-/* this latter line used to have masks 0xf000 and 0x0f00, but selection
- requires a self-inverse operation; moreover, the old version looks wrong */
-
-extern void getconsxy(int currcons, char *p);
-extern void putconsxy(int currcons, char *p);
-
-
-/* how to access screen memory */
-
-#include <linux/config.h>
-
-#if defined(CONFIG_TGA_CONSOLE)
-
-extern int tga_blitc(unsigned int, unsigned long);
-extern unsigned long video_mem_term;
-
-/*
- * TGA console screen memory access
- *
- * TGA is *not* a character/attribute cell device; font bitmaps must be rendered
- * to the screen pixels.
- *
- * We must test for an Alpha kernel virtual address that falls within
- * the "shadow screen" memory. This condition indicates we really want
- * to write to the screen, so, we do... :-)
- *
- * NOTE also: there's only *TWO* operations: to put/get a character/attribute.
- * All the others needed by VGA support go away, as Not Applicable for TGA.
- */
-static inline void scr_writew(unsigned short val, unsigned short * addr)
-{
- /*
- * always deposit the char/attr, then see if it was to "screen" mem.
- * if so, then render the char/attr onto the real screen.
- */
- *addr = val;
- if ((unsigned long)addr < video_mem_term &&
- (unsigned long)addr >= video_mem_base) {
- tga_blitc(val, (unsigned long) addr);
- }
-}
-
-static inline unsigned short scr_readw(unsigned short * addr)
-{
- return *addr;
-}
-
-#elif defined (CONFIG_SGI)
-
-#include "vt_kern.h"
-#include <linux/kd.h>
-extern void newport_blitc(unsigned short, unsigned long);
-extern void memsetw(void * s, unsigned short c, unsigned int count);
-extern void memcpyw(unsigned short *to, unsigned short *from, unsigned int count);
-extern unsigned long video_mem_term;
-
-static inline void scr_writew(unsigned short val, unsigned short * addr)
-{
- /* always deposit the char/attr, then see if it was to "screen" mem.
- * if so, then render the char/attr onto the real screen.
- */
- if(*addr != val) {
- *addr = val;
- if ((unsigned long)addr < video_mem_term &&
- (unsigned long)addr >= video_mem_base &&
- vt_cons [fg_console]->vc_mode == KD_TEXT)
- newport_blitc(val, (unsigned long) addr);
- }
-}
-
-static inline unsigned short scr_readw(unsigned short * addr)
-{
- return *addr;
-}
-
-#elif defined (CONFIG_VIDEO_G364) /* The G364 cards: same as above. */
-
-extern void g364_blitc(unsigned short, unsigned long);
-extern void g364_blitc_colour(unsigned short, unsigned long);
-extern unsigned long video_mem_term;
-
-/*
- * G364 console screen memory access
- *
- * G364 is *not* a character/attribute cell device; font bitmaps must be
- * rendered to the screen pixels.
- *
- * The "unsigned short * addr" is *ALWAYS* a kernel virtual address, either
- * of the VC's backing store, or the "shadow screen" memory where the screen
- * contents are kept, as the G364 frame buffer is *not* char/attr cells.
- *
- * We must test for a Mips kernel virtual address that falls within
- * the "shadow screen" memory. This condition indicates we really want
- * to write to the screen, so, we do... :-)
- *
- * NOTE also: there's only *TWO* operations: to put/get a character/attribute.
- * All the others needed by VGA support go away, as Not Applicable for G364.
- */
-static inline void scr_writew(unsigned short val, unsigned short * addr)
-{
- /*
- * always deposit the char/attr, then see if it was to "screen" mem.
- * if so, then render the char/attr onto the real screen.
- */
- *addr = val;
- if ((unsigned long)addr < video_mem_term &&
- (unsigned long)addr >= video_mem_base) {
- if ((val & 0xff00) == 0x0700)
- g364_blitc(val, (unsigned long) addr); /* B&W faster */
- else
- g364_blitc_colour(val, (unsigned long) addr);
- }
-}
-
-static inline unsigned short scr_readw(unsigned short * addr)
-{
- return *addr;
-}
-
-#elif defined(CONFIG_SUN_CONSOLE)
-
-#include "vt_kern.h"
-#include <linux/kd.h>
-extern int sun_blitc(unsigned int, unsigned long);
-extern void memsetw(void * s, unsigned short c, unsigned int count);
-extern void memcpyw(unsigned short *to, unsigned short *from, unsigned int count);
-extern unsigned long video_mem_term;
-
-/* Basically the same as the TGA stuff. */
-static inline void scr_writew(unsigned short val, unsigned short * addr)
-{
- /*
- * always deposit the char/attr, then see if it was to "screen" mem.
- * if so, then render the char/attr onto the real screen.
- */
- if (*addr != val) {
- *addr = val;
- if ((unsigned long)addr < video_mem_term &&
- (unsigned long)addr >= video_mem_base &&
- vt_cons [fg_console]->vc_mode == KD_TEXT)
- sun_blitc(val, (unsigned long) addr);
- }
-}
-
-static inline unsigned short scr_readw(unsigned short * addr)
-{
- return *addr;
-}
-
-#else
-
-/*
- * normal VGA console access
- *
- */
-
-#include <asm/io.h>
-
-/*
- * NOTE: "(long) addr < 0" tests for an Alpha kernel virtual address; this
- * indicates a VC's backing store; otherwise, it's a bus memory address, for
- * the VGA's screen memory, so we do the Alpha "swizzle"... :-)
- */
-static inline void scr_writeb(unsigned char val, unsigned char * addr)
-{
- if ((long) addr < 0)
- *addr = val;
- else
- writeb(val, (unsigned long) addr);
-}
-
-static inline unsigned char scr_readb(unsigned char * addr)
-{
- if ((long) addr < 0)
- return *addr;
- return readb((unsigned long) addr);
-}
-
-static inline void scr_writew(unsigned short val, unsigned short * addr)
-{
- if ((long) addr < 0)
- *addr = val;
- else
- writew(val, (unsigned long) addr);
-}
-
-static inline unsigned short scr_readw(unsigned short * addr)
-{
- if ((long) addr < 0)
- return *addr;
- return readw((unsigned long) addr);
-}
-
-#endif /* CONFIG_TGA_CONSOLE */
-
-#if !defined(CONFIG_SUN_CONSOLE) && !defined(CONFIG_SGI)
-static inline void memsetw(void * s, unsigned short c, unsigned int count)
-{
- unsigned short * addr = (unsigned short *) s;
-
- count /= 2;
- while (count) {
- count--;
- scr_writew(c, addr++);
- }
-}
-
-static inline void memcpyw(unsigned short *to, unsigned short *from,
- unsigned int count)
-{
- count /= 2;
- while (count) {
- count--;
- scr_writew(scr_readw(from++), to++);
- }
-}
-#endif /* !defined(CONFIG_SUN_CONSOLE) && !defined(CONFIG_SGI) */
diff --git a/drivers/char/softdog.c b/drivers/char/softdog.c
index d16227d83..2eda6ef10 100644
--- a/drivers/char/softdog.c
+++ b/drivers/char/softdog.c
@@ -42,6 +42,10 @@
static int soft_margin = TIMER_MARGIN; /* in seconds */
+#ifdef MODULE
+MODULE_PARM(soft_margin,"i");
+#endif
+
/*
* Our timer
*/
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
new file mode 100644
index 000000000..e2044c086
--- /dev/null
+++ b/drivers/char/sysrq.c
@@ -0,0 +1,248 @@
+/* -*- linux-c -*-
+ *
+ * $Id: sysrq.c,v 1.2 1997/05/31 18:33:11 mj Exp $
+ *
+ * Linux Magic System Request Key Hacks
+ *
+ * (c) 1997 Martin Mares <mj@atrey.karlin.mff.cuni.cz>
+ * based on ideas by Pavel Machek <pavel@atrey.karlin.mff.cuni.cz>
+ */
+
+#include <linux/config.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/kdev_t.h>
+#include <linux/major.h>
+#include <linux/reboot.h>
+#include <linux/sysrq.h>
+#include <linux/kbd_kern.h>
+#include <asm/ptrace.h>
+#include <asm/smp_lock.h>
+
+#ifdef CONFIG_APM
+#include <linux/apm_bios.h>
+#endif
+
+extern void wakeup_bdflush(int);
+extern void reset_vc(unsigned int);
+extern int console_loglevel;
+extern struct vfsmount *vfsmntlist;
+
+#ifdef __sparc__
+extern void halt_now(void);
+#endif
+
+/* Send a signal to all user processes */
+
+static void send_sig_all(int sig, int even_init)
+{
+ struct task_struct *p;
+
+ for_each_task(p) {
+ if (p->pid && p->mm != &init_mm) { /* Not swapper nor kernel thread */
+ if (p->pid == 1 && even_init) /* Ugly hack to kill init */
+ p->pid = 0x8000;
+ force_sig(sig, p);
+ }
+ }
+}
+
+/*
+ * This function is called by the keyboard handler when SysRq is pressed
+ * and any other keycode arrives.
+ */
+
+void handle_sysrq(int key, struct pt_regs *pt_regs,
+ struct kbd_struct *kbd, struct tty_struct *tty)
+{
+ int orig_log_level = console_loglevel;
+
+ console_loglevel = 7;
+ printk(KERN_INFO "SysRq: ");
+ switch (key) {
+ case 19: /* R -- Reset raw mode */
+ kbd->kbdmode = VC_XLATE;
+ printk("Keyboard mode set to XLATE\n");
+ break;
+ case 30: /* A -- SAK */
+ printk("SAK\n");
+ do_SAK(tty);
+ reset_vc(fg_console);
+ break;
+ case 48: /* B -- boot immediately */
+ printk("Resetting\n");
+ machine_restart(NULL);
+ break;
+#ifdef __sparc__
+ case 35: /* H -- halt immediately */
+ printk("Halting\n");
+ halt_now();
+ break;
+#endif
+#ifdef CONFIG_APM
+ case 24: /* O -- power off */
+ printk("Power off\n");
+ apm_set_power_state(APM_STATE_OFF);
+ break;
+#endif
+ case 31: /* S -- emergency sync */
+ printk("Emergency Sync\n");
+ emergency_sync_scheduled = EMERG_SYNC;
+ wakeup_bdflush(0);
+ break;
+ case 22: /* U -- emergency remount R/O */
+ printk("Emergency Remount R/O\n");
+ emergency_sync_scheduled = EMERG_REMOUNT;
+ wakeup_bdflush(0);
+ break;
+ case 25: /* P -- show PC */
+ printk("Show Regs\n");
+ if (pt_regs)
+ show_regs(pt_regs);
+ break;
+ case 20: /* T -- show task info */
+ printk("Show State\n");
+ show_state();
+ break;
+ case 50: /* M -- show memory info */
+ printk("Show Memory\n");
+ show_mem();
+ break;
+ case 2 ... 11: /* 0-9 -- set console logging level */
+ key -= 2;
+ if (key == 10)
+ key = 0;
+ orig_log_level = key;
+ printk("Log level set to %d\n", key);
+ break;
+ case 18: /* E -- terminate all user processes */
+ printk("Terminate All Tasks\n");
+ send_sig_all(SIGTERM, 0);
+ orig_log_level = 8; /* We probably have killed syslogd */
+ break;
+ case 37: /* K -- kill all user processes */
+ printk("Kill All Tasks\n");
+ send_sig_all(SIGKILL, 0);
+ orig_log_level = 8;
+ break;
+ case 38: /* L -- kill all processes including init */
+ printk("Kill ALL Tasks (even init)\n");
+ send_sig_all(SIGKILL, 1);
+ orig_log_level = 8;
+ break;
+ default: /* Unknown: help */
+ printk("unRaw sAk Boot "
+#ifdef __sparc__
+ "Halt "
+#endif
+#ifdef CONFIG_APM
+ "Off "
+#endif
+ "Sync Unmount showPc showTasks showMem loglevel0-8 tErm Kill killalL\n");
+ }
+
+ console_loglevel = orig_log_level;
+}
+
+/* Aux routines for the syncer */
+
+static void all_files_read_only(void) /* Kill write permissions of all files */
+{
+ struct file *file;
+
+ for (file = inuse_filps; file; file = file->f_next)
+ if (file->f_inode && file->f_count && S_ISREG(file->f_inode->i_mode))
+ file->f_mode &= ~2;
+}
+
+static int is_local_disk(kdev_t dev) /* Guess if the device is a local hard drive */
+{
+ unsigned int major = MAJOR(dev);
+
+ switch (major) {
+ case IDE0_MAJOR:
+ case IDE1_MAJOR:
+ case IDE2_MAJOR:
+ case IDE3_MAJOR:
+ case SCSI_DISK_MAJOR:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static void go_sync(kdev_t dev, int remount_flag)
+{
+ printk(KERN_INFO "%sing device %04x ... ",
+ remount_flag ? "Remount" : "Sync",
+ dev);
+
+ if (remount_flag) { /* Remount R/O */
+ struct super_block *sb = get_super(dev);
+ struct vfsmount *vfsmnt;
+ int ret, flags;
+
+ if (!sb) {
+ printk("Superblock not found\n");
+ return;
+ }
+ if (sb->s_flags & MS_RDONLY) {
+ printk("R/O\n");
+ return;
+ }
+ quota_off(dev, -1);
+ fsync_dev(dev);
+ flags = MS_RDONLY;
+ if (sb->s_op && sb->s_op->remount_fs) {
+ ret = sb->s_op->remount_fs(sb, &flags, NULL);
+ if (ret)
+ printk("error %d\n", ret);
+ else {
+ sb->s_flags = (sb->s_flags & ~MS_RMT_MASK) | (flags & MS_RMT_MASK);
+ if ((vfsmnt = lookup_vfsmnt(sb->s_dev)))
+ vfsmnt->mnt_flags = sb->s_flags;
+ printk("OK\n");
+ }
+ } else
+ printk("nothing to do\n");
+ } else {
+ fsync_dev(dev); /* Sync only */
+ printk("OK\n");
+ }
+}
+
+/*
+ * Emergency Sync or Unmount. We cannot do it directly, so we set a special
+ * flag and wake up the bdflush kernel thread which immediately calls this function.
+ * We process all mounted hard drives first to recover from crashed experimental
+ * block devices and malfunctional network filesystems.
+ */
+
+int emergency_sync_scheduled;
+
+void do_emergency_sync(void)
+{
+ struct vfsmount *mnt;
+ int remount_flag;
+
+ lock_kernel();
+ remount_flag = (emergency_sync_scheduled == EMERG_REMOUNT);
+ emergency_sync_scheduled = 0;
+
+ if (remount_flag)
+ all_files_read_only();
+
+ for (mnt = vfsmntlist; mnt; mnt = mnt->mnt_next)
+ if (is_local_disk(mnt->mnt_dev))
+ go_sync(mnt->mnt_dev, remount_flag);
+
+ for (mnt = vfsmntlist; mnt; mnt = mnt->mnt_next)
+ if (!is_local_disk(mnt->mnt_dev) && MAJOR(mnt->mnt_dev))
+ go_sync(mnt->mnt_dev, remount_flag);
+
+ unlock_kernel();
+ printk(KERN_INFO "Done.\n");
+}
diff --git a/drivers/char/tga.c b/drivers/char/tga.c
index a85f4cba4..f4e7b48ab 100644
--- a/drivers/char/tga.c
+++ b/drivers/char/tga.c
@@ -33,11 +33,11 @@
#include <asm/uaccess.h>
#include <asm/bitops.h>
-#include "kbd_kern.h"
-#include "vt_kern.h"
-#include "consolemap.h"
-#include "selection.h"
-#include "console_struct.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
extern struct console vt_console_driver;
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 12109e524..c08e44a27 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -77,9 +77,9 @@
#include <asm/system.h>
#include <asm/bitops.h>
-#include "kbd_kern.h"
-#include "vt_kern.h"
-#include "selection.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
#ifdef CONFIG_KERNELD
#include <linux/kerneld.h>
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index cb91431dc..603250b81 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -31,9 +31,9 @@
#include <linux/interrupt.h>
#include <linux/mm.h>
#include <linux/init.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
#include <asm/uaccess.h>
-#include "vt_kern.h"
-#include "selection.h"
#undef attr
#undef org
diff --git a/drivers/char/vga.c b/drivers/char/vga.c
index e82bbc083..afce24c98 100644
--- a/drivers/char/vga.c
+++ b/drivers/char/vga.c
@@ -72,11 +72,11 @@ unsigned long video_port_base;
#include <asm/uaccess.h>
#include <asm/bitops.h>
-#include "kbd_kern.h"
-#include "vt_kern.h"
-#include "consolemap.h"
-#include "selection.h"
-#include "console_struct.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
#define CAN_LOAD_PALETTE /* undefine if the user must not do this */
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index b3e25c010..7b007f465 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -26,10 +26,10 @@
#include <asm/io.h>
#include <asm/uaccess.h>
-#include "kbd_kern.h"
-#include "vt_kern.h"
-#include "diacr.h"
-#include "selection.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/kbd_diacr.h>
+#include <linux/selection.h>
char vt_dont_switch = 0;
extern struct tty_driver console_driver;
diff --git a/drivers/char/vt_kern.h b/drivers/char/vt_kern.h
deleted file mode 100644
index 1692f991c..000000000
--- a/drivers/char/vt_kern.h
+++ /dev/null
@@ -1,39 +0,0 @@
-#ifndef _VT_KERN_H
-#define _VT_KERN_H
-
-/*
- * this really is an extension of the vc_cons structure in console.c, but
- * with information needed by the vt package
- */
-
-#include <linux/vt.h>
-
-/*
- * Presently, a lot of graphics programs do not restore the contents of
- * the higher font pages. Defining this flag will avoid use of them, but
- * will lose support for PIO_FONTRESET. Note that many font operations are
- * not likely to work with these programs anyway; they need to be
- * fixed. The linux/Documentation directory includes a code snippet
- * to save and restore the text font.
- */
-#define BROKEN_GRAPHICS_PROGRAMS 1
-
-extern struct vt_struct {
- int vc_num; /* The console number */
- unsigned char vc_mode; /* KD_TEXT, ... */
- unsigned char vc_kbdraw;
- unsigned char vc_kbde0;
- unsigned char vc_kbdleds;
- struct vt_mode vt_mode;
- int vt_pid;
- int vt_newvt;
- struct wait_queue *paste_wait;
-} *vt_cons[MAX_NR_CONSOLES];
-
-void (*kd_mksound)(unsigned int hz, unsigned int ticks);
-int vc_allocate(unsigned int console);
-int vc_cons_allocated(unsigned int console);
-int vc_resize(unsigned long lines, unsigned long cols);
-void vc_disallocate(unsigned int console);
-
-#endif /* _VT_KERN_H */
diff --git a/drivers/isdn/hisax/callc.c b/drivers/isdn/hisax/callc.c
index dc29bdf79..91c868942 100644
--- a/drivers/isdn/hisax/callc.c
+++ b/drivers/isdn/hisax/callc.c
@@ -1,4 +1,4 @@
-/* $Id: callc.c,v 1.29 1997/04/23 20:09:49 fritz Exp $
+/* $Id: callc.c,v 1.30 1997/05/29 10:40:43 keil Exp $
* Author Karsten Keil (keil@temic-ech.spacenet.de)
* based on the teles driver from Jan den Ouden
@@ -7,6 +7,9 @@
* Fritz Elfert
*
* $Log: callc.c,v $
+ * Revision 1.30 1997/05/29 10:40:43 keil
+ * chanp->impair was uninitialised
+ *
* Revision 1.29 1997/04/23 20:09:49 fritz
* Removed tmp, used by removed debugging code.
*
@@ -109,7 +112,7 @@ extern long mod_use_count_;
#endif
#endif /* MODULE */
-const char *l4_revision = "$Revision: 1.29 $";
+const char *l4_revision = "$Revision: 1.30 $";
extern struct IsdnCard cards[];
extern int nrcards;
@@ -1504,6 +1507,7 @@ init_chan(int chan, struct IsdnCardState *csta, int hscx,
chanp->debug = 0;
chanp->Flags = 0;
chanp->leased = 0;
+ chanp->impair = 0;
init_is(chanp, ces);
chanp->fi.fsm = &callcfsm;
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index e14c76a61..23befe03c 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -142,10 +142,15 @@ if [ "$CONFIG_NET_RADIO" != "n" ]; then
bool 'Soundmodem support for Soundblaster and compatible cards' CONFIG_SOUNDMODEM_SBC
bool 'Soundmodem support for WSS and Crystal cards' CONFIG_SOUNDMODEM_WSS
bool 'Soundmodem support for 1200 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK1200
+ bool 'Soundmodem support for 2400 baud AFSK modulation (7.3728MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_7
+ bool 'Soundmodem support for 2400 baud AFSK modulation (8MHz crystal)' CONFIG_SOUNDMODEM_AFSK2400_8
bool 'Soundmodem support for 4800 baud HAPN-1 modulation' CONFIG_SOUNDMODEM_HAPN4800
bool 'Soundmodem support for 9600 baud FSK G3RUH modulation' CONFIG_SOUNDMODEM_FSK9600
- if [ "$CONFIG_M586" = "y" -o "$CONFIG_M686" = "y" ]; then
- bool 'Soundmodem using floating point' CONFIG_SOUNDMODEM_FLOAT
+ if [ -f drivers/net/soundmodem/sm_afsk2666.c ]; then
+ bool 'Soundmodem support for 2666 baud AFSK modulation' CONFIG_SOUNDMODEM_AFSK2666
+ fi
+ if [ -f drivers/net/soundmodem/sm_psk4800.c ]; then
+ bool 'Soundmodem support for 4800 baud PSK modulation' CONFIG_SOUNDMODEM_PSK4800
fi
fi
fi
diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c
index 7a8069fd6..c9f13150c 100644
--- a/drivers/net/arcnet.c
+++ b/drivers/net/arcnet.c
@@ -751,8 +751,8 @@ __initfunc(int arcnet_probe(struct device *dev))
* FIXME: grab all devices in one shot and eliminate the big static array.
*/
-static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata;
-static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata;
+static int ports[(0x3f0 - 0x200) / 16 + 1] __initdata = { 0 };
+static u_long shmems[(0xFF800 - 0xA0000) / 2048 + 1] __initdata = { 0 };
__initfunc(int arcnet_probe(struct device *dev))
{
diff --git a/drivers/net/baycom.c b/drivers/net/baycom.c
index 7569d66e7..74c041342 100644
--- a/drivers/net/baycom.c
+++ b/drivers/net/baycom.c
@@ -68,6 +68,7 @@
* History:
* 0.1 26.06.96 Adapted from baycom.c and made network driver interface
* 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
+ * 0.3 26.04.96 init code/data tagged
*/
/*****************************************************************************/
@@ -89,7 +90,6 @@
#include <linux/netdevice.h>
#include <linux/hdlcdrv.h>
#include <linux/baycom.h>
-#include <linux/init.h>
/* --------------------------------------------------------------------- */
@@ -133,6 +133,14 @@ extern inline int copy_to_user(void *to, const void *from, unsigned long n)
}
#endif
+#if LINUX_VERSION_CODE >= 0x20123
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(x) x
+#endif
+
/* --------------------------------------------------------------------- */
#define BAYCOM_DEBUG
@@ -1001,7 +1009,7 @@ MODULE_DESCRIPTION("Baycom ser12, par96 and picpar amateur radio modem driver");
#endif
-int init_module(void)
+__initfunc(int init_module(void))
{
baycom_ports[0].mode = mode;
baycom_ports[0].iobase = iobase;
diff --git a/drivers/net/defxx.c b/drivers/net/defxx.c
index 659e71f32..b841a01bb 100644
--- a/drivers/net/defxx.c
+++ b/drivers/net/defxx.c
@@ -229,7 +229,11 @@ static const char *version = "defxx.c:v1.04 09/16/96 Lawrence V. Stefani (stefa
#define DYNAMIC_BUFFERS 1
#define SKBUFF_RX_COPYBREAK 200
-#define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX)
+/*
+ * NEW_SKB_SIZE = PI_RCV_DATA_K_SIZE_MAX+128 to allow 128 byte
+ * alignment for compatibility with old EISA boards.
+ */
+#define NEW_SKB_SIZE (PI_RCV_DATA_K_SIZE_MAX+128)
/* Define global routines */
@@ -2944,6 +2948,12 @@ void dfx_rcv_init(
bp->descr_block_virt->rcv_data[i+j].long_0 = (u32) (PI_RCV_DESCR_M_SOP |
((PI_RCV_DATA_K_SIZE_MAX / PI_ALIGN_K_RCV_DATA_BUFF) << PI_RCV_DESCR_V_SEG_LEN));
newskb = dev_alloc_skb(NEW_SKB_SIZE);
+ /*
+ * align to 128 bytes for compatibility with
+ * the old EISA boards.
+ */
+ newskb->data = (char *)((unsigned long)
+ (newskb->data+127) & ~128);
bp->descr_block_virt->rcv_data[i+j].long_1 = virt_to_bus(newskb->data);
/*
* p_rcv_buff_va is only used inside the
@@ -3012,8 +3022,6 @@ void dfx_rcv_queue_process(
u32 descr, pkt_len; /* FMC descriptor field and packet length */
struct sk_buff *skb; /* pointer to a sk_buff to hold incoming packet data */
- static int testing_dyn;
-
/* Service all consumed LLC receive frames */
p_type_2_cons = (PI_TYPE_2_CONSUMER *)(&bp->cons_block_virt->xmt_rcv_data);
@@ -3056,18 +3064,12 @@ void dfx_rcv_queue_process(
newskb = dev_alloc_skb(NEW_SKB_SIZE);
if (newskb){
rx_in_place = 1;
-#define JES_TESTING
-#ifdef JES_TESTING
- if(testing_dyn++ < 5)
- printk("Skipping a memcpy\n");
+
+ newskb->data = (char *)((unsigned long)(newskb->data+127) & ~128);
skb = (struct sk_buff *)bp->p_rcv_buff_va[entry];
skb->data += RCV_BUFF_K_PADDING;
bp->p_rcv_buff_va[entry] = (char *)newskb;
bp->descr_block_virt->rcv_data[entry].long_1 = virt_to_bus(newskb->data);
-#else
- memcpy(newskb->data, p_buff + RCV_BUFF_K_PADDING, pkt_len+3);
- skb = newskb;
-#endif
} else
skb = 0;
} else
@@ -3240,12 +3242,14 @@ int dfx_xmt_queue_pkt(
p_xmt_descr = &(bp->descr_block_virt->xmt_data[prod]);
/*
- * Get pointer to auxiliary queue entry to contain information for this packet.
+ * Get pointer to auxiliary queue entry to contain information
+ * for this packet.
*
- * Note: The current xmt producer index will become the current xmt completion
- * index when we complete this packet later on. So, we'll get the
- * pointer to the next auxiliary queue entry now before we bump the
- * producer index.
+ * Note: The current xmt producer index will become the
+ * current xmt completion index when we complete this
+ * packet later on. So, we'll get the pointer to the
+ * next auxiliary queue entry now before we bump the
+ * producer index.
*/
p_xmt_drv_descr = &(bp->xmt_drv_descr_blk[prod++]); /* also bump producer index */
@@ -3290,15 +3294,15 @@ int dfx_xmt_queue_pkt(
* Verify that descriptor is actually available
*
* Note: If descriptor isn't available, return 1 which tells
- * the upper layer to requeue the packet for later
- * transmission.
+ * the upper layer to requeue the packet for later
+ * transmission.
*
* We need to ensure that the producer never reaches the
- * completion, except to indicate that the queue is empty.
+ * completion, except to indicate that the queue is empty.
*/
if (prod == bp->rcv_xmt_reg.index.xmt_comp)
- return(1); /* requeue packet for later */
+ return(1); /* requeue packet for later */
/*
* Save info for this packet for xmt done indication routine
@@ -3311,9 +3315,9 @@ int dfx_xmt_queue_pkt(
* one (1) for each completed packet.
*
* Note: If this assumption changes and we're presented with
- * an inconsistent number of transmit fragments for packet
- * data, we'll need to modify this code to save the current
- * transmit producer index.
+ * an inconsistent number of transmit fragments for packet
+ * data, we'll need to modify this code to save the current
+ * transmit producer index.
*/
p_xmt_drv_descr->p_skb = skb;
diff --git a/drivers/net/hdlcdrv.c b/drivers/net/hdlcdrv.c
index 467980406..666bf3858 100644
--- a/drivers/net/hdlcdrv.c
+++ b/drivers/net/hdlcdrv.c
@@ -32,6 +32,7 @@
* (copy_{to,from}_user)
* 0.2 21.11.96 various small changes
* 0.3 03.03.97 fixed (hopefully) IP not working with ax.25 as a module
+ * 0.4 16.04.97 init code/data tagged
*/
/*****************************************************************************/
@@ -119,6 +120,23 @@ extern __inline__ void dev_init_buffers(struct device *dev)
/* --------------------------------------------------------------------- */
+#if LINUX_VERSION_CODE >= 0x20123
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(x) x
+#endif
+
+/* --------------------------------------------------------------------- */
+
+#if LINUX_VERSION_CODE < 0x20125
+#define test_and_set_bit set_bit
+#define test_and_clear_bit clear_bit
+#endif
+
+/* --------------------------------------------------------------------- */
+
/*
* The name of the card. Is used for messages and in the requests for
* io regions, irqs and dma channels
@@ -998,10 +1016,10 @@ MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
/* --------------------------------------------------------------------- */
-int init_module(void)
+__initfunc(int init_module(void))
{
printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
- printk(KERN_INFO "hdlcdrv: version 0.3 compiled " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "hdlcdrv: version 0.4 compiled " __TIME__ " " __DATE__ "\n");
#if LINUX_VERSION_CODE < 0x20115
register_symtab(&hdlcdrv_syms);
#endif
diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c
index 9d8e30761..ef15a14da 100644
--- a/drivers/net/net_init.c
+++ b/drivers/net/net_init.c
@@ -248,7 +248,7 @@ void fddi_setup(struct device *dev)
#endif
-#ifdef CONFIG_ATALK
+#if defined(CONFIG_ATALK) || defined(CONFIG_ATALK_MODULE)
static int ltalk_change_mtu(struct device *dev, int mtu)
{
diff --git a/drivers/net/soundmodem/Makefile b/drivers/net/soundmodem/Makefile
index 119118128..5259b724c 100644
--- a/drivers/net/soundmodem/Makefile
+++ b/drivers/net/soundmodem/Makefile
@@ -21,6 +21,12 @@ endif
ifeq ($(CONFIG_SOUNDMODEM_AFSK1200),y)
O_OBJS += sm_afsk1200.o
endif
+ifeq ($(CONFIG_SOUNDMODEM_AFSK2400_7),y)
+O_OBJS += sm_afsk2400_7.o
+endif
+ifeq ($(CONFIG_SOUNDMODEM_AFSK2400_8),y)
+O_OBJS += sm_afsk2400_8.o
+endif
ifeq ($(CONFIG_SOUNDMODEM_AFSK2666),y)
O_OBJS += sm_afsk2666.o
endif
@@ -39,7 +45,8 @@ M_OBJS := $(O_TARGET)
gentbl: gentbl.c
$(HOSTCC) -Wall $< -o $@ -lm
-TBLHDR := sm_tbl_afsk1200.h sm_tbl_afsk2666.h sm_tbl_psk4800.h
+TBLHDR := sm_tbl_afsk1200.h sm_tbl_afsk2400_8.h
+TBLHDR += sm_tbl_afsk2666.h sm_tbl_psk4800.h
TBLHDR += sm_tbl_hapn4800.h sm_tbl_fsk9600.h
$(TBLHDR): gentbl
diff --git a/drivers/net/soundmodem/gentbl.c b/drivers/net/soundmodem/gentbl.c
index d617865e3..cb8cb246f 100644
--- a/drivers/net/soundmodem/gentbl.c
+++ b/drivers/net/soundmodem/gentbl.c
@@ -31,27 +31,44 @@
/* -------------------------------------------------------------------- */
-#define OFFSCOSTABBITS 6
-#define OFFSCOSTABSIZE (1<<OFFSCOSTABBITS)
-
-static void gentbl_offscostab(FILE *f)
+static void gentbl_offscostab(FILE *f, unsigned int nbits)
{
int i;
fprintf(f, "\n/*\n * small cosine table in U8 format\n */\n"
"#define OFFSCOSTABBITS %u\n"
"#define OFFSCOSTABSIZE (1<<OFFSCOSTABBITS)\n\n",
- OFFSCOSTABBITS);
+ nbits);
fprintf(f, "static unsigned char offscostab[OFFSCOSTABSIZE] = {\n\t");
- for (i = 0; i < OFFSCOSTABSIZE; i++) {
+ for (i = 0; i < (1<<nbits); i++) {
fprintf(f, "%4u", (int)
- (128+127.0*cos(i*2.0*M_PI/OFFSCOSTABSIZE)));
- if (i < OFFSCOSTABSIZE-1)
+ (128+127.0*cos(i*2.0*M_PI/(1<<nbits))));
+ if (i < (1<<nbits)-1)
fprintf(f, "%s", (i & 7) == 7 ? ",\n\t" : ",");
}
fprintf(f, "\n};\n\n"
"#define OFFSCOS(x) offscostab[((x)>>%d)&0x%x]\n\n",
- 16-OFFSCOSTABBITS, OFFSCOSTABSIZE-1);
+ 16-nbits, (1<<nbits)-1);
+}
+
+/* -------------------------------------------------------------------- */
+
+static void gentbl_costab(FILE *f, unsigned int nbits)
+{
+ int i;
+
+ fprintf(f, "\n/*\n * more accurate cosine table\n */\n\n"
+ "static const short costab[%d] = {", (1<<nbits));
+ for (i = 0; i < (1<<nbits); i++) {
+ if (!(i & 7))
+ fprintf(f, "\n\t");
+ fprintf(f, "%6d", (int)(32767.0*cos(i*2.0*M_PI/(1<<nbits))));
+ if (i != ((1<<nbits)-1))
+ fprintf(f, ", ");
+ }
+ fprintf(f, "\n};\n\n#define COS(x) costab[((x)>>%d)&0x%x]\n"
+ "#define SIN(x) COS((x)+0xc000)\n\n", 16-nbits,
+ (1<<nbits)-1);
}
/* -------------------------------------------------------------------- */
@@ -63,7 +80,8 @@ static void gentbl_offscostab(FILE *f)
static void gentbl_afsk1200(FILE *f)
{
- int i;
+ int i, v, sum;
+ float fv, fsum;
#define ARGLO(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_LO/(double)AFSK12_SAMPLE_RATE
#define ARGHI(x) 2.0*M_PI*(double)x*(double)AFSK12_TX_FREQ_HI/(double)AFSK12_SAMPLE_RATE
@@ -75,42 +93,58 @@ static void gentbl_afsk1200(FILE *f)
"#define AFSK12_CORRLEN %u\n\n",
AFSK12_SAMPLE_RATE, AFSK12_TX_FREQ_LO,
AFSK12_TX_FREQ_HI, AFSK12_CORRLEN);
- fprintf(f, "#if defined (CONFIG_SOUNDMODEM__AFSK1200_FP) && "
+ fprintf(f, "#if defined(CONFIG_SOUNDMODEM_FLOAT) && "
"(defined(CONFIG_M586) || defined(CONFIG_M686))\n\n"
"static const float afsk12_tx_lo_i_f[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %7f%c", cos(ARGLO(i)),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const float afsk12_tx_lo_q_f[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %7f%c", sin(ARGLO(i)),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const float afsk12_tx_hi_i_f[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %7f%c", cos(ARGHI(i)),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const float afsk12_tx_hi_q_f[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %7f%c", sin(ARGHI(i)),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\n#else /* CONFIG_SOUNDMODEM_AFSK1200_FP */\n\n"
- "static const signed char afsk12_tx_lo_i[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %4i%c", (int)(127.0*cos(ARGLO(i))),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const signed char afsk12_tx_lo_q[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %4i%c", (int)(127.0*sin(ARGLO(i))),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const signed char afsk12_tx_hi_i[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %4i%c", (int)(127.0*cos(ARGHI(i))),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\nstatic const signed char afsk12_tx_hi_q[] = {\n\t");
- for(i = 0; i < AFSK12_CORRLEN; i++)
- fprintf(f, " %4i%c", (int)(127.0*sin(ARGHI(i))),
- (i < AFSK12_CORRLEN-1) ? ',' : ' ');
- fprintf(f, "\n};\n\n#endif /* CONFIG_SOUNDMODEM_AFSK1200_FP */\n\n");
+ for(fsum = i = 0; i < AFSK12_CORRLEN; i++) {
+ fsum += (fv = cos(ARGLO(i)));
+ fprintf(f, " %7f%c", fv, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_Q %7f\n\n"
+ "static const float afsk12_tx_lo_q_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK12_CORRLEN; i++) {
+ fsum += (fv = sin(ARGLO(i)));
+ fprintf(f, " %7f%c", fv, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_Q %7f\n\n"
+ "static const float afsk12_tx_hi_i_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK12_CORRLEN; i++) {
+ fsum += (fv = cos(ARGHI(i)));
+ fprintf(f, " %7f%c", fv, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_I %7f\n\n"
+ "static const float afsk12_tx_hi_q_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK12_CORRLEN; i++) {
+ fsum += (fv = sin(ARGHI(i)));
+ fprintf(f, " %7f%c", fv, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_Q %7f\n\n"
+ "#else /* CONFIG_SOUNDMODEM_FLOAT */\n\n"
+ "static const int afsk12_tx_lo_i[] = {\n\t", fsum);
+ for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
+ sum += (v = 127.0*cos(ARGLO(i)));
+ fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_I %d\n\n"
+ "static const int afsk12_tx_lo_q[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
+ sum += (v = 127.0*sin(ARGLO(i)));
+ fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_LO_Q %d\n\n"
+ "static const int afsk12_tx_hi_i[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
+ sum += (v = 127.0*cos(ARGHI(i)));
+ fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_I %d\n\n"
+ "static const int afsk12_tx_hi_q[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK12_CORRLEN; i++) {
+ sum += (v = 127.0*sin(ARGHI(i)));
+ fprintf(f, " %4i%c", v, (i < AFSK12_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK12_TX_HI_Q %d\n\n"
+ "#endif /* CONFIG_SOUNDMODEM_FLOAT */\n\n", sum);
#undef ARGLO
#undef ARGHI
}
@@ -252,7 +286,7 @@ static void gentbl_fsk9600(FILE *f)
static void gentbl_afsk2666(FILE *f)
{
- int i, j, k, l, o;
+ int i, j, k, l, o, v, sumi, sumq;
float window[AFSK26_DEMCORRLEN*AFSK26_RXOVER];
int cfreq[AFSK26_NUMCAR];
@@ -274,32 +308,30 @@ static void gentbl_afsk2666(FILE *f)
window[i] = AFSK26_WINDOW(((float)i)/(AFSK26_DEMCORRLEN*
AFSK26_RXOVER)) * 127.0;
fprintf(f, "\nstatic const struct {\n\t"
- "signed char i[%d];\n\tsigned char q[%d];\n} afsk26_dem_tables[%d][2] = {\n",
- AFSK26_DEMCORRLEN, AFSK26_DEMCORRLEN, AFSK26_RXOVER);
+ "int i[%d];\n\tint q[%d];\n} afsk26_dem_tables[%d][%d] = {\n",
+ AFSK26_DEMCORRLEN, AFSK26_DEMCORRLEN, AFSK26_RXOVER, AFSK26_NUMCAR);
for (o = AFSK26_RXOVER-1; o >= 0; o--) {
fprintf(f, "\t{\n");
for (i = 0; i < AFSK26_NUMCAR; i++) {
j = cfreq[i];
fprintf(f, "\t\t{{ ");
- for (l = AFSK26_DEMCORRLEN-1,
- k = (j * o)/AFSK26_RXOVER; l >= 0;
- l--, k = (k+j)&0xffffu)
- fprintf(f, "%6d%s", (int)
- (AFSK26_AMPL(i)*
- window[l*AFSK26_RXOVER+o]*
- cos(M_PI*k/32768.0)),
- l ? ", " : " }, { ");
- for (l = AFSK26_DEMCORRLEN-1,
- k = (j * o)/AFSK26_RXOVER; l >= 0;
- l--, k = (k+j)&0xffffu)
- fprintf(f, "%6d%s", (int)
- (AFSK26_AMPL(i)*
- window[l*AFSK26_RXOVER+o]*
- sin(M_PI*k/32768.0)),
- l ? ", " : " }}");
+ for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumi = 0; l >= 0;
+ l--, k = (k+j)&0xffffu) {
+ sumi += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
+ cos(M_PI*k/32768.0));
+ fprintf(f, "%6d%s", v, l ? ", " : " }, { ");
+ }
+ for (l = AFSK26_DEMCORRLEN-1, k = (j * o)/AFSK26_RXOVER, sumq = 0; l >= 0;
+ l--, k = (k+j)&0xffffu) {
+ sumq += (v = AFSK26_AMPL(i)*window[l*AFSK26_RXOVER+o]*
+ sin(M_PI*k/32768.0));
+ fprintf(f, "%6d%s", v, l ? ", " : " }}");
+ }
if (i < 1)
fprintf(f, ",");
- fprintf(f, "\n");
+ fprintf(f, "\n#define AFSK26_DEM_SUM_I_%d_%d %d\n"
+ "#define AFSK26_DEM_SUM_Q_%d_%d %d\n",
+ AFSK26_RXOVER-1-o, i, sumi, AFSK26_RXOVER-1-o, i, sumq);
}
fprintf(f, "\t}%s\n", o ? "," : "");
}
@@ -308,28 +340,6 @@ static void gentbl_afsk2666(FILE *f)
/* -------------------------------------------------------------------- */
-#define COSTABBITS 8
-
-static void gentbl_costab(FILE *f)
-{
- int i;
-
- fprintf(f, "\n/*\n * more accurate cosine table\n */\n\n"
- "static const short costab[%d] = {", (1<<COSTABBITS));
- for (i = 0; i < (1<<COSTABBITS); i++) {
- if (!(i & 7))
- fprintf(f, "\n\t");
- fprintf(f, "%6d", (int)(32767.0*cos(i*2.0*M_PI/(1<<COSTABBITS))));
- if (i != ((1<<COSTABBITS)-1))
- fprintf(f, ", ");
- }
- fprintf(f, "\n};\n\n#define COS(x) costab[((x)>>%d)&0x%x]\n"
- "#define SIN(x) COS((x)+0xc000)\n\n", 16-COSTABBITS,
- (1<<COSTABBITS)-1);
-}
-
-/* -------------------------------------------------------------------- */
-
#define ATAN_TABLEN 1024
static void gentbl_atantab(FILE *f)
@@ -578,6 +588,85 @@ static void gentbl_hapn4800(FILE *f)
/* -------------------------------------------------------------------- */
+#define AFSK24_SAMPLERATE 16000
+#define AFSK24_CORRLEN 14
+
+static void gentbl_afsk2400(FILE *f, float tcm3105clk)
+{
+ int i, sum, v;
+ float fsum, fv;
+
+ fprintf(f, "\n/*\n * afsk2400 specific tables (tcm3105 clk %7fHz)\n */\n"
+ "#define AFSK24_TX_FREQ_LO %d\n"
+ "#define AFSK24_TX_FREQ_HI %d\n"
+ "#define AFSK24_BITPLL_INC %d\n"
+ "#define AFSK24_SAMPLERATE %d\n\n", tcm3105clk,
+ (int)(tcm3105clk/3694.0), (int)(tcm3105clk/2015.0),
+ 0x10000*2400/AFSK24_SAMPLERATE, AFSK24_SAMPLERATE);
+
+#define ARGLO(x) 2.0*M_PI*(double)x*(tcm3105clk/3694.0)/(double)AFSK24_SAMPLERATE
+#define ARGHI(x) 2.0*M_PI*(double)x*(tcm3105clk/2015.0)/(double)AFSK24_SAMPLERATE
+#define WINDOW(x) hamming((float)(x)/(AFSK24_CORRLEN-1.0))
+
+ fprintf(f, "#if defined(CONFIG_SOUNDMODEM_FLOAT) && "
+ "(defined(CONFIG_M586) || defined(CONFIG_M686))\n\n"
+ "static const float afsk24_tx_lo_i_f[] = {\n\t");
+ for(fsum = i = 0; i < AFSK24_CORRLEN; i++) {
+ fsum += (fv = cos(ARGLO(i))*WINDOW(i));
+ fprintf(f, " %7f%c", fv, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_Q %7f\n\n"
+ "static const float afsk24_tx_lo_q_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK24_CORRLEN; i++) {
+ fsum += (fv = sin(ARGLO(i))*WINDOW(i));
+ fprintf(f, " %7f%c", fv, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_Q %7f\n\n"
+ "static const float afsk24_tx_hi_i_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK24_CORRLEN; i++) {
+ fsum += (fv = cos(ARGHI(i))*WINDOW(i));
+ fprintf(f, " %7f%c", fv, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_I %7f\n\n"
+ "static const float afsk24_tx_hi_q_f[] = {\n\t", fsum);
+ for(fsum = i = 0; i < AFSK24_CORRLEN; i++) {
+ fsum += (fv = sin(ARGHI(i))*WINDOW(i));
+ fprintf(f, " %7f%c", fv, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_Q %7f\n\n"
+ "#else /* CONFIG_SOUNDMODEM_FLOAT */\n\n"
+ "static const int afsk24_tx_lo_i[] = {\n\t", fsum);
+ for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
+ sum += (v = 127.0*cos(ARGLO(i))*WINDOW(i));
+ fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_I %d\n\n"
+ "static const int afsk24_tx_lo_q[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
+ sum += (v = 127.0*sin(ARGLO(i))*WINDOW(i));
+ fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_LO_Q %d\n\n"
+ "static const int afsk24_tx_hi_i[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
+ sum += (v = 127.0*cos(ARGHI(i))*WINDOW(i));
+ fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_I %d\n\n"
+ "static const int afsk24_tx_hi_q[] = {\n\t", sum);
+ for(sum = i = 0; i < AFSK24_CORRLEN; i++) {
+ sum += (v = 127.0*sin(ARGHI(i))*WINDOW(i));
+ fprintf(f, " %4i%c", v, (i < AFSK24_CORRLEN-1) ? ',' : ' ');
+ }
+ fprintf(f, "\n};\n#define SUM_AFSK24_TX_HI_Q %d\n\n"
+ "#endif /* CONFIG_SOUNDMODEM_FLOAT */\n\n", sum);
+#undef ARGLO
+#undef ARGHI
+#undef WINDOW
+}
+
+/* -------------------------------------------------------------------- */
+
static char *progname;
static void gentbl_banner(FILE *f)
@@ -586,6 +675,11 @@ static void gentbl_banner(FILE *f)
"DO NOT EDIT!\n */\n\n", progname);
}
+static void gentbl_needs_config(FILE *f)
+{
+ fprintf(f, "\n#include <linux/config.h>\n\n");
+}
+
/* -------------------------------------------------------------------- */
void main(int argc, char *argv[])
@@ -596,20 +690,23 @@ void main(int argc, char *argv[])
if (!(f = fopen("sm_tbl_afsk1200.h", "w")))
exit(1);
gentbl_banner(f);
- gentbl_offscostab(f);
+ gentbl_needs_config(f);
+ gentbl_offscostab(f, 6);
+ gentbl_costab(f, 6);
gentbl_afsk1200(f);
fclose(f);
if (!(f = fopen("sm_tbl_afsk2666.h", "w")))
exit(1);
gentbl_banner(f);
- gentbl_offscostab(f);
+ gentbl_offscostab(f, 6);
+ gentbl_costab(f, 6);
gentbl_afsk2666(f);
fclose(f);
if (!(f = fopen("sm_tbl_psk4800.h", "w")))
exit(1);
gentbl_banner(f);
gentbl_psk4800(f);
- gentbl_costab(f);
+ gentbl_costab(f, 8);
gentbl_atantab(f);
fclose(f);
if (!(f = fopen("sm_tbl_hapn4800.h", "w")))
@@ -622,6 +719,22 @@ void main(int argc, char *argv[])
gentbl_banner(f);
gentbl_fsk9600(f);
fclose(f);
+ if (!(f = fopen("sm_tbl_afsk2400_8.h", "w")))
+ exit(1);
+ gentbl_banner(f);
+ gentbl_needs_config(f);
+ gentbl_offscostab(f, 6);
+ gentbl_costab(f, 6);
+ gentbl_afsk2400(f, 8000000);
+ fclose(f);
+ if (!(f = fopen("sm_tbl_afsk2400_7.h", "w")))
+ exit(1);
+ gentbl_banner(f);
+ gentbl_needs_config(f);
+ gentbl_offscostab(f, 6);
+ gentbl_costab(f, 6);
+ gentbl_afsk2400(f, 7372800);
+ fclose(f);
exit(0);
}
diff --git a/drivers/net/soundmodem/sm.c b/drivers/net/soundmodem/sm.c
index d55bc0c04..ac1fbac48 100644
--- a/drivers/net/soundmodem/sm.c
+++ b/drivers/net/soundmodem/sm.c
@@ -38,6 +38,7 @@
* 18.10.96 Changed to new user space access routines (copy_{to,from}_user)
* 0.4 21.01.97 Separately compileable soundcard/modem modules
* 0.5 03.03.97 fixed LPT probing (check_lpt result was interpreted the wrong way round)
+ * 0.6 16.04.97 init code/data tagged
*/
/*****************************************************************************/
@@ -56,7 +57,6 @@
#include <asm/bitops.h>
#include <linux/delay.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include "sm.h"
/* --------------------------------------------------------------------- */
@@ -101,18 +101,32 @@ extern inline int copy_to_user(void *to, const void *from, unsigned long n)
}
#endif
+#if LINUX_VERSION_CODE >= 0x20123
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(x) x
+#endif
+
/* --------------------------------------------------------------------- */
-const char sm_drvname[] = "soundmodem";
-static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996 Thomas Sailer, HB9JNX/AE4WA\n"
-KERN_INFO "soundmodem: version 0.5 compiled " __TIME__ " " __DATE__ "\n";
+/*static*/ const char sm_drvname[] = "soundmodem";
+static const char sm_drvinfo[] = KERN_INFO "soundmodem: (C) 1996-1997 Thomas Sailer, HB9JNX/AE4WA\n"
+KERN_INFO "soundmodem: version 0.6 compiled " __TIME__ " " __DATE__ "\n";
/* --------------------------------------------------------------------- */
-const struct modem_tx_info *sm_modem_tx_table[] = {
+/*static*/ const struct modem_tx_info *sm_modem_tx_table[] = {
#ifdef CONFIG_SOUNDMODEM_AFSK1200
&sm_afsk1200_tx,
#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
+#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
+ &sm_afsk2400_7_tx,
+#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
+#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
+ &sm_afsk2400_8_tx,
+#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
#ifdef CONFIG_SOUNDMODEM_AFSK2666
&sm_afsk2666_tx,
#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
@@ -132,10 +146,16 @@ const struct modem_tx_info *sm_modem_tx_table[] = {
NULL
};
-const struct modem_rx_info *sm_modem_rx_table[] = {
+/*static*/ const struct modem_rx_info *sm_modem_rx_table[] = {
#ifdef CONFIG_SOUNDMODEM_AFSK1200
&sm_afsk1200_rx,
#endif /* CONFIG_SOUNDMODEM_AFSK1200 */
+#ifdef CONFIG_SOUNDMODEM_AFSK2400_7
+ &sm_afsk2400_7_rx,
+#endif /* CONFIG_SOUNDMODEM_AFSK2400_7 */
+#ifdef CONFIG_SOUNDMODEM_AFSK2400_8
+ &sm_afsk2400_8_rx,
+#endif /* CONFIG_SOUNDMODEM_AFSK2400_8 */
#ifdef CONFIG_SOUNDMODEM_AFSK2666
&sm_afsk2666_rx,
#endif /* CONFIG_SOUNDMODEM_AFSK2666 */
@@ -344,7 +364,7 @@ void sm_output_status(struct sm_state *sm)
int invert_dcd = 0;
int invert_ptt = 0;
- int ptt = hdlcdrv_ptt(&sm->hdrv) ^ invert_ptt;
+ int ptt = /*hdlcdrv_ptt(&sm->hdrv)*/(sm->dma.ptt_cnt > 0) ^ invert_ptt;
int dcd = (!!sm->hdrv.hdlcrx.dcd) ^ invert_dcd;
if (sm->hdrv.ptt_out.flags & SP_SER) {
@@ -457,9 +477,9 @@ static int sm_open(struct device *dev)
return err;
sm_output_open(sm);
MOD_INC_USE_COUNT;
- printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u\n",
+ printk(KERN_INFO "%s: %s mode %s.%s at iobase 0x%lx irq %u dma %u dma2 %u\n",
sm_drvname, sm->hwdrv->hw_name, sm->mode_tx->name,
- sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma);
+ sm->mode_rx->name, dev->base_addr, dev->irq, dev->dma, sm->hdrv.ptt_out.dma2);
return 0;
}
@@ -664,7 +684,56 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
/* --------------------------------------------------------------------- */
+#ifdef __i386__
+
+int sm_x86_capability = 0;
+
+__initfunc(static void i386_capability(void))
+{
+ unsigned long flags;
+ unsigned long fl1;
+ union {
+ struct {
+ unsigned int ebx, edx, ecx;
+ } r;
+ unsigned char s[13];
+ } id;
+ unsigned int eax;
+
+ save_flags(flags);
+ flags |= 0x200000;
+ restore_flags(flags);
+ save_flags(flags);
+ fl1 = flags;
+ flags &= ~0x200000;
+ restore_flags(flags);
+ save_flags(flags);
+ if (!(fl1 & 0x200000) || (flags & 0x200000)) {
+ printk(KERN_WARNING "%s: cpu does not support CPUID\n", sm_drvname);
+ return;
+ }
+ __asm__ ("cpuid" : "=a" (eax), "=b" (id.r.ebx), "=c" (id.r.ecx), "=d" (id.r.edx) :
+ "0" (0));
+ id.s[12] = 0;
+ if (eax < 1) {
+ printk(KERN_WARNING "%s: cpu (vendor string %s) does not support capability "
+ "list\n", sm_drvname, id.s);
+ return;
+ }
+ printk(KERN_INFO "%s: cpu: vendor string %s ", sm_drvname, id.s);
+ __asm__ ("cpuid" : "=a" (eax), "=d" (sm_x86_capability) : "0" (1) : "ebx", "ecx");
+ printk("fam %d mdl %d step %d cap 0x%x\n", (eax >> 8) & 15, (eax >> 4) & 15,
+ eax & 15, sm_x86_capability);
+}
+#endif /* __i386__ */
+
+/* --------------------------------------------------------------------- */
+
+#ifdef MODULE
+__initfunc(static int sm_init(void))
+#else /* MODULE */
__initfunc(int sm_init(void))
+#endif /* MODULE */
{
int i, j, found = 0;
char set_hw = 1;
@@ -672,6 +741,9 @@ __initfunc(int sm_init(void))
char ifname[HDLCDRV_IFNAMELEN];
printk(sm_drvinfo);
+#ifdef __i386__
+ i386_capability();
+#endif /* __i386__ */
/*
* register net devices
*/
@@ -745,7 +817,7 @@ MODULE_DESCRIPTION("Soundcard amateur radio modem driver");
#endif
-int init_module(void)
+__initfunc(int init_module(void))
{
if (mode) {
if (iobase == -1)
diff --git a/drivers/net/soundmodem/sm.h b/drivers/net/soundmodem/sm.h
index 2cce82992..25bbc8ba9 100644
--- a/drivers/net/soundmodem/sm.h
+++ b/drivers/net/soundmodem/sm.h
@@ -30,16 +30,11 @@
/* ---------------------------------------------------------------------- */
-#include <linux/config.h>
#include <linux/hdlcdrv.h>
#include <linux/soundmodem.h>
#define SM_DEBUG
-/* --------------------------------------------------------------------- */
-
-#define DMA_MODE_AUTOINIT 0x10
-
/* ---------------------------------------------------------------------- */
/*
* Information that need to be kept for each board.
@@ -56,6 +51,18 @@ struct sm_state {
/*
* Hardware (soundcard) access routines state
*/
+ struct {
+ void *ibuf;
+ unsigned int ifragsz;
+ unsigned int ifragptr;
+ unsigned int i16bit;
+ void *obuf;
+ unsigned int ofragsz;
+ unsigned int ofragptr;
+ unsigned int o16bit;
+ int ptt_cnt;
+ } dma;
+
union {
long hw[32/sizeof(long)];
} hw;
@@ -101,9 +108,9 @@ struct modem_tx_info {
unsigned int loc_storage;
int srate;
int bitrate;
- unsigned int dmabuflenmodulo;
- void (*modulator)(struct sm_state *, unsigned char *, int);
- void (*init)(struct sm_state *);
+ void (*modulator_u8)(struct sm_state *, unsigned char *, unsigned int);
+ void (*modulator_s16)(struct sm_state *, short *, unsigned int);
+ void (*init)(struct sm_state *);
};
struct modem_rx_info {
@@ -111,10 +118,11 @@ struct modem_rx_info {
unsigned int loc_storage;
int srate;
int bitrate;
- unsigned int dmabuflenmodulo;
+ unsigned int overlap;
unsigned int sperbit;
- void (*demodulator)(struct sm_state *, unsigned char *, int);
- void (*init)(struct sm_state *);
+ void (*demodulator_u8)(struct sm_state *, const unsigned char *, unsigned int);
+ void (*demodulator_s16)(struct sm_state *, const short *, unsigned int);
+ void (*init)(struct sm_state *);
};
/* ---------------------------------------------------------------------- */
@@ -281,30 +289,41 @@ extern inline unsigned int lcm(unsigned int x, unsigned int y)
*/
-#if defined(SM_DEBUG) && (defined(CONFIG_M586) || defined(CONFIG_M686))
+#ifdef __i386__
+
+extern int sm_x86_capability;
+
+#define HAS_RDTSC (sm_x86_capability & 0x10)
/*
* only do 32bit cycle counter arithmetic; we hope we won't overflow :-)
* in fact, overflowing modems would require over 2THz clock speeds :-)
*/
-#define time_exec(var,cmd) \
-({ \
- unsigned int cnt1, cnt2, cnt3; \
- __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); \
- cmd; \
- __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); \
- var = cnt2-cnt1; \
+#define time_exec(var,cmd) \
+({ \
+ if (HAS_RDTSC) { \
+ unsigned int cnt1, cnt2, cnt3; \
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt1), "=d" (cnt3)); \
+ cmd; \
+ __asm__(".byte 0x0f,0x31" : "=a" (cnt2), "=d" (cnt3)); \
+ var = cnt2-cnt1; \
+ } else { \
+ cmd; \
+ } \
})
-#else /* defined(SM_DEBUG) && (defined(CONFIG_M586) || defined(CONFIG_M686)) */
+
+#else /* __i386__ */
#define time_exec(var,cmd) cmd
-#endif /* defined(SM_DEBUG) && (defined(CONFIG_M586) || defined(CONFIG_M686)) */
+#endif /* __i386__ */
/* --------------------------------------------------------------------- */
extern const struct modem_tx_info sm_afsk1200_tx;
+extern const struct modem_tx_info sm_afsk2400_7_tx;
+extern const struct modem_tx_info sm_afsk2400_8_tx;
extern const struct modem_tx_info sm_afsk2666_tx;
extern const struct modem_tx_info sm_psk4800_tx;
extern const struct modem_tx_info sm_hapn4800_8_tx;
@@ -315,6 +334,8 @@ extern const struct modem_tx_info sm_fsk9600_4_tx;
extern const struct modem_tx_info sm_fsk9600_5_tx;
extern const struct modem_rx_info sm_afsk1200_rx;
+extern const struct modem_rx_info sm_afsk2400_7_rx;
+extern const struct modem_rx_info sm_afsk2400_8_rx;
extern const struct modem_rx_info sm_afsk2666_rx;
extern const struct modem_rx_info sm_psk4800_rx;
extern const struct modem_rx_info sm_hapn4800_8_rx;
diff --git a/drivers/net/soundmodem/sm_afsk1200.c b/drivers/net/soundmodem/sm_afsk1200.c
index 0519c5e79..64b20a57c 100644
--- a/drivers/net/soundmodem/sm_afsk1200.c
+++ b/drivers/net/soundmodem/sm_afsk1200.c
@@ -38,174 +38,176 @@ struct demod_state_afsk12 {
int dcd_sum0, dcd_sum1, dcd_sum2;
unsigned int dcd_time;
unsigned char last_rxbit;
- union {
- signed char c[8];
- float f[8];
- } filt;
};
struct mod_state_afsk12 {
unsigned int shreg;
unsigned char tx_bit;
unsigned int bit_pll;
+ unsigned int dds_inc;
+ unsigned int txphase;
};
/* --------------------------------------------------------------------- */
-static void modulator_1200(struct sm_state *sm, unsigned char *buf, int buflen)
+static const int dds_inc[2] = {
+ AFSK12_TX_FREQ_LO*0x10000/AFSK12_SAMPLE_RATE,
+ AFSK12_TX_FREQ_HI*0x10000/AFSK12_SAMPLE_RATE
+};
+
+static void modulator_1200_u8(struct sm_state *sm, unsigned char *buf,
+ unsigned int buflen)
{
struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
- static const int dds_inc[2] = { AFSK12_TX_FREQ_LO*0x10000/AFSK12_SAMPLE_RATE,
- AFSK12_TX_FREQ_HI*0x10000/AFSK12_SAMPLE_RATE };
- int j, k;
-
- for (; buflen >= 8; buflen -= 8) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit ^
- (!(st->shreg & 1))) & 1;
- st->shreg >>= 1;
- k = dds_inc[st->tx_bit & 1];
- for (j = 0; j < 8; j++) {
- *buf++ = OFFSCOS(st->bit_pll);
- st->bit_pll += k;
+
+ for (; buflen > 0; buflen--) {
+ if (!((st->txphase++) & 7)) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
}
+ st->dds_inc = dds_inc[st->tx_bit & 1];
+ *buf++ = OFFSCOS(st->bit_pll);
+ st->bit_pll += st->dds_inc;
}
}
/* --------------------------------------------------------------------- */
+static void modulator_1200_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_afsk12 *st = (struct mod_state_afsk12 *)(&sm->m);
-/*
- * should eventually move to an asm header file
- */
-
-
-#if defined (CONFIG_SOUNDMODEM__AFSK1200_FP) && (defined(CONFIG_M586) || defined(CONFIG_M686))
-
+ for (; buflen > 0; buflen--) {
+ if (!((st->txphase++) & 7)) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
+ }
+ st->dds_inc = dds_inc[st->tx_bit & 1];
+ *buf++ = COS(st->bit_pll);
+ st->bit_pll += st->dds_inc;
+ }
+}
+/* --------------------------------------------------------------------- */
-#define ENV_STORAGE unsigned char fpu_save[108];
+extern __inline__ int convolution8_u8(const unsigned char *st, const int *coeff, int csum)
+{
+ int sum = -0x80 * csum;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
-#define ENV_SAVE asm("fsave %0;\n\tfninit;\n\t" : "=m" (*fpu_save) : : "memory");
-#define ENV_RESTORE asm("frstor %0;\n\t" : : "m" (*fpu_save));
+ sum >>= 7;
+ return sum * sum;
+}
-static inline float convolution8(const float *st, const float *coeff)
+extern __inline__ int convolution8_s16(const short *st, const int *coeff, int csum)
{
- float f;
-
- /*
- * from Phil Karn, KA9Q's home page
- */
- asm volatile ("flds (%1);\n\t"
- "fmuls (%2);\n\t"
- "flds 4(%1);\n\t"
- "fmuls 4(%2);\n\t"
- "flds 8(%1);\n\t"
- "fmuls 8(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "flds 12(%1);\n\t"
- "fmuls 12(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "flds 16(%1);\n\t"
- "fmuls 16(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "flds 20(%1);\n\t"
- "fmuls 20(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "flds 24(%1);\n\t"
- "fmuls 24(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "flds 28(%1);\n\t"
- "fmuls 28(%2);\n\t"
- "fxch %%st(2);\n\t"
- "faddp;\n\t"
- "faddp;\n\t"
- "fmul %%st(0),%%st;\n\t" :
- "=t" (f) :
- "r" (st),
- "r" (coeff) : "memory");
-
- return f;
+ int sum = 0;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
+
+ sum >>= 15;
+ return sum * sum;
}
-static inline int do_filter_1200(struct demod_state_afsk12 *st, unsigned char newval)
+extern __inline__ int do_filter_1200_u8(const unsigned char *buf)
{
- float sum;
-
- memmove(st->filt.f+1, st->filt.f,sizeof(st->filt.f) - sizeof(st->filt.f[0]));
- st->filt.f[0] = (((int)newval)-0x80);
-
- sum = convolution8(st->filt.f, afsk12_tx_lo_i_f);
- sum += convolution8(st->filt.f, afsk12_tx_lo_q_f);
- sum -= convolution8(st->filt.f, afsk12_tx_hi_i_f);
- sum -= convolution8(st->filt.f, afsk12_tx_hi_q_f);
+ int sum = convolution8_u8(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
+ sum += convolution8_u8(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
+ sum -= convolution8_u8(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
+ sum -= convolution8_u8(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
return sum;
}
-#else /* defined (CONFIG_SOUNDMODEM__AFSK1200_FP) && (defined(CONFIG_M586) || defined(CONFIG_M686)) */
-
-#define ENV_STORAGE
-#define ENV_SAVE
-#define ENV_RESTORE
-
-static inline void datamove8(signed char *st, unsigned char newval)
+extern __inline__ int do_filter_1200_s16(const short *buf)
{
- memmove(st+1, st, 7);
- *st = newval - 0x80;
+ int sum = convolution8_s16(buf, afsk12_tx_lo_i, SUM_AFSK12_TX_LO_I);
+ sum += convolution8_s16(buf, afsk12_tx_lo_q, SUM_AFSK12_TX_LO_Q);
+ sum -= convolution8_s16(buf, afsk12_tx_hi_i, SUM_AFSK12_TX_HI_I);
+ sum -= convolution8_s16(buf, afsk12_tx_hi_q, SUM_AFSK12_TX_HI_Q);
+ return sum;
}
-static inline int convolution8(const signed char *st, const signed char *coeff)
-{
- int sum = (st[0] * coeff[0]);
-
- sum += (st[1] * coeff[1]);
- sum += (st[2] * coeff[2]);
- sum += (st[3] * coeff[3]);
- sum += (st[4] * coeff[4]);
- sum += (st[5] * coeff[5]);
- sum += (st[6] * coeff[6]);
- sum += (st[7] * coeff[7]);
+/* --------------------------------------------------------------------- */
- sum >>= 7;
- return sum * sum;
-}
+static const int pll_corr[2] = { -0x1000, 0x1000 };
-static inline int do_filter_1200(struct demod_state_afsk12 *st, unsigned char newval)
+static void demodulator_1200_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
{
+ struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
+ int j;
int sum;
+ unsigned char newsample;
- datamove8(st->filt.c, newval);
-
- sum = convolution8(st->filt.c, afsk12_tx_lo_i);
- sum += convolution8(st->filt.c, afsk12_tx_lo_q);
- sum -= convolution8(st->filt.c, afsk12_tx_hi_i);
- sum -= convolution8(st->filt.c, afsk12_tx_hi_q);
- return sum;
+ for (; buflen > 0; buflen--, buf++) {
+ sum = do_filter_1200_u8(buf);
+ st->dcd_shreg <<= 1;
+ st->bit_pll += 0x2000;
+ newsample = (sum > 0);
+ if (st->last_sample ^ newsample) {
+ st->last_sample = newsample;
+ st->dcd_shreg |= 1;
+ st->bit_pll += pll_corr
+ [st->bit_pll < 0x9000];
+ j = 4 * hweight8(st->dcd_shreg & 0x38)
+ - hweight16(st->dcd_shreg & 0x7c0);
+ st->dcd_sum0 += j;
+ }
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 120;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->shreg >>= 1;
+ st->shreg |= (!(st->last_rxbit ^
+ st->last_sample)) << 16;
+ st->last_rxbit = st->last_sample;
+ diag_trigger(sm);
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ }
+ diag_add(sm, (((int)*buf)-0x80) << 8, sum);
+ }
}
-#endif /* defined (CONFIG_SOUNDMODEM__AFSK1200_FP) && (defined(CONFIG_M586) || defined(CONFIG_M686)) */
-
-
/* --------------------------------------------------------------------- */
-static void demodulator_1200(struct sm_state *sm, unsigned char *buf, int buflen)
+static void demodulator_1200_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
{
struct demod_state_afsk12 *st = (struct demod_state_afsk12 *)(&sm->d);
- static const int pll_corr[2] = { -0x1000, 0x1000 };
int j;
int sum;
unsigned char newsample;
- ENV_STORAGE;
- ENV_SAVE;
for (; buflen > 0; buflen--, buf++) {
- sum = do_filter_1200(st, *buf);
+ sum = do_filter_1200_s16(buf);
st->dcd_shreg <<= 1;
st->bit_pll += 0x2000;
newsample = (sum > 0);
@@ -240,9 +242,8 @@ static void demodulator_1200(struct sm_state *sm, unsigned char *buf, int buflen
st->shreg = 0x10000;
}
}
- diag_add(sm, (((int)*buf)-0x80) << 8, sum);
+ diag_add(sm, *buf, sum);
}
- ENV_RESTORE;
}
/* --------------------------------------------------------------------- */
@@ -259,13 +260,13 @@ static void demod_init_1200(struct sm_state *sm)
const struct modem_tx_info sm_afsk1200_tx = {
"afsk1200", sizeof(struct mod_state_afsk12),
- AFSK12_SAMPLE_RATE, 1200, AFSK12_SAMPLE_RATE/1200, modulator_1200, NULL
+ AFSK12_SAMPLE_RATE, 1200, modulator_1200_u8, modulator_1200_s16, NULL
};
const struct modem_rx_info sm_afsk1200_rx = {
"afsk1200", sizeof(struct demod_state_afsk12),
- AFSK12_SAMPLE_RATE, 1200, AFSK12_SAMPLE_RATE/1200,
- AFSK12_SAMPLE_RATE/1200, demodulator_1200, demod_init_1200
+ AFSK12_SAMPLE_RATE, 1200, 8, AFSK12_SAMPLE_RATE/1200,
+ demodulator_1200_u8, demodulator_1200_s16, demod_init_1200
};
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/soundmodem/sm_afsk2400_7.c b/drivers/net/soundmodem/sm_afsk2400_7.c
new file mode 100644
index 000000000..36e0f328f
--- /dev/null
+++ b/drivers/net/soundmodem/sm_afsk2400_7.c
@@ -0,0 +1,297 @@
+/*****************************************************************************/
+
+/*
+ * sm_afsk2400_7.c -- soundcard radio modem driver, 2400 baud AFSK modem
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ */
+
+/*
+ * This driver is intended to be compatible with TCM3105 modems
+ * overclocked to 7.3728MHz. The mark and space frequencies therefore
+ * lie at 3658 and 1996 Hz.
+ * Note that I do _not_ recommend the building of such links, I provide
+ * this only for the users who live in the coverage area of such
+ * a "legacy" link.
+ */
+
+#include <linux/config.h>
+#include "sm.h"
+#include "sm_tbl_afsk2400_7.h"
+
+/* --------------------------------------------------------------------- */
+
+struct demod_state_afsk24 {
+ unsigned int shreg;
+ unsigned int bit_pll;
+ unsigned char last_sample;
+ unsigned int dcd_shreg;
+ int dcd_sum0, dcd_sum1, dcd_sum2;
+ unsigned int dcd_time;
+ unsigned char last_rxbit;
+};
+
+struct mod_state_afsk24 {
+ unsigned int shreg;
+ unsigned char tx_bit;
+ unsigned int bit_pll;
+ unsigned int tx_seq;
+ unsigned int phinc;
+};
+
+/* --------------------------------------------------------------------- */
+
+static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
+ AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
+
+static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
+{
+ struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (st->tx_seq < 0x5555) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
+ st->phinc = dds_inc[st->tx_bit & 1];
+ }
+ st->tx_seq += 0x5555;
+ st->tx_seq &= 0xffff;
+ *buf = OFFSCOS(st->bit_pll);
+ st->bit_pll += st->phinc;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (st->tx_seq < 0x5555) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
+ st->phinc = dds_inc[st->tx_bit & 1];
+ }
+ st->tx_seq += 0x5555;
+ st->tx_seq &= 0xffff;
+ *buf = COS(st->bit_pll);
+ st->bit_pll += st->phinc;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
+{
+ int sum = -0x80 * csum;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
+ sum += (st[-8] * coeff[8]);
+ sum += (st[-9] * coeff[9]);
+ sum += (st[-10] * coeff[10]);
+ sum += (st[-11] * coeff[11]);
+ sum += (st[-12] * coeff[12]);
+ sum += (st[-13] * coeff[13]);
+
+ sum >>= 7;
+ return sum * sum;
+}
+
+extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
+{
+ int sum = 0;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
+ sum += (st[-8] * coeff[8]);
+ sum += (st[-9] * coeff[9]);
+ sum += (st[-10] * coeff[10]);
+ sum += (st[-11] * coeff[11]);
+ sum += (st[-12] * coeff[12]);
+ sum += (st[-13] * coeff[13]);
+
+ sum >>= 15;
+ return sum * sum;
+}
+
+extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
+{
+ int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
+ sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
+ sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
+ sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
+ return sum;
+}
+
+extern __inline__ int do_filter_2400_s16(const short *buf)
+{
+ int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
+ sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
+ sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
+ sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
+ return sum;
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+ int j;
+ int sum;
+ unsigned char newsample;
+
+ for (; buflen > 0; buflen--, buf++) {
+ sum = do_filter_2400_u8(buf);
+ st->dcd_shreg <<= 1;
+ st->bit_pll += AFSK24_BITPLL_INC;
+ newsample = (sum > 0);
+ if (st->last_sample ^ newsample) {
+ st->last_sample = newsample;
+ st->dcd_shreg |= 1;
+ if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
+ st->bit_pll += AFSK24_BITPLL_INC/2;
+ else
+ st->bit_pll -= AFSK24_BITPLL_INC/2;
+ j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
+ - hweight16(st->dcd_shreg & 0x1e0);
+ st->dcd_sum0 += j;
+ }
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 120;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->shreg >>= 1;
+ st->shreg |= (!(st->last_rxbit ^
+ st->last_sample)) << 16;
+ st->last_rxbit = st->last_sample;
+ diag_trigger(sm);
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ }
+ diag_add(sm, (((int)*buf)-0x80) << 8, sum);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+ int j;
+ int sum;
+ unsigned char newsample;
+
+ for (; buflen > 0; buflen--, buf++) {
+ sum = do_filter_2400_s16(buf);
+ st->dcd_shreg <<= 1;
+ st->bit_pll += AFSK24_BITPLL_INC;
+ newsample = (sum > 0);
+ if (st->last_sample ^ newsample) {
+ st->last_sample = newsample;
+ st->dcd_shreg |= 1;
+ if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
+ st->bit_pll += AFSK24_BITPLL_INC/2;
+ else
+ st->bit_pll -= AFSK24_BITPLL_INC/2;
+ j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
+ - hweight16(st->dcd_shreg & 0x1e0);
+ st->dcd_sum0 += j;
+ }
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 120;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->shreg >>= 1;
+ st->shreg |= (!(st->last_rxbit ^
+ st->last_sample)) << 16;
+ st->last_rxbit = st->last_sample;
+ diag_trigger(sm);
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ }
+ diag_add(sm, *buf, sum);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demod_init_2400(struct sm_state *sm)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+
+ st->dcd_time = 120;
+ st->dcd_sum0 = 2;
+}
+
+/* --------------------------------------------------------------------- */
+
+const struct modem_tx_info sm_afsk2400_7_tx = {
+ "afsk2400_7", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400,
+ modulator_2400_u8, modulator_2400_s16, NULL
+};
+
+const struct modem_rx_info sm_afsk2400_7_rx = {
+ "afsk2400_7", sizeof(struct demod_state_afsk24),
+ AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400,
+ demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
+};
+
+/* --------------------------------------------------------------------- */
diff --git a/drivers/net/soundmodem/sm_afsk2400_8.c b/drivers/net/soundmodem/sm_afsk2400_8.c
new file mode 100644
index 000000000..8234815d6
--- /dev/null
+++ b/drivers/net/soundmodem/sm_afsk2400_8.c
@@ -0,0 +1,297 @@
+/*****************************************************************************/
+
+/*
+ * sm_afsk2400_8.c -- soundcard radio modem driver, 2400 baud AFSK modem
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ */
+
+/*
+ * This driver is intended to be compatible with TCM3105 modems
+ * overclocked to 8MHz. The mark and space frequencies therefore
+ * lie at 3970 and 2165 Hz.
+ * Note that I do _not_ recommend the building of such links, I provide
+ * this only for the users who live in the coverage area of such
+ * a "legacy" link.
+ */
+
+#include <linux/config.h>
+#include "sm.h"
+#include "sm_tbl_afsk2400_8.h"
+
+/* --------------------------------------------------------------------- */
+
+struct demod_state_afsk24 {
+ unsigned int shreg;
+ unsigned int bit_pll;
+ unsigned char last_sample;
+ unsigned int dcd_shreg;
+ int dcd_sum0, dcd_sum1, dcd_sum2;
+ unsigned int dcd_time;
+ unsigned char last_rxbit;
+};
+
+struct mod_state_afsk24 {
+ unsigned int shreg;
+ unsigned char tx_bit;
+ unsigned int bit_pll;
+ unsigned int tx_seq;
+ unsigned int phinc;
+};
+
+/* --------------------------------------------------------------------- */
+
+static const int dds_inc[2] = { AFSK24_TX_FREQ_LO*0x10000/AFSK24_SAMPLERATE,
+ AFSK24_TX_FREQ_HI*0x10000/AFSK24_SAMPLERATE };
+
+static void modulator_2400_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
+{
+ struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (st->tx_seq < 0x5555) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
+ st->phinc = dds_inc[st->tx_bit & 1];
+ }
+ st->tx_seq += 0x5555;
+ st->tx_seq &= 0xffff;
+ *buf = OFFSCOS(st->bit_pll);
+ st->bit_pll += st->phinc;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_2400_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_afsk24 *st = (struct mod_state_afsk24 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (st->tx_seq < 0x5555) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit ^ (!(st->shreg & 1))) & 1;
+ st->shreg >>= 1;
+ st->phinc = dds_inc[st->tx_bit & 1];
+ }
+ st->tx_seq += 0x5555;
+ st->tx_seq &= 0xffff;
+ *buf = COS(st->bit_pll);
+ st->bit_pll += st->phinc;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+extern __inline__ int convolution14_u8(const unsigned char *st, const int *coeff, int csum)
+{
+ int sum = -0x80 * csum;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
+ sum += (st[-8] * coeff[8]);
+ sum += (st[-9] * coeff[9]);
+ sum += (st[-10] * coeff[10]);
+ sum += (st[-11] * coeff[11]);
+ sum += (st[-12] * coeff[12]);
+ sum += (st[-13] * coeff[13]);
+
+ sum >>= 7;
+ return sum * sum;
+}
+
+extern __inline__ int convolution14_s16(const short *st, const int *coeff, int csum)
+{
+ int sum = 0;
+
+ sum += (st[0] * coeff[0]);
+ sum += (st[-1] * coeff[1]);
+ sum += (st[-2] * coeff[2]);
+ sum += (st[-3] * coeff[3]);
+ sum += (st[-4] * coeff[4]);
+ sum += (st[-5] * coeff[5]);
+ sum += (st[-6] * coeff[6]);
+ sum += (st[-7] * coeff[7]);
+ sum += (st[-8] * coeff[8]);
+ sum += (st[-9] * coeff[9]);
+ sum += (st[-10] * coeff[10]);
+ sum += (st[-11] * coeff[11]);
+ sum += (st[-12] * coeff[12]);
+ sum += (st[-13] * coeff[13]);
+
+ sum >>= 15;
+ return sum * sum;
+}
+
+extern __inline__ int do_filter_2400_u8(const unsigned char *buf)
+{
+ int sum = convolution14_u8(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
+ sum += convolution14_u8(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
+ sum -= convolution14_u8(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
+ sum -= convolution14_u8(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
+ return sum;
+}
+
+extern __inline__ int do_filter_2400_s16(const short *buf)
+{
+ int sum = convolution14_s16(buf, afsk24_tx_lo_i, SUM_AFSK24_TX_LO_I);
+ sum += convolution14_s16(buf, afsk24_tx_lo_q, SUM_AFSK24_TX_LO_Q);
+ sum -= convolution14_s16(buf, afsk24_tx_hi_i, SUM_AFSK24_TX_HI_I);
+ sum -= convolution14_s16(buf, afsk24_tx_hi_q, SUM_AFSK24_TX_HI_Q);
+ return sum;
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_2400_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+ int j;
+ int sum;
+ unsigned char newsample;
+
+ for (; buflen > 0; buflen--, buf++) {
+ sum = do_filter_2400_u8(buf);
+ st->dcd_shreg <<= 1;
+ st->bit_pll += AFSK24_BITPLL_INC;
+ newsample = (sum > 0);
+ if (st->last_sample ^ newsample) {
+ st->last_sample = newsample;
+ st->dcd_shreg |= 1;
+ if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
+ st->bit_pll += AFSK24_BITPLL_INC/2;
+ else
+ st->bit_pll -= AFSK24_BITPLL_INC/2;
+ j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
+ - hweight16(st->dcd_shreg & 0x1e0);
+ st->dcd_sum0 += j;
+ }
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 120;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->shreg >>= 1;
+ st->shreg |= (!(st->last_rxbit ^
+ st->last_sample)) << 16;
+ st->last_rxbit = st->last_sample;
+ diag_trigger(sm);
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ }
+ diag_add(sm, (((int)*buf)-0x80) << 8, sum);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_2400_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+ int j;
+ int sum;
+ unsigned char newsample;
+
+ for (; buflen > 0; buflen--, buf++) {
+ sum = do_filter_2400_s16(buf);
+ st->dcd_shreg <<= 1;
+ st->bit_pll += AFSK24_BITPLL_INC;
+ newsample = (sum > 0);
+ if (st->last_sample ^ newsample) {
+ st->last_sample = newsample;
+ st->dcd_shreg |= 1;
+ if (st->bit_pll < (0x8000+AFSK24_BITPLL_INC/2))
+ st->bit_pll += AFSK24_BITPLL_INC/2;
+ else
+ st->bit_pll -= AFSK24_BITPLL_INC/2;
+ j = /* 2 * */ hweight8(st->dcd_shreg & 0x1c)
+ - hweight16(st->dcd_shreg & 0x1e0);
+ st->dcd_sum0 += j;
+ }
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 120;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->shreg >>= 1;
+ st->shreg |= (!(st->last_rxbit ^
+ st->last_sample)) << 16;
+ st->last_rxbit = st->last_sample;
+ diag_trigger(sm);
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ }
+ diag_add(sm, *buf, sum);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demod_init_2400(struct sm_state *sm)
+{
+ struct demod_state_afsk24 *st = (struct demod_state_afsk24 *)(&sm->d);
+
+ st->dcd_time = 120;
+ st->dcd_sum0 = 2;
+}
+
+/* --------------------------------------------------------------------- */
+
+const struct modem_tx_info sm_afsk2400_8_tx = {
+ "afsk2400_8", sizeof(struct mod_state_afsk24), AFSK24_SAMPLERATE, 2400,
+ modulator_2400_u8, modulator_2400_s16, NULL
+};
+
+const struct modem_rx_info sm_afsk2400_8_rx = {
+ "afsk2400_8", sizeof(struct demod_state_afsk24),
+ AFSK24_SAMPLERATE, 2400, 14, AFSK24_SAMPLERATE/2400,
+ demodulator_2400_u8, demodulator_2400_s16, demod_init_2400
+};
+
+/* --------------------------------------------------------------------- */
diff --git a/drivers/net/soundmodem/sm_fsk9600.c b/drivers/net/soundmodem/sm_fsk9600.c
index 8fbf9d218..bc2fb53b1 100644
--- a/drivers/net/soundmodem/sm_fsk9600.c
+++ b/drivers/net/soundmodem/sm_fsk9600.c
@@ -45,6 +45,8 @@ struct mod_state_fsk96 {
unsigned int shreg;
unsigned long scram;
unsigned char tx_bit;
+ unsigned char *txtbl;
+ unsigned int txphase;
};
/* --------------------------------------------------------------------- */
@@ -62,30 +64,57 @@ struct mod_state_fsk96 {
/* --------------------------------------------------------------------- */
-static void modulator_9600_4(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_9600_4_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
{
struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 4; buflen -= 4) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- cp = fsk96_txfilt_4 + (st->tx_bit & 0xff);
- for (j = 0; j < 4; j++, cp += 0x100)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--) {
+ if (!st->txphase++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->scram = (st->scram << 1) | (st->scram & 1);
+ st->scram ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ if (st->scram & (SCRAM_TAP1 << 1))
+ st->scram ^= SCRAM_TAPN << 1;
+ st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
+ st->txtbl = fsk96_txfilt_4 + (st->tx_bit & 0xff);
+ }
+ if (st->txphase >= 4)
+ st->txphase = 0;
+ *buf++ = *st->txtbl;
+ st->txtbl += 0x100;
}
}
/* --------------------------------------------------------------------- */
-static void demodulator_9600_4(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_9600_4_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
+
+ for (; buflen > 0; buflen--) {
+ if (!st->txphase++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->scram = (st->scram << 1) | (st->scram & 1);
+ st->scram ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ if (st->scram & (SCRAM_TAP1 << 1))
+ st->scram ^= SCRAM_TAPN << 1;
+ st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
+ st->txtbl = fsk96_txfilt_4 + (st->tx_bit & 0xff);
+ }
+ if (st->txphase >= 4)
+ st->txphase = 0;
+ *buf++ = ((*st->txtbl)-0x80) << 8;
+ st->txtbl += 0x100;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_9600_4_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
{
struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
static const int pll_corr[2] = { -0x1000, 0x1000 };
@@ -133,30 +162,105 @@ static void demodulator_9600_4(struct sm_state *sm, unsigned char *buf, int bufl
/* --------------------------------------------------------------------- */
-static void modulator_9600_5(struct sm_state *sm, unsigned char *buf, int buflen)
+static void demodulator_9600_4_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
+{
+ struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
+ static const int pll_corr[2] = { -0x1000, 0x1000 };
+ unsigned char curbit;
+ unsigned int descx;
+
+ for (; buflen > 0; buflen--, buf++) {
+ st->dcd_shreg <<= 1;
+ st->bit_pll += 0x4000;
+ curbit = (*buf >= 0);
+ if (st->last_sample ^ curbit) {
+ st->dcd_shreg |= 1;
+ st->bit_pll += pll_corr[st->bit_pll < 0xa000];
+ st->dcd_sum0 += 8 * hweight8(st->dcd_shreg & 0x0c) -
+ !!(st->dcd_shreg & 0x10);
+ }
+ st->last_sample = curbit;
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 240;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->descram = (st->descram << 1) | curbit;
+ descx = st->descram ^ (st->descram >> 1);
+ descx ^= ((descx >> DESCRAM_TAPSH1) ^
+ (descx >> DESCRAM_TAPSH2));
+ st->shreg >>= 1;
+ st->shreg |= (!(descx & 1)) << 16;
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ diag_trigger(sm);
+ }
+ diag_add_one(sm, *buf);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_9600_5_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
{
struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 5; buflen -= 5) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->scram = (st->scram << 1) | (st->scram & 1);
- st->scram ^= !(st->shreg & 1);
- st->shreg >>= 1;
- if (st->scram & (SCRAM_TAP1 << 1))
- st->scram ^= SCRAM_TAPN << 1;
- st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
- cp = fsk96_txfilt_5 + (st->tx_bit & 0xff);
- for (j = 0; j < 5; j++, cp += 0x100)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--) {
+ if (!st->txphase++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->scram = (st->scram << 1) | (st->scram & 1);
+ st->scram ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ if (st->scram & (SCRAM_TAP1 << 1))
+ st->scram ^= SCRAM_TAPN << 1;
+ st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
+ st->txtbl = fsk96_txfilt_5 + (st->tx_bit & 0xff);
+ }
+ if (st->txphase >= 5)
+ st->txphase = 0;
+ *buf++ = *st->txtbl;
+ st->txtbl += 0x100;
}
}
/* --------------------------------------------------------------------- */
-static void demodulator_9600_5(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_9600_5_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_fsk96 *st = (struct mod_state_fsk96 *)(&sm->m);
+
+ for (; buflen > 0; buflen--) {
+ if (!st->txphase++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->scram = (st->scram << 1) | (st->scram & 1);
+ st->scram ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ if (st->scram & (SCRAM_TAP1 << 1))
+ st->scram ^= SCRAM_TAPN << 1;
+ st->tx_bit = (st->tx_bit << 1) | (!!(st->scram & (SCRAM_TAP1 << 2)));
+ st->txtbl = fsk96_txfilt_5 + (st->tx_bit & 0xff);
+ }
+ if (st->txphase >= 5)
+ st->txphase = 0;
+ *buf++ = ((*st->txtbl)-0x80)<<8;
+ st->txtbl += 0x100;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_9600_5_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
{
struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
static const int pll_corr[2] = { -0x1000, 0x1000 };
@@ -204,6 +308,54 @@ static void demodulator_9600_5(struct sm_state *sm, unsigned char *buf, int bufl
/* --------------------------------------------------------------------- */
+static void demodulator_9600_5_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
+{
+ struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
+ static const int pll_corr[2] = { -0x1000, 0x1000 };
+ unsigned char curbit;
+ unsigned int descx;
+
+ for (; buflen > 0; buflen--, buf++) {
+ st->dcd_shreg <<= 1;
+ st->bit_pll += 0x3333;
+ curbit = (*buf >= 0);
+ if (st->last_sample ^ curbit) {
+ st->dcd_shreg |= 1;
+ st->bit_pll += pll_corr[st->bit_pll < 0x9999];
+ st->dcd_sum0 += 16 * hweight8(st->dcd_shreg & 0x0c) -
+ hweight8(st->dcd_shreg & 0x70);
+ }
+ st->last_sample = curbit;
+ hdlcdrv_channelbit(&sm->hdrv, st->last_sample);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 240;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->descram = (st->descram << 1) | curbit;
+ descx = st->descram ^ (st->descram >> 1);
+ descx ^= ((descx >> DESCRAM_TAPSH1) ^
+ (descx >> DESCRAM_TAPSH2));
+ st->shreg >>= 1;
+ st->shreg |= (!(descx & 1)) << 16;
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ diag_trigger(sm);
+ }
+ diag_add_one(sm, *buf);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
static void demod_init_9600(struct sm_state *sm)
{
struct demod_state_fsk96 *st = (struct demod_state_fsk96 *)(&sm->d);
@@ -215,25 +367,25 @@ static void demod_init_9600(struct sm_state *sm)
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_fsk9600_4_tx = {
- "fsk9600", sizeof(struct mod_state_fsk96), 38400, 9600, 4,
- modulator_9600_4, NULL
+ "fsk9600", sizeof(struct mod_state_fsk96), 38400, 9600,
+ modulator_9600_4_u8, modulator_9600_4_s16, NULL
};
const struct modem_rx_info sm_fsk9600_4_rx = {
- "fsk9600", sizeof(struct demod_state_fsk96), 38400, 9600, 4, 4,
- demodulator_9600_4, demod_init_9600
+ "fsk9600", sizeof(struct demod_state_fsk96), 38400, 9600, 1, 4,
+ demodulator_9600_4_u8, demodulator_9600_4_s16, demod_init_9600
};
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_fsk9600_5_tx = {
- "fsk9600", sizeof(struct mod_state_fsk96), 48000, 9600, 5,
- modulator_9600_5, NULL
+ "fsk9600", sizeof(struct mod_state_fsk96), 48000, 9600,
+ modulator_9600_5_u8, modulator_9600_5_s16, NULL
};
const struct modem_rx_info sm_fsk9600_5_rx = {
- "fsk9600", sizeof(struct demod_state_fsk96), 48000, 9600, 5, 5,
- demodulator_9600_5, demod_init_9600
+ "fsk9600", sizeof(struct demod_state_fsk96), 48000, 9600, 1, 5,
+ demodulator_9600_5_u8, demodulator_9600_5_s16, demod_init_9600
};
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/soundmodem/sm_hapn4800.c b/drivers/net/soundmodem/sm_hapn4800.c
index 9472d5e06..f6babcd9d 100644
--- a/drivers/net/soundmodem/sm_hapn4800.c
+++ b/drivers/net/soundmodem/sm_hapn4800.c
@@ -49,133 +49,290 @@ struct demod_state_hapn48 {
unsigned int dcd_shreg;
int dcd_sum0, dcd_sum1, dcd_sum2;
unsigned int dcd_time;
- int inphist[5];
int lvlhi, lvllo;
};
struct mod_state_hapn48 {
unsigned int shreg;
unsigned char tx_bit;
+ unsigned int tx_seq;
+ const unsigned char *tbl;
};
/* --------------------------------------------------------------------- */
-static void modulator_hapn4800_10(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_hapn4800_10_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
{
struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 10; buflen -= 10) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- cp = hapn48_txfilt_10 + (st->tx_bit & 0xf);
- for (j = 0; j < 10; j++, cp += 0x10)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = ((st->tx_bit << 1) |
+ (st->tx_bit & 1));
+ st->tx_bit ^= (!(st->shreg & 1));
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_10 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 10)
+ st->tx_seq = 0;
+ *buf = *st->tbl;
+ st->tbl += 0x10;
}
}
/* --------------------------------------------------------------------- */
-static void modulator_hapn4800_8(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_hapn4800_10_s16(struct sm_state *sm, short *buf, unsigned int buflen)
{
struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 8; buflen -= 8) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- cp = hapn48_txfilt_8 + (st->tx_bit & 0xf);
- for (j = 0; j < 8; j++, cp += 0x10)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = ((st->tx_bit << 1) |
+ (st->tx_bit & 1));
+ st->tx_bit ^= (!(st->shreg & 1));
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_10 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 10)
+ st->tx_seq = 0;
+ *buf = ((*st->tbl)-0x80)<<8;
+ st->tbl += 0x10;
}
}
/* --------------------------------------------------------------------- */
-static void modulator_hapn4800_pm10(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_hapn4800_8_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
{
struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 10; buflen -= 10) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = ((st->tx_bit << 1) |
- (st->tx_bit & 1));
- st->tx_bit ^= (!(st->shreg & 1));
- st->shreg >>= 1;
- cp = hapn48_txfilt_pm10 + (st->tx_bit & 0xf);
- for (j = 0; j < 10; j++, cp += 0x10)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
+ st->tx_bit ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_8 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 8)
+ st->tx_seq = 0;
+ *buf = *st->tbl;
+ st->tbl += 0x10;
}
}
/* --------------------------------------------------------------------- */
-static void modulator_hapn4800_pm8(struct sm_state *sm, unsigned char *buf, int buflen)
+static void modulator_hapn4800_8_s16(struct sm_state *sm, short *buf, unsigned int buflen)
{
struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
- int j;
- const unsigned char *cp;
-
- for (; buflen >= 8; buflen -= 8) {
- if (st->shreg <= 1)
- st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
- st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
- st->tx_bit ^= !(st->shreg & 1);
- st->shreg >>= 1;
- cp = hapn48_txfilt_pm8 + (st->tx_bit & 0xf);
- for (j = 0; j < 8; j++, cp += 0x10)
- *buf++ = *cp;
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
+ st->tx_bit ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_8 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 8)
+ st->tx_seq = 0;
+ *buf = ((*st->tbl)-0x80)<<8;
+ st->tbl += 0x10;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_hapn4800_pm10_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
+{
+ struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = ((st->tx_bit << 1) |
+ (st->tx_bit & 1));
+ st->tx_bit ^= (!(st->shreg & 1));
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_pm10 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 10)
+ st->tx_seq = 0;
+ *buf = *st->tbl;
+ st->tbl += 0x10;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_hapn4800_pm10_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = ((st->tx_bit << 1) |
+ (st->tx_bit & 1));
+ st->tx_bit ^= (!(st->shreg & 1));
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_pm10 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 10)
+ st->tx_seq = 0;
+ *buf = ((*st->tbl)-0x80)<<8;
+ st->tbl += 0x10;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_hapn4800_pm8_u8(struct sm_state *sm, unsigned char *buf, unsigned int buflen)
+{
+ struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
+ st->tx_bit ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_pm8 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 8)
+ st->tx_seq = 0;
+ *buf = *st->tbl;
+ st->tbl += 0x10;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void modulator_hapn4800_pm8_s16(struct sm_state *sm, short *buf, unsigned int buflen)
+{
+ struct mod_state_hapn48 *st = (struct mod_state_hapn48 *)(&sm->m);
+
+ for (; buflen > 0; buflen--, buf++) {
+ if (!st->tx_seq++) {
+ if (st->shreg <= 1)
+ st->shreg = hdlcdrv_getbits(&sm->hdrv) | 0x10000;
+ st->tx_bit = (st->tx_bit << 1) | (st->tx_bit & 1);
+ st->tx_bit ^= !(st->shreg & 1);
+ st->shreg >>= 1;
+ st->tbl = hapn48_txfilt_pm8 + (st->tx_bit & 0xf);
+ }
+ if (st->tx_seq >= 8)
+ st->tx_seq = 0;
+ *buf = ((*st->tbl)-0x80)<<8;
+ st->tbl += 0x10;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_hapn4800_10_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
+{
+ struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
+ static const int pll_corr[2] = { -0x800, 0x800 };
+ int curst, cursync;
+ int inv;
+
+ for (; buflen > 0; buflen--, buf++) {
+ inv = ((int)(buf[-2])-0x80) << 8;
+ st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
+ st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
+ if (inv > st->lvlhi)
+ st->lvlhi = inv;
+ if (inv < st->lvllo)
+ st->lvllo = inv;
+ if (buflen & 1)
+ st->dcd_shreg <<= 1;
+ st->bit_pll += 0x199a;
+ curst = cursync = 0;
+ if (inv > st->lvlhi >> 1) {
+ curst = 1;
+ cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
+ buf[-2] > buf[-0] && buf[-2] > buf[-4]);
+ } else if (inv < st->lvllo >> 1) {
+ curst = -1;
+ cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
+ buf[-2] < buf[-0] && buf[-2] < buf[-4]);
+ }
+ if (cursync) {
+ st->dcd_shreg |= cursync;
+ st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x8ccdu];
+ st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x18c6318c) -
+ hweight32(st->dcd_shreg & 0xe739ce70);
+ }
+ hdlcdrv_channelbit(&sm->hdrv, cursync);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 240;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->last_bit2 = st->last_bit;
+ if (curst < 0)
+ st->last_bit = 0;
+ else if (curst > 0)
+ st->last_bit = 1;
+ st->shreg >>= 1;
+ st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ diag_trigger(sm);
+ }
+ diag_add_one(sm, inv);
}
}
/* --------------------------------------------------------------------- */
-static void demodulator_hapn4800_10(struct sm_state *sm, unsigned char *buf, int buflen)
+static void demodulator_hapn4800_10_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
{
struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
static const int pll_corr[2] = { -0x800, 0x800 };
int curst, cursync;
+ int inv;
for (; buflen > 0; buflen--, buf++) {
- st->inphist[4] = st->inphist[3];
- st->inphist[3] = st->inphist[2];
- st->inphist[2] = st->inphist[1];
- st->inphist[1] = st->inphist[0];
- st->inphist[0] = ((int)(*buf)-0x80) << 8;
+ inv = buf[-2];
st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (st->inphist[2] > st->lvlhi)
- st->lvlhi = st->inphist[2];
- if (st->inphist[2] < st->lvllo)
- st->lvllo = st->inphist[2];
+ if (inv > st->lvlhi)
+ st->lvlhi = inv;
+ if (inv < st->lvllo)
+ st->lvllo = inv;
if (buflen & 1)
st->dcd_shreg <<= 1;
st->bit_pll += 0x199a;
curst = cursync = 0;
- if (st->inphist[2] > st->lvlhi >> 1) {
+ if (inv > st->lvlhi >> 1) {
curst = 1;
- cursync = (st->inphist[2] > st->inphist[1] &&
- st->inphist[2] > st->inphist[3] &&
- st->inphist[2] > st->inphist[0] &&
- st->inphist[2] > st->inphist[4]);
- } else if (st->inphist[2] < st->lvllo >> 1) {
+ cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
+ buf[-2] > buf[-0] && buf[-2] > buf[-4]);
+ } else if (inv < st->lvllo >> 1) {
curst = -1;
- cursync = (st->inphist[2] < st->inphist[1] &&
- st->inphist[2] < st->inphist[3] &&
- st->inphist[2] < st->inphist[0] &&
- st->inphist[2] < st->inphist[4]);
+ cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
+ buf[-2] < buf[-0] && buf[-2] < buf[-4]);
}
if (cursync) {
st->dcd_shreg |= cursync;
@@ -208,46 +365,104 @@ static void demodulator_hapn4800_10(struct sm_state *sm, unsigned char *buf, int
}
diag_trigger(sm);
}
- diag_add_one(sm, st->inphist[2]);
+ diag_add_one(sm, inv);
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+static void demodulator_hapn4800_8_u8(struct sm_state *sm, const unsigned char *buf, unsigned int buflen)
+{
+ struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
+ static const int pll_corr[2] = { -0x800, 0x800 };
+ int curst, cursync;
+ int inv;
+
+ for (; buflen > 0; buflen--, buf++) {
+ inv = ((int)(buf[-2])-0x80) << 8;
+ st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
+ st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
+ if (inv > st->lvlhi)
+ st->lvlhi = inv;
+ if (inv < st->lvllo)
+ st->lvllo = inv;
+ if (buflen & 1)
+ st->dcd_shreg <<= 1;
+ st->bit_pll += 0x2000;
+ curst = cursync = 0;
+ if (inv > st->lvlhi >> 1) {
+ curst = 1;
+ cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
+ buf[-2] > buf[-0] && buf[-2] > buf[-4]);
+ } else if (inv < st->lvllo >> 1) {
+ curst = -1;
+ cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
+ buf[-2] < buf[-0] && buf[-2] < buf[-4]);
+ }
+ if (cursync) {
+ st->dcd_shreg |= cursync;
+ st->bit_pll += pll_corr[((st->bit_pll - 0x8000u) & 0xffffu) < 0x9000u];
+ st->dcd_sum0 += 16 * hweight32(st->dcd_shreg & 0x44444444) -
+ hweight32(st->dcd_shreg & 0xbbbbbbbb);
+ }
+ hdlcdrv_channelbit(&sm->hdrv, cursync);
+ if ((--st->dcd_time) <= 0) {
+ hdlcdrv_setdcd(&sm->hdrv, (st->dcd_sum0 +
+ st->dcd_sum1 +
+ st->dcd_sum2) < 0);
+ st->dcd_sum2 = st->dcd_sum1;
+ st->dcd_sum1 = st->dcd_sum0;
+ st->dcd_sum0 = 2; /* slight bias */
+ st->dcd_time = 240;
+ }
+ if (st->bit_pll >= 0x10000) {
+ st->bit_pll &= 0xffff;
+ st->last_bit2 = st->last_bit;
+ if (curst < 0)
+ st->last_bit = 0;
+ else if (curst > 0)
+ st->last_bit = 1;
+ st->shreg >>= 1;
+ st->shreg |= ((st->last_bit ^ st->last_bit2 ^ 1) & 1) << 16;
+ if (st->shreg & 1) {
+ hdlcdrv_putbits(&sm->hdrv, st->shreg >> 1);
+ st->shreg = 0x10000;
+ }
+ diag_trigger(sm);
+ }
+ diag_add_one(sm, inv);
}
}
/* --------------------------------------------------------------------- */
-static void demodulator_hapn4800_8(struct sm_state *sm, unsigned char *buf, int buflen)
+static void demodulator_hapn4800_8_s16(struct sm_state *sm, const short *buf, unsigned int buflen)
{
struct demod_state_hapn48 *st = (struct demod_state_hapn48 *)(&sm->d);
static const int pll_corr[2] = { -0x800, 0x800 };
int curst, cursync;
+ int inv;
for (; buflen > 0; buflen--, buf++) {
- st->inphist[4] = st->inphist[3];
- st->inphist[3] = st->inphist[2];
- st->inphist[2] = st->inphist[1];
- st->inphist[1] = st->inphist[0];
- st->inphist[0] = ((int)(*buf)-0x80) << 8;
+ inv = buf[-2];
st->lvlhi = (st->lvlhi * 65309) >> 16; /* decay */
st->lvllo = (st->lvllo * 65309) >> 16; /* decay */
- if (st->inphist[2] > st->lvlhi)
- st->lvlhi = st->inphist[2];
- if (st->inphist[2] < st->lvllo)
- st->lvllo = st->inphist[2];
+ if (inv > st->lvlhi)
+ st->lvlhi = inv;
+ if (inv < st->lvllo)
+ st->lvllo = inv;
if (buflen & 1)
st->dcd_shreg <<= 1;
st->bit_pll += 0x2000;
curst = cursync = 0;
- if (st->inphist[2] > st->lvlhi >> 1) {
+ if (inv > st->lvlhi >> 1) {
curst = 1;
- cursync = (st->inphist[2] > st->inphist[1] &&
- st->inphist[2] > st->inphist[3] &&
- st->inphist[2] > st->inphist[0] &&
- st->inphist[2] > st->inphist[4]);
- } else if (st->inphist[2] < st->lvllo >> 1) {
+ cursync = (buf[-2] > buf[-1] && buf[-2] > buf[-3] &&
+ buf[-2] > buf[-0] && buf[-2] > buf[-4]);
+ } else if (inv < st->lvllo >> 1) {
curst = -1;
- cursync = (st->inphist[2] < st->inphist[1] &&
- st->inphist[2] < st->inphist[3] &&
- st->inphist[2] < st->inphist[0] &&
- st->inphist[2] < st->inphist[4]);
+ cursync = (buf[-2] < buf[-1] && buf[-2] < buf[-3] &&
+ buf[-2] < buf[-0] && buf[-2] < buf[-4]);
}
if (cursync) {
st->dcd_shreg |= cursync;
@@ -280,7 +495,7 @@ static void demodulator_hapn4800_8(struct sm_state *sm, unsigned char *buf, int
}
diag_trigger(sm);
}
- diag_add_one(sm, st->inphist[2]);
+ diag_add_one(sm, inv);
}
}
@@ -297,51 +512,49 @@ static void demod_init_hapn4800(struct sm_state *sm)
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_hapn4800_8_tx = {
- "hapn4800", sizeof(struct mod_state_hapn48),
- 38400, 4800, 8, modulator_hapn4800_8, NULL
+ "hapn4800", sizeof(struct mod_state_hapn48), 38400, 4800,
+ modulator_hapn4800_8_u8, modulator_hapn4800_8_s16, NULL
};
const struct modem_rx_info sm_hapn4800_8_rx = {
- "hapn4800", sizeof(struct demod_state_hapn48),
- 38400, 4800, 8, 8, demodulator_hapn4800_8, demod_init_hapn4800
+ "hapn4800", sizeof(struct demod_state_hapn48), 38400, 4800, 5, 8,
+ demodulator_hapn4800_8_u8, demodulator_hapn4800_8_s16, demod_init_hapn4800
};
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_hapn4800_10_tx = {
- "hapn4800", sizeof(struct mod_state_hapn48),
- 48000, 4800, 10,
- modulator_hapn4800_10, NULL
+ "hapn4800", sizeof(struct mod_state_hapn48), 48000, 4800,
+ modulator_hapn4800_10_u8, modulator_hapn4800_10_s16, NULL
};
const struct modem_rx_info sm_hapn4800_10_rx = {
- "hapn4800", sizeof(struct demod_state_hapn48),
- 48000, 4800, 10, 10, demodulator_hapn4800_10, demod_init_hapn4800
+ "hapn4800", sizeof(struct demod_state_hapn48), 48000, 4800, 5, 10,
+ demodulator_hapn4800_10_u8, demodulator_hapn4800_10_s16, demod_init_hapn4800
};
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_hapn4800_pm8_tx = {
- "hapn4800pm", sizeof(struct mod_state_hapn48),
- 38400, 4800, 8, modulator_hapn4800_pm8, NULL
+ "hapn4800pm", sizeof(struct mod_state_hapn48), 38400, 4800,
+ modulator_hapn4800_pm8_u8, modulator_hapn4800_pm8_s16, NULL
};
const struct modem_rx_info sm_hapn4800_pm8_rx = {
- "hapn4800pm", sizeof(struct demod_state_hapn48),
- 38400, 4800, 8, 8, demodulator_hapn4800_8, demod_init_hapn4800
+ "hapn4800pm", sizeof(struct demod_state_hapn48), 38400, 4800, 5, 8,
+ demodulator_hapn4800_8_u8, demodulator_hapn4800_8_s16, demod_init_hapn4800
};
/* --------------------------------------------------------------------- */
const struct modem_tx_info sm_hapn4800_pm10_tx = {
- "hapn4800pm", sizeof(struct mod_state_hapn48),
- 48000, 4800, 10,
- modulator_hapn4800_pm10, NULL
+ "hapn4800pm", sizeof(struct mod_state_hapn48), 48000, 4800,
+ modulator_hapn4800_pm10_u8, modulator_hapn4800_pm10_s16, NULL
};
const struct modem_rx_info sm_hapn4800_pm10_rx = {
- "hapn4800pm", sizeof(struct demod_state_hapn48),
- 48000, 4800, 10, 10, demodulator_hapn4800_10, demod_init_hapn4800
+ "hapn4800pm", sizeof(struct demod_state_hapn48), 48000, 4800, 5, 10,
+ demodulator_hapn4800_10_u8, demodulator_hapn4800_10_s16, demod_init_hapn4800
};
/* --------------------------------------------------------------------- */
diff --git a/drivers/net/soundmodem/sm_sbc.c b/drivers/net/soundmodem/sm_sbc.c
index 1011dca97..2a2f874aa 100644
--- a/drivers/net/soundmodem/sm_sbc.c
+++ b/drivers/net/soundmodem/sm_sbc.c
@@ -26,12 +26,14 @@
*/
#include <linux/ptrace.h>
+#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/ioport.h>
#include <linux/soundmodem.h>
#include "sm.h"
+#include "smdma.h"
/* --------------------------------------------------------------------- */
@@ -81,12 +83,6 @@ struct sc_state_sbc {
unsigned char revhi, revlo;
unsigned char fmt[2];
unsigned int sr[2];
- unsigned int dmabuflen;
- unsigned char *dmabuf;
- unsigned char *dmabuf2;
- unsigned char dmabufidx;
- unsigned char dma2bufidx;
- unsigned char ptt;
};
#define SCSTATE ((struct sc_state_sbc *)(&sm->hw))
@@ -136,6 +132,7 @@ struct sc_state_sbc {
#define SBC4_OUT8_AI 0xc6
#define SBC4_IN8_AI 0xce
#define SBC4_MODE_UNS_MONO 0x00
+#define SBC4_MODE_SIGN_MONO 0x10
#define SBC4_OUT16_AI 0xb6
#define SBC4_IN16_AI 0xbe
@@ -260,9 +257,8 @@ static int config_resources(struct device *dev, struct sm_state *sm, int fdx)
realdma = inb(DSP_MIXER_DATA(dev->base_addr));
restore_flags(flags);
if ((~realirq) & irqreg || (~realdma) & dmareg) {
- printk(KERN_ERR "%s: sbc resource registers cannot be set; "
- "PnP device and IRQ/DMA specified wrongly?\n",
- sm_drvname);
+ printk(KERN_ERR "%s: sbc resource registers cannot be set; PnP device "
+ "and IRQ/DMA specified wrongly?\n", sm_drvname);
return -EINVAL;
}
return 0;
@@ -292,41 +288,31 @@ static void setup_dma_dsp(struct device *dev, struct sm_state *sm, int send)
{ SBC_HI_INPUT_AUTOINIT, SBC_HI_OUTPUT_AUTOINIT }
};
static const unsigned char sbc4mode[2] = { SBC4_IN8_AI, SBC4_OUT8_AI };
- static const unsigned char dmamode[2] = {
- DMA_MODE_READ | DMA_MODE_AUTOINIT, DMA_MODE_WRITE | DMA_MODE_AUTOINIT
- };
static const unsigned char sbcskr[2] = { SBC_SPEAKER_OFF, SBC_SPEAKER_ON };
- unsigned long dmabufaddr = virt_to_bus(SCSTATE->dmabuf);
+ unsigned int nsamps;
send = !!send;
if (!reset_dsp(dev)) {
printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
return;
}
- if ((dmabufaddr & 0xffff) + SCSTATE->dmabuflen > 0x10000)
- panic("sm: DMA buffer violates DMA boundary!");
save_flags(flags);
cli();
sbc_int_ack_8bit(dev);
write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */
write_dsp(dev, SCSTATE->fmt[send]);
write_dsp(dev, sbcskr[send]);
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, dmamode[send]);
- set_dma_addr(dev->dma, dmabufaddr);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
+ nsamps = dma_setup(sm, send, dev->dma) - 1;
sbc_int_ack_8bit(dev);
if (SCSTATE->revhi >= 4) {
write_dsp(dev, sbc4mode[send]);
write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ write_dsp(dev, nsamps & 0xff);
+ write_dsp(dev, nsamps >> 8);
} else {
write_dsp(dev, SBC_BLOCKSIZE);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ write_dsp(dev, nsamps & 0xff);
+ write_dsp(dev, nsamps >> 8);
write_dsp(dev, sbcmode[SCSTATE->fmt[send] >= 180][send]);
/* hispeed mode if sample rate > 13kHz */
}
@@ -339,53 +325,41 @@ static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_id;
struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned char new_ptt;
- unsigned char *buf;
+ unsigned int curfrag;
if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
return;
- new_ptt = hdlcdrv_ptt(&sm->hdrv);
+ cli();
sbc_int_ack_8bit(dev);
- buf = SCSTATE->dmabuf;
- if (SCSTATE->dmabufidx)
- buf += SCSTATE->dmabuflen/2;
- SCSTATE->dmabufidx = !SCSTATE->dmabufidx;
+ disable_dma(dev->dma);
+ clear_dma_ff(dev->dma);
+ dma_ptr(sm, sm->dma.ptt_cnt > 0, dev->dma, &curfrag);
+ enable_dma(dev->dma);
sm_int_freq(sm);
sti();
- if (new_ptt && !SCSTATE->ptt) {
- /* starting to transmit */
- disable_dma(dev->dma);
- SCSTATE->dmabufidx = 0;
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2));
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, SCSTATE->dmabuf,
- SCSTATE->dmabuflen/2));
- setup_dma_dsp(dev, sm, 1);
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, SCSTATE->dmabuf +
- SCSTATE->dmabuflen/2,
- SCSTATE->dmabuflen/2));
- } else if (SCSTATE->ptt == 1 && !new_ptt) {
+ if (sm->dma.ptt_cnt <= 0) {
+ dma_receive(sm, curfrag);
+ if (hdlcdrv_ptt(&sm->hdrv)) {
+ /* starting to transmit */
+ disable_dma(dev->dma);
+ dma_start_transmit(sm);
+ setup_dma_dsp(dev, sm, 1);
+ dma_transmit(sm);
+ }
+ } else if (dma_end_transmit(sm, curfrag)) {
/* stopping transmission */
disable_dma(dev->dma);
- SCSTATE->dmabufidx = 0;
+ sti();
+ dma_init_receive(sm);
setup_dma_dsp(dev, sm, 0);
- SCSTATE->ptt = 0;
- } else if (SCSTATE->ptt) {
- SCSTATE->ptt--;
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, buf, SCSTATE->dmabuflen/2));
} else {
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2));
+ dma_transmit(sm);
hdlcdrv_arbitrate(dev, &sm->hdrv);
}
- if (new_ptt)
- SCSTATE->ptt = 2;
sm_output_status(sm);
hdlcdrv_transmitter(dev, &sm->hdrv);
hdlcdrv_receiver(dev, &sm->hdrv);
+
}
/* --------------------------------------------------------------------- */
@@ -393,6 +367,7 @@ static void sbc_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int sbc_open(struct device *dev, struct sm_state *sm)
{
int err;
+ unsigned int dmasz, u;
if (sizeof(sm->m) < sizeof(struct sc_state_sbc)) {
printk(KERN_ERR "sm sbc: sbc state too big: %d > %d\n",
@@ -409,12 +384,17 @@ static int sbc_open(struct device *dev, struct sm_state *sm)
/*
* check if a card is available
*/
- if (!reset_dsp(dev))
+ if (!reset_dsp(dev)) {
+ printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
+ sm_drvname, dev->base_addr);
return -ENODEV;
+ }
write_dsp(dev, SBC_GET_REVISION);
if (!read_dsp(dev, &SCSTATE->revhi) ||
!read_dsp(dev, &SCSTATE->revlo))
return -ENODEV;
+ printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
+ SCSTATE->revhi, SCSTATE->revlo);
if (SCSTATE->revhi < 2) {
printk(KERN_ERR "%s: your card is an antiquity, at least DSP "
"rev 2.00 required\n", sm_drvname);
@@ -435,9 +415,19 @@ static int sbc_open(struct device *dev, struct sm_state *sm)
/*
* initialize some variables
*/
- if (!(SCSTATE->dmabuf = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA)))
+ dma_init_receive(sm);
+ dmasz = (NUM_FRAGMENTS + 1) * sm->dma.ifragsz;
+ if (sm->dma.i16bit)
+ dmasz <<= 1;
+ u = NUM_FRAGMENTS * sm->dma.ofragsz;
+ if (sm->dma.o16bit)
+ u <<= 1;
+ if (u > dmasz)
+ dmasz = u;
+ if (!(sm->dma.ibuf = sm->dma.obuf = kmalloc(dmasz, GFP_KERNEL | GFP_DMA)))
return -ENOMEM;
- SCSTATE->dmabufidx = SCSTATE->ptt = 0;
+ dma_init_transmit(sm);
+ dma_init_receive(sm);
memset(&sm->m, 0, sizeof(sm->m));
memset(&sm->d, 0, sizeof(sm->d));
@@ -447,13 +437,13 @@ static int sbc_open(struct device *dev, struct sm_state *sm)
sm->mode_rx->init(sm);
if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree_s(sm->dma.obuf, dmasz);
return -EBUSY;
}
if (request_irq(dev->irq, sbc_interrupt, SA_INTERRUPT,
sm->hwdrv->hw_name, dev)) {
free_dma(dev->dma);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree_s(sm->dma.obuf, dmasz);
return -EBUSY;
}
request_region(dev->base_addr, SBC_EXTENT, sm->hwdrv->hw_name);
@@ -475,7 +465,7 @@ static int sbc_close(struct device *dev, struct sm_state *sm)
free_irq(dev->irq, dev);
free_dma(dev->dma);
release_region(dev->base_addr, SBC_EXTENT);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree(sm->dma.obuf);
return 0;
}
@@ -486,7 +476,6 @@ static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode)
char *cp = strchr(mode, '.');
const struct modem_tx_info **mtp = sm_modem_tx_table;
const struct modem_rx_info **mrp;
- int dv;
if (!strcmp(mode, "off")) {
sm->mode_tx = NULL;
@@ -507,12 +496,16 @@ static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode)
continue;
if ((*mtp)->srate < 5000 || (*mtp)->srate > 44100)
continue;
+ if (!(*mtp)->modulator_u8)
+ continue;
for (mrp = sm_modem_rx_table; *mrp; mrp++) {
if ((*mrp)->loc_storage > sizeof(sm->d)) {
printk(KERN_ERR "%s: insufficient storage for demodulator %s (%d)\n",
sm_drvname, (*mrp)->name, (*mrp)->loc_storage);
continue;
}
+ if (!(*mrp)->demodulator_u8)
+ continue;
if ((*mrp)->name && !strcmp((*mrp)->name, cp) &&
(*mrp)->srate >= 5000 && (*mrp)->srate <= 44100) {
sm->mode_tx = *mtp;
@@ -521,11 +514,11 @@ static int sbc_sethw(struct device *dev, struct sm_state *sm, char *mode)
sm->mode_rx->srate);
SCSTATE->fmt[1] = 256-((1000000L+sm->mode_tx->srate/2)/
sm->mode_tx->srate);
- dv = lcm(sm->mode_tx->dmabuflenmodulo,
- sm->mode_rx->dmabuflenmodulo);
- SCSTATE->dmabuflen = sm->mode_rx->srate/100+dv-1;
- SCSTATE->dmabuflen /= dv;
- SCSTATE->dmabuflen *= 2*dv; /* make sure DMA buf is even */
+ sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
+ sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
+ if (sm->dma.ifragsz < sm->mode_rx->overlap)
+ sm->dma.ifragsz = sm->mode_rx->overlap;
+ sm->dma.i16bit = sm->dma.o16bit = 0;
return 0;
}
}
@@ -633,50 +626,61 @@ const struct hardware_info sm_hw_sbc = {
static void setup_dma_fdx_dsp(struct device *dev, struct sm_state *sm)
{
unsigned long flags;
- unsigned long dmabufaddr = virt_to_bus(SCSTATE->dmabuf);
- unsigned long dmabuf2addr = virt_to_bus(SCSTATE->dmabuf2);
+ unsigned int isamps, osamps;
if (!reset_dsp(dev)) {
printk(KERN_ERR "%s: sbc: cannot reset sb dsp\n", sm_drvname);
return;
}
- if (((dmabufaddr & 0xffff) + SCSTATE->dmabuflen > 0x10000) ||
- ((dmabuf2addr & 0xffff) + 2*(SCSTATE->dmabuflen) > 0x10000))
- panic("sm: DMA buffer violates DMA boundary!");
save_flags(flags);
cli();
sbc_int_ack_8bit(dev);
sbc_int_ack_16bit(dev);
/* should eventually change to set rates individually by SBC_SAMPLE_RATE_{IN/OUT} */
- write_dsp(dev, SBC_SAMPLE_RATE); /* set sampling rate */
- write_dsp(dev, SCSTATE->fmt[0]);
+ write_dsp(dev, SBC_SAMPLE_RATE_IN);
+ write_dsp(dev, SCSTATE->sr[0] >> 8);
+ write_dsp(dev, SCSTATE->sr[0] & 0xff);
+ write_dsp(dev, SBC_SAMPLE_RATE_OUT);
+ write_dsp(dev, SCSTATE->sr[1] >> 8);
+ write_dsp(dev, SCSTATE->sr[1] & 0xff);
write_dsp(dev, SBC_SPEAKER_ON);
- /*
- * DMA channel 1 (8bit) does input (capture),
- * DMA channel 2 (16bit) does output (playback)
- */
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_READ | DMA_MODE_AUTOINIT);
- set_dma_addr(dev->dma, dmabufaddr);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- set_dma_mode(sm->hdrv.ptt_out.dma2, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
- set_dma_addr(sm->hdrv.ptt_out.dma2, dmabuf2addr);
- set_dma_count(sm->hdrv.ptt_out.dma2, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
- enable_dma(sm->hdrv.ptt_out.dma2);
- sbc_int_ack_8bit(dev);
- sbc_int_ack_16bit(dev);
- write_dsp(dev, SBC4_IN8_AI);
- write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
- write_dsp(dev, SBC4_OUT16_AI);
- write_dsp(dev, SBC4_MODE_UNS_MONO);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_dsp(dev, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ if (sm->dma.o16bit) {
+ /*
+ * DMA channel 1 (8bit) does input (capture),
+ * DMA channel 2 (16bit) does output (playback)
+ */
+ isamps = dma_setup(sm, 0, dev->dma) - 1;
+ osamps = dma_setup(sm, 1, sm->hdrv.ptt_out.dma2) - 1;
+ sbc_int_ack_8bit(dev);
+ sbc_int_ack_16bit(dev);
+ write_dsp(dev, SBC4_IN8_AI);
+ write_dsp(dev, SBC4_MODE_UNS_MONO);
+ write_dsp(dev, isamps & 0xff);
+ write_dsp(dev, isamps >> 8);
+ write_dsp(dev, SBC4_OUT16_AI);
+ write_dsp(dev, SBC4_MODE_SIGN_MONO);
+ write_dsp(dev, osamps & 0xff);
+ write_dsp(dev, osamps >> 8);
+ } else {
+ /*
+ * DMA channel 1 (8bit) does output (playback),
+ * DMA channel 2 (16bit) does input (capture)
+ */
+ isamps = dma_setup(sm, 0, sm->hdrv.ptt_out.dma2) - 1;
+ osamps = dma_setup(sm, 1, dev->dma) - 1;
+ sbc_int_ack_8bit(dev);
+ sbc_int_ack_16bit(dev);
+ write_dsp(dev, SBC4_OUT8_AI);
+ write_dsp(dev, SBC4_MODE_UNS_MONO);
+ write_dsp(dev, osamps & 0xff);
+ write_dsp(dev, osamps >> 8);
+ write_dsp(dev, SBC4_IN16_AI);
+ write_dsp(dev, SBC4_MODE_SIGN_MONO);
+ write_dsp(dev, isamps & 0xff);
+ write_dsp(dev, isamps >> 8);
+ }
+ dma_init_receive(sm);
+ dma_init_transmit(sm);
restore_flags(flags);
}
@@ -686,41 +690,58 @@ static void sbcfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_id;
struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned char *buf;
- unsigned char *buf2;
- unsigned char intsrc;
+ unsigned char intsrc, pbint = 0, captint = 0;
+ unsigned int ocfrag, icfrag;
+ unsigned long flags;
if (!dev || !sm || sm->hdrv.magic != HDLCDRV_MAGIC)
return;
- buf = SCSTATE->dmabuf;
- buf2 = SCSTATE->dmabuf2;
+ save_flags(flags);
+ cli();
outb(0x82, DSP_MIXER_ADDR(dev->base_addr));
intsrc = inb(DSP_MIXER_DATA(dev->base_addr));
if (intsrc & 0x01) {
sbc_int_ack_8bit(dev);
- if (SCSTATE->dmabufidx)
- buf += SCSTATE->dmabuflen/2;
- SCSTATE->dmabufidx = !SCSTATE->dmabufidx;
+ if (sm->dma.o16bit) {
+ captint = 1;
+ disable_dma(dev->dma);
+ clear_dma_ff(dev->dma);
+ dma_ptr(sm, 0, dev->dma, &icfrag);
+ enable_dma(dev->dma);
+ } else {
+ pbint = 1;
+ disable_dma(dev->dma);
+ clear_dma_ff(dev->dma);
+ dma_ptr(sm, 1, dev->dma, &ocfrag);
+ enable_dma(dev->dma);
+ }
}
if (intsrc & 0x02) {
sbc_int_ack_16bit(dev);
- if (SCSTATE->dma2bufidx)
- buf2 += SCSTATE->dmabuflen/2;
- SCSTATE->dma2bufidx = !SCSTATE->dma2bufidx;
+ if (sm->dma.o16bit) {
+ pbint = 1;
+ disable_dma(sm->hdrv.ptt_out.dma2);
+ clear_dma_ff(sm->hdrv.ptt_out.dma2);
+ dma_ptr(sm, 1, sm->hdrv.ptt_out.dma2, &ocfrag);
+ enable_dma(sm->hdrv.ptt_out.dma2);
+ } else {
+ captint = 1;
+ disable_dma(sm->hdrv.ptt_out.dma2);
+ clear_dma_ff(sm->hdrv.ptt_out.dma2);
+ dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag);
+ enable_dma(sm->hdrv.ptt_out.dma2);
+ }
}
+ restore_flags(flags);
sm_int_freq(sm);
sti();
- if (intsrc & 0x02) {
- if ((SCSTATE->ptt = hdlcdrv_ptt(&sm->hdrv)))
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, buf2, SCSTATE->dmabuflen/2));
- else
- time_exec(sm->debug_vals.mod_cyc,
- memset(buf2, 0x80, SCSTATE->dmabuflen/2));
+ if (pbint) {
+ if (dma_end_transmit(sm, ocfrag))
+ dma_clear_transmit(sm);
+ dma_transmit(sm);
}
- if (intsrc & 0x01) {
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2));
+ if (captint) {
+ dma_receive(sm, icfrag);
hdlcdrv_arbitrate(dev, &sm->hdrv);
}
sm_output_status(sm);
@@ -749,12 +770,17 @@ static int sbcfdx_open(struct device *dev, struct sm_state *sm)
/*
* check if a card is available
*/
- if (!reset_dsp(dev))
+ if (!reset_dsp(dev)) {
+ printk(KERN_ERR "%s: sbc: no card at io address 0x%lx\n",
+ sm_drvname, dev->base_addr);
return -ENODEV;
+ }
write_dsp(dev, SBC_GET_REVISION);
if (!read_dsp(dev, &SCSTATE->revhi) ||
!read_dsp(dev, &SCSTATE->revlo))
return -ENODEV;
+ printk(KERN_INFO "%s: SoundBlaster DSP revision %d.%d\n", sm_drvname,
+ SCSTATE->revhi, SCSTATE->revlo);
if (SCSTATE->revhi < 4) {
printk(KERN_ERR "%s: at least DSP rev 4.00 required\n", sm_drvname);
return -ENODEV;
@@ -766,13 +792,14 @@ static int sbcfdx_open(struct device *dev, struct sm_state *sm)
/*
* initialize some variables
*/
- if (!(SCSTATE->dmabuf = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA)))
+ if (!(sm->dma.ibuf = kmalloc(sm->dma.ifragsz * (NUM_FRAGMENTS+1), GFP_KERNEL | GFP_DMA)))
return -ENOMEM;
- if (!(SCSTATE->dmabuf2 = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA))) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ if (!(sm->dma.obuf = kmalloc(sm->dma.ofragsz * NUM_FRAGMENTS, GFP_KERNEL | GFP_DMA))) {
+ kfree(sm->dma.ibuf);
return -ENOMEM;
}
- SCSTATE->dmabufidx = SCSTATE->dma2bufidx = SCSTATE->ptt = 0;
+ dma_init_transmit(sm);
+ dma_init_receive(sm);
memset(&sm->m, 0, sizeof(sm->m));
memset(&sm->d, 0, sizeof(sm->d));
@@ -782,20 +809,20 @@ static int sbcfdx_open(struct device *dev, struct sm_state *sm)
sm->mode_rx->init(sm);
if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
return -EBUSY;
}
if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
free_dma(dev->dma);
return -EBUSY;
}
if (request_irq(dev->irq, sbcfdx_interrupt, SA_INTERRUPT,
sm->hwdrv->hw_name, dev)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
free_dma(dev->dma);
free_dma(sm->hdrv.ptt_out.dma2);
return -EBUSY;
@@ -821,8 +848,8 @@ static int sbcfdx_close(struct device *dev, struct sm_state *sm)
free_dma(dev->dma);
free_dma(sm->hdrv.ptt_out.dma2);
release_region(dev->base_addr, SBC_EXTENT);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
return 0;
}
@@ -833,7 +860,6 @@ static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode)
char *cp = strchr(mode, '.');
const struct modem_tx_info **mtp = sm_modem_tx_table;
const struct modem_rx_info **mrp;
- int dv;
if (!strcmp(mode, "off")) {
sm->mode_tx = NULL;
@@ -867,13 +893,25 @@ static int sbcfdx_sethw(struct device *dev, struct sm_state *sm, char *mode)
sm->mode_rx = *mrp;
SCSTATE->sr[0] = sm->mode_rx->srate;
SCSTATE->sr[1] = sm->mode_tx->srate;
- dv = lcm(sm->mode_tx->dmabuflenmodulo,
- sm->mode_rx->dmabuflenmodulo);
- if (dv & 1)
- dv <<= 1; /* dmabuflen must be a multiple of 4 */
- SCSTATE->dmabuflen = sm->mode_rx->srate/100+dv-1;
- SCSTATE->dmabuflen /= dv;
- SCSTATE->dmabuflen *= 2*dv; /* make sure DMA buf is even */
+ sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
+ sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
+ if (sm->dma.ifragsz < sm->mode_rx->overlap)
+ sm->dma.ifragsz = sm->mode_rx->overlap;
+ if (sm->mode_rx->demodulator_s16 && sm->mode_tx->modulator_u8) {
+ sm->dma.i16bit = 1;
+ sm->dma.o16bit = 0;
+ sm->dma.ifragsz <<= 1;
+ } else if (sm->mode_rx->demodulator_u8 && sm->mode_tx->modulator_s16) {
+ sm->dma.i16bit = 0;
+ sm->dma.o16bit = 1;
+ sm->dma.ofragsz <<= 1;
+ } else {
+ printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
+ sm->mode_rx->name, sm->mode_tx->name);
+ sm->mode_tx = NULL;
+ sm->mode_rx = NULL;
+ return -EINVAL;
+ }
return 0;
}
}
diff --git a/drivers/net/soundmodem/sm_wss.c b/drivers/net/soundmodem/sm_wss.c
index 0123a9aa4..021ecc165 100644
--- a/drivers/net/soundmodem/sm_wss.c
+++ b/drivers/net/soundmodem/sm_wss.c
@@ -26,12 +26,14 @@
*/
#include <linux/ptrace.h>
+#include <linux/sched.h>
#include <linux/interrupt.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/ioport.h>
#include <linux/soundmodem.h>
#include "sm.h"
+#include "smdma.h"
/* --------------------------------------------------------------------- */
@@ -81,12 +83,6 @@ struct sc_state_wss {
unsigned char revwss, revid, revv, revcid;
unsigned char fmt[2];
unsigned char crystal;
- unsigned int dmabuflen;
- unsigned char *dmabuf;
- unsigned char dmabufidx;
- unsigned char ptt;
- /* Full Duplex extensions */
- unsigned char *dmabuf2;
};
#define SCSTATE ((struct sc_state_wss *)(&sm->hw))
@@ -156,8 +152,8 @@ static int wss_srate_index(int srate)
/* --------------------------------------------------------------------- */
-static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm,
- unsigned char fmt, char fdx, char fullcalib)
+static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm, unsigned char fmt,
+ unsigned char fmt2, char fdx, char fullcalib)
{
unsigned long time;
unsigned long flags;
@@ -167,7 +163,7 @@ static int wss_set_codec_fmt(struct device *dev, struct sm_state *sm,
/* Clock and data format register */
write_codec(dev, 0x48, fmt);
if (SCSTATE->crystal) {
- write_codec(dev, 0x5c, fmt & 0xf0);
+ write_codec(dev, 0x5c, fmt2 & 0xf0);
/* MCE and interface config reg */
write_codec(dev, 0x49, (fdx ? 0 : 0x4) | (fullcalib ? 0x18 : 0));
} else
@@ -306,7 +302,7 @@ static int wss_init_codec(struct device *dev, struct sm_state *sm, char fdx,
write_codec(dev, 0x1d, 0x00); /* right out no att */
}
- if (wss_set_codec_fmt(dev, sm, SCSTATE->fmt[0], fdx, 1))
+ if (wss_set_codec_fmt(dev, sm, SCSTATE->fmt[0], SCSTATE->fmt[0], fdx, 1))
goto codec_err;
write_codec(dev, 0, reg0); /* left input control */
@@ -345,18 +341,14 @@ static void setup_dma_wss(struct device *dev, struct sm_state *sm, int send)
{
unsigned long flags;
static const unsigned char codecmode[2] = { 0x0e, 0x0d };
- static const unsigned char dmamode[2] = {
- DMA_MODE_READ | DMA_MODE_AUTOINIT,
- DMA_MODE_WRITE | DMA_MODE_AUTOINIT
- };
unsigned char oldcodecmode;
long abrt;
- unsigned long dmabufaddr = virt_to_bus(SCSTATE->dmabuf);
+ unsigned char fmt;
+ unsigned int numsamps;
- if ((dmabufaddr & 0xffffu) + SCSTATE->dmabuflen > 0x10000)
- panic("%s: DMA buffer violates DMA boundary!", sm_drvname);
send = !!send;
- save_flags(flags);
+ fmt = SCSTATE->fmt[send];
+ save_flags(flags);
cli();
/*
* perform the final DMA sequence to disable the codec request
@@ -365,28 +357,18 @@ static void setup_dma_wss(struct device *dev, struct sm_state *sm, int send)
write_codec(dev, 9, 0xc); /* disable codec */
wss_ack_int(dev);
if (read_codec(dev, 11) & 0x10) {
- disable_dma(dev->dma);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, dmamode[oldcodecmode & 1]);
- set_dma_addr(dev->dma, dmabufaddr);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
+ dma_setup(sm, oldcodecmode & 1, dev->dma);
abrt = 0;
while ((read_codec(dev, 11) & 0x10) || ((++abrt) >= 0x10000));
}
- disable_dma(dev->dma);
- if (read_codec(dev, 0x8) != SCSTATE->fmt[send])
- wss_set_codec_fmt(dev, sm, SCSTATE->fmt[send], 0, 0);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, dmamode[send]);
- set_dma_addr(dev->dma, dmabufaddr);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
- write_codec(dev, 15, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_codec(dev, 14, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ if (read_codec(dev, 0x8) != fmt)
+ wss_set_codec_fmt(dev, sm, fmt, fmt, 0, 0);
+ numsamps = dma_setup(sm, send, dev->dma) - 1;
+ write_codec(dev, 15, numsamps & 0xff);
+ write_codec(dev, 14, numsamps >> 8);
if (SCSTATE->crystal) {
- write_codec(dev, 31, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_codec(dev, 30, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ write_codec(dev, 31, numsamps & 0xff);
+ write_codec(dev, 30, numsamps >> 8);
}
write_codec(dev, 9, codecmode[send]);
restore_flags(flags);
@@ -398,74 +380,45 @@ static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_id;
struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned char new_ptt;
- unsigned char *buf;
- int dmares;
+ unsigned int curfrag;
+ unsigned int nums;
if (!dev || !sm || !sm->mode_rx || !sm->mode_tx ||
sm->hdrv.magic != HDLCDRV_MAGIC)
return;
- new_ptt = hdlcdrv_ptt(&sm->hdrv);
cli();
wss_ack_int(dev);
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
- dmares = get_dma_residue(dev->dma);
- if (dmares <= 0)
- dmares = SCSTATE->dmabuflen;
- buf = SCSTATE->dmabuf;
- if (dmares > SCSTATE->dmabuflen/2) {
- buf += SCSTATE->dmabuflen/2;
- dmares -= SCSTATE->dmabuflen/2;
- }
-#ifdef SM_DEBUG
- if (!sm->debug_vals.dma_residue ||
- dmares < sm->debug_vals.dma_residue)
- sm->debug_vals.dma_residue = dmares;
-#endif /* SM_DEBUG */
- dmares--;
- write_codec(dev, 15, dmares & 0xff);
- write_codec(dev, 14, dmares >> 8);
+ nums = dma_ptr(sm, sm->dma.ptt_cnt > 0, dev->dma, &curfrag) - 1;
+ write_codec(dev, 15, nums & 0xff);
+ write_codec(dev, 14, nums >> 8);
if (SCSTATE->crystal) {
- write_codec(dev, 31, dmares & 0xff);
- write_codec(dev, 30, dmares >> 8);
+ write_codec(dev, 31, nums & 0xff);
+ write_codec(dev, 30, nums >> 8);
}
enable_dma(dev->dma);
sm_int_freq(sm);
sti();
- if (new_ptt && !SCSTATE->ptt) {
- /* starting to transmit */
- disable_dma(dev->dma);
- sti();
- SCSTATE->dmabufidx = 0;
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2));
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, SCSTATE->dmabuf,
- SCSTATE->dmabuflen/2));
- setup_dma_wss(dev, sm, 1);
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, SCSTATE->dmabuf +
- SCSTATE->dmabuflen/2,
- SCSTATE->dmabuflen/2));
- } else if (SCSTATE->ptt == 1 && !new_ptt) {
+ if (sm->dma.ptt_cnt <= 0) {
+ dma_receive(sm, curfrag);
+ if (hdlcdrv_ptt(&sm->hdrv)) {
+ /* starting to transmit */
+ disable_dma(dev->dma);
+ dma_start_transmit(sm);
+ setup_dma_wss(dev, sm, 1);
+ dma_transmit(sm);
+ }
+ } else if (dma_end_transmit(sm, curfrag)) {
/* stopping transmission */
disable_dma(dev->dma);
sti();
- SCSTATE->dmabufidx = 0;
+ dma_init_receive(sm);
setup_dma_wss(dev, sm, 0);
- SCSTATE->ptt = 0;
- } else if (SCSTATE->ptt) {
- SCSTATE->ptt--;
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, buf, SCSTATE->dmabuflen/2));
} else {
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf, SCSTATE->dmabuflen/2));
+ dma_transmit(sm);
hdlcdrv_arbitrate(dev, &sm->hdrv);
}
- if (new_ptt)
- SCSTATE->ptt = 2;
sm_output_status(sm);
hdlcdrv_transmitter(dev, &sm->hdrv);
hdlcdrv_receiver(dev, &sm->hdrv);
@@ -475,6 +428,8 @@ static void wss_interrupt(int irq, void *dev_id, struct pt_regs *regs)
static int wss_open(struct device *dev, struct sm_state *sm)
{
+ unsigned int dmasz, u;
+
if (sizeof(sm->m) < sizeof(struct sc_state_wss)) {
printk(KERN_ERR "sm wss: wss state too big: %d > %d\n",
sizeof(struct sc_state_wss), sizeof(sm->m));
@@ -495,9 +450,19 @@ static int wss_open(struct device *dev, struct sm_state *sm)
/*
* initialize some variables
*/
- if (!(SCSTATE->dmabuf = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA)))
+ dma_init_receive(sm);
+ dmasz = (NUM_FRAGMENTS + 1) * sm->dma.ifragsz;
+ if (sm->dma.i16bit)
+ dmasz <<= 1;
+ u = NUM_FRAGMENTS * sm->dma.ofragsz;
+ if (sm->dma.o16bit)
+ u <<= 1;
+ if (u > dmasz)
+ dmasz = u;
+ if (!(sm->dma.ibuf = sm->dma.obuf = kmalloc(dmasz, GFP_KERNEL | GFP_DMA)))
return -ENOMEM;
- SCSTATE->dmabufidx = SCSTATE->ptt = 0;
+ dma_init_transmit(sm);
+ dma_init_receive(sm);
memset(&sm->m, 0, sizeof(sm->m));
memset(&sm->d, 0, sizeof(sm->d));
@@ -507,13 +472,13 @@ static int wss_open(struct device *dev, struct sm_state *sm)
sm->mode_rx->init(sm);
if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree_s(sm->dma.obuf, dmasz);
return -EBUSY;
}
if (request_irq(dev->irq, wss_interrupt, SA_INTERRUPT,
sm->hwdrv->hw_name, dev)) {
free_dma(dev->dma);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree_s(sm->dma.obuf, dmasz);
return -EBUSY;
}
request_region(dev->base_addr, WSS_EXTENT, sm->hwdrv->hw_name);
@@ -535,7 +500,7 @@ static int wss_close(struct device *dev, struct sm_state *sm)
free_irq(dev->irq, dev);
free_dma(dev->dma);
release_region(dev->base_addr, WSS_EXTENT);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ kfree(sm->dma.obuf);
return 0;
}
@@ -546,7 +511,7 @@ static int wss_sethw(struct device *dev, struct sm_state *sm, char *mode)
char *cp = strchr(mode, '.');
const struct modem_tx_info **mtp = sm_modem_tx_table;
const struct modem_rx_info **mrp;
- int i, j, dv;
+ int i, j;
if (!strcmp(mode, "off")) {
sm->mode_tx = NULL;
@@ -579,11 +544,57 @@ static int wss_sethw(struct device *dev, struct sm_state *sm, char *mode)
sm->mode_rx = *mrp;
SCSTATE->fmt[0] = j;
SCSTATE->fmt[1] = i;
- dv = lcm(sm->mode_tx->dmabuflenmodulo,
- sm->mode_rx->dmabuflenmodulo);
- SCSTATE->dmabuflen = sm->mode_rx->srate/100+dv-1;
- SCSTATE->dmabuflen /= dv;
- SCSTATE->dmabuflen *= 2*dv; /* make sure DMA buf is even */
+ sm->dma.ifragsz = (sm->mode_rx->srate + 50)/100;
+ sm->dma.ofragsz = (sm->mode_tx->srate + 50)/100;
+ if (sm->dma.ifragsz < sm->mode_rx->overlap)
+ sm->dma.ifragsz = sm->mode_rx->overlap;
+ /* prefer same data format if possible to minimize switching times */
+ sm->dma.i16bit = sm->dma.o16bit = 2;
+ if (sm->mode_rx->srate == sm->mode_tx->srate) {
+ if (sm->mode_rx->demodulator_s16 && sm->mode_tx->modulator_s16)
+ sm->dma.i16bit = sm->dma.o16bit = 1;
+ else if (sm->mode_rx->demodulator_u8 && sm->mode_tx->modulator_u8)
+ sm->dma.i16bit = sm->dma.o16bit = 0;
+ }
+ if (sm->dma.i16bit == 2) {
+ if (sm->mode_rx->demodulator_s16)
+ sm->dma.i16bit = 1;
+ else if (sm->mode_rx->demodulator_u8)
+ sm->dma.i16bit = 0;
+ }
+ if (sm->dma.o16bit == 2) {
+ if (sm->mode_tx->modulator_s16)
+ sm->dma.o16bit = 1;
+ else if (sm->mode_tx->modulator_u8)
+ sm->dma.o16bit = 0;
+ }
+ if (sm->dma.i16bit == 2 || sm->dma.o16bit == 2) {
+ printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
+ sm->mode_rx->name, sm->mode_tx->name);
+ sm->mode_tx = NULL;
+ sm->mode_rx = NULL;
+ return -EINVAL;
+ }
+#ifdef __BIG_ENDIAN
+ /* big endian 16bit only works on crystal cards... */
+ if (sm->dma.i16bit) {
+ SCSTATE->fmt[0] |= 0xc0;
+ sm->dma.ifragsz <<= 1;
+ }
+ if (sm->dma.o16bit) {
+ SCSTATE->fmt[1] |= 0xc0;
+ sm->dma.ofragsz <<= 1;
+ }
+#else /* __BIG_ENDIAN */
+ if (sm->dma.i16bit) {
+ SCSTATE->fmt[0] |= 0x40;
+ sm->dma.ifragsz <<= 1;
+ }
+ if (sm->dma.o16bit) {
+ SCSTATE->fmt[1] |= 0x40;
+ sm->dma.ofragsz <<= 1;
+ }
+#endif /* __BIG_ENDIAN */
return 0;
}
}
@@ -663,12 +674,8 @@ static void setup_fdx_dma_wss(struct device *dev, struct sm_state *sm)
unsigned long flags;
unsigned char oldcodecmode, codecdma;
long abrt;
- unsigned long dmabufaddr1 = virt_to_bus(SCSTATE->dmabuf);
- unsigned long dmabufaddr2 = virt_to_bus(SCSTATE->dmabuf2);
-
- if (((dmabufaddr1 & 0xffffu) + SCSTATE->dmabuflen > 0x10000) ||
- ((dmabufaddr2 & 0xffffu) + SCSTATE->dmabuflen > 0x10000))
- panic("%s: DMA buffer violates DMA boundary!", sm_drvname);
+ unsigned int osamps, isamps;
+
save_flags(flags);
cli();
/*
@@ -678,39 +685,19 @@ static void setup_fdx_dma_wss(struct device *dev, struct sm_state *sm)
write_codec(dev, 9, 0); /* disable codec DMA */
wss_ack_int(dev);
if ((codecdma = read_codec(dev, 11)) & 0x10) {
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
- set_dma_addr(dev->dma, dmabufaddr1);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- set_dma_mode(sm->hdrv.ptt_out.dma2, DMA_MODE_READ | DMA_MODE_AUTOINIT);
- set_dma_addr(sm->hdrv.ptt_out.dma2, dmabufaddr2);
- set_dma_count(sm->hdrv.ptt_out.dma2, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
- enable_dma(sm->hdrv.ptt_out.dma2);
+ dma_setup(sm, 1, dev->dma);
+ dma_setup(sm, 0, sm->hdrv.ptt_out.dma2);
abrt = 0;
- while (((codecdma = read_codec(dev, 11)) & 0x10) ||
- ((++abrt) >= 0x10000));
+ while (((codecdma = read_codec(dev, 11)) & 0x10) || ((++abrt) >= 0x10000));
}
- disable_dma(dev->dma);
- disable_dma(sm->hdrv.ptt_out.dma2);
- clear_dma_ff(dev->dma);
- set_dma_mode(dev->dma, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
- set_dma_addr(dev->dma, dmabufaddr1);
- set_dma_count(dev->dma, SCSTATE->dmabuflen);
- clear_dma_ff(sm->hdrv.ptt_out.dma2);
- set_dma_mode(sm->hdrv.ptt_out.dma2, DMA_MODE_READ | DMA_MODE_AUTOINIT);
- set_dma_addr(sm->hdrv.ptt_out.dma2, dmabufaddr2);
- set_dma_count(sm->hdrv.ptt_out.dma2, SCSTATE->dmabuflen);
- enable_dma(dev->dma);
- enable_dma(sm->hdrv.ptt_out.dma2);
- write_codec(dev, 15, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_codec(dev, 14, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ wss_set_codec_fmt(dev, sm, SCSTATE->fmt[1], SCSTATE->fmt[0], 1, 1);
+ osamps = dma_setup(sm, 1, dev->dma) - 1;
+ isamps = dma_setup(sm, 0, sm->hdrv.ptt_out.dma2) - 1;
+ write_codec(dev, 15, osamps & 0xff);
+ write_codec(dev, 14, osamps >> 8);
if (SCSTATE->crystal) {
- write_codec(dev, 31, ((SCSTATE->dmabuflen >> 1) - 1) & 0xff);
- write_codec(dev, 30, ((SCSTATE->dmabuflen >> 1) - 1) >> 8);
+ write_codec(dev, 31, isamps & 0xff);
+ write_codec(dev, 30, isamps >> 8);
}
write_codec(dev, 9, 3);
restore_flags(flags);
@@ -722,68 +709,74 @@ static void wssfdx_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_id;
struct sm_state *sm = (struct sm_state *)dev->priv;
- unsigned char *buf1;
- unsigned char *buf2;
unsigned long flags;
- int dmares1, dmares2;
+ unsigned char cry_int_src;
+ unsigned icfrag, ocfrag, isamps, osamps;
if (!dev || !sm || !sm->mode_rx || !sm->mode_tx ||
sm->hdrv.magic != HDLCDRV_MAGIC)
return;
save_flags(flags);
cli();
- if (SCSTATE->crystal && (!(read_codec(dev, 0x18) & 0x20))) {
- /* only regard Crystal Playback interrupts! */
+ if (SCSTATE->crystal) {
+ /* Crystal has an essentially different interrupt handler! */
+ cry_int_src = read_codec(dev, 0x18);
wss_ack_int(dev);
+ if (cry_int_src & 0x10) { /* playback interrupt */
+ disable_dma(dev->dma);
+ clear_dma_ff(dev->dma);
+ osamps = dma_ptr(sm, 1, dev->dma, &ocfrag)-1;
+ write_codec(dev, 15, osamps & 0xff);
+ write_codec(dev, 14, osamps >> 8);
+ enable_dma(dev->dma);
+ }
+ if (cry_int_src & 0x20) { /* capture interrupt */
+ disable_dma(sm->hdrv.ptt_out.dma2);
+ clear_dma_ff(sm->hdrv.ptt_out.dma2);
+ isamps = dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag)-1;
+ write_codec(dev, 31, isamps & 0xff);
+ write_codec(dev, 30, isamps >> 8);
+ enable_dma(sm->hdrv.ptt_out.dma2);
+ }
+ restore_flags(flags);
+ sm_int_freq(sm);
+ sti();
+ if (cry_int_src & 0x10) {
+ if (dma_end_transmit(sm, ocfrag))
+ dma_clear_transmit(sm);
+ dma_transmit(sm);
+ }
+ if (cry_int_src & 0x20) {
+ dma_receive(sm, icfrag);
+ hdlcdrv_arbitrate(dev, &sm->hdrv);
+ }
+ sm_output_status(sm);
+ hdlcdrv_transmitter(dev, &sm->hdrv);
+ hdlcdrv_receiver(dev, &sm->hdrv);
return;
}
wss_ack_int(dev);
disable_dma(dev->dma);
disable_dma(sm->hdrv.ptt_out.dma2);
clear_dma_ff(dev->dma);
- dmares1 = get_dma_residue(dev->dma);
clear_dma_ff(sm->hdrv.ptt_out.dma2);
- dmares2 = get_dma_residue(sm->hdrv.ptt_out.dma2);
- if (dmares1 <= 0)
- dmares1 = SCSTATE->dmabuflen;
- buf1 = SCSTATE->dmabuf;
- if (dmares1 > SCSTATE->dmabuflen/2) {
- buf1 += SCSTATE->dmabuflen/2;
- dmares1 -= SCSTATE->dmabuflen/2;
- }
- if (dmares2 <= 0)
- dmares2 = SCSTATE->dmabuflen;
- buf2 = SCSTATE->dmabuf2;
- if (dmares2 > SCSTATE->dmabuflen/2) {
- buf2 += SCSTATE->dmabuflen/2;
- dmares2 -= SCSTATE->dmabuflen/2;
- }
-#ifdef SM_DEBUG
- if (!sm->debug_vals.dma_residue ||
- dmares1 < sm->debug_vals.dma_residue)
- sm->debug_vals.dma_residue = dmares1;
-#endif /* SM_DEBUG */
- dmares1--;
- dmares2--;
- write_codec(dev, 15, dmares1 & 0xff);
- write_codec(dev, 14, dmares1 >> 8);
+ osamps = dma_ptr(sm, 1, dev->dma, &ocfrag)-1;
+ isamps = dma_ptr(sm, 0, sm->hdrv.ptt_out.dma2, &icfrag)-1;
+ write_codec(dev, 15, osamps & 0xff);
+ write_codec(dev, 14, osamps >> 8);
if (SCSTATE->crystal) {
- write_codec(dev, 31, dmares2 & 0xff);
- write_codec(dev, 30, dmares2 >> 8);
+ write_codec(dev, 31, isamps & 0xff);
+ write_codec(dev, 30, isamps >> 8);
}
enable_dma(dev->dma);
enable_dma(sm->hdrv.ptt_out.dma2);
restore_flags(flags);
sm_int_freq(sm);
sti();
- if ((SCSTATE->ptt = hdlcdrv_ptt(&sm->hdrv)))
- time_exec(sm->debug_vals.mod_cyc,
- sm->mode_tx->modulator(sm, buf1, SCSTATE->dmabuflen/2));
- else
- time_exec(sm->debug_vals.mod_cyc,
- memset(buf1, 0x80, SCSTATE->dmabuflen/2));
- time_exec(sm->debug_vals.demod_cyc,
- sm->mode_rx->demodulator(sm, buf2, SCSTATE->dmabuflen/2));
+ if (dma_end_transmit(sm, ocfrag))
+ dma_clear_transmit(sm);
+ dma_transmit(sm);
+ dma_receive(sm, icfrag);
hdlcdrv_arbitrate(dev, &sm->hdrv);
sm_output_status(sm);
hdlcdrv_transmitter(dev, &sm->hdrv);
@@ -809,13 +802,14 @@ static int wssfdx_open(struct device *dev, struct sm_state *sm)
/*
* initialize some variables
*/
- if (!(SCSTATE->dmabuf = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA)))
+ if (!(sm->dma.ibuf = kmalloc(sm->dma.ifragsz * (NUM_FRAGMENTS+1), GFP_KERNEL | GFP_DMA)))
return -ENOMEM;
- if (!(SCSTATE->dmabuf2 = kmalloc(SCSTATE->dmabuflen, GFP_KERNEL | GFP_DMA))) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
+ if (!(sm->dma.obuf = kmalloc(sm->dma.ofragsz * NUM_FRAGMENTS, GFP_KERNEL | GFP_DMA))) {
+ kfree(sm->dma.ibuf);
return -ENOMEM;
}
- SCSTATE->dmabufidx = SCSTATE->ptt = 0;
+ dma_init_transmit(sm);
+ dma_init_receive(sm);
memset(&sm->m, 0, sizeof(sm->m));
memset(&sm->d, 0, sizeof(sm->d));
@@ -825,20 +819,20 @@ static int wssfdx_open(struct device *dev, struct sm_state *sm)
sm->mode_rx->init(sm);
if (request_dma(dev->dma, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
return -EBUSY;
}
if (request_dma(sm->hdrv.ptt_out.dma2, sm->hwdrv->hw_name)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
free_dma(dev->dma);
return -EBUSY;
}
if (request_irq(dev->irq, wssfdx_interrupt, SA_INTERRUPT,
sm->hwdrv->hw_name, dev)) {
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
free_dma(dev->dma);
free_dma(sm->hdrv.ptt_out.dma2);
return -EBUSY;
@@ -858,13 +852,14 @@ static int wssfdx_close(struct device *dev, struct sm_state *sm)
* disable interrupts
*/
disable_dma(dev->dma);
+ disable_dma(sm->hdrv.ptt_out.dma2);
write_codec(dev, 9, 0xc); /* disable codec */
free_irq(dev->irq, dev);
free_dma(dev->dma);
free_dma(sm->hdrv.ptt_out.dma2);
release_region(dev->base_addr, WSS_EXTENT);
- kfree_s(SCSTATE->dmabuf, SCSTATE->dmabuflen);
- kfree_s(SCSTATE->dmabuf2, SCSTATE->dmabuflen);
+ kfree(sm->dma.ibuf);
+ kfree(sm->dma.obuf);
return 0;
}
@@ -875,7 +870,7 @@ static int wssfdx_sethw(struct device *dev, struct sm_state *sm, char *mode)
char *cp = strchr(mode, '.');
const struct modem_tx_info **mtp = sm_modem_tx_table;
const struct modem_rx_info **mrp;
- int i, dv;
+ int i;
if (!strcmp(mode, "off")) {
sm->mode_tx = NULL;
@@ -907,11 +902,37 @@ static int wssfdx_sethw(struct device *dev, struct sm_state *sm, char *mode)
sm->mode_tx = *mtp;
sm->mode_rx = *mrp;
SCSTATE->fmt[0] = SCSTATE->fmt[1] = i;
- dv = lcm(sm->mode_tx->dmabuflenmodulo,
- sm->mode_rx->dmabuflenmodulo);
- SCSTATE->dmabuflen = sm->mode_rx->srate/100+dv-1;
- SCSTATE->dmabuflen /= dv;
- SCSTATE->dmabuflen *= 2*dv; /* make sure DMA buf is even */
+ sm->dma.ifragsz = sm->dma.ofragsz = (sm->mode_rx->srate + 50)/100;
+ if (sm->dma.ifragsz < sm->mode_rx->overlap)
+ sm->dma.ifragsz = sm->mode_rx->overlap;
+ sm->dma.i16bit = sm->dma.o16bit = 2;
+ if (sm->mode_rx->demodulator_s16) {
+ sm->dma.i16bit = 1;
+ sm->dma.ifragsz <<= 1;
+#ifdef __BIG_ENDIAN /* big endian 16bit only works on crystal cards... */
+ SCSTATE->fmt[0] |= 0xc0;
+#else /* __BIG_ENDIAN */
+ SCSTATE->fmt[0] |= 0x40;
+#endif /* __BIG_ENDIAN */
+ } else if (sm->mode_rx->demodulator_u8)
+ sm->dma.i16bit = 0;
+ if (sm->mode_tx->modulator_s16) {
+ sm->dma.o16bit = 1;
+ sm->dma.ofragsz <<= 1;
+#ifdef __BIG_ENDIAN /* big endian 16bit only works on crystal cards... */
+ SCSTATE->fmt[1] |= 0xc0;
+#else /* __BIG_ENDIAN */
+ SCSTATE->fmt[1] |= 0x40;
+#endif /* __BIG_ENDIAN */
+ } else if (sm->mode_tx->modulator_u8)
+ sm->dma.o16bit = 0;
+ if (sm->dma.i16bit == 2 || sm->dma.o16bit == 2) {
+ printk(KERN_INFO "%s: mode %s or %s unusable\n", sm_drvname,
+ sm->mode_rx->name, sm->mode_tx->name);
+ sm->mode_tx = NULL;
+ sm->mode_rx = NULL;
+ return -EINVAL;
+ }
return 0;
}
}
diff --git a/drivers/net/soundmodem/smdma.h b/drivers/net/soundmodem/smdma.h
new file mode 100644
index 000000000..27cea09e7
--- /dev/null
+++ b/drivers/net/soundmodem/smdma.h
@@ -0,0 +1,210 @@
+/*****************************************************************************/
+
+/*
+ * smdma.h -- soundcard radio modem driver dma buffer routines.
+ *
+ * Copyright (C) 1996 Thomas Sailer (sailer@ife.ee.ethz.ch)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Please note that the GPL allows you to use the driver, NOT the radio.
+ * In order to use the radio, you need a license from the communications
+ * authority of your country.
+ *
+ */
+
+#ifndef _SMDMA_H
+#define _SMDMA_H
+
+/* ---------------------------------------------------------------------- */
+
+#include "sm.h"
+
+/* ---------------------------------------------------------------------- */
+
+#define DMA_MODE_AUTOINIT 0x10
+#define NUM_FRAGMENTS 4
+
+/* --------------------------------------------------------------------- */
+/*
+ * ===================== DMA buffer management ===========================
+ */
+
+/*
+ * returns the number of samples per fragment
+ */
+extern __inline__ unsigned int dma_setup(struct sm_state *sm, int send, unsigned int dmanr)
+{
+ if (send) {
+ disable_dma(dmanr);
+ clear_dma_ff(dmanr);
+ set_dma_mode(dmanr, DMA_MODE_WRITE | DMA_MODE_AUTOINIT);
+ set_dma_addr(dmanr, virt_to_bus(sm->dma.obuf));
+ set_dma_count(dmanr, sm->dma.ofragsz * NUM_FRAGMENTS);
+ enable_dma(dmanr);
+ if (sm->dma.o16bit)
+ return sm->dma.ofragsz/2;
+ return sm->dma.ofragsz;
+ } else {
+ disable_dma(dmanr);
+ clear_dma_ff(dmanr);
+ set_dma_mode(dmanr, DMA_MODE_READ | DMA_MODE_AUTOINIT);
+ set_dma_addr(dmanr, virt_to_bus(sm->dma.ibuf));
+ set_dma_count(dmanr, sm->dma.ifragsz * NUM_FRAGMENTS);
+ enable_dma(dmanr);
+ if (sm->dma.i16bit)
+ return sm->dma.ifragsz/2;
+ return sm->dma.ifragsz;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+extern __inline__ unsigned int dma_ptr(struct sm_state *sm, int send, unsigned int dmanr,
+ unsigned int *curfrag)
+{
+ unsigned int dmaptr, sz, frg, offs;
+
+ dmaptr = get_dma_residue(dmanr);
+ if (send) {
+ sz = sm->dma.ofragsz * NUM_FRAGMENTS;
+ if (dmaptr == 0 || dmaptr > sz)
+ dmaptr = sz;
+ dmaptr--;
+ frg = dmaptr / sm->dma.ofragsz;
+ offs = (dmaptr % sm->dma.ofragsz) + 1;
+ *curfrag = NUM_FRAGMENTS - 1 - frg;
+#ifdef SM_DEBUG
+ if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
+ sm->debug_vals.dma_residue = offs;
+#endif /* SM_DEBUG */
+ if (sm->dma.o16bit)
+ return offs/2;
+ return offs;
+ } else {
+ sz = sm->dma.ifragsz * NUM_FRAGMENTS;
+ if (dmaptr == 0 || dmaptr > sz)
+ dmaptr = sz;
+ dmaptr--;
+ frg = dmaptr / sm->dma.ifragsz;
+ offs = (dmaptr % sm->dma.ifragsz) + 1;
+ *curfrag = NUM_FRAGMENTS - 1 - frg;
+#ifdef SM_DEBUG
+ if (!sm->debug_vals.dma_residue || offs < sm->debug_vals.dma_residue)
+ sm->debug_vals.dma_residue = offs;
+#endif /* SM_DEBUG */
+ if (sm->dma.i16bit)
+ return offs/2;
+ return offs;
+ }
+}
+
+/* --------------------------------------------------------------------- */
+
+extern __inline__ int dma_end_transmit(struct sm_state *sm, unsigned int curfrag)
+{
+ unsigned int diff = (NUM_FRAGMENTS + curfrag - sm->dma.ofragptr) % NUM_FRAGMENTS;
+
+ sm->dma.ofragptr = curfrag;
+ if (sm->dma.ptt_cnt <= 0) {
+ sm->dma.ptt_cnt = 0;
+ return 0;
+ }
+ sm->dma.ptt_cnt -= diff;
+ if (sm->dma.ptt_cnt <= 0) {
+ sm->dma.ptt_cnt = 0;
+ return -1;
+ }
+ return 0;
+}
+
+extern __inline__ void dma_transmit(struct sm_state *sm)
+{
+ void *p;
+
+ while (sm->dma.ptt_cnt < NUM_FRAGMENTS && hdlcdrv_ptt(&sm->hdrv)) {
+ p = (unsigned char *)sm->dma.obuf + sm->dma.ofragsz *
+ ((sm->dma.ofragptr + sm->dma.ptt_cnt) % NUM_FRAGMENTS);
+ if (sm->dma.o16bit) {
+ time_exec(sm->debug_vals.mod_cyc,
+ sm->mode_tx->modulator_s16(sm, p, sm->dma.ofragsz/2));
+ } else {
+ time_exec(sm->debug_vals.mod_cyc,
+ sm->mode_tx->modulator_u8(sm, p, sm->dma.ofragsz));
+ }
+ sm->dma.ptt_cnt++;
+ }
+}
+
+extern __inline__ void dma_init_transmit(struct sm_state *sm)
+{
+ sm->dma.ofragptr = 0;
+ sm->dma.ptt_cnt = 0;
+}
+
+extern __inline__ void dma_start_transmit(struct sm_state *sm)
+{
+ sm->dma.ofragptr = 0;
+ if (sm->dma.o16bit) {
+ time_exec(sm->debug_vals.mod_cyc,
+ sm->mode_tx->modulator_s16(sm, sm->dma.obuf, sm->dma.ofragsz/2));
+ } else {
+ time_exec(sm->debug_vals.mod_cyc,
+ sm->mode_tx->modulator_u8(sm, sm->dma.obuf, sm->dma.ofragsz));
+ }
+ sm->dma.ptt_cnt = 1;
+}
+
+extern __inline__ void dma_clear_transmit(struct sm_state *sm)
+{
+ sm->dma.ptt_cnt = 0;
+ memset(sm->dma.obuf, (sm->dma.o16bit) ? 0 : 0x80, sm->dma.ofragsz * NUM_FRAGMENTS);
+}
+
+/* --------------------------------------------------------------------- */
+
+extern __inline__ void dma_receive(struct sm_state *sm, unsigned int curfrag)
+{
+ void *p;
+
+ while (sm->dma.ifragptr != curfrag) {
+ if (sm->dma.ifragptr)
+ p = (unsigned char *)sm->dma.ibuf +
+ sm->dma.ifragsz * sm->dma.ifragptr;
+ else {
+ p = (unsigned char *)sm->dma.ibuf + NUM_FRAGMENTS * sm->dma.ifragsz;
+ memcpy(p, sm->dma.ibuf, sm->dma.ifragsz);
+ }
+ if (sm->dma.o16bit) {
+ time_exec(sm->debug_vals.demod_cyc,
+ sm->mode_rx->demodulator_s16(sm, p, sm->dma.ifragsz/2));
+ } else {
+ time_exec(sm->debug_vals.demod_cyc,
+ sm->mode_rx->demodulator_u8(sm, p, sm->dma.ifragsz));
+ }
+ sm->dma.ifragptr = (sm->dma.ifragptr + 1) % NUM_FRAGMENTS;
+ }
+}
+
+extern __inline__ void dma_init_receive(struct sm_state *sm)
+{
+ sm->dma.ifragptr = 0;
+}
+
+/* --------------------------------------------------------------------- */
+#endif /* _SMDMA_H */
+
+
+
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 2aae7a2db..7118164b6 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -56,7 +56,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( ATI, ATI_68800, "68800AX"),
DEVICE( ATI, ATI_215CT222, "215CT222"),
DEVICE( ATI, ATI_210888CX, "210888CX"),
+ DEVICE( ATI, ATI_215GT, "Mach64 GT (Rage II)"),
DEVICE( ATI, ATI_210888GX, "210888GX"),
+ DEVICE( ATI, ATI_264VT, "Mach64 VT"),
DEVICE( VLSI, VLSI_82C592, "82C592-FC1"),
DEVICE( VLSI, VLSI_82C593, "82C593-FC1"),
DEVICE( VLSI, VLSI_82C594, "82C594-AFC2"),
@@ -76,6 +78,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( DEC, DEC_TULIP_FAST, "DC21140"),
DEVICE( DEC, DEC_FDDI, "DEFPA"),
DEVICE( DEC, DEC_TULIP_PLUS, "DC21041"),
+ DEVICE( DEC, DEC_21142, "DC21142"),
DEVICE( DEC, DEC_21052, "DC21052"),
DEVICE( DEC, DEC_21152, "DC21152"),
DEVICE( CIRRUS, CIRRUS_7548, "GD 7548"),
@@ -83,10 +86,14 @@ struct pci_dev_info dev_info[] = {
DEVICE( CIRRUS, CIRRUS_5434_4, "GD 5434"),
DEVICE( CIRRUS, CIRRUS_5434_8, "GD 5434"),
DEVICE( CIRRUS, CIRRUS_5436, "GD 5436"),
+ DEVICE( CIRRUS, CIRRUS_5446, "GD 5446"),
+ DEVICE( CIRRUS, CIRRUS_5464, "GD 5464"),
DEVICE( CIRRUS, CIRRUS_6729, "CL 6729"),
DEVICE( CIRRUS, CIRRUS_7542, "CL 7542"),
DEVICE( CIRRUS, CIRRUS_7543, "CL 7543"),
+ DEVICE( CIRRUS, CIRRUS_7541, "CL 7541"),
DEVICE( IBM, IBM_82G2675, "82G2675"),
+ DEVICE( IBM, IBM_82351, "82351"),
DEVICE( WD, WD_7197, "WD 7197"),
DEVICE( AMD, AMD_LANCE, "79C970"),
DEVICE( AMD, AMD_SCSI, "53C974"),
@@ -101,6 +108,7 @@ struct pci_dev_info dev_info[] = {
DEVICE( CT, CT_65545, "65545"),
DEVICE( CT, CT_65548, "65548"),
DEVICE( CT, CT_65550, "65550"),
+ DEVICE( CT, CT_65554, "65554"),
DEVICE( MIRO, MIRO_36050, "ZR36050"),
DEVICE( FD, FD_36C70, "TMC-18C30"),
DEVICE( SI, SI_6201, "6201"),
@@ -112,7 +120,10 @@ struct pci_dev_info dev_info[] = {
DEVICE( SI, SI_601, "85C601"),
DEVICE( SI, SI_5511, "85C5511"),
DEVICE( SI, SI_5513, "85C5513"),
+ DEVICE( SI, SI_5571, "5571"),
+ DEVICE( SI, SI_7001, "7001"),
DEVICE( HP, HP_J2585A, "J2585A"),
+ DEVICE( HP, HP_J2585B, "J2585B"),
DEVICE( PCTECH, PCTECH_RZ1000, "RZ1000 (buggy)"),
DEVICE( PCTECH, PCTECH_RZ1001, "RZ1001 (buggy?)"),
DEVICE( DPT, DPT, "SmartCache/Raid"),
@@ -128,6 +139,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( BUSLOGIC, BUSLOGIC_FLASHPOINT, "FlashPoint"),
DEVICE( OAK, OAK_OTI107, "OTI107"),
DEVICE( WINBOND2, WINBOND2_89C940,"NE2000-PCI"),
+ DEVICE( MOTOROLA, MOTOROLA_MPC105,"MPC105 Eagle"),
+ DEVICE( MOTOROLA, MOTOROLA_MPC106,"MPC106 Grackle"),
+ DEVICE( MOTOROLA, MOTOROLA_RAVEN, "Raven"),
DEVICE( PROMISE, PROMISE_5300, "DC5030"),
DEVICE( N9, N9_I128, "Imagine 128"),
DEVICE( N9, N9_I128_2, "Imagine 128v2"),
@@ -155,11 +169,13 @@ struct pci_dev_info dev_info[] = {
DEVICE( ACC, ACC_2056, "2056"),
DEVICE( WINBOND, WINBOND_83769, "W83769F"),
DEVICE( WINBOND, WINBOND_82C105, "SL82C105"),
+ DEVICE( WINBOND, WINBOND_83C553, "W83C553"),
DEVICE( 3COM, 3COM_3C590, "3C590 10bT"),
DEVICE( 3COM, 3COM_3C595TX, "3C595 100bTX"),
DEVICE( 3COM, 3COM_3C595T4, "3C595 100bT4"),
DEVICE( 3COM, 3COM_3C595MII, "3C595 100b-MII"),
DEVICE( 3COM, 3COM_3C900TPO, "3C900 10bTPO"),
+ DEVICE( 3COM, 3COM_3C900COMBO,"3C900 10b Combo"),
DEVICE( 3COM, 3COM_3C905TX, "3C905 100bTX"),
DEVICE( AL, AL_M1445, "M1445"),
DEVICE( AL, AL_M1449, "M1449"),
@@ -171,18 +187,24 @@ struct pci_dev_info dev_info[] = {
DEVICE( AL, AL_M4803, "M4803"),
DEVICE( NEOMAGIC, NEOMAGIC_MAGICGRAPH_NM2070, "Magicgraph NM2070"),
DEVICE( ASP, ASP_ABP940, "ABP940"),
+ DEVICE( ASP, ASP_ABP940U, "ABP940U"),
DEVICE( CERN, CERN_SPSB_PMC, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( CERN, CERN_SPSB_PCI, "STAR/RD24 SCI-PCI (PMC)"),
DEVICE( IMS, IMS_8849, "8849"),
DEVICE( TEKRAM2, TEKRAM2_690c, "DC690c"),
+ DEVICE( TUNDRA, TUNDRA_CA91C042,"CA91C042 Universe"),
DEVICE( AMCC, AMCC_MYRINET, "Myrinet PCI (M2-PCI-32)"),
+ DEVICE( AMCC, AMCC_S5933, "S5933"),
DEVICE( INTERG, INTERG_1680, "IGA-1680"),
DEVICE( INTERG, INTERG_1682, "IGA-1682"),
DEVICE( REALTEK, REALTEK_8029, "8029"),
DEVICE( INIT, INIT_320P, "320 P"),
DEVICE( VIA, VIA_82C505, "VT 82C505"),
DEVICE( VIA, VIA_82C561, "VT 82C561"),
+ DEVICE( VIA, VIA_82C586_1, "VT 82C586 Apollo VP-1"),
DEVICE( VIA, VIA_82C576, "VT 82C576 3V"),
+ DEVICE( VIA, VIA_82C585, "VT 82C585VP Apollo VP-1"),
+ DEVICE( VIA, VIA_82C586_0, "VT 82C586 Apollo VP-1"),
DEVICE( VIA, VIA_82C416, "VT 82C416MV"),
DEVICE( VORTEX, VORTEX_GDT60x0, "GDT 60x0"),
DEVICE( VORTEX, VORTEX_GDT6000B,"GDT 6000b"),
@@ -200,19 +222,22 @@ struct pci_dev_info dev_info[] = {
DEVICE( VORTEX, VORTEX_GDT6555, "GDT 6555"),
DEVICE( EF, EF_ATM_FPGA, "155P-MF1 (FPGA)"),
DEVICE( EF, EF_ATM_ASIC, "155P-MF1 (ASIC)"),
- DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
DEVICE( FORE, FORE_PCA200PC, "PCA-200PC"),
DEVICE( FORE, FORE_PCA200E, "PCA-200E"),
+ DEVICE( IMAGINGTECH, IMAGINGTECH_ICPCI, "MVC IC-PCI"),
DEVICE( PLX, PLX_9060, "PCI9060 i960 bridge"),
DEVICE( ALLIANCE, ALLIANCE_PROMOTIO, "Promotion-6410"),
DEVICE( ALLIANCE, ALLIANCE_PROVIDEO, "Provideo"),
DEVICE( VMIC, VMIC_VME, "VMIVME-7587"),
DEVICE( DIGI, DIGI_RIGHTSWITCH, "RightSwitch SE-6"),
DEVICE( MUTECH, MUTECH_MV1000, "MV-1000"),
+ DEVICE( TOSHIBA, TOSHIBA_601, "Laptop"),
DEVICE( ZEITNET, ZEITNET_1221, "1221"),
DEVICE( ZEITNET, ZEITNET_1225, "1225"),
+ DEVICE( OMEGA, OMEGA_PCMCIA, "PCMCIA"),
DEVICE( SPECIALIX, SPECIALIX_XIO, "XIO/SIO host"),
DEVICE( SPECIALIX, SPECIALIX_RIO, "RIO host"),
+ DEVICE( ZORAN, ZORAN_36120, "ZR36120"),
DEVICE( COMPEX, COMPEX_RL2000, "ReadyLink 2000"),
DEVICE( RP, RP8OCTA, "RocketPort 8 Oct"),
DEVICE( RP, RP8INTF, "RocketPort 8 Intf"),
@@ -222,6 +247,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( CYCLADES, CYCLOM_Y_Hi, "Cyclom-Y above 1Mbyte"),
DEVICE( CYCLADES, CYCLOM_Z_Lo, "Cyclom-Z below 1Mbyte"),
DEVICE( CYCLADES, CYCLOM_Z_Hi, "Cyclom-Z above 1Mbyte"),
+ DEVICE( 3DFX, 3DFX_VOODOO, "Voodoo"),
+ DEVICE( SIGMADES, SIGMADES_6425, "REALmagic64/GX"),
DEVICE( OPTIBASE, OPTIBASE_FORGE, "MPEG Forge"),
DEVICE( OPTIBASE, OPTIBASE_FUSION,"MPEG Fusion"),
DEVICE( OPTIBASE, OPTIBASE_VPLEX, "VideoPlex"),
@@ -230,6 +257,9 @@ struct pci_dev_info dev_info[] = {
DEVICE( SYMPHONY, SYMPHONY_101, "82C101"),
DEVICE( TEKRAM, TEKRAM_DC290, "DC-290"),
DEVICE( 3DLABS, 3DLABS_300SX, "GLINT 300SX"),
+ DEVICE( 3DLABS, 3DLABS_DELTA, "GLINT Delta"),
+ DEVICE( 3DLABS, 3DLABS_PERMEDIA,"PERMEDIA"),
+ DEVICE( AVANCE, AVANCE_ALG2064, "ALG2064i"),
DEVICE( AVANCE, AVANCE_2302, "ALG-2302"),
DEVICE( S3, S3_ViRGE, "ViRGE"),
DEVICE( S3, S3_TRIO, "Trio32/Trio64"),
@@ -248,6 +278,8 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82378, "82378IB"),
DEVICE( INTEL, INTEL_82430, "82430ZX Aries"),
BRIDGE( INTEL, INTEL_82434, "82434LX Mercury/Neptune", 0x00),
+ DEVICE( INTEL, INTEL_82092AA_0,"82092AA PCMCIA bridge"),
+ DEVICE( INTEL, INTEL_82092AA_1,"82092AA EIDE"),
DEVICE( INTEL, INTEL_7116, "SAA7116"),
DEVICE( INTEL, INTEL_82596, "82596"),
DEVICE( INTEL, INTEL_82865, "82865"),
@@ -255,15 +287,19 @@ struct pci_dev_info dev_info[] = {
DEVICE( INTEL, INTEL_82437, "82437"),
DEVICE( INTEL, INTEL_82371_0, "82371 Triton PIIX"),
DEVICE( INTEL, INTEL_82371_1, "82371 Triton PIIX"),
- DEVICE( INTEL, INTEL_430MX_0, "Triton I"),
- DEVICE( INTEL, INTEL_430MX_1, "Triton I"),
+ DEVICE( INTEL, INTEL_82371MX, "430MX - 82371MX MPIIX"),
+ DEVICE( INTEL, INTEL_82437MX, "430MX - 82437MX MTSC"),
DEVICE( INTEL, INTEL_82441, "82441FX Natoma"),
DEVICE( INTEL, INTEL_82439, "82439HX Triton II"),
DEVICE( INTEL, INTEL_82371SB_0,"82371SB Natoma/Triton II PIIX3"),
DEVICE( INTEL, INTEL_82371SB_1,"82371SB Natoma/Triton II PIIX3"),
DEVICE( INTEL, INTEL_82371SB_2,"82371SB Natoma/Triton II PIIX3"),
DEVICE( INTEL, INTEL_82437VX, "82437VX Triton II"),
+ DEVICE( INTEL, INTEL_82439TX, "82439TX"),
+ DEVICE( INTEL, INTEL_82371AB_0,"82371AB PIIX4"),
DEVICE( INTEL, INTEL_82371AB, "82371AB 430TX PIIX4"),
+ DEVICE( INTEL, INTEL_82371AB_2,"82371AB PIIX4"),
+ DEVICE( INTEL, INTEL_82371AB_3,"82371AB PIIX4 Power Management"),
DEVICE( INTEL, INTEL_P6, "Orion P6"),
DEVICE( INTEL, INTEL_P6_2, "82450GX Orion P6"),
DEVICE( KTI, KTI_ET32P2, "ET32P2"),
@@ -508,6 +544,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_BUSLOGIC: return "BusLogic";
case PCI_VENDOR_ID_OAK: return "OAK";
case PCI_VENDOR_ID_WINBOND2: return "Winbond";
+ case PCI_VENDOR_ID_MOTOROLA: return "Motorola";
case PCI_VENDOR_ID_PROMISE: return "Promise Technology";
case PCI_VENDOR_ID_N9: return "Number Nine";
case PCI_VENDOR_ID_UMC: return "UMC";
@@ -531,6 +568,7 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_CERN: return "CERN";
case PCI_VENDOR_ID_IMS: return "IMS";
case PCI_VENDOR_ID_TEKRAM2: return "Tekram";
+ case PCI_VENDOR_ID_TUNDRA: return "Tundra";
case PCI_VENDOR_ID_AMCC: return "AMCC";
case PCI_VENDOR_ID_INTERG: return "Intergraphics";
case PCI_VENDOR_ID_REALTEK: return "Realtek";
@@ -547,10 +585,14 @@ const char *pci_strvendor(unsigned int vendor)
case PCI_VENDOR_ID_MUTECH: return "Mutech";
case PCI_VENDOR_ID_TOSHIBA: return "Toshiba";
case PCI_VENDOR_ID_ZEITNET: return "ZeitNet";
+ case PCI_VENDOR_ID_OMEGA: return "Omega Micro";
case PCI_VENDOR_ID_SPECIALIX: return "Specialix";
+ case PCI_VENDOR_ID_ZORAN: return "Zoran";
case PCI_VENDOR_ID_COMPEX: return "Compex";
case PCI_VENDOR_ID_RP: return "Comtrol";
case PCI_VENDOR_ID_CYCLADES: return "Cyclades";
+ case PCI_VENDOR_ID_3DFX: return "3Dfx";
+ case PCI_VENDOR_ID_SIGMADES: return "Sigma Designs";
case PCI_VENDOR_ID_OPTIBASE: return "Optibase";
case PCI_VENDOR_ID_SYMPHONY: return "Symphony";
case PCI_VENDOR_ID_TEKRAM: return "Tekram";
diff --git a/drivers/sbus/char/bwtwo.c b/drivers/sbus/char/bwtwo.c
index be68d09c9..ae81e1260 100644
--- a/drivers/sbus/char/bwtwo.c
+++ b/drivers/sbus/char/bwtwo.c
@@ -1,4 +1,4 @@
-/* $Id: bwtwo.c,v 1.13 1997/04/14 17:04:55 jj Exp $
+/* $Id: bwtwo.c,v 1.16 1997/06/04 08:27:26 davem Exp $
* bwtwo.c: bwtwo console driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -15,9 +15,11 @@
#include <asm/fbio.h>
#include <asm/pgtable.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
+
#include "fb.h"
#include "cg_common.h"
@@ -91,7 +93,7 @@ bwtwo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
vma->vm_page_prot, fb->space);
if (r) return -EAGAIN;
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/cgfourteen.c b/drivers/sbus/char/cgfourteen.c
index d42a4343c..2cb4c21c9 100644
--- a/drivers/sbus/char/cgfourteen.c
+++ b/drivers/sbus/char/cgfourteen.c
@@ -1,4 +1,4 @@
-/* $Id: cgfourteen.c,v 1.19 1997/04/14 17:04:57 jj Exp $
+/* $Id: cgfourteen.c,v 1.22 1997/06/04 08:27:27 davem Exp $
* cgfourteen.c: Sun SparcStation console support.
*
* Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -23,9 +23,10 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#define CG14_MCR_INTENABLE_SHIFT 7
@@ -272,7 +273,7 @@ cg14_mmap (struct inode *inode, struct file *file,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/cgsix.c b/drivers/sbus/char/cgsix.c
index 5f91c1308..e53fcf09e 100644
--- a/drivers/sbus/char/cgsix.c
+++ b/drivers/sbus/char/cgsix.c
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.27 1997/04/14 17:04:55 jj Exp $
+/* $Id: cgsix.c,v 1.30 1997/06/04 08:27:28 davem Exp $
* cgsix.c: cgsix frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -15,9 +15,10 @@
#include <asm/fbio.h>
#include <asm/pgtable.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#include "cg_common.h"
@@ -296,7 +297,7 @@ cg6_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/cgthree.c b/drivers/sbus/char/cgthree.c
index ac1265c61..0e1446c0e 100644
--- a/drivers/sbus/char/cgthree.c
+++ b/drivers/sbus/char/cgthree.c
@@ -1,4 +1,4 @@
-/* $Id: cgthree.c,v 1.18 1997/04/16 17:51:09 jj Exp $
+/* $Id: cgthree.c,v 1.21 1997/06/04 08:27:29 davem Exp $
* cgtree.c: cg3 frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -18,9 +18,10 @@
#include <asm/fbio.h>
#include <asm/pgtable.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#include "cg_common.h"
@@ -131,7 +132,7 @@ cg3_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/creator.c b/drivers/sbus/char/creator.c
index 9bf72a3b9..4ff2caf31 100644
--- a/drivers/sbus/char/creator.c
+++ b/drivers/sbus/char/creator.c
@@ -15,9 +15,10 @@
#include <asm/pgtable.h>
#include <asm/uaccess.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
__initfunc(void creator_setup (fbinfo_t *fb, int slot, int con_node, unsigned long creator, int creator_io))
diff --git a/drivers/sbus/char/leo.c b/drivers/sbus/char/leo.c
index b3ec23867..61e646e9f 100644
--- a/drivers/sbus/char/leo.c
+++ b/drivers/sbus/char/leo.c
@@ -1,4 +1,4 @@
-/* $Id: leo.c,v 1.15 1997/04/14 17:04:54 jj Exp $
+/* $Id: leo.c,v 1.18 1997/06/04 08:27:30 davem Exp $
* leo.c: SUNW,leo 24/8bit frame buffer driver
*
* Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -17,9 +17,10 @@
#include <asm/delay.h>
#include <asm/uaccess.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#include "cg_common.h"
@@ -221,7 +222,7 @@ leo_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/suncons.c b/drivers/sbus/char/suncons.c
index d1a2dfd45..1d3815dd3 100644
--- a/drivers/sbus/char/suncons.c
+++ b/drivers/sbus/char/suncons.c
@@ -1,4 +1,4 @@
-/* $Id: suncons.c,v 1.62 1997/05/02 22:32:32 davem Exp $
+/* $Id: suncons.c,v 1.63 1997/05/31 18:33:25 mj Exp $
*
* suncons.c: Sun SparcStation console support.
*
@@ -76,11 +76,11 @@
#include <asm/io.h>
#include <asm/smp.h>
-#include "../../char/kbd_kern.h"
-#include "../../char/vt_kern.h"
-#include "../../char/consolemap.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
diff --git a/drivers/sbus/char/sunfb.c b/drivers/sbus/char/sunfb.c
index e803344bd..68856c9ee 100644
--- a/drivers/sbus/char/sunfb.c
+++ b/drivers/sbus/char/sunfb.c
@@ -1,4 +1,4 @@
-/* $Id: sunfb.c,v 1.22 1997/04/03 08:47:56 davem Exp $
+/* $Id: sunfb.c,v 1.23 1997/05/31 18:33:26 mj Exp $
* sunfb.c: Sun generic frame buffer support.
*
* Copyright (C) 1995, 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -33,11 +33,11 @@
#include <asm/fbio.h>
#include <asm/io.h>
-#include "../../char/kbd_kern.h"
-#include "../../char/vt_kern.h"
-#include "../../char/consolemap.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+#include <linux/kbd_kern.h>
+#include <linux/vt_kern.h>
+#include <linux/consolemap.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
diff --git a/drivers/sbus/char/sunkbd.c b/drivers/sbus/char/sunkbd.c
index 8e398f345..1ddaaecd4 100644
--- a/drivers/sbus/char/sunkbd.c
+++ b/drivers/sbus/char/sunkbd.c
@@ -25,9 +25,9 @@
#include <asm/oplib.h>
#include <asm/uaccess.h>
-#include "../../char/kbd_kern.h"
-#include "../../char/diacr.h"
-#include "../../char/vt_kern.h"
+#include <linux/kbd_kern.h>
+#include <linux/kbd_diacr.h>
+#include <linux/vt_kern.h>
#define SIZE(x) (sizeof(x)/sizeof((x)[0]))
diff --git a/drivers/sbus/char/tcx.c b/drivers/sbus/char/tcx.c
index 2ecabda62..db66383ac 100644
--- a/drivers/sbus/char/tcx.c
+++ b/drivers/sbus/char/tcx.c
@@ -1,4 +1,4 @@
-/* $Id: tcx.c,v 1.12 1997/04/14 17:04:51 jj Exp $
+/* $Id: tcx.c,v 1.15 1997/06/04 08:27:32 davem Exp $
* tcx.c: SUNW,tcx 24/8bit frame buffer driver
*
* Copyright (C) 1996 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -16,9 +16,10 @@
#include <asm/fbio.h>
#include <asm/pgtable.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#include "cg_common.h"
@@ -171,7 +172,7 @@ tcx_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/vfc_dev.c b/drivers/sbus/char/vfc_dev.c
index 20e04258b..00cdfe35c 100644
--- a/drivers/sbus/char/vfc_dev.c
+++ b/drivers/sbus/char/vfc_dev.c
@@ -581,7 +581,7 @@ static int vfc_mmap(struct inode *inode, struct file *file,
vma->vm_page_prot, dev->which_io);
if(ret) return -EAGAIN;
vma->vm_inode=inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
diff --git a/drivers/sbus/char/weitek.c b/drivers/sbus/char/weitek.c
index 0fa0cb5fc..d2ac4d135 100644
--- a/drivers/sbus/char/weitek.c
+++ b/drivers/sbus/char/weitek.c
@@ -1,4 +1,4 @@
-/* $Id: weitek.c,v 1.9 1997/04/14 17:04:57 jj Exp $
+/* $Id: weitek.c,v 1.12 1997/06/04 08:27:34 davem Exp $
* weitek.c: Tadpole P9100/P9000 console driver
*
* Copyright (C) 1996 David Redman (djhr@tadpole.co.uk)
@@ -15,9 +15,10 @@
#include <asm/fbio.h>
#include <asm/pgtable.h>
-#include "../../char/vt_kern.h"
-#include "../../char/selection.h"
-#include "../../char/console_struct.h"
+/* These must be included after asm/fbio.h */
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/console_struct.h>
#include "fb.h"
#include "cg_common.h"
@@ -82,7 +83,7 @@ weitek_mmap(struct inode *inode, struct file *file, struct vm_area_struct *vma,
page += map_size;
}
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
return 0;
}
#endif
diff --git a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
index 2e4b1aa3e..6edd01320 100644
--- a/drivers/scsi/amiga7xx.c
+++ b/drivers/scsi/amiga7xx.c
@@ -50,20 +50,20 @@ int amiga7xx_detect(Scsi_Host_Template *tpnt)
#ifdef CONFIG_WARPENGINE_SCSI
if ((key = zorro_find(MANUF_MACROSYSTEMS, PROD_WARP_ENGINE, 0, 0)))
{
- cd = zorro_get_board(key);
- address = (unsigned long)kernel_map((unsigned long)cd->cd_BoardAddr,
+ cd = zorro_get_board(key);
+ address = (unsigned long)kernel_map((unsigned long)cd->cd_BoardAddr,
cd->cd_BoardSize, KERNELMAP_NOCACHE_SER, NULL);
- options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
+ options = OPTION_MEMORY_MAPPED|OPTION_DEBUG_TEST1|OPTION_INTFLY|OPTION_SYNCHRONOUS|OPTION_ALWAYS_SYNCHRONOUS|OPTION_DISCONNECT;
clock = 50000000; /* 50MHz SCSI Clock */
- ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address + 0x40000),
- 0, IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC, DMA_NONE,
+ ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address + 0x40000),
+ 0, IRQ_AMIGA_PORTS, DMA_NONE,
options, clock);
- zorro_config_board(key, 0);
- num++;
+ zorro_config_board(key, 0);
+ num++;
}
#endif
@@ -94,7 +94,7 @@ int amiga7xx_detect(Scsi_Host_Template *tpnt)
clock = 50000000; /* 50MHz SCSI Clock */
ncr53c7xx_init(tpnt, 0, 710, (u32)(unsigned char *)(address+0x800000),
- 0, IRQ_AMIGA_PORTS & ~IRQ_MACHSPEC, DMA_NONE,
+ 0, IRQ_AMIGA_PORTS, DMA_NONE,
options, clock);
zorro_config_board(key, 0);
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c
index 5bffb2762..1e398a152 100644
--- a/drivers/scsi/g_NCR5380.c
+++ b/drivers/scsi/g_NCR5380.c
@@ -619,7 +619,10 @@ int generic_NCR5380_proc_info(char* buffer, char** start, off_t offset, int leng
struct Scsi_Host *scsi_ptr;
Scsi_Cmnd *ptr;
struct NCR5380_hostdata *hostdata;
-
+#ifdef NCR5380_STATS
+ Scsi_Device *dev;
+ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
+#endif
cli();
for (scsi_ptr = first_instance; scsi_ptr; scsi_ptr=scsi_ptr->next)
diff --git a/drivers/scsi/script_asm.pl b/drivers/scsi/script_asm.pl
index 2599a966e..d99fcc950 100644
--- a/drivers/scsi/script_asm.pl
+++ b/drivers/scsi/script_asm.pl
@@ -1,4 +1,4 @@
-#! /usr/local/bin/perl
+#!/usr/bin/perl -s
# NCR 53c810 script assembler
# Sponsored by
@@ -10,6 +10,9 @@
# drew@Colorado.EDU
# +1 (303) 786-7975
#
+# Support for 53c710 (via -ncr7x0_family switch) added by Richard
+# Hirst <richard@sleepie.demon.co.uk> - 15th March 1997
+#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
@@ -74,7 +77,15 @@ $prefix = ''; # define all arrays having this prefix so we
# and = 0x04_00_00_00
# add = 0x06_00_00_00
-%operators_810 = (
+if ($ncr7x0_family) {
+ %operators = (
+ '|', 0x02_00_00_00, 'OR', 0x02_00_00_00,
+ '&', 0x04_00_00_00, 'AND', 0x04_00_00_00,
+ '+', 0x06_00_00_00
+ );
+}
+else {
+ %operators = (
'SHL', 0x01_00_00_00,
'|', 0x02_00_00_00, 'OR', 0x02_00_00_00,
'XOR', 0x03_00_00_00,
@@ -83,11 +94,33 @@ $prefix = ''; # define all arrays having this prefix so we
# Note : low bit of the operator bit should be set for add with
# carry.
'+', 0x06_00_00_00
-);
-
+ );
+}
# Table of register addresses
-%registers_810 = (
+
+if ($ncr7x0_family) {
+ %registers = (
+ 'SCNTL0', 0, 'SCNTL1', 1, 'SDID', 2, 'SIEN', 3,
+ 'SCID', 4, 'SXFER', 5, 'SODL', 6, 'SOCL', 7,
+ 'SFBR', 8, 'SIDL', 9, 'SBDL', 10, 'SBCL', 11,
+ 'DSTAT', 12, 'SSTAT0', 13, 'SSTAT1', 14, 'SSTAT2', 15,
+ 'DSA0', 16, 'DSA1', 17, 'DSA2', 18, 'DSA3', 19,
+ 'CTEST0', 20, 'CTEST1', 21, 'CTEST2', 22, 'CTEST3', 23,
+ 'CTEST4', 24, 'CTEST5', 25, 'CTEST6', 26, 'CTEST7', 27,
+ 'TEMP0', 28, 'TEMP1', 29, 'TEMP2', 30, 'TEMP3', 31,
+ 'DFIFO', 32, 'ISTAT', 33, 'CTEST8', 34, 'LCRC', 35,
+ 'DBC0', 36, 'DBC1', 37, 'DBC2', 38, 'DCMD', 39,
+ 'DNAD0', 40, 'DNAD1', 41, 'DNAD2', 42, 'DNAD3', 43,
+ 'DSP0', 44, 'DSP1', 45, 'DSP2', 46, 'DSP3', 47,
+ 'DSPS0', 48, 'DSPS1', 49, 'DSPS2', 50, 'DSPS3', 51,
+ 'SCRATCH0', 52, 'SCRATCH1', 53, 'SCRATCH2', 54, 'SCRATCH3', 55,
+ 'DMODE', 56, 'DIEN', 57, 'DWT', 58, 'DCNTL', 59,
+ 'ADDER0', 60, 'ADDER1', 61, 'ADDER2', 62, 'ADDER3', 63,
+ );
+}
+else {
+ %registers = (
'SCNTL0', 0, 'SCNTL1', 1, 'SCNTL2', 2, 'SCNTL3', 3,
'SCID', 4, 'SXFER', 5, 'SDID', 6, 'GPREG', 7,
'SFBR', 8, 'SOCL', 9, 'SSID', 10, 'SBCL', 11,
@@ -113,7 +146,8 @@ $prefix = ''; # define all arrays having this prefix so we
'SODL', 84,
'SBDL', 88,
'SCRATCHB0', 92, 'SCRATCHB1', 93, 'SCRATCHB2', 94, 'SCRATCHB3', 95
-);
+ );
+}
# Parsing regular expressions
$identifier = '[A-Za-z_][A-Za-z_0-9]*';
@@ -131,17 +165,22 @@ print STDERR "value regex = $value\n" if ($debug);
$phase = join ('|', keys %scsi_phases);
print STDERR "phase regex = $phase\n" if ($debug);
-$register = join ('|', keys %registers_810);
+$register = join ('|', keys %registers);
-# yucky - since %operators_810 includes meta-characters which must
+# yucky - since %operators includes meta-characters which must
# be escaped, I can't use the join() trick I used for the register
# regex
-$operator = '\||OR|AND|XOR|\&|\+';
+if ($ncr7x0_family) {
+ $operator = '\||OR|AND|\&|\+';
+}
+else {
+ $operator = '\||OR|AND|XOR|\&|\+';
+}
# Global variables
-%symbol_values = (%registers_810) ; # Traditional symbol table
+%symbol_values = (%registers) ; # Traditional symbol table
%symbol_references = () ; # Table of symbol references, where
# the index is the symbol name,
@@ -421,6 +460,7 @@ print STDERR "defined external $1 to $external\n" if ($debug_external);
if ($1 =~ /^($identifier)\s*$/) {
push (@entry, $1);
} else {
+ die
"$0 : syntax error in line $lineno : $_
expected ENTRY <identifier>
";
@@ -558,13 +598,13 @@ print STDERR "data8 source\n" if ($debug);
# instruction.
if (($src_reg eq undef) || ($src_reg eq $dst_reg)) {
$code[$address] |= 0x38_00_00_00 |
- ($registers_810{$dst_reg} << 16);
+ ($registers{$dst_reg} << 16);
} elsif ($dst_reg =~ /SFBR/i) {
$code[$address] |= 0x30_00_00_00 |
- ($registers_810{$src_reg} << 16);
+ ($registers{$src_reg} << 16);
} elsif ($src_reg =~ /SFBR/i) {
$code[$address] |= 0x28_00_00_00 |
- ($registers_810{$dst_reg} << 16);
+ ($registers{$dst_reg} << 16);
} else {
die
"$0 : Illegal combination of registers in line $lineno : $_
@@ -573,10 +613,10 @@ print STDERR "data8 source\n" if ($debug);
";
}
- $code[$address] |= $operators_810{$op};
+ $code[$address] |= $operators{$op};
&parse_value ($data8, 0, 1, 1);
- $code[$address] |= $operators_810{$op};
+ $code[$address] |= $operators{$op};
$code[$address + 1] = 0x00_00_00_00;# Reserved
$address += 2;
} else {
diff --git a/drivers/sound/dmabuf.c b/drivers/sound/dmabuf.c
index 38b7af597..54523d88f 100644
--- a/drivers/sound/dmabuf.c
+++ b/drivers/sound/dmabuf.c
@@ -802,6 +802,8 @@ DMAbuf_space_in_queue (int dev)
*/
max = dmap->max_fragments;
+ if (max > dmap->nbufs)
+ max = dmap->nbufs;
len = dmap->qlen;
if (audio_devs[dev]->d->local_qlen)
diff --git a/drivers/sound/soundcard.c b/drivers/sound/soundcard.c
index 088591b9d..957150f7b 100644
--- a/drivers/sound/soundcard.c
+++ b/drivers/sound/soundcard.c
@@ -327,7 +327,7 @@ sound_mmap (struct inode *inode, struct file *file, struct vm_area_struct *vma)
return -EAGAIN;
vma->vm_inode = inode;
- inode->i_count++;
+ atomic_inc(&inode->i_count);
dmap->mapping_flags |= DMA_MAP_MAPPED;