1
0
mirror of https://git.openwrt.org/openwrt/openwrt.git synced 2024-11-18 14:47:46 +01:00

add nozomi driver

SVN-Revision: 5431
This commit is contained in:
Felix Fietkau 2006-11-03 23:55:49 +00:00
parent b7bede71f6
commit 68334478aa
4 changed files with 335 additions and 0 deletions

50
package/nozomi/Makefile Normal file

@ -0,0 +1,50 @@
#
# Copyright (C) 2006 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
# $Id: Makefile 4855 2006-09-24 20:49:31Z nico $
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=nozomi
PKG_VERSION:=060209
PKG_RELEASE:=1
PKG_SOURCE:=nozomi_$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=http://www.pharscape.org/3G
PKG_MD5SUM:=a90e4d8f389a18b5579f7234a23e32e99
PKG_CAT:=zcat
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
include $(INCLUDE_DIR)/package.mk
PKG_UNPACK:=mkdir -p $(PKG_BUILD_DIR); $(ZCAT) $(DL_DIR)/$(PKG_SOURCE) | $(TAR) -C $(PKG_BUILD_DIR) $(TAR_OPTIONS)
define KernelPackage/nozomi
SUBMENU:=Other modules
TITLE:=Option Globetrotter HSDPA driver
DESCRIPTION:=Option Globetrotter HSDPA driver
URL:=http://www.pharscape.org/
VERSION:=$(LINUX_VERSION)+$(PKG_VERSION)-$(BOARD)-$(PKG_RELEASE)
FILES:=$(PKG_BUILD_DIR)/noz.$(LINUX_KMOD_SUFFIX)
AUTOLOAD:=$(call AutoLoad,70,noz)
endef
define Build/Configure
$(CP) ./files/Makefile $(PKG_BUILD_DIR)/
endef
define Build/Compile
$(MAKE) -C "$(LINUX_DIR)" \
CROSS_COMPILE="$(TARGET_CROSS)" \
ARCH="$(LINUX_KARCH)" \
PATH="$(TARGET_PATH)" \
SUBDIRS="$(PKG_BUILD_DIR)" \
modules
endef
$(eval $(call KernelPackage,nozomi))

@ -0,0 +1,15 @@
# $Id$
O_TARGET := noz.o
export-objs := nozomi.o kfifo.o
list-multi := noz.o
noz-objs := nozomi.o kfifo.o
obj-m := noz.o
include $(TOPDIR)/Rules.make
noz.o: $(noz-objs)
$(LD) -r -o $@ $(noz-objs)

@ -0,0 +1,19 @@
--- kmod-nozomi.orig/nozomi.c 2006-02-09 18:07:27.000000000 +0100
+++ kmod-nozomi/nozomi.c 2006-09-06 10:55:48.000000000 +0200
@@ -2093,11 +2093,15 @@
td->magic = TTY_DRIVER_MAGIC;
td->driver_name = NOZOMI_NAME_TTY;
+#ifndef CONFIG_DEVFS_FS
td->name = "noz";
+#else
+ td->name = "noz%d";
+#endif
td->major = NTTY_TTY_MAJOR,
td->type = TTY_DRIVER_TYPE_SERIAL,
td->subtype = SERIAL_TYPE_NORMAL,
- td->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+ td->flags = TTY_DRIVER_REAL_RAW,
td->init_termios = tty_std_termios;
td->init_termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;

