From: Felix Fietkau Date: Fri, 3 Nov 2006 23:55:49 +0000 (+0000) Subject: add nozomi driver X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fsvn-archive%2Farchive.git;a=commitdiff_plain;h=bf616f72fbe6f9e0493a1681f0fccb078fa743a4 add nozomi driver SVN-Revision: 5431 --- diff --git a/package/nozomi/Makefile b/package/nozomi/Makefile new file mode 100644 index 0000000000..6a698032bc --- /dev/null +++ b/package/nozomi/Makefile @@ -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)) diff --git a/package/nozomi/files/Makefile b/package/nozomi/files/Makefile new file mode 100644 index 0000000000..85ea948f6f --- /dev/null +++ b/package/nozomi/files/Makefile @@ -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) diff --git a/package/nozomi/patches/001-devfs.patch b/package/nozomi/patches/001-devfs.patch new file mode 100644 index 0000000000..a532e579ff --- /dev/null +++ b/package/nozomi/patches/001-devfs.patch @@ -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; + diff --git a/package/nozomi/patches/002-nozomi_vf_01.patch b/package/nozomi/patches/002-nozomi_vf_01.patch new file mode 100644 index 0000000000..77dca1fbbf --- /dev/null +++ b/package/nozomi/patches/002-nozomi_vf_01.patch @@ -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 + #include + #include ++#include + #include + + +@@ -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;iport[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: