patch-2.4.0-test11 linux/drivers/char/synclink.c
Next file: linux/drivers/i2o/i2o_block.c
Previous file: linux/drivers/char/sx.c
Back to the patch index
Back to the overall index
- Lines: 940
- Date:
Tue Nov 7 10:36:42 2000
- Orig file:
v2.4.0-test10/linux/drivers/char/synclink.c
- Orig date:
Tue Oct 31 12:42:26 2000
diff -u --recursive --new-file v2.4.0-test10/linux/drivers/char/synclink.c linux/drivers/char/synclink.c
@@ -1,7 +1,7 @@
/*
* linux/drivers/char/synclink.c
*
- * ==FILEDATE 20000707==
+ * $Id: synclink.c,v 3.2 2000/11/06 22:34:38 paul Exp $
*
* Device driver for Microgate SyncLink ISA and PCI
* high speed multiprotocol serial adapters.
@@ -82,13 +82,9 @@
#include <linux/netdevice.h>
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
#include <linux/vmalloc.h>
#include <linux/init.h>
#include <asm/serial.h>
-#else
-#include <linux/bios32.h>
-#endif
#include <linux/delay.h>
#include <linux/ioctl.h>
@@ -102,98 +98,21 @@
#include <linux/termios.h>
#include <linux/tqueue.h>
-#if LINUX_VERSION_CODE < VERSION(2,3,0)
-typedef struct wait_queue *wait_queue_head_t;
-#define DECLARE_WAITQUEUE(name,task) struct wait_queue (name) = {(task),NULL}
-#define init_waitqueue_head(head) *(head) = NULL
-#define DECLARE_MUTEX(name) struct semaphore (name) = MUTEX
-#define set_current_state(a) current->state = (a)
-#endif
-
#ifdef CONFIG_SYNCLINK_SYNCPPP_MODULE
#define CONFIG_SYNCLINK_SYNCPPP 1
#endif
#ifdef CONFIG_SYNCLINK_SYNCPPP
-#if LINUX_VERSION_CODE < VERSION(2,3,43)
-#include "../net/syncppp.h"
-#define net_device device
-#define netif_stop_queue(a) (a)->tbusy = 1
-#define netif_start_queue(a) (a)->tbusy = 0
-#define netif_wake_queue(a) (a)->tbusy = 0; mark_bh(NET_BH)
-#define netif_queue_stopped(a) ((a)->tbusy)
-#else
#include "../net/wan/syncppp.h"
#endif
-#endif
-#if LINUX_VERSION_CODE >= VERSION(2,1,4)
#include <asm/segment.h>
#define GET_USER(error,value,addr) error = get_user(value,addr)
#define COPY_FROM_USER(error,dest,src,size) error = copy_from_user(dest,src,size) ? -EFAULT : 0
#define PUT_USER(error,value,addr) error = put_user(value,addr)
#define COPY_TO_USER(error,dest,src,size) error = copy_to_user(dest,src,size) ? -EFAULT : 0
-#if LINUX_VERSION_CODE >= VERSION(2,1,5)
#include <asm/uaccess.h>
-#endif
-
-#else /* 2.0.x and 2.1.x before 2.1.4 */
-
-#define GET_USER(error,value,addr) \
-do { \
- error = verify_area (VERIFY_READ, (void *) addr, sizeof (value)); \
- if (error == 0) \
- value = get_user(addr); \
-} while (0)
-
-#define COPY_FROM_USER(error,dest,src,size) \
-do { \
- error = verify_area (VERIFY_READ, (void *) src, size); \
- if (error == 0) \
- memcpy_fromfs (dest, src, size); \
-} while (0)
-
-#define PUT_USER(error,value,addr) \
-do { \
- error = verify_area (VERIFY_WRITE, (void *) addr, sizeof (value)); \
- if (error == 0) \
- put_user (value, addr); \
-} while (0)
-
-#define COPY_TO_USER(error,dest,src,size) \
-do { \
- error = verify_area (VERIFY_WRITE, (void *) dest, size); \
- if (error == 0) \
- memcpy_tofs (dest, src, size); \
-} while (0)
-
-#endif
-
-#if LINUX_VERSION_CODE < VERSION(2,1,0)
-/*
- * This is used to figure out the divisor speeds and the timeouts
- */
-static int baud_table[] = {
- 0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
- 9600, 19200, 38400, 57600, 115200, 230400, 460800, 0 };
-
-#define __init
-#define ioremap(a,b) vremap((a),(b))
-#define iounmap(a) vfree((a))
-#define SERIAL_TYPE_NORMAL 1
-#define SERIAL_TYPE_CALLOUT 2
-typedef int spinlock_t;
-#define spin_lock_init(a)
-#define spin_lock_irqsave(a,b) {save_flags((b));cli();}
-#define spin_unlock_irqrestore(a,b) {restore_flags((b));}
-#define spin_lock(a)
-#define spin_unlock(a)
-#define schedule_timeout(a){current->timeout = jiffies + (a); schedule();}
-#define signal_pending(a) ((a)->signal & ~(a)->blocked)
-#endif
-
-
#include "linux/synclink.h"
@@ -365,10 +284,12 @@
u32 last_mem_alloc;
unsigned char* memory_base; /* shared memory address (PCI only) */
u32 phys_memory_base;
+ int shared_mem_requested;
unsigned char* lcr_base; /* local config registers (PCI only) */
u32 phys_lcr_base;
u32 lcr_offset;
+ int lcr_mem_requested;
u32 misc_ctrl_value;
char flag_buf[MAX_ASYNC_BUFFER_SIZE];
@@ -389,10 +310,8 @@
char netname[10];
struct net_device *netdev;
struct net_device_stats netstats;
-#if LINUX_VERSION_CODE >= VERSION(2,2,16)
struct net_device netdevice;
#endif
-#endif
};
#define MGSL_MAGIC 0x5401
@@ -845,7 +764,7 @@
void mgsl_release_resources(struct mgsl_struct *info);
void mgsl_add_device(struct mgsl_struct *info);
struct mgsl_struct* mgsl_allocate_device(void);
-int mgsl_enumerate_devices(void);
+int mgsl_enum_isa_devices(void);
/*
* DMA buffer manupulation functions.
@@ -952,7 +871,6 @@
static int maxframe[MAX_TOTAL_DEVICES] = {0,};
static int dosyncppp[MAX_TOTAL_DEVICES] = {0,};
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
MODULE_PARM(break_on_load,"i");
MODULE_PARM(ttymajor,"i");
MODULE_PARM(cuamajor,"i");
@@ -962,10 +880,26 @@
MODULE_PARM(debug_level,"i");
MODULE_PARM(maxframe,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
MODULE_PARM(dosyncppp,"1-" __MODULE_STRING(MAX_TOTAL_DEVICES) "i");
-#endif
static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "1.21";
+static char *driver_version = "3.2";
+
+static int __init synclink_init_one (struct pci_dev *dev,
+ const struct pci_device_id *ent);
+static void __exit synclink_remove_one (struct pci_dev *dev);
+
+static struct pci_device_id synclink_pci_tbl[] __devinitdata = {
+ { PCI_VENDOR_ID_MICROGATE, PCI_DEVICE_ID_MICROGATE_USC, PCI_ANY_ID, PCI_ANY_ID, },
+ { 0, }, /* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, synclink_pci_tbl);
+
+static struct pci_driver synclink_pci_driver = {
+ name: "synclink",
+ id_table: synclink_pci_tbl,
+ probe: synclink_init_one,
+ remove: synclink_remove_one,
+};
static struct tty_driver serial_driver, callout_driver;
static int serial_refcount;
@@ -977,9 +911,9 @@
static void mgsl_change_params(struct mgsl_struct *info);
static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout);
-static struct tty_struct **serial_table = NULL;
-static struct termios **serial_termios = NULL;
-static struct termios **serial_termios_locked = NULL;
+static struct tty_struct *serial_table[MAX_TOTAL_DEVICES];
+static struct termios *serial_termios[MAX_TOTAL_DEVICES];
+static struct termios *serial_termios_locked[MAX_TOTAL_DEVICES];
#ifndef MIN
#define MIN(a,b) ((a) < (b) ? (a) : (b))
@@ -1591,16 +1525,9 @@
icount->parity,icount->frame,icount->overrun);
}
- if ( tty->flip.count ) {
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
+ if ( tty->flip.count )
tty_flip_buffer_push(tty);
-#else
- queue_task(&tty->flip.tqueue, &tq_timer);
-#endif
- }
-
-
-} /* end of mgsl_isr_receive_data() */
+}
/* mgsl_isr_misc()
*
@@ -1795,11 +1722,7 @@
retval = mgsl_adapter_test(info);
if ( retval ) {
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
if (capable(CAP_SYS_ADMIN) && info->tty)
-#else
- if (suser() && info->tty)
-#endif
set_bit(TTY_IO_ERROR, &info->tty->flags);
mgsl_release_resources(info);
return retval;
@@ -1974,21 +1897,8 @@
* allow tty settings to override, otherwise keep the
* current data rate.
*/
- if (info->params.data_rate <= 460800) {
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
+ if (info->params.data_rate <= 460800)
info->params.data_rate = tty_get_baud_rate(info->tty);
-#else
- int i = cflag & CBAUD;
- if (i & CBAUDEX) {
- i &= ~CBAUDEX;
- if (i < 1 || i > 4)
- info->tty->termios->c_cflag &= ~CBAUDEX;
- else
- i += 15;
- }
- info->params.data_rate = baud_table[i];
-#endif
- }
if ( info->params.data_rate ) {
info->timeout = (32*HZ*bits_per_char) /
@@ -2950,7 +2860,6 @@
} /* end of set_modem_info() */
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
/* mgsl_break() Set or clear transmit break condition
*
* Arguments: tty pointer to tty instance data
@@ -2977,7 +2886,6 @@
spin_unlock_irqrestore(&info->irq_spinlock,flags);
} /* end of mgsl_break() */
-#endif
/* mgsl_ioctl() Service an IOCTL request
*
@@ -3100,7 +3008,6 @@
if (error) return error;
PUT_USER(error,cnow.dcd, &p_cuser->dcd);
if (error) return error;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
PUT_USER(error,cnow.rx, &p_cuser->rx);
if (error) return error;
PUT_USER(error,cnow.tx, &p_cuser->tx);
@@ -3115,7 +3022,6 @@
if (error) return error;
PUT_USER(error,cnow.buf_overrun, &p_cuser->buf_overrun);
if (error) return error;
-#endif
return 0;
default:
return -ENOIOCTLCMD;
@@ -3596,9 +3502,7 @@
tmp_buf = (unsigned char *) page;
}
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
-#endif
spin_lock_irqsave(&info->netlock, flags);
if (info->netcount) {
@@ -3985,22 +3889,14 @@
} /* end of mgsl_alloc_buffer_list_memory() */
-/*
- * mgsl_free_buffer_list_memory()
- *
- * Free the common DMA buffer allocated for use as the
- * receive and transmit buffer lists. The associated Memory
- * Descriptor List (MDL) is also freed.
- *
+/* Free DMA buffers allocated for use as the
+ * receive and transmit buffer lists.
* Warning:
*
* The data transfer buffers associated with the buffer list
* MUST be freed before freeing the buffer list itself because
* the buffer list contains the information necessary to free
* the individual buffers!
- *
- * Arguments: info pointer to device extension
- * Return Value: None
*/
void mgsl_free_buffer_list_memory( struct mgsl_struct *info )
{
@@ -4138,67 +4034,61 @@
void mgsl_free_intermediate_rxbuffer_memory(struct mgsl_struct *info)
{
if ( info->intermediate_rxbuffer )
- kfree( info->intermediate_rxbuffer );
+ kfree(info->intermediate_rxbuffer);
info->intermediate_rxbuffer = NULL;
} /* end of mgsl_free_intermediate_rxbuffer_memory() */
-/* mgsl_claim_resources()
- *
- * Claim all resources used by a device
- *
- * Arguments: info pointer to device instance data
- * Return Value: 0 if success, otherwise -ENODEV
- */
int mgsl_claim_resources(struct mgsl_struct *info)
{
- /* claim 16C32 I/O base address */
-
- if ( check_region(info->io_base,info->io_addr_size) < 0 ) {
+ if (request_region(info->io_base,info->io_addr_size,"synclink") == NULL) {
printk( "%s(%d):I/O address conflict on device %s Addr=%08X\n",
- __FILE__,__LINE__,info->device_name, info->io_base );
+ __FILE__,__LINE__,info->device_name, info->io_base);
return -ENODEV;
}
- request_region(info->io_base,info->io_addr_size,"synclink.o");
info->io_addr_requested = 1;
- /* claim interrupt level */
-
if ( request_irq(info->irq_level,mgsl_interrupt,info->irq_flags,
info->device_name, info ) < 0 ) {
printk( "%s(%d):Cant request interrupt on device %s IRQ=%d\n",
__FILE__,__LINE__,info->device_name, info->irq_level );
- mgsl_release_resources( info );
- return -ENODEV;
+ goto errout;
}
info->irq_requested = 1;
if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
- /* claim shared memory range */
+ if (request_mem_region(info->phys_memory_base,0x40000,"synclink") == NULL) {
+ printk( "%s(%d):mem addr conflict device %s Addr=%08X\n",
+ __FILE__,__LINE__,info->device_name, info->phys_memory_base);
+ goto errout;
+ }
+ info->shared_mem_requested = 1;
+ if (request_mem_region(info->phys_lcr_base,128,"synclink") == NULL) {
+ printk( "%s(%d):lcr mem addr conflict device %s Addr=%08X\n",
+ __FILE__,__LINE__,info->device_name, info->phys_lcr_base);
+ goto errout;
+ }
+ info->lcr_mem_requested = 1;
+
info->memory_base = ioremap(info->phys_memory_base,0x40000);
if (!info->memory_base) {
printk( "%s(%d):Cant map shared memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
- mgsl_release_resources( info );
- return -ENODEV;
+ goto errout;
}
- /* test the shared memory range */
if ( !mgsl_memory_test(info) ) {
printk( "%s(%d):Failed shared memory test %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_memory_base );
- mgsl_release_resources( info );
- return -ENODEV;
+ goto errout;
}
- /* claim LCR memory range */
info->lcr_base = ioremap(info->phys_lcr_base,PAGE_SIZE) + info->lcr_offset;
if (!info->lcr_base) {
printk( "%s(%d):Cant map LCR memory on device %s MemAddr=%08X\n",
__FILE__,__LINE__,info->device_name, info->phys_lcr_base );
- mgsl_release_resources( info );
- return -ENODEV;
+ goto errout;
}
} else {
@@ -4220,21 +4110,16 @@
if ( mgsl_allocate_dma_buffers(info) < 0 ) {
printk( "%s(%d):Cant allocate DMA buffers on device %s DMA=%d\n",
__FILE__,__LINE__,info->device_name, info->dma_level );
- mgsl_release_resources( info );
- return -ENODEV;
+ goto errout;
}
return 0;
-
+errout:
+ mgsl_release_resources(info);
+ return ENODEV;
+
} /* end of mgsl_claim_resources() */
-/* mgsl_release_resources()
- *
- * Release all resources used by a device
- *
- * Arguments: info pointer to device instance data
- * Return Value: None
- */
void mgsl_release_resources(struct mgsl_struct *info)
{
if ( debug_level >= DEBUG_LEVEL_INFO )
@@ -4245,7 +4130,6 @@
free_irq(info->irq_level, info);
info->irq_requested = 0;
}
-
if ( info->dma_requested ) {
disable_dma(info->dma_level);
free_dma(info->dma_level);
@@ -4258,12 +4142,18 @@
release_region(info->io_base,info->io_addr_size);
info->io_addr_requested = 0;
}
-
+ if ( info->shared_mem_requested ) {
+ release_mem_region(info->phys_memory_base,0x40000);
+ info->shared_mem_requested = 0;
+ }
+ if ( info->lcr_mem_requested ) {
+ release_mem_region(info->phys_lcr_base,128);
+ info->lcr_mem_requested = 0;
+ }
if (info->memory_base){
iounmap(info->memory_base);
info->memory_base = 0;
}
-
if (info->lcr_base){
iounmap(info->lcr_base - info->lcr_offset);
info->lcr_base = 0;
@@ -4367,210 +4257,23 @@
} /* end of mgsl_allocate_device()*/
-/* mgsl_enumerate_devices()
- *
- * Enumerate SyncLink serial devices based on user specified
- * options for ISA adapters and autodetected PCI adapters.
- *
- * Arguments: None
- * Return Value: 0 if success, otherwise error code
- */
-int mgsl_enumerate_devices()
-{
- struct mgsl_struct *info;
- int i;
-
- /* Check for user specified ISA devices */
-
- for (i=0 ;(i < MAX_ISA_DEVICES) && io[i] && irq[i]; i++){
- if ( debug_level >= DEBUG_LEVEL_INFO )
- printk("ISA device specified io=%04X,irq=%d,dma=%d\n",
- io[i], irq[i], dma[i] );
-
- info = mgsl_allocate_device();
- if ( !info ) {
- /* error allocating device instance data */
- if ( debug_level >= DEBUG_LEVEL_ERROR )
- printk( "can't allocate device instance data.\n");
- continue;
- }
-
- /* Copy user configuration info to device instance data */
- info->io_base = (unsigned int)io[i];
- info->irq_level = (unsigned int)irq[i];
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
- info->irq_level = irq_cannonicalize(info->irq_level);
-#else
- if (info->irq_level == 2)
- info->irq_level = 9;
-#endif
- info->dma_level = (unsigned int)dma[i];
- info->bus_type = MGSL_BUS_TYPE_ISA;
- info->io_addr_size = 16;
- info->irq_flags = 0;
-
- mgsl_add_device( info );
- }
-
-
-#ifdef CONFIG_PCI
- /* Auto detect PCI adapters */
-
- if ( pcibios_present() ) {
- unsigned char bus;
- unsigned char func;
- unsigned int shared_mem_base;
- unsigned int lcr_mem_base;
- unsigned int io_base;
- unsigned char irq_line;
-
- for(i=0;;i++){
- if ( PCIBIOS_SUCCESSFUL == pcibios_find_device(
- MICROGATE_VENDOR_ID, SYNCLINK_DEVICE_ID, i, &bus, &func) ) {
-
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
- struct pci_dev *pdev = pci_find_slot(bus,func);
- irq_line = pdev->irq;
-#else
- if (pcibios_read_config_byte(bus,func,
- PCI_INTERRUPT_LINE,&irq_line) ) {
- printk( "%s(%d):USC I/O addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-#endif
-
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_3,&shared_mem_base) ) {
- printk( "%s(%d):Shared mem addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_0,&lcr_mem_base) ) {
- printk( "%s(%d):LCR mem addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
- if (pcibios_read_config_dword(bus,func,
- PCI_BASE_ADDRESS_2,&io_base) ) {
- printk( "%s(%d):USC I/O addr not set.\n",
- __FILE__,__LINE__);
- continue;
- }
-
- info = mgsl_allocate_device();
- if ( !info ) {
- /* error allocating device instance data */
- if ( debug_level >= DEBUG_LEVEL_ERROR )
- printk( "can't allocate device instance data.\n");
- continue;
- }
-
- /* Copy user configuration info to device instance data */
-
- info->io_base = io_base & PCI_BASE_ADDRESS_IO_MASK;
- info->irq_level = (unsigned int)irq_line;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
- info->irq_level = irq_cannonicalize(info->irq_level);
-#else
- if (info->irq_level == 2)
- info->irq_level = 9;
-#endif
- info->phys_memory_base = shared_mem_base & PCI_BASE_ADDRESS_MEM_MASK;
-
- /* Because veremap only works on page boundaries we must map
- * a larger area than is actually implemented for the LCR
- * memory range. We map a full page starting at the page boundary.
- */
- info->phys_lcr_base = lcr_mem_base & PCI_BASE_ADDRESS_MEM_MASK;
- info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1);
- info->phys_lcr_base &= ~(PAGE_SIZE-1);
-
- info->bus_type = MGSL_BUS_TYPE_PCI;
- info->io_addr_size = 8;
- info->irq_flags = SA_SHIRQ;
- info->bus = bus;
- info->function = func;
-
- /* Store the PCI9050 misc control register value because a flaw
- * in the PCI9050 prevents LCR registers from being read if
- * BIOS assigns an LCR base address with bit 7 set.
- *
- * Only the misc control register is accessed for which only
- * write access is needed, so set an initial value and change
- * bits to the device instance data as we write the value
- * to the actual misc control register.
- */
- info->misc_ctrl_value = 0x087e4546;
-
- /* add new device to device list */
- mgsl_add_device( info );
- } else {
- break;
- }
- }
- }
-#endif
-
- /*
- * Allocate memory to hold the following tty/termios arrays
- * with an element for each enumerated device.
- */
-
- serial_table = (struct tty_struct**)kmalloc(sizeof(struct tty_struct*)*mgsl_device_count, GFP_KERNEL);
- serial_termios = (struct termios**)kmalloc(sizeof(struct termios*)*mgsl_device_count, GFP_KERNEL);
- serial_termios_locked = (struct termios**)kmalloc(sizeof(struct termios*)*mgsl_device_count, GFP_KERNEL);
-
- if (!serial_table || !serial_termios || !serial_termios_locked){
- printk("%s(%d):Can't allocate tty/termios arrays.\n",
- __FILE__,__LINE__);
- return -ENOMEM;
- }
-
- memset(serial_table,0,sizeof(struct tty_struct*)*mgsl_device_count);
- memset(serial_termios,0,sizeof(struct termios*)*mgsl_device_count);
- memset(serial_termios_locked,0,sizeof(struct termios*)*mgsl_device_count);
-
- return 0;
-
-} /* end of mgsl_enumerate_devices() */
-
-/* mgsl_init()
- *
- * Driver initialization entry point.
- *
- * Arguments: None
- * Return Value: 0 if success, otherwise error code
+/*
+ * perform tty device initialization
*/
-int __init mgsl_init(void)
+int mgsl_init_tty(void);
+int mgsl_init_tty()
{
struct mgsl_struct *info;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
- EXPORT_NO_SYMBOLS;
-#else
- register_symtab(NULL);
-#endif
-
- printk("%s version %s\n", driver_name, driver_version);
-
- /* determine how many SyncLink devices are installed */
- mgsl_enumerate_devices();
- if ( !mgsl_device_list ) {
- printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
- return -ENODEV;
- }
+ memset(serial_table,0,sizeof(struct tty_struct*)*MAX_TOTAL_DEVICES);
+ memset(serial_termios,0,sizeof(struct termios*)*MAX_TOTAL_DEVICES);
+ memset(serial_termios_locked,0,sizeof(struct termios*)*MAX_TOTAL_DEVICES);
/* Initialize the tty_driver structure */
memset(&serial_driver, 0, sizeof(struct tty_driver));
serial_driver.magic = TTY_DRIVER_MAGIC;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
serial_driver.driver_name = "synclink";
-#endif
serial_driver.name = "ttySL";
serial_driver.major = ttymajor;
serial_driver.minor_start = 64;
@@ -4597,12 +4300,10 @@
serial_driver.ioctl = mgsl_ioctl;
serial_driver.throttle = mgsl_throttle;
serial_driver.unthrottle = mgsl_unthrottle;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
serial_driver.send_xchar = mgsl_send_xchar;
serial_driver.break_ctl = mgsl_break;
serial_driver.wait_until_sent = mgsl_wait_until_sent;
serial_driver.read_proc = mgsl_read_proc;
-#endif
serial_driver.set_termios = mgsl_set_termios;
serial_driver.stop = mgsl_stop;
serial_driver.start = mgsl_start;
@@ -4616,10 +4317,8 @@
callout_driver.name = "cuaSL";
callout_driver.major = cuamajor;
callout_driver.subtype = SERIAL_TYPE_CALLOUT;
-#if LINUX_VERSION_CODE >= VERSION(2,1,0)
callout_driver.read_proc = 0;
callout_driver.proc_entry = 0;
-#endif
if (tty_register_driver(&serial_driver) < 0)
printk("%s(%d):Couldn't register serial driver\n",
@@ -4641,13 +4340,76 @@
info->normal_termios = serial_driver.init_termios;
info = info->next_device;
}
+
+ return 0;
+}
+
+/* enumerate user specified ISA adapters
+ */
+int mgsl_enum_isa_devices()
+{
+ struct mgsl_struct *info;
+ int i;
+
+ /* Check for user specified ISA devices */
+
+ for (i=0 ;(i < MAX_ISA_DEVICES) && io[i] && irq[i]; i++){
+ if ( debug_level >= DEBUG_LEVEL_INFO )
+ printk("ISA device specified io=%04X,irq=%d,dma=%d\n",
+ io[i], irq[i], dma[i] );
+
+ info = mgsl_allocate_device();
+ if ( !info ) {
+ /* error allocating device instance data */
+ if ( debug_level >= DEBUG_LEVEL_ERROR )
+ printk( "can't allocate device instance data.\n");
+ continue;
+ }
+
+ /* Copy user configuration info to device instance data */
+ info->io_base = (unsigned int)io[i];
+ info->irq_level = (unsigned int)irq[i];
+ info->irq_level = irq_cannonicalize(info->irq_level);
+ info->dma_level = (unsigned int)dma[i];
+ info->bus_type = MGSL_BUS_TYPE_ISA;
+ info->io_addr_size = 16;
+ info->irq_flags = 0;
+
+ mgsl_add_device( info );
+ }
return 0;
+}
+
+/* mgsl_init()
+ *
+ * Driver initialization entry point.
+ *
+ * Arguments: None
+ * Return Value: 0 if success, otherwise error code
+ */
+int __init mgsl_init(void)
+{
+ int rc;
+
+ EXPORT_NO_SYMBOLS;
+
+ printk("%s version %s\n", driver_name, driver_version);
-} /* end of mgsl_init() */
+ mgsl_enum_isa_devices();
+ pci_register_driver(&synclink_pci_driver);
-#ifdef MODULE
-int init_module(void)
+ if ( !mgsl_device_list ) {
+ printk("%s(%d):No SyncLink devices found.\n",__FILE__,__LINE__);
+ return -ENODEV;
+ }
+ if ((rc = mgsl_init_tty()))
+ return rc;
+
+ return 0;
+}
+
+static int __init synclink_init(void)
{
/* Uncomment this to kernel debug module.
* mgsl_get_text_ptr() leaves the .text address in eax
@@ -4661,7 +4423,7 @@
return mgsl_init();
}
-void cleanup_module(void)
+static void __exit synclink_exit(void)
{
unsigned long flags;
int rc;
@@ -4693,19 +4455,11 @@
tmp_buf = NULL;
}
- if (serial_table)
- kfree(serial_table);
-
- if (serial_termios)
- kfree(serial_termios);
-
- if (serial_termios_locked)
- kfree(serial_termios_locked);
-
-} /* end of cleanup_module() */
-
-#endif /* MODULE */
+ pci_unregister_driver(&synclink_pci_driver);
+}
+module_init(synclink_init);
+module_exit(synclink_exit);
/*
* usc_RTCmd()
@@ -6953,7 +6707,6 @@
while( EndTime-- && !info->irq_occurred ) {
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(jiffies_from_ms(10));
- set_current_state(TASK_RUNNING);
}
spin_lock_irqsave(&info->irq_spinlock,flags);
@@ -7567,16 +7320,13 @@
sprintf(info->netname,"mgsl%d",info->line);
-#if LINUX_VERSION_CODE < VERSION(2,2,16)
- info->netdev = &info->pppdev.dev;
-#else
info->if_ptr = &info->pppdev;
info->netdev = info->pppdev.dev = &info->netdevice;
-#endif
+
sppp_attach(&info->pppdev);
d = info->netdev;
- strcpy(d->name, info->netname);
+ strcpy(d->name,info->netname);
d->base_addr = info->io_base;
d->irq = info->irq_level;
d->dma = info->dma_level;
@@ -7587,10 +7337,9 @@
d->hard_start_xmit = mgsl_sppp_tx;
d->do_ioctl = mgsl_sppp_ioctl;
d->get_stats = mgsl_net_stats;
-#if LINUX_VERSION_CODE >= VERSION(2,3,43)
d->tx_timeout = mgsl_sppp_tx_timeout;
d->watchdog_timeo = 10*HZ;
-#endif
+
dev_init_buffers(d);
if (register_netdev(d) == -1) {
@@ -7680,17 +7429,7 @@
if (debug_level >= DEBUG_LEVEL_INFO)
printk("mgsl_sppp_tx(%s)\n",info->netname);
-#if LINUX_VERSION_CODE < VERSION(2,3,43)
- if (dev->tbusy) {
- if (time_before(jiffies, dev->trans_start+10*HZ))
- return -EBUSY; /* 10 seconds timeout */
- mgsl_sppp_tx_timeout(dev);
- }
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
- return -EBUSY;
-#else
netif_stop_queue(dev);
-#endif
info->xmit_cnt = skb->len;
mgsl_load_tx_dma_buffer(info, skb->data, skb->len);
@@ -7777,3 +7516,57 @@
}
#endif /* ifdef CONFIG_SYNCLINK_SYNCPPP */
+
+static int __init synclink_init_one (struct pci_dev *dev,
+ const struct pci_device_id *ent)
+{
+ struct mgsl_struct *info;
+
+ if (pci_enable_device(dev)) {
+ printk("error enabling pci device %p\n", dev);
+ return -EIO;
+ }
+
+ if (!(info = mgsl_allocate_device())) {
+ printk("can't allocate device instance data.\n");
+ return -EIO;
+ }
+
+ /* Copy user configuration info to device instance data */
+
+ info->io_base = pci_resource_start(dev, 2);
+ info->irq_level = dev->irq;
+ info->phys_memory_base = pci_resource_start(dev, 3);
+
+ /* Because veremap only works on page boundaries we must map
+ * a larger area than is actually implemented for the LCR
+ * memory range. We map a full page starting at the page boundary.
+ */
+ info->phys_lcr_base = pci_resource_start(dev, 0);
+ info->lcr_offset = info->phys_lcr_base & (PAGE_SIZE-1);
+ info->phys_lcr_base &= ~(PAGE_SIZE-1);
+
+ info->bus_type = MGSL_BUS_TYPE_PCI;
+ info->io_addr_size = 8;
+ info->irq_flags = SA_SHIRQ;
+
+ /* Store the PCI9050 misc control register value because a flaw
+ * in the PCI9050 prevents LCR registers from being read if
+ * BIOS assigns an LCR base address with bit 7 set.
+ *
+ * Only the misc control register is accessed for which only
+ * write access is needed, so set an initial value and change
+ * bits to the device instance data as we write the value
+ * to the actual misc control register.
+ */
+ info->misc_ctrl_value = 0x087e4546;
+
+ mgsl_add_device(info);
+
+ return 0;
+}
+
+static void __exit synclink_remove_one (struct pci_dev *dev)
+{
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)