@ -0,0 +1,251 @@
--- nozomi/nozomi.c.orig 2006-04-16 12:15:42.000000000 +0100
+++ nozomi/nozomi.c 2006-04-19 18:27:29.000000000 +0100
@@ -7,6 +7,9 @@
*
* Maintained by: Paul Hardwick, p.hardwick@option.com
*
+ * Patches:
+ * Locking code changes for Vodafone, Andrew Bird & Phil Sanderson
+ *
* Source has been ported from an implementation made by Filip Aben, f.aben@option.com
*
* --------------------------------------------------------------------------
@@ -61,6 +64,7 @@
#include <linux/interrupt.h>
#include <linux/kmod.h>
#include <linux/proc_fs.h>
+#include <linux/init.h>
#include <asm/uaccess.h>
@@ -133,23 +137,23 @@
/* TODO: rewrite to optimize macros... */
#define SET_FCR(value__) \
do { \
- writew((value__), (void*) (dc->REG_FCR )); \
+ writew((value__), (dc->REG_FCR )); \
} while(0)
#define SET_IER(value__, mask__) \
do { \
dc->ier_last_written = (dc->ier_last_written & ~mask__) | (value__ & mask__ );\
- writew( dc->ier_last_written, (void*) (dc->REG_IER));\
+ writew( dc->ier_last_written, (dc->REG_IER));\
} while(0)
#define GET_IER(read_val__) \
do { \
- (read_val__) = readw((void*) (dc->REG_IER));\
+ (read_val__) = readw((dc->REG_IER));\
} while(0)
#define GET_IIR(read_val__) \
do { \
- (read_val__) = readw((void*) (dc->REG_IIR));\
+ (read_val__) = readw( (dc->REG_IIR));\
} while(0)
#define GET_MEM(value__, addr__, length__) \
@@ -265,7 +268,7 @@
/* There are two types of nozomi cards, one with 2048 memory and with 8192 memory */
typedef enum {
F32_2 = 2048, /* Has 512 bytes downlink and uplink * 2 -> 2048 */
- F32_8 = 9192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
+ F32_8 = 8192, /* Has 3072 bytes downlink and 1024 bytes uplink * 2 -> 8192 */
} card_type_t;
/* Two different toggle channels exist */
@@ -438,12 +441,12 @@
u32 base_addr;
u8 closing;
- /* Register addresses */
- u32 REG_IIR;
- u32 REG_FCR;
- u32 REG_IER;
+ /* Pointers to registers ( register is tagged volatile, not pointer ) */
+ volatile u16 * REG_IIR;
+ volatile u16 * REG_FCR;
+ volatile u16 * REG_IER;
- volatile u16 ier_last_written;
+ u16 ier_last_written;
card_type_t card_type;
config_table_t config_table; /* Configuration table */
struct pci_dev *pdev;
@@ -490,7 +493,7 @@
/* Used to store interrupt variables */
typedef struct {
- volatile u16 read_iir; /* Holds current interrupt tokens */
+ u16 read_iir; /* Holds current interrupt tokens */
} irq_t;
MODULE_DEVICE_TABLE(pci, nozomi_pci_tbl);
@@ -1345,9 +1348,9 @@
u32 offset = dc->base_addr + dc->card_type/2;
int i;
- dc->REG_FCR = offset + R_FCR;
- dc->REG_IIR = offset + R_IIR;
- dc->REG_IER = offset + R_IER;
+ dc->REG_FCR = (u16 *) (offset + R_FCR);
+ dc->REG_IIR = (u16 *) (offset + R_IIR);
+ dc->REG_IER = (u16 *) (offset + R_IER);
dc->ier_last_written = 0;
dc->closing = 0;
@@ -1366,13 +1369,16 @@
static void tty_flip_queue_function(void *tmp_dc) {
dc_t *dc = (dc_t*) tmp_dc;
int i;
+ u32 flags;
/* Enable interrupt for that port */
for(i=0;i<MAX_PORT;i++) {
if (dc->port[i].tty_dont_flip) {
D6("Enable for port: %d", i);
dc->port[i].tty_dont_flip = 0;
+ spin_lock_irqsave(&dc->spin_mutex, flags);
enable_transmit_dl(dc->port[i].tty_index, dc);
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
}
}
}
@@ -1555,7 +1561,11 @@
static void tty_do_close(dc_t *dc, port_t *port) {
- down(&port->tty_sem);
+ u32 flags;
+
+ if(down_interruptible(&port->tty_sem)){
+ return;
+ }
if ( !port->tty_open_count ) {
goto exit;
@@ -1569,7 +1579,9 @@
if ( port->tty_open_count == 0) {
D1("close: %d", port->token_dl );
+ spin_lock_irqsave(&dc->spin_mutex, flags);
SET_IER( 0, port->token_dl );
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
}
exit:
@@ -1679,8 +1691,11 @@
s32 index = get_index(tty);
port_t *port = get_port_by_tty(tty);
dc_t *dc = get_dc_by_tty(tty);
+ u32 flags;
- down(&port->tty_sem);
+ if(down_interruptible(&port->tty_sem)){
+ return -ERESTARTSYS;
+ }
tty->low_latency = 1;
tty->driver_data = port;
@@ -1698,7 +1713,9 @@
if ( port->tty_open_count == 1) {
port->rx_data = port->tx_data = 0;
D1("open: %d", port->token_dl );
+ spin_lock_irqsave(&dc->spin_mutex, flags);
SET_IER( port->token_dl, port->token_dl );
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
}
up(&port->tty_sem);
@@ -1722,6 +1739,7 @@
int rval = -EINVAL;
dc_t *dc = get_dc_by_tty(tty);
port_t *port = (port_t *) tty->driver_data;
+ u32 flags;
/* D1( "WRITEx: %d, index = %d", count, index); */
@@ -1729,7 +1747,10 @@
return -ENODEV;
}
- down(&port->tty_sem);
+ if(down_trylock(&port->tty_sem) ) { // must test lock as tty layer wraps calls to this function with BKL
+ ERR("Would have deadlocked - return ERESTARTSYS");
+ return -ERESTARTSYS;
+ }
if (! port->tty_open_count) {
D1( " ");
@@ -1752,6 +1773,7 @@
goto exit;
}
+ spin_lock_irqsave(&dc->spin_mutex, flags);
// CTS is only valid on the modem channel
if ( port == &(dc->port[PORT_MDM]) ) {
if ( port->ctrl_dl.CTS ) {
@@ -1763,6 +1785,7 @@
} else {
enable_transmit_ul(port->tty_index, dc );
}
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
exit:
up(&port->tty_sem);
@@ -1782,7 +1805,9 @@
return 0;
}
- down(&port->tty_sem);
+ if(down_interruptible(&port->tty_sem)){
+ return 0;
+ }
if (! port->tty_open_count) {
goto exit;
@@ -1969,6 +1994,8 @@
static int ntty_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) {
port_t *port = (port_t *) tty->driver_data;
+ dc_t *dc = get_dc_by_tty(tty);
+ u32 flags;
int mask;
int rval = -ENOIOCTLCMD;
@@ -1991,7 +2018,9 @@
rval = ntty_ioctl_tiocgicount(tty, file, cmd, arg);
break;
case TIOCMGET:
+ spin_lock_irqsave(&dc->spin_mutex, flags);
rval = ntty_tiocmget(tty, file);
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
break;
case TIOCMSET:
rval = ntty_tiocmset(tty, file, arg);
@@ -2000,20 +2029,24 @@
if (get_user(mask, (unsigned long *) arg))
return -EFAULT;
+ spin_lock_irqsave(&dc->spin_mutex, flags);
if (mask & TIOCM_RTS)
set_rts(port->tty_index, 0);
if (mask & TIOCM_DTR)
set_dtr(port->tty_index, 0);
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
rval = 0;
break;
case TIOCMBIS:
if (get_user(mask, (unsigned long *) arg))
return -EFAULT;
+ spin_lock_irqsave(&dc->spin_mutex, flags);
if (mask & TIOCM_RTS)
set_rts(port->tty_index, 1);
if (mask & TIOCM_DTR)
set_dtr(port->tty_index, 1);
+ spin_unlock_irqrestore(&dc->spin_mutex, flags);
rval = 0;
break;
case TCFLSH: