driver for Diamond HomeFree Wireless ISA/PCI released (fwd)

Pavel Machek (pavel@suse.cz)
Wed, 1 Dec 1999 00:10:28 +0100


Hi!

So DiamondMM homefree drivers are finally out (year sooner than
expected :-), under GPL and with no hooks included. Be sure to try
them out! (http://david.poda.cz/Homefree)
Pavel

PS: This patch relative to 2.3.29 allows you to run the cards without
need for HZ=1000. Hopefully ted merges it soon. (Aha, plus you need to
make tir2000.c actually use bigger flipbufs).

PPS: Why I'm ccing to linux-irda? Well, DiamondMM cards actually use
tir2000 chips (as you can guess from source name), and tir2000 are
irda chips in fact. So if you have tir2000 based irda chips, you are
also interested in this driver.

--- clean//drivers/char/tty_io.c Sat Oct 23 20:54:45 1999
+++ linux/drivers/char/tty_io.c Fri Nov 19 23:04:38 1999
@@ -54,6 +54,9 @@
*
* Added support for a Unix98-style ptmx device.
* -- C. Scott Ananian <cananian@alumni.princeton.edu>, 14-Jan-1998
+ *
+ * Added support for bigger flipbuf sizes
+ * -- Pavel Machek <pavel@ucw.cz>, June 99
*/

#include <linux/config.h>
@@ -115,7 +118,7 @@
*/
struct tty_struct * redirect = NULL;

-static void initialize_tty_struct(struct tty_struct *tty);
+static int initialize_tty_struct(struct tty_struct *tty, int);

static ssize_t tty_read(struct file *, char *, size_t, loff_t *);
static ssize_t tty_write(struct file *, const char *, size_t, loff_t *);
@@ -798,10 +801,15 @@
tp = o_tp = NULL;
ltp = o_ltp = NULL;

- tty = (struct tty_struct*) get_zeroed_page(GFP_KERNEL);
+ tty = (struct tty_struct*) kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
+ memset(tty, 0, sizeof(struct tty_struct));
if(!tty)
goto fail_no_mem;
- initialize_tty_struct(tty);
+
+ if (initialize_tty_struct(tty, driver->flip_size)) {
+ kfree(tty);
+ goto fail_no_mem;
+ }
tty->device = device;
tty->driver = *driver;

@@ -824,10 +832,15 @@
}

if (driver->type == TTY_DRIVER_TYPE_PTY) {
- o_tty = (struct tty_struct *) get_zeroed_page(GFP_KERNEL);
+ o_tty = (struct tty_struct *) kmalloc(sizeof(struct tty_struct), GFP_KERNEL);
+ memset(o_tty, 0, sizeof(struct tty_struct));
if (!o_tty)
goto free_mem_out;
- initialize_tty_struct(o_tty);
+ if (initialize_tty_struct(o_tty, 512)) {
+ kfree(o_tty);
+ o_tty = NULL;
+ goto free_mem_out;
+ }
o_tty->device = (kdev_t) MKDEV(driver->other->major,
driver->other->minor_start + idx);
o_tty->driver = *driver->other;
@@ -943,13 +956,16 @@
free_mem_out:
if (o_tp)
kfree_s(o_tp, sizeof(struct termios));
- if (o_tty)
- free_page((unsigned long) o_tty);
+ if (o_tty) {
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
+ }
if (ltp)
kfree_s(ltp, sizeof(struct termios));
if (tp)
kfree_s(tp, sizeof(struct termios));
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);

fail_no_mem:
retval = -ENOMEM;
@@ -980,7 +996,8 @@
}
o_tty->magic = 0;
(*o_tty->driver.refcount)--;
- free_page((unsigned long) o_tty);
+ kfree(o_tty->flip.char_buf);
+ kfree(o_tty);
}

tty->driver.table[idx] = NULL;
@@ -991,7 +1008,8 @@
}
tty->magic = 0;
(*tty->driver.refcount)--;
- free_page((unsigned long) tty);
+ kfree(tty->flip.char_buf);
+ kfree(tty);
}

/*
@@ -1862,8 +1880,8 @@
return;
}
if (tty->flip.buf_num) {
- cp = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- fp = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ cp = tty->flip.char_buf + tty->flip.flipbuf_size;
+ fp = tty->flip.flag_buf + tty->flip.flipbuf_size;
tty->flip.buf_num = 0;

save_flags(flags); cli();
@@ -1875,8 +1893,8 @@
tty->flip.buf_num = 1;

save_flags(flags); cli();
- tty->flip.char_buf_ptr = tty->flip.char_buf + TTY_FLIPBUF_SIZE;
- tty->flip.flag_buf_ptr = tty->flip.flag_buf + TTY_FLIPBUF_SIZE;
+ tty->flip.char_buf_ptr = tty->flip.char_buf + tty->flip.flipbuf_size;
+ tty->flip.flag_buf_ptr = tty->flip.flag_buf + tty->flip.flipbuf_size;
}
count = tty->flip.count;
tty->flip.count = 0;
@@ -1940,9 +1958,17 @@
/*
* This subroutine initializes a tty structure.
*/
-static void initialize_tty_struct(struct tty_struct *tty)
+static int initialize_tty_struct(struct tty_struct *tty, int flip_size)
{
memset(tty, 0, sizeof(struct tty_struct));
+
+ /* there was notice about buffer overrun in original code -- that's why I do +4 */
+ tty->flip.char_buf = kmalloc(flip_size*4 +4, GFP_KERNEL);
+ if (!tty->flip.char_buf)
+ return -ENOMEM;
+
+ tty->flip.flag_buf = tty->flip.char_buf + flip_size*2;
+ tty->flip.flipbuf_size = flip_size;
tty->magic = TTY_MAGIC;
tty->ldisc = ldiscs[N_TTY];
tty->pgrp = -1;
@@ -1957,6 +1983,7 @@
tty->tq_hangup.data = tty;
sema_init(&tty->atomic_read, 1);
INIT_LIST_HEAD(&tty->tty_files);
+ return 0;
}

/*
@@ -1976,6 +2003,9 @@

if (driver->flags & TTY_DRIVER_INSTALLED)
return 0;
+
+ if (!(driver->flags & TTY_DRIVER_SPECIAL_FLIPSIZE))
+ driver->flip_size = 512;

error = register_chrdev(driver->major, driver->name, &tty_fops);
if (error < 0)
--- clean//drivers/char/serial.c Fri Nov 26 21:13:56 1999
+++ linux/drivers/char/serial.c Thu Nov 25 21:56:52 1999
@@ -34,6 +34,8 @@
* 4/98: Added changes to support the ARM architecture proposed by
* Russell King
*
+ * 10/98: Added support for hispeed serials. Pavel Machek <pavel@ucw.cz>
+ *
* 5/99: Updated to include support for the XR16C850 and ST16C654
* uarts. Stuart MacDonald <stuartm@connecttech.com>
*
@@ -280,6 +282,7 @@
UART_STARTECH },
{ "XR16850", 128, UART_CLEAR_FIFO | UART_USE_FIFO |
UART_STARTECH },
+ { "hispeed", 16, UART_CLEAR_FIFO | UART_USE_FIFO},
{ 0, 0}
};

@@ -516,7 +519,7 @@
icount = &info->state->icount;
do {
ch = serial_inp(info, UART_RX);
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ if (tty->flip.count >= tty->flip.flipbuf_size)
goto ignore_char;
*tty->flip.char_buf_ptr = ch;
icount->rx++;
@@ -582,7 +585,7 @@
tty->flip.flag_buf_ptr++;
tty->flip.char_buf_ptr++;
*tty->flip.flag_buf_ptr = TTY_OVERRUN;
- if (tty->flip.count >= TTY_FLIPBUF_SIZE)
+ if (tty->flip.count >= tty->flip.flipbuf_size)
goto ignore_char;
}
}
@@ -1608,6 +1611,10 @@
(cflag & CRTSCTS) ? UART_EFR_CTS : 0);
}
serial_outp(info, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
+ if (info->state->type == PORT_HISPEED) /* Use alternate registers in bank 2 */
+ serial_outp(info, UART_LCR, 0xe0); /* select bank 2 */
+
+
serial_outp(info, UART_DLL, quot & 0xff); /* LS of divisor */
serial_outp(info, UART_DLM, quot >> 8); /* MS of divisor */
if (info->state->type == PORT_16750)
@@ -2143,6 +2150,7 @@
(info->state->port != 0) &&
(info->state->type != PORT_UNKNOWN))
info->state->irq = detect_uart_irq(info->state);
+ print_info(info->state);

retval = startup(info);
if (retval)
@@ -3523,6 +3531,15 @@
int register_serial(struct serial_struct *req);
void unregister_serial(int line);

+static int print_info(struct serial_state * state)
+{
+ printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n",
+ state->line + SERIAL_DEV_OFFSET,
+ (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
+ state->port, state->irq,
+ uart_config[state->type].name);
+}
+
#if (LINUX_VERSION_CODE > 0x20100)
EXPORT_SYMBOL(register_serial);
EXPORT_SYMBOL(unregister_serial);
@@ -4281,11 +4298,7 @@
&& (state->flags & ASYNC_AUTO_IRQ)
&& (state->port != 0))
state->irq = detect_uart_irq(state);
- printk(KERN_INFO "ttyS%02d%s at 0x%04x (irq = %d) is a %s\n",
- state->line + SERIAL_DEV_OFFSET,
- (state->flags & ASYNC_FOURPORT) ? " FourPort" : "",
- state->port, state->irq,
- uart_config[state->type].name);
+ print_info(state);
}
#ifdef ENABLE_SERIAL_PCI
probe_serial_pci();
--- clean//include/linux/tty.h Thu Oct 28 15:08:13 1999
+++ linux/include/linux/tty.h Thu Nov 25 21:54:28 1999
@@ -124,13 +124,14 @@
*/
#define __DISABLED_CHAR '\0'

+/* HACK for old drivers, don't include this constant in new code */
+#define TTY_FLIPBUF_SIZE 512
+
/*
* This is the flip buffer used for the tty driver. The buffer is
- * located in the tty structure, and is used as a high speed interface
- * between the tty driver and the tty line discipline.
+ * kmalloced, and is used as a high speed interface between tty driver
+ * and the line discipline.
*/
-#define TTY_FLIPBUF_SIZE 512
-
struct tty_flip_buffer {
struct tq_struct tqueue;
struct semaphore pty_sem;
@@ -138,9 +139,9 @@
unsigned char *flag_buf_ptr;
int count;
int buf_num;
- unsigned char char_buf[2*TTY_FLIPBUF_SIZE];
- char flag_buf[2*TTY_FLIPBUF_SIZE];
- unsigned char slop[4]; /* N.B. bug overwrites buffer by 1 */
+ int flipbuf_size;
+ unsigned char *char_buf;
+ char *flag_buf;
};
/*
* The pty uses char_buf and flag_buf as a contiguous buffer
--- clean//include/linux/tty_driver.h Sun Aug 16 22:34:51 1998
+++ linux/include/linux/tty_driver.h Thu Nov 25 21:54:28 1999
@@ -132,6 +132,7 @@
int *refcount; /* for loadable tty drivers */
struct proc_dir_entry *proc_entry; /* /proc fs entry */
struct tty_driver *other; /* only used for the PTY driver */
+ int flip_size; /* requested size of flip buffer */

/*
* Pointer to the tty data structures
@@ -197,10 +198,13 @@
* optimize for this case if this flag is set. (Note that there
* is also a promise, if the above case is true, not to signal
* overruns, either.)
+ *
+ * TTY_DRIVER_SPECIAL_FLIPSIZE --- we want non-512 bytes flip buffer
*/
#define TTY_DRIVER_INSTALLED 0x0001
#define TTY_DRIVER_RESET_TERMIOS 0x0002
#define TTY_DRIVER_REAL_RAW 0x0004
+#define TTY_DRIVER_SPECIAL_FLIPSIZE 0x0008

/* tty driver types */
#define TTY_DRIVER_TYPE_SYSTEM 0x0001
--- clean//include/linux/tty_flip.h Wed Sep 10 04:41:41 1997
+++ linux/include/linux/tty_flip.h Fri Nov 19 23:04:40 1999
@@ -10,7 +10,7 @@
_INLINE_ void tty_insert_flip_char(struct tty_struct *tty,
unsigned char ch, char flag)
{
- if (tty->flip.count < TTY_FLIPBUF_SIZE) {
+ if (tty->flip.count < tty->flip.flipbuf_size) {
tty->flip.count++;
*tty->flip.flag_buf_ptr++ = flag;
*tty->flip.char_buf_ptr++ = ch;

----- Forwarded message from David Trcka <trcka@poda.cz> -----

To: linux-kernel@vger.rutgers.edu
Subject: driver for Diamond HomeFree Wireless ISA/PCI released
X-Loop: majordomo@vger.rutgers.edu
X-Orcpt: rfc822;linux-kernel-outgoing-dig

Hi,

see http://david.poda.cz/Homefree for more information.

Any questions, comments or suggestions please mail to pavel@ucw.cz and
please cc: to trcka@poda.cz.

David

__________________________________________
David Trcka, network administrator
PODA s.r.o., Internet Service Provider
Ostrava, 28. rijna 150, The Czech Republic
Voice/Fax: +420 69 6612600

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/

----- End forwarded message -----

-- 
I'm really pavel@ucw.cz. Look at http://195.113.31.123/~pavel.  Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/