diff options
author | Shaun Ruffell <sruffell@digium.com> | 2009-03-23 23:48:16 +0000 |
---|---|---|
committer | Shaun Ruffell <sruffell@digium.com> | 2009-03-23 23:48:16 +0000 |
commit | cce5ba73cfe1bd9d39993e33acb776c0f2641cd7 (patch) | |
tree | 9bcb189717cb2f405e53db32e3ec5b2805b5aeb6 /drivers/dahdi/wctc4xxp/base.c | |
parent | c553932df6d6d5d96fb7ab718ba80f3c9e827ed9 (diff) |
Refactor channel command handling.
Makes commands and reponses clearer and easier to trouble shoot, reduces
pressure on the stack, and brings driver closer to kernel coding standards.
git-svn-id: http://svn.asterisk.org/svn/dahdi/linux/trunk@6217 a0bf4364-ded3-4de4-8d8a-66a801d63aff
Diffstat (limited to 'drivers/dahdi/wctc4xxp/base.c')
-rw-r--r-- | drivers/dahdi/wctc4xxp/base.c | 2085 |
1 files changed, 1089 insertions, 996 deletions
diff --git a/drivers/dahdi/wctc4xxp/base.c b/drivers/dahdi/wctc4xxp/base.c index 5fcdabe..262d8ed 100644 --- a/drivers/dahdi/wctc4xxp/base.c +++ b/drivers/dahdi/wctc4xxp/base.c @@ -1,7 +1,7 @@ /* * Wildcard TC400B Driver * - * Copyright (C) 2006-2008, Digium, Inc. + * Copyright (C) 2006-2009, Digium, Inc. * * All rights reserved. * @@ -30,7 +30,7 @@ #include <linux/pci.h> #include <linux/interrupt.h> #include <linux/delay.h> -#include <asm/io.h> +#include <linux/io.h> #include <linux/jiffies.h> #include <linux/moduleparam.h> #include <linux/firmware.h> @@ -48,7 +48,7 @@ #define WORKQUEUE 1 #define TASKLET 2 -#ifndef DEFERRED_PROCESSING +#ifndef DEFERRED_PROCESSING # define DEFERRED_PROCESSING WORKQUEUE #endif @@ -63,16 +63,16 @@ #define WARN_ALWAYS() WARN_ON(1) #define DTE_PRINTK(_lvl, _fmt, _args...) \ - printk(KERN_##_lvl "%s: %s: " _fmt, THIS_MODULE->name, \ - (wc)->board_name, ## _args) + printk(KERN_##_lvl "%s: %s: " _fmt, THIS_MODULE->name, \ + (wc)->board_name, ## _args) -#define DTE_DEBUG(_dbgmask, _fmt, _args...) \ - if ((debug & _dbgmask) == (_dbgmask)) { \ - printk(KERN_DEBUG "%s: %s: " _fmt, THIS_MODULE->name, \ - (wc)->board_name, ## _args); \ - } \ +#define DTE_DEBUG(_dbgmask, _fmt, _args...) \ + if ((debug & _dbgmask) == (_dbgmask)) { \ + printk(KERN_DEBUG "%s: %s: " _fmt, THIS_MODULE->name, \ + (wc)->board_name, ## _args); \ + } \ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) #ifndef WARN_ON_ONCE #define WARN_ON_ONCE(__condition) do { \ static int __once = 1; \ @@ -82,12 +82,12 @@ WARN_ON(0); \ } \ } \ -} while(0) +} while (0) #endif #endif #define INVALID 999 /* Used to mark invalid channels, commands, etc.. */ -#define MAX_CHANNEL_PACKETS 5 /* Never let more than 5 outstanding packets exist for any channel. */ +#define MAX_CHANNEL_PACKETS 5 #define G729_LENGTH 20 #define G723_LENGTH 30 @@ -103,13 +103,13 @@ #define MAX_CAPTURED_PACKETS 5000 /* The following bit fields are used to set the various debug levels. */ -#define DTE_DEBUG_GENERAL (1 << 0) /* 1 */ -#define DTE_DEBUG_CHANNEL_SETUP (1 << 1) /* 2 */ -#define DTE_DEBUG_RTP_TX (1 << 2) /* 4 */ -#define DTE_DEBUG_RTP_RX (1 << 3) /* 8 */ -#define DTE_DEBUG_RX_TIMEOUT (1 << 4) /* 16 */ -#define DTE_DEBUG_NETWORK_IF (1 << 5) /* 32 */ -#define DTE_DEBUG_NETWORK_EARLY (1 << 6) /* 64 */ +#define DTE_DEBUG_GENERAL (1 << 0) /* 1 */ +#define DTE_DEBUG_CHANNEL_SETUP (1 << 1) /* 2 */ +#define DTE_DEBUG_RTP_TX (1 << 2) /* 4 */ +#define DTE_DEBUG_RTP_RX (1 << 3) /* 8 */ +#define DTE_DEBUG_RX_TIMEOUT (1 << 4) /* 16 */ +#define DTE_DEBUG_NETWORK_IF (1 << 5) /* 32 */ +#define DTE_DEBUG_NETWORK_EARLY (1 << 6) /* 64 */ static int debug; static char *mode; @@ -148,7 +148,7 @@ struct rtp_packet { struct udphdr udphdr; struct rtphdr rtphdr; __u8 payload[0]; -}__attribute__((packed)); +} __attribute__((packed)); /* Ethernet packet type for communication control information to the DTE. */ struct csm_encaps_hdr { @@ -168,167 +168,25 @@ struct csm_encaps_hdr { __le16 params[0]; } __attribute__((packed)); -struct csm_create_channel_cmd { - struct csm_encaps_hdr hdr; - __le16 channel_type; - __le16 timeslot; -} __attribute__((packed)); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14) -/* also added in RHEL kernels with the OpenInfiniband backport: */ -#if LINUX_VERSION_CODE != KERNEL_VERSION(2,6,9) || !defined(DEFINE_SPINLOCK) -typedef unsigned gfp_t; /* Added in 2.6.14 */ -#endif -#endif - -#define CMD_MSG_TDM_SELECT_BUS_MODE_LEN 30 -#define CMD_MSG_TDM_SELECT_BUS_MODE(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x01, 0x00,0x06,0x17,0x04, 0xFF,0xFF, \ - 0x04,0x00 } -#define CMD_MSG_TDM_ENABLE_BUS_LEN 30 -#define CMD_MSG_TDM_ENABLE_BUS(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x02, 0x00,0x06,0x05,0x04, 0xFF,0xFF, \ - 0x04,0x00 } -#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS_LEN 34 -#define CMD_MSG_SUPVSR_SETUP_TDM_PARMS(s,p1,p2,p3) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x10, p1, 0x00,0x06,0x07,0x04, 0xFF,0xFF, \ - p2,0x83, 0x00,0x0C, 0x00,0x00, p3,0x00 } -#define CMD_MSG_TDM_OPT_LEN 30 -#define CMD_MSG_TDM_OPT(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x35,0x04, 0xFF,0xFF, \ - 0x00,0x00 } -#define CMD_MSG_DEVICE_SET_COUNTRY_CODE_LEN 30 -#define CMD_MSG_DEVICE_SET_COUNTRY_CODE(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x1B,0x04, 0xFF,0xFF, \ - 0x00,0x00 } - -/* CPU Commands */ -#define CMD_MSG_SET_ARM_CLK_LEN 32 -#define CMD_MSG_SET_ARM_CLK(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x11,0x04, 0x00,0x00, \ - 0x2C,0x01, 0x00,0x00 } -#define CMD_MSG_SET_SPU_CLK_LEN 32 -#define CMD_MSG_SET_SPU_CLK(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0C, 0x00, 0x00,0x06,0x12,0x04, 0x00,0x00, \ - 0x2C,0x01, 0x00,0x00 } -#define CMD_MSG_SPU_FEATURES_CONTROL_LEN 30 -#define CMD_MSG_SPU_FEATURES_CONTROL(s,p1) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x13,0x00, 0xFF,0xFF, \ - p1,0x00 } -#define CMD_MSG_DEVICE_STATUS_CONFIG_LEN 30 -#define CMD_MSG_DEVICE_STATUS_CONFIG(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x0F,0x04, 0xFF,0xFF, \ - 0x05,0x00 } - -/* General IP/RTP Commands */ -#define CMD_MSG_SET_ETH_HEADER_LEN 44 -#define CMD_MSG_SET_ETH_HEADER(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x18, 0x00, 0x00,0x06,0x00,0x01, 0xFF,0xFF, \ - 0x01,0x00, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x00,0x11,0x22,0x33,0x44,0x55, 0x08,0x00 } -#define CMD_MSG_IP_SERVICE_CONFIG_LEN 30 -#define CMD_MSG_IP_SERVICE_CONFIG(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x02,0x03, 0xFF,0xFF, \ - 0x00,0x02 } -#define CMD_MSG_ARP_SERVICE_CONFIG_LEN 30 -#define CMD_MSG_ARP_SERVICE_CONFIG(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x05,0x01, 0xFF,0xFF, \ - 0x01,0x00 } -#define CMD_MSG_ICMP_SERVICE_CONFIG_LEN 30 -#define CMD_MSG_ICMP_SERVICE_CONFIG(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x04,0x03, 0xFF,0xFF, \ - 0x01,0xFF } -#define CMD_MSG_IP_OPTIONS_LEN 30 -#define CMD_MSG_IP_OPTIONS(s) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x06,0x03, 0xFF,0xFF, \ - 0x02,0x00 } - #define CONTROL_PACKET_OPCODE 0x0001 /* Control bits */ -#define LITTLE_ENDIAN 0x01 -#define SUPPRESS_ACK 0x40 -#define MESSAGE_PACKET 0x80 +#define LITTLE_ENDIAN 0x01 +#define SUPPRESS_ACK 0x40 +#define MESSAGE_PACKET 0x80 #define SUPERVISOR_CHANNEL 0xffff /* Supervisor function codes */ -#define SUPVSR_CREATE_CHANNEL 0x0010 +#define SUPVSR_CREATE_CHANNEL 0x0010 #define MONITOR_LIVE_INDICATION_TYPE 0x75 -#define CONFIG_CHANGE_TYPE 0x00 -#define CONFIG_DEVICE_CLASS 0x06 - -#define CMD_MSG_QUERY_CHANNEL_LEN 30 -#define CMD_MSG_QUERY_CHANNEL(s,t) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x01,0x06,0x10,0x00, 0x00,0x00, \ - (t&0x00FF), ((t&0xFF00) >> 8) } - -#define CMD_MSG_TRANS_CONNECT_LEN 38 -#define CMD_MSG_TRANS_CONNECT(s,e,c1,c2,f1,f2) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x12, 0x00, 0x00,0x06,0x22,0x93, 0x00,0x00, \ - e,0x00, (c1&0x00FF),((c1&0xFF00)>>8), f1,0x00, (c2&0x00FF),((c2&0xFF00)>>8), f2,0x00 } -#define CMD_MSG_DESTROY_CHANNEL_LEN 32 -#define CMD_MSG_DESTROY_CHANNEL(s,t) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, 0xFF,0xFF, 0x0A, 0x00, 0x00,0x06,0x11,0x00, 0x00,0x00, \ - (t&0x00FF),((t&0xFF00)>>8), 0x00, 0x00 } +#define CONFIG_CHANGE_TYPE 0x00 +#define CONFIG_CHANNEL_CLASS 0x02 +#define CONFIG_DEVICE_CLASS 0x06 /* Individual channel config commands */ -#define CMD_MSG_SET_IP_HDR_CHANNEL_LEN 58 -#define CMD_MSG_SET_IP_HDR_CHANNEL(s,c,t2,t1) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00) >> 8),(c&0x00FF), 0x26, 0x00, 0x00,0x02,0x00,0x90, 0x00,0x00, \ - 0x00,0x00, 0x45,0x00, 0x00,0x00, 0x00,0x00, 0x40,0x00, 0x80,0x11, 0x00,0x00, \ - 0xC0,0xA8,0x09,0x03, 0xC0,0xA8,0x09,0x03, \ - ((t2&0xFF00)>>8)+0x50,(t2&0x00FF), ((t1&0xFF00)>>8)+0x50,(t1&0x00FF), 0x00,0x00, 0x00,0x00 } -#define CMD_MSG_VOIP_VCEOPT_LEN 40 -#define CMD_MSG_VOIP_VCEOPT(s,c,l,w) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x12, 0x00, 0x00,0x02,0x01,0x80, 0x00,0x00, \ - 0x21,l, 0x00,0x1C, 0x04,0x00, 0x00,0x00, w,0x00, 0x80,0x11 } -#define CMD_MSG_VOIP_VOPENA_LEN 44 -#define CMD_MSG_VOIP_VOPENA(s,c,f) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x16, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \ - 0x01,0x00, 0x80,f, 0x00,0x00, 0x00,0x00, 0x00,0x00, 0x12,0x34, 0x56,0x78, 0x00,0x00 } -#define CMD_MSG_VOIP_VOPENA_CLOSE_LEN 32 -#define CMD_MSG_VOIP_VOPENA_CLOSE(s,c) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x00,0x80, 0x00,0x00, \ - 0x00,0x00, 0x00,0x00 } -#define CMD_MSG_VOIP_INDCTRL_LEN 32 -#define CMD_MSG_VOIP_INDCTRL(s,c) {0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x84,0x80, 0x00,0x00, \ - 0x07,0x00, 0x00,0x00 } -#define CMD_MSG_VOIP_DTMFOPT_LEN 32 -#define CMD_MSG_VOIP_DTMFOPT(s,c) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x02,0x80, 0x00,0x00, \ - 0x08,0x00, 0x00,0x00 } - -#define CMD_MSG_VOIP_TONECTL_LEN 32 -#define CMD_MSG_VOIP_TONECTL(s,c) { \ - 0x00,0x11,0x22,0x33,0x44,0x55, 0xAA,0xBB,0xCC,0xDD,0xEE,0xFF, 0x88,0x9B, \ - 0x00,0x01, s&0x0F, 0x01, ((c&0xFF00)>>8),(c&0x00FF), 0x0A, 0x00, 0x00,0x02,0x5B,0x80, 0x00,0x00, \ - 0x00,0x00, 0x00,0x00 } - #define MAX_FRAME_SIZE 1518 -#define SFRAME_SIZE MAX_FRAME_SIZE +#define SFRAME_SIZE MAX_FRAME_SIZE /* Transcoder buffer (tcb) */ struct tcb { @@ -343,7 +201,7 @@ struct tcb { #define TX_COMPLETE (1 << 1) #define DO_NOT_CAPTURE (1 << 2) #define __WAIT_FOR_ACK (1 << 3) -#define __WAIT_FOR_RESPONSE (1 << 4) +#define __WAIT_FOR_RESPONSE (1 << 4) #define DTE_CMD_TIMEOUT (1 << 5) #define WAIT_FOR_ACK (__WAIT_FOR_ACK | DO_NOT_AUTO_FREE) #define WAIT_FOR_RESPONSE (__WAIT_FOR_RESPONSE | DO_NOT_AUTO_FREE) @@ -353,15 +211,23 @@ struct tcb { struct timer_list timer; void *data; /* The number of bytes available in data. */ - int data_len; + int data_len; }; -static inline void *hdr_from_cmd(struct tcb *cmd) { +static inline void *hdr_from_cmd(struct tcb *cmd) +{ return cmd->data; } -static inline void -initialize_cmd(struct tcb *cmd, unsigned long cmd_flags) +static inline const struct csm_encaps_hdr * +response_header(struct tcb *cmd) +{ + BUG_ON(!cmd->response); + return (const struct csm_encaps_hdr *)(cmd)->response->data; +} + +static inline void +initialize_cmd(struct tcb *cmd, unsigned long cmd_flags) { memset(cmd, 0, sizeof(*cmd)); INIT_LIST_HEAD(&cmd->node); @@ -371,7 +237,7 @@ initialize_cmd(struct tcb *cmd, unsigned long cmd_flags) cmd->data_len = SFRAME_SIZE; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) /*! Used to allocate commands to submit to the dte. */ kmem_cache_t *cmd_cache; #else @@ -385,9 +251,8 @@ __alloc_cmd(gfp_t alloc_flags, unsigned long cmd_flags) struct tcb *cmd; cmd = kmem_cache_alloc(cmd_cache, alloc_flags); - if (likely(cmd)) { + if (likely(cmd)) initialize_cmd(cmd, cmd_flags); - } return cmd; } @@ -397,53 +262,43 @@ alloc_cmd(void) return __alloc_cmd(GFP_KERNEL, 0); } -static void +static void __free_cmd(struct tcb *cmd) { - if (cmd->data != &cmd->cmd[0]) { + if (cmd->data != &cmd->cmd[0]) kfree(cmd->data); - } kmem_cache_free(cmd_cache, cmd); return; } -static void +static void free_cmd(struct tcb *cmd) { - if (cmd->response) { + if (cmd->response) __free_cmd(cmd->response); - } __free_cmd(cmd); } -typedef enum { DECODER=0, ENCODER, } encode_t; - struct channel_stats { atomic_t packets_sent; atomic_t packets_received; }; struct channel_pvt { - spinlock_t lock; /* Lock for this structure */ - encode_t encoder; /* If we're an encoder */ + spinlock_t lock; /* Lock for this structure */ + int encoder; /* If we're an encoder */ struct wcdte *wc; - - unsigned int timestamp; - unsigned int seqno; - - unsigned int cmd_seqno; - - unsigned int timeslot_in_num; /* DTE channel on which results will be received from */ - unsigned int timeslot_out_num; /* DTE channel to send data to */ - - unsigned int chan_in_num; /* DTE channel on which results will be received from */ - unsigned int chan_out_num; /* DTE channel to send data to */ - + u32 timestamp; + u16 seqno; + u8 cmd_seqno; + u16 timeslot_in_num; /* DTE timeslot to receive from */ + u16 timeslot_out_num; /* DTE timeslot to send data to */ + u16 chan_in_num; /* DTE channel to receive from */ + u16 chan_out_num; /* DTE channel to send data to */ struct channel_stats stats; - u16 last_dte_seqno; - unsigned char ssrc; - struct list_head rx_queue; /* Transcoded packets for this channel. */ + u8 ssrc; + struct list_head rx_queue; /* Transcoded packets for this channel. */ }; struct wcdte { @@ -455,7 +310,7 @@ struct wcdte { wait_queue_head_t waitq; struct semaphore chansem; #define DTE_READY 1 -#define DTE_SHUTDOWN 2 +#define DTE_SHUTDOWN 2 unsigned long flags; spinlock_t cmd_list_lock; @@ -477,7 +332,7 @@ struct wcdte { unsigned long iobase; struct wctc4xxp_descriptor_ring *txd; struct wctc4xxp_descriptor_ring *rxd; - + struct dahdi_transcoder *uencode; struct dahdi_transcoder *udecode; struct channel_pvt *encoders; @@ -496,7 +351,7 @@ struct wcdte { struct sk_buff_head captured_packets; struct net_device *netdev; struct net_device_stats net_stats; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,24) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 24) struct napi_struct napi; #endif struct timer_list watchdog; @@ -522,40 +377,16 @@ wcdte_from_netdev(struct net_device *netdev) } -static inline void wctc4xxp_set_ready(struct wcdte *wc) { +static inline void wctc4xxp_set_ready(struct wcdte *wc) +{ set_bit(DTE_READY, &wc->flags); } -static inline int wctc4xxp_is_ready(struct wcdte *wc) { + +static inline int wctc4xxp_is_ready(struct wcdte *wc) +{ return test_bit(DTE_READY, &wc->flags); } -#if 1 - /* \todo This macro is a candidate for removal. It's still here because of - * how the commands are passed to this dahdi_send_cmd */ -#define wctc4xxp_send_cmd(wc, command) ({ \ - int __res; \ - u8 _cmd[] = command; \ - struct tcb *__cmd; \ - if (!(__cmd=__alloc_cmd(GFP_KERNEL, WAIT_FOR_RESPONSE))) \ - return -ENOMEM; \ - BUG_ON(sizeof(_cmd) > SFRAME_SIZE); \ - memcpy(__cmd->data, _cmd, sizeof(_cmd)); \ - __cmd->data_len = sizeof(_cmd); \ - __res = __wctc4xxp_send_cmd(wc, __cmd); \ - __res; \ -}) -#define wctc4xxp_create_cmd(wc, command) ({ \ - u8 _command[] = command; \ - struct tcb *_cmd; \ - if (!(_cmd=__alloc_cmd(GFP_KERNEL, WAIT_FOR_RESPONSE))) \ - return -ENOMEM; \ - BUG_ON(sizeof(_command) > SFRAME_SIZE); \ - memcpy(_cmd->data, _command, sizeof(_command)); \ - _cmd->data_len = sizeof(_command); \ - _cmd; \ -}) -#endif - #define DTE_FORMAT_ULAW 0x00 #define DTE_FORMAT_G723_1 0x04 #define DTE_FORMAT_ALAW 0x08 @@ -565,29 +396,29 @@ static inline int wctc4xxp_is_ready(struct wcdte *wc) { static inline u8 wctc4xxp_dahdifmt_to_dtefmt(unsigned int fmt) { u8 pt; - - switch(fmt) { - case DAHDI_FORMAT_G723_1: - pt = DTE_FORMAT_G723_1; - break; - case DAHDI_FORMAT_ULAW: - pt = DTE_FORMAT_ULAW; - break; - case DAHDI_FORMAT_ALAW: - pt = DTE_FORMAT_ALAW; - break; - case DAHDI_FORMAT_G729A: - pt = DTE_FORMAT_G729A; - break; - default: - pt = DTE_FORMAT_UNDEF; - break; + + switch (fmt) { + case DAHDI_FORMAT_G723_1: + pt = DTE_FORMAT_G723_1; + break; + case DAHDI_FORMAT_ULAW: + pt = DTE_FORMAT_ULAW; + break; + case DAHDI_FORMAT_ALAW: + pt = DTE_FORMAT_ALAW; + break; + case DAHDI_FORMAT_G729A: + pt = DTE_FORMAT_G729A; + break; + default: + pt = DTE_FORMAT_UNDEF; + break; } return pt; } -static struct sk_buff * +static struct sk_buff * tcb_to_skb(struct net_device *netdev, const struct tcb *cmd) { struct sk_buff *skb; @@ -596,12 +427,12 @@ tcb_to_skb(struct net_device *netdev, const struct tcb *cmd) skb->dev = netdev; skb_put(skb, cmd->data_len); memcpy(skb->data, cmd->data, cmd->data_len); - skb->protocol = eth_type_trans(skb,netdev); + skb->protocol = eth_type_trans(skb, netdev); } return skb; } -/** +/** * wctc4xxp_skb_to_cmd - Convert a socket buffer (skb) to a tcb * @wc: The transcoder that we're going to send this command to. * @skb: socket buffer to convert. @@ -612,68 +443,58 @@ wctc4xxp_skb_to_cmd(struct wcdte *wc, const struct sk_buff *skb) { const gfp_t alloc_flags = in_interrupt() ? GFP_ATOMIC : GFP_KERNEL; struct tcb *cmd; - /* const static char dev_mac[] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; */ - if ((cmd = __alloc_cmd(alloc_flags, 0))) { + cmd = __alloc_cmd(alloc_flags, 0); + if (cmd) { int res; cmd->data_len = skb->len; - if ((res = skb_copy_bits(skb, 0, cmd->data, cmd->data_len))) { - DTE_PRINTK(WARNING, + res = skb_copy_bits(skb, 0, cmd->data, cmd->data_len); + if (res) { + DTE_PRINTK(WARNING, "Failed call to skb_copy_bits.\n"); free_cmd(cmd); cmd = NULL; } - /* When we set up our interface we indicated that we do not - * support ARP. Therefore, the destination MAC on packets - * arriving from the kernel networking components are not - * going to be correct. Let's fix that here. - */ - /* \todo let us just use whatever was in the packet already... */ - /* memcpy(&cmd->cmd[6], dev_mac, sizeof(dev_mac)); */ } return cmd; } -static void +static void wctc4xxp_net_set_multi(struct net_device *netdev) { struct wcdte *wc = wcdte_from_netdev(netdev); - DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n", - __FUNCTION__, netdev->promiscuity); + DTE_DEBUG(DTE_DEBUG_GENERAL, "%s promiscuity:%d\n", + __func__, netdev->promiscuity); } -static int +static int wctc4xxp_net_up(struct net_device *netdev) { struct wcdte *wc = wcdte_from_netdev(netdev); - DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__); -#if 1 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __func__); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) netif_poll_enable(netdev); #else napi_enable(&wc->napi); #endif -#endif return 0; } -static int +static int wctc4xxp_net_down(struct net_device *netdev) { struct wcdte *wc = wcdte_from_netdev(netdev); - DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __FUNCTION__); -#if 1 -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) + DTE_DEBUG(DTE_DEBUG_GENERAL, "%s\n", __func__); +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) netif_poll_disable(netdev); #else napi_disable(&wc->napi); #endif -#endif return 0; } static void wctc4xxp_transmit_cmd(struct wcdte *, struct tcb *); -static int +static int wctc4xxp_net_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) { struct wcdte *wc = wcdte_from_netdev(netdev); @@ -681,10 +502,11 @@ wctc4xxp_net_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) /* We set DO_NOT_CAPTURE because this packet was already captured by * in code higher up in the networking stack. We don't want to - * capture it twice. + * capture it twice. */ - if ((cmd = wctc4xxp_skb_to_cmd(wc, skb))) { - cmd->flags |= DO_NOT_CAPTURE; + cmd = wctc4xxp_skb_to_cmd(wc, skb); + if (cmd) { + cmd->flags |= DO_NOT_CAPTURE; wctc4xxp_transmit_cmd(wc, cmd); } @@ -692,7 +514,7 @@ wctc4xxp_net_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) return NETDEV_TX_OK; } -static int +static int wctc4xxp_net_receive(struct wcdte *wc, int max) { int count = 0; @@ -700,15 +522,14 @@ wctc4xxp_net_receive(struct wcdte *wc, int max) WARN_ON(0 == max); while ((skb = skb_dequeue(&wc->captured_packets))) { netif_receive_skb(skb); - if (++count >= max) { + if (++count >= max) break; - } } return count; } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) -static int +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) +static int wctc4xxp_poll(struct net_device *netdev, int *budget) { struct wcdte *wc = wcdte_from_netdev(netdev); @@ -728,7 +549,7 @@ wctc4xxp_poll(struct net_device *netdev, int *budget) } } #else -static int +static int wctc4xxp_poll(struct napi_struct *napi, int budget) { struct wcdte *wc = container_of(napi, struct wcdte, napi); @@ -755,20 +576,20 @@ wctc4xxp_net_get_stats(struct net_device *netdev) } /* Wait until this device is put into promiscuous mode, or we timeout. */ -static void +static void wctc4xxp_net_waitfor_promiscuous(struct wcdte *wc) { unsigned int seconds = 15; unsigned long start = jiffies; struct net_device *netdev = wc->netdev; - DTE_PRINTK(INFO, + DTE_PRINTK(INFO, "Waiting %d seconds for adapter to be placed in " \ "promiscuous mode for early trace.\n", seconds); while (!netdev->promiscuity) { if (signal_pending(current)) { - DTE_PRINTK(INFO, + DTE_PRINTK(INFO, "Aborting wait due to signal.\n"); break; } @@ -784,11 +605,11 @@ wctc4xxp_net_waitfor_promiscuous(struct wcdte *wc) static int wctc4xxp_turn_off_booted_led(struct wcdte *wc); static void wctc4xxp_turn_on_booted_led(struct wcdte *wc); -static int +static int wctc4xxp_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) { struct wcdte *wc = wcdte_from_netdev(netdev); - switch(cmd) { + switch (cmd) { case 0x89f0: down(&wc->chansem); wctc4xxp_turn_off_booted_led(wc); @@ -803,15 +624,15 @@ wctc4xxp_net_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) return 0; } -/** +/** * wctc4xxp_net_register - Register a new network interface. * @wc: transcoder card to register the interface for. * * The network interface is primarily used for debugging in order to watch the * traffic between the transcoder and the host. - * + * */ -static int +static int wctc4xxp_net_register(struct wcdte *wc) { int res; @@ -842,15 +663,16 @@ wctc4xxp_net_register(struct wcdte *wc) netdev->do_ioctl = &wctc4xxp_net_ioctl; netdev->promiscuity = 0; netdev->flags |= IFF_NOARP; -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) netdev->poll = &wctc4xxp_poll; netdev->weight = 64; # else netif_napi_add(netdev, &wc->napi, &wctc4xxp_poll, 64); # endif - if ((res = register_netdev(netdev))) { - DTE_PRINTK(WARNING, + res = register_netdev(netdev); + if (res) { + DTE_PRINTK(WARNING, "Failed to register network device %s.\n", wc->board_name); goto error_sw; @@ -859,33 +681,29 @@ wctc4xxp_net_register(struct wcdte *wc) wc->netdev = netdev; skb_queue_head_init(&wc->captured_packets); - if (debug & DTE_DEBUG_NETWORK_EARLY) { + if (debug & DTE_DEBUG_NETWORK_EARLY) wctc4xxp_net_waitfor_promiscuous(wc); - } - DTE_PRINTK(DEBUG, + DTE_PRINTK(DEBUG, "Created network device %s for debug.\n", wc->board_name); return 0; error_sw: - if (netdev) free_netdev(netdev); + if (netdev) + free_netdev(netdev); return res; } -static void +static void wctc4xxp_net_unregister(struct wcdte *wc) { struct sk_buff *skb; - if (!wc->netdev) { - return; - } + if (!wc->netdev) + return; unregister_netdev(wc->netdev); - - while ((skb = skb_dequeue(&wc->captured_packets))) { + while ((skb = skb_dequeue(&wc->captured_packets))) kfree_skb(skb); - } - free_netdev(wc->netdev); wc->netdev = NULL; } @@ -897,29 +715,27 @@ wctc4xxp_net_unregister(struct wcdte *wc) * @cmd: command to send to network stack. * */ -static void +static void wctc4xxp_net_capture_cmd(struct wcdte *wc, const struct tcb *cmd) { struct sk_buff *skb; struct net_device *netdev = wc->netdev; - if (!netdev) { + if (!netdev) return; - } /* No need to capture if there isn't anyone listening. */ - if (!(netdev->flags & IFF_UP)) { + if (!(netdev->flags & IFF_UP)) return; - } - + if (skb_queue_len(&wc->captured_packets) > MAX_CAPTURED_PACKETS) { WARN_ON_ONCE(1); return; } - if (!(skb = tcb_to_skb(netdev, cmd))) { + skb = tcb_to_skb(netdev, cmd); + if (!skb) return; - } skb_queue_tail(&wc->captured_packets, skb); # if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 24) @@ -947,7 +763,7 @@ struct wctc4xxp_descriptor { struct wctc4xxp_descriptor_ring { /* Pointer to an array of descriptors to give to hardware. */ - struct wctc4xxp_descriptor* desc; + struct wctc4xxp_descriptor *desc; /* Read completed buffers from the head. */ unsigned int head; /* Write ready buffers to the tail. */ @@ -972,54 +788,52 @@ struct wctc4xxp_descriptor_ring { * wctc4xxp_descriptor - Returns the desriptor at index. * @dr: The descriptor ring we're using. * @index: index of the descriptor we want. - * + * * We need this function because we do not know what the padding on the * descriptors will be. Otherwise, we would just use an array. */ static inline struct wctc4xxp_descriptor * wctc4xxp_descriptor(struct wctc4xxp_descriptor_ring *dr, int index) { - return (struct wctc4xxp_descriptor *)((u8*)dr->desc + + return (struct wctc4xxp_descriptor *)((u8 *)dr->desc + ((sizeof(*dr->desc) + dr->padding) * index)); } static int -wctc4xxp_initialize_descriptor_ring(struct pci_dev *pdev, struct wctc4xxp_descriptor_ring *dr, - u32 des1, unsigned int direction) +wctc4xxp_initialize_descriptor_ring(struct pci_dev *pdev, + struct wctc4xxp_descriptor_ring *dr, u32 des1, unsigned int direction) { - int i; + int i; const u32 END_OF_RING = 0x02000000; u8 cache_line_size = 0; struct wctc4xxp_descriptor *d; + int add_padding; BUG_ON(!pdev); BUG_ON(!dr); - if (pci_read_config_byte(pdev, 0x0c, &cache_line_size)) { - /* \todo Print an error message... */ + if (pci_read_config_byte(pdev, 0x0c, &cache_line_size)) return -EIO; - } memset(dr, 0, sizeof(*dr)); /* * Add some padding to each descriptor to ensure that they are - * aligned on host system cache-line boundaries, but only for the + * aligned on host system cache-line boundaries, but only for the * cache-line sizes that we support. * */ - if ((0x08 == cache_line_size) || (0x10 == cache_line_size) || - (0x20 == cache_line_size)) - { + add_padding = (0x08 == cache_line_size) || + (0x10 == cache_line_size) || + (0x20 == cache_line_size); + if (add_padding) dr->padding = (cache_line_size*sizeof(u32)) - sizeof(*d); - } - dr->desc = pci_alloc_consistent(pdev, + dr->desc = pci_alloc_consistent(pdev, (sizeof(*d)+dr->padding)*DRING_SIZE, &dr->desc_dma); - if (!dr->desc) { + if (!dr->desc) return -ENOMEM; - } memset(dr->desc, 0, (sizeof(*d) + dr->padding) * DRING_SIZE); for (i = 0; i < DRING_SIZE; ++i) { @@ -1036,12 +850,12 @@ wctc4xxp_initialize_descriptor_ring(struct pci_dev *pdev, struct wctc4xxp_descri #define OWN_BIT cpu_to_le32(0x80000000) #define OWNED(_d_) (((_d_)->des0)&OWN_BIT) -#define SET_OWNED(_d_) do { wmb(); (_d_)->des0 |= OWN_BIT; wmb();} while (0) +#define SET_OWNED(_d_) do { wmb(); (_d_)->des0 |= OWN_BIT; wmb(); } while (0) static const unsigned int BUFFER1_SIZE_MASK = 0x7ff; -static int -wctc4xxp_submit(struct wctc4xxp_descriptor_ring* dr, struct tcb *c) +static int +wctc4xxp_submit(struct wctc4xxp_descriptor_ring *dr, struct tcb *c) { volatile struct wctc4xxp_descriptor *d; unsigned int len; @@ -1055,7 +869,7 @@ wctc4xxp_submit(struct wctc4xxp_descriptor_ring* dr, struct tcb *c) } spin_lock_irqsave(&dr->lock, flags); - d = wctc4xxp_descriptor(dr, dr->tail); + d = wctc4xxp_descriptor(dr, dr->tail); WARN_ON(!d); if (d->buffer1) { spin_unlock_irqrestore(&dr->lock, flags); @@ -1064,10 +878,10 @@ wctc4xxp_submit(struct wctc4xxp_descriptor_ring* dr, struct tcb *c) } d->des1 &= cpu_to_le32(~(BUFFER1_SIZE_MASK)); d->des1 |= cpu_to_le32(len & BUFFER1_SIZE_MASK); - d->buffer1 = pci_map_single(dr->pdev, c->data, - SFRAME_SIZE, dr->direction); + d->buffer1 = pci_map_single(dr->pdev, c->data, + SFRAME_SIZE, dr->direction); - SET_OWNED(d); /* That's it until the hardware is done with it. */ + SET_OWNED(d); /* That's it until the hardware is done with it. */ dr->pending[dr->tail] = c; dr->tail = ++dr->tail & DRING_MASK; ++dr->count; @@ -1075,7 +889,7 @@ wctc4xxp_submit(struct wctc4xxp_descriptor_ring* dr, struct tcb *c) return 0; } -static inline struct tcb* +static inline struct tcb* wctc4xxp_retrieve(struct wctc4xxp_descriptor_ring *dr) { volatile struct wctc4xxp_descriptor *d; @@ -1085,11 +899,11 @@ wctc4xxp_retrieve(struct wctc4xxp_descriptor_ring *dr) spin_lock_irqsave(&dr->lock, flags); d = wctc4xxp_descriptor(dr, head); if (d->buffer1 && !OWNED(d)) { - pci_unmap_single(dr->pdev, d->buffer1, - SFRAME_SIZE, dr->direction); + pci_unmap_single(dr->pdev, d->buffer1, + SFRAME_SIZE, dr->direction); c = dr->pending[head]; WARN_ON(!c); - dr->head = (++head) & DRING_MASK; + dr->head = (++head) & DRING_MASK; d->buffer1 = 0; --dr->count; WARN_ON(!c); @@ -1102,7 +916,7 @@ wctc4xxp_retrieve(struct wctc4xxp_descriptor_ring *dr) return c; } -static inline int wctc4xxp_getcount(struct wctc4xxp_descriptor_ring *dr) +static inline int wctc4xxp_getcount(struct wctc4xxp_descriptor_ring *dr) { int count; unsigned long flags; @@ -1112,19 +926,19 @@ static inline int wctc4xxp_getcount(struct wctc4xxp_descriptor_ring *dr) return count; } -static inline void +static inline void __wctc4xxp_setctl(struct wcdte *wc, unsigned int addr, unsigned int val) { outl(val, wc->iobase + addr); } -static inline unsigned int +static inline unsigned int __wctc4xxp_getctl(struct wcdte *wc, unsigned int addr) { return inl(wc->iobase + addr); } -static inline void +static inline void wctc4xxp_setctl(struct wcdte *wc, unsigned int addr, unsigned int val) { spin_lock_bh(&wc->reglock); @@ -1132,13 +946,13 @@ wctc4xxp_setctl(struct wcdte *wc, unsigned int addr, unsigned int val) spin_unlock_bh(&wc->reglock); } -static inline void -wctc4xxp_receive_demand_poll(struct wcdte *wc) +static inline void +wctc4xxp_receive_demand_poll(struct wcdte *wc) { __wctc4xxp_setctl(wc, 0x0010, 0x00000000); } -static inline void +static inline void wctc4xxp_transmit_demand_poll(struct wcdte *wc) { __wctc4xxp_setctl(wc, 0x0008, 0x00000000); @@ -1154,7 +968,8 @@ wctc4xxp_transmit_demand_poll(struct wcdte *wc) /* Returns the size, in bytes, of a CSM_ENCAPS packet, given the number of * parameters used. */ -#define SIZE_WITH_N_PARAMETERS(__n) (sizeof(struct csm_encaps_hdr) + ((__n) * (sizeof(u16)))) +#define SIZE_WITH_N_PARAMETERS(__n) (sizeof(struct csm_encaps_hdr) + \ + ((__n) * (sizeof(u16)))) /* There are 20 bytes in the ethernet header and the common CSM_ENCAPS header * that we don't want in the length of the actual CSM_ENCAPS command */ @@ -1163,7 +978,9 @@ wctc4xxp_transmit_demand_poll(struct wcdte *wc) static const u8 dst_mac[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55}; static const u8 src_mac[6] = {0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF}; -static void +static int wctc4xxp_transmit_cmd_and_wait(struct wcdte *wc, struct tcb *cmd); + +static void setup_common_header(struct wcdte *wc, struct csm_encaps_hdr *hdr) { memcpy(hdr->ethhdr.h_dest, dst_mac, sizeof(dst_mac)); @@ -1171,7 +988,7 @@ setup_common_header(struct wcdte *wc, struct csm_encaps_hdr *hdr) hdr->ethhdr.h_proto = cpu_to_be16(ETH_P_CSM_ENCAPS); } -static void +static void setup_supervisor_header(struct wcdte *wc, struct csm_encaps_hdr *hdr) { setup_common_header(wc, hdr); @@ -1182,132 +999,454 @@ setup_supervisor_header(struct wcdte *wc, struct csm_encaps_hdr *hdr) hdr->channel = cpu_to_be16(SUPERVISOR_CHANNEL); } -static void -__wctc4xxp_create_channel_cmd(struct wcdte *wc, struct tcb *cmd, u16 timeslot) +static void +setup_channel_header(struct channel_pvt *pvt, struct csm_encaps_hdr *hdr) { - struct csm_create_channel_cmd *c; - c = hdr_from_cmd(cmd); + setup_common_header(pvt->wc, hdr); + hdr->op_code = cpu_to_be16(CONTROL_PACKET_OPCODE); + hdr->seq_num = (pvt->cmd_seqno++)&0xf; + hdr->channel = cpu_to_be16(pvt->chan_in_num); +} - BUG_ON(timeslot > 0x01ff); +static void +create_supervisor_cmd(struct wcdte *wc, struct tcb *cmd, u8 type, u8 class, + u16 function, const u16 *parameters, int num_parameters) +{ + struct csm_encaps_hdr *hdr = cmd->data; + int i; + + if (cmd->response) { + free_cmd(cmd->response); + cmd->response = NULL; + } - setup_supervisor_header(wc, &c->hdr); + setup_supervisor_header(wc, hdr); - c->hdr.length = LENGTH_WITH_N_PARAMETERS(2); - c->hdr.index = 0x0; - c->hdr.type = CONFIG_CHANGE_TYPE; - c->hdr.class = CONFIG_DEVICE_CLASS; - c->hdr.function = cpu_to_le16(SUPVSR_CREATE_CHANNEL); - c->hdr.reserved = 0x0000; + hdr->length = LENGTH_WITH_N_PARAMETERS(num_parameters); + hdr->index = 0; + hdr->type = type; + hdr->class = class; + hdr->function = cpu_to_le16(function); + hdr->reserved = 0; - c->channel_type = cpu_to_le16(0x0002); /* Channel type is VoIP */ - c->timeslot = cpu_to_le16(timeslot); + for (i = 0; i < num_parameters; ++i) + hdr->params[i] = cpu_to_le16(parameters[i]); - cmd->flags |= WAIT_FOR_RESPONSE; - cmd->data_len = sizeof(*c); + cmd->flags = WAIT_FOR_RESPONSE; + cmd->data_len = SIZE_WITH_N_PARAMETERS(num_parameters); } -static struct tcb * -wctc4xxp_create_channel_cmd(struct wcdte *wc, u16 timeslot) +static void +create_channel_cmd(struct channel_pvt *pvt, struct tcb *cmd, u8 type, u8 class, + u16 function, const u16 *parameters, int num_parameters) { - struct tcb *cmd; - if (!(cmd = alloc_cmd())) { - return NULL; + int i; + struct csm_encaps_hdr *hdr = cmd->data; + + if (cmd->response) { + free_cmd(cmd->response); + cmd->response = NULL; } - __wctc4xxp_create_channel_cmd(wc, cmd, timeslot); - return cmd; + + setup_channel_header(pvt, hdr); + + hdr->length = LENGTH_WITH_N_PARAMETERS(num_parameters); + hdr->index = 0; + hdr->type = type; + hdr->class = class; + hdr->function = cpu_to_le16(function); + hdr->reserved = 0; + + for (i = 0; i < num_parameters; ++i) + hdr->params[i] = cpu_to_le16(parameters[i]); + + cmd->flags = WAIT_FOR_RESPONSE; + cmd->data_len = SIZE_WITH_N_PARAMETERS(num_parameters); } -static void -__wctc4xxp_create_set_arm_clk_cmd(struct wcdte *wc, struct tcb *cmd) +static int +send_create_channel_cmd(struct wcdte *wc, struct tcb *cmd, u16 timeslot, + u16 *channel_number) { - struct csm_encaps_hdr *hdr = cmd->data; - BUG_ON(SIZE_WITH_N_PARAMETERS(2) > cmd->data_len); + int res; + const u16 parameters[] = {0x0002, timeslot}; - setup_supervisor_header(wc, hdr); + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, CONFIG_DEVICE_CLASS, + SUPVSR_CREATE_CHANNEL, parameters, ARRAY_SIZE(parameters)); - hdr->length = LENGTH_WITH_N_PARAMETERS(2); - hdr->index = 0x0; - hdr->type = CONFIG_CHANGE_TYPE; - hdr->class = CONFIG_DEVICE_CLASS; - hdr->function = cpu_to_le16(0x0411); - hdr->reserved = 0x0000; - hdr->params[0] = cpu_to_le16(0x012c); - hdr->params[1] = cpu_to_le16(0x0000); - - cmd->flags |= WAIT_FOR_RESPONSE; - cmd->data_len = SIZE_WITH_N_PARAMETERS(2); - return; + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + + if (0x0000 != response_header(cmd)->params[0]) { + /* The DTE failed to create the channel. */ + /* TODO put some debug information here. */ + WARN_ON(1); + free_cmd(cmd->response); + cmd->response = NULL; + return -EIO; + } + *channel_number = le16_to_cpu(response_header(cmd)->params[1]); + free_cmd(cmd->response); + cmd->response = NULL; + return 0; +} + +static int +send_set_arm_clk_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x012c, 0x0000}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0411, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_set_spu_clk_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x012c, 0x0000}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0412, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_tdm_select_bus_mode_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0004}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0417, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_set_eth_header_cmd(struct wcdte *wc, struct tcb *cmd, + const u8 *host_mac, const u8 *assigned_mac) +{ + u16 parameters[8]; + u16 *part; + + parameters[0] = 0x0001; + part = (u16 *)host_mac; + parameters[1] = part[0]; + parameters[2] = part[1]; + parameters[3] = part[2]; + part = (u16 *)assigned_mac; + parameters[4] = part[0]; + parameters[5] = part[1]; + parameters[6] = part[2]; + parameters[7] = 0x0008; + + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0100, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_supvsr_setup_tdm_parms(struct wcdte *wc, struct tcb *cmd, + u8 bus_number) +{ + const u16 parameters[] = {0x8380, 0x0c00, 0, (bus_number << 2)&0xc}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0407, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_ip_service_config_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0200}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0302, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_arp_service_config_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0001}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0105, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_icmp_service_config_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0xff01}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0304, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_device_set_country_code_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0000}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x041b, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_spu_features_control_cmd(struct wcdte *wc, struct tcb *cmd, u16 options) +{ + const u16 parameters[] = {options}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0013, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_tdm_opt_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0000}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0435, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_destroy_channel_cmd(struct wcdte *wc, struct tcb *cmd, u16 channel) +{ + int res; + u16 result; + const u16 parameters[] = {channel}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0011, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + /* Let's check the response for any error codes.... */ + result = le16_to_cpu(response_header(cmd)->params[0]); + if (0x0000 != result) { + DTE_PRINTK(ERR, "Failed to destroy channel %04d (%04x)\n", + channel, result); + return -EIO; + } + return 0; +} + +static int +send_set_ip_hdr_channel_cmd(struct channel_pvt *pvt, struct tcb *cmd) +{ + int res; + u16 result; + struct wcdte *wc = pvt->wc; + const u16 parameters[] = {0, 0x0045, 0, 0, 0x0040, 0x1180, 0, + 0xa8c0, 0x0309, 0xa8c0, 0x0309, + cpu_to_be16(pvt->timeslot_out_num + 0x5000), + cpu_to_be16(pvt->timeslot_in_num + 0x5000), + 0, 0}; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x9000, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + /* Let's check the response for any error codes.... */ + result = le16_to_cpu(response_header(cmd)->params[0]); + if (0x0000 != result) { + DTE_PRINTK(ERR, "Failure in %s (%04x)\n", + __func__, result); + return -EIO; + } + return 0; +} + +static int +send_voip_vceopt_cmd(struct channel_pvt *pvt, struct tcb *cmd, u16 length) +{ + int res; + u16 result; + const u16 parameters[] = {((length << 8)|0x21), 0x1c00, 0x0004, 0, 0}; + struct wcdte *wc = pvt->wc; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x8001, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + /* Let's check the response for any error codes.... */ + result = le16_to_cpu(response_header(cmd)->params[0]); + if (0x0000 != result) { + DTE_PRINTK(ERR, "Failure in %s (%04x)\n", + __func__, result); + return -EIO; + } + return 0; +} + +static int +send_voip_tonectl_cmd(struct channel_pvt *pvt, struct tcb *cmd) +{ + int res; + u16 result; + const u16 parameters[] = {0}; + struct wcdte *wc = pvt->wc; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x805b, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + /* Let's check the response for any error codes.... */ + result = le16_to_cpu(response_header(cmd)->params[0]); + if (0x0000 != result) { + DTE_PRINTK(ERR, "Failure in %s (%04x)\n", + __func__, result); + return -EIO; + } + return 0; +} + +static int +send_voip_dtmfopt_cmd(struct channel_pvt *pvt, struct tcb *cmd) +{ + const u16 parameters[] = {0x0008}; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x8002, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(pvt->wc, cmd); +} + +static int +send_voip_indctrl_cmd(struct channel_pvt *pvt, struct tcb *cmd) +{ + const u16 parameters[] = {0x0007}; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x8084, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(pvt->wc, cmd); +} + +static int +send_voip_vopena_cmd(struct channel_pvt *pvt, struct tcb *cmd, u8 format) +{ + const u16 parameters[] = {1, ((format<<8)|0x80), 0, 0, 0, + 0x3412, 0x7856}; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x8000, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(pvt->wc, cmd); +} + +static int +send_voip_vopena_close_cmd(struct channel_pvt *pvt, struct tcb *cmd) +{ + int res; + const u16 parameters[] = {0}; + create_channel_cmd(pvt, cmd, CONFIG_CHANGE_TYPE, CONFIG_CHANNEL_CLASS, + 0x8000, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(pvt->wc, cmd); + if (res) + return res; + /* Let's check the response for any error codes.... */ + if (0x0000 != response_header(cmd)->params[0]) { + WARN_ON(1); + return -EIO; + } + return 0; +} + +static int +send_ip_options_cmd(struct wcdte *wc, struct tcb *cmd) +{ + const u16 parameters[] = {0x0002}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x0306, parameters, ARRAY_SIZE(parameters)); + return wctc4xxp_transmit_cmd_and_wait(wc, cmd); +} + +static int +send_trans_connect_cmd(struct wcdte *wc, struct tcb *cmd, u16 enable, u16 + encoder_channel, u16 decoder_channel, u16 encoder_format, + u16 decoder_format) +{ + int res; + const u16 parameters[] = {enable, encoder_channel, encoder_format, + decoder_channel, decoder_format}; + create_supervisor_cmd(wc, cmd, CONFIG_CHANGE_TYPE, + CONFIG_DEVICE_CLASS, 0x9322, parameters, ARRAY_SIZE(parameters)); + res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); + if (res) + return res; + + /* Let's check the response for any error codes.... */ + if (0x0000 != response_header(cmd)->params[0]) { + WARN_ON(1); + return -EIO; + } + return 0; } static struct tcb * -wctc4xxp_create_rtp_cmd(struct wcdte *wc, struct dahdi_transcoder_channel *dtc, size_t inbytes) +wctc4xxp_create_rtp_cmd(struct wcdte *wc, struct dahdi_transcoder_channel *dtc, + size_t inbytes) { const struct channel_pvt *cpvt = dtc->pvt; struct rtp_packet *packet; struct tcb *cmd; - if (!(cmd = alloc_cmd())) { + cmd = alloc_cmd(); + if (!cmd) return NULL; - } packet = cmd->data; BUG_ON(cmd->data_len < sizeof(*packet)); - + /* setup the ethernet header */ memcpy(packet->ethhdr.h_dest, dst_mac, sizeof(dst_mac)); memcpy(packet->ethhdr.h_source, src_mac, sizeof(src_mac)); packet->ethhdr.h_proto = cpu_to_be16(ETH_P_IP); - + /* setup the IP header */ - packet->iphdr.ihl = 5; - packet->iphdr.version = 4; - packet->iphdr.tos = 0; - packet->iphdr.tot_len = cpu_to_be16(inbytes+40); - packet->iphdr.id = cpu_to_be16(cpvt->seqno); - packet->iphdr.frag_off= cpu_to_be16(0x4000); - packet->iphdr.ttl = 64; - packet->iphdr.protocol= 0x11; /* UDP */ - packet->iphdr.check = 0; - packet->iphdr.saddr = cpu_to_be32(0xc0a80903); - packet->iphdr.daddr = cpu_to_be32(0xc0a80903); - packet->iphdr.check = ip_fast_csum((void*)&packet->iphdr, sizeof(struct iphdr)); + packet->iphdr.ihl = 5; + packet->iphdr.version = 4; + packet->iphdr.tos = 0; + packet->iphdr.tot_len = cpu_to_be16(inbytes+40); + packet->iphdr.id = cpu_to_be16(cpvt->seqno); + packet->iphdr.frag_off = cpu_to_be16(0x4000); + packet->iphdr.ttl = 64; + packet->iphdr.protocol = 0x11; /* UDP */ + packet->iphdr.check = 0; + packet->iphdr.saddr = cpu_to_be32(0xc0a80903); + packet->iphdr.daddr = cpu_to_be32(0xc0a80903); + + packet->iphdr.check = ip_fast_csum((void *)&packet->iphdr, + sizeof(struct iphdr)); /* setup the UDP header */ packet->udphdr.source = cpu_to_be16(cpvt->timeslot_out_num + 0x5000); packet->udphdr.dest = cpu_to_be16(cpvt->timeslot_in_num + 0x5000); - packet->udphdr.len = cpu_to_be16(inbytes + sizeof(struct rtphdr) + sizeof(struct udphdr)); + packet->udphdr.len = cpu_to_be16(inbytes + sizeof(struct rtphdr) + + sizeof(struct udphdr)); packet->udphdr.check = 0; /* Setup the RTP header */ - packet->rtphdr.ver = 2; - packet->rtphdr.padding = 0; - packet->rtphdr.extension = 0; - packet->rtphdr.csrc_count = 0; - packet->rtphdr.marker = 0; - packet->rtphdr.type = wctc4xxp_dahdifmt_to_dtefmt(dtc->srcfmt); - packet->rtphdr.seqno = cpu_to_be16(cpvt->seqno); - packet->rtphdr.timestamp = cpu_to_be32(cpvt->timestamp); - packet->rtphdr.ssrc = cpu_to_be32(cpvt->ssrc); + packet->rtphdr.ver = 2; + packet->rtphdr.padding = 0; + packet->rtphdr.extension = 0; + packet->rtphdr.csrc_count = 0; + packet->rtphdr.marker = 0; + packet->rtphdr.type = wctc4xxp_dahdifmt_to_dtefmt(dtc->srcfmt); + packet->rtphdr.seqno = cpu_to_be16(cpvt->seqno); + packet->rtphdr.timestamp = cpu_to_be32(cpvt->timestamp); + packet->rtphdr.ssrc = cpu_to_be32(cpvt->ssrc); cmd->data_len = sizeof(*packet) + inbytes; return cmd; } static void -wctc4xxp_cleanup_descriptor_ring(struct wctc4xxp_descriptor_ring *dr) +wctc4xxp_cleanup_descriptor_ring(struct wctc4xxp_descriptor_ring *dr) { - int i; + int i; struct wctc4xxp_descriptor *d; unsigned long flags; - + /* NOTE: The DTE must be in the stopped state. */ spin_lock_irqsave(&dr->lock, flags); for (i = 0; i < DRING_SIZE; ++i) { d = wctc4xxp_descriptor(dr, i); if (d->buffer1) { - pci_unmap_single(dr->pdev, d->buffer1, - SFRAME_SIZE, dr->direction); + pci_unmap_single(dr->pdev, d->buffer1, + SFRAME_SIZE, dr->direction); d->buffer1 = 0; /* Commands will also be sitting on the waiting for * response list, so we want to make sure to delete @@ -1321,8 +1460,8 @@ wctc4xxp_cleanup_descriptor_ring(struct wctc4xxp_descriptor_ring *dr) dr->tail = 0; dr->count = 0; spin_unlock_irqrestore(&dr->lock, flags); - pci_free_consistent(dr->pdev, (sizeof(*d)+dr->padding) * DRING_SIZE, - dr->desc, dr->desc_dma); + pci_free_consistent(dr->pdev, (sizeof(*d)+dr->padding) * DRING_SIZE, + dr->desc, dr->desc_dma); } static void wctc4xxp_cleanup_command_list(struct wcdte *wc) @@ -1337,7 +1476,7 @@ static void wctc4xxp_cleanup_command_list(struct wcdte *wc) spin_unlock_bh(&wc->cmd_list_lock); while (!list_empty(&local_list)) { - cmd = list_entry(local_list.next, struct tcb, node); + cmd = list_entry(local_list.next, struct tcb, node); list_del_init(&cmd->node); free_cmd(cmd); } @@ -1345,10 +1484,10 @@ static void wctc4xxp_cleanup_command_list(struct wcdte *wc) /** * The command list is used to store commands that couldn't fit in the tx - * descriptor list when they were requested. + * descriptor list when they were requested. */ -static void -wctc4xxp_add_to_command_list(struct wcdte *wc, struct tcb *cmd) +static void +wctc4xxp_add_to_command_list(struct wcdte *wc, struct tcb *cmd) { spin_lock_bh(&wc->cmd_list_lock); list_add_tail(&cmd->node, &wc->cmd_list); @@ -1371,16 +1510,16 @@ wctc4xxp_remove_from_response_list(struct wcdte *wc, struct tcb *cmd) spin_unlock_bh(&wc->cmd_list_lock); } -static void +static void wctc4xxp_transmit_cmd(struct wcdte *wc, struct tcb *cmd) { int res; if (cmd->data_len < MIN_PACKET_LEN) { - memset((u8*)(cmd->data) + cmd->data_len, 0, + memset((u8 *)(cmd->data) + cmd->data_len, 0, MIN_PACKET_LEN-cmd->data_len); cmd->data_len = MIN_PACKET_LEN; - } + } WARN_ON(cmd->response); WARN_ON(cmd->flags & TX_COMPLETE); cmd->timeout = jiffies + HZ/4; @@ -1391,32 +1530,32 @@ wctc4xxp_transmit_cmd(struct wcdte *wc, struct tcb *cmd) * retry if we do not get the response within the * timeout period. */ struct csm_encaps_hdr *hdr = cmd->data; - hdr->control |= SUPPRESS_ACK; + hdr->control |= SUPPRESS_ACK; } WARN_ON(!list_empty(&cmd->node)); wctc4xxp_add_to_response_list(wc, cmd); mod_timer(&wc->watchdog, jiffies + HZ/2); } - if (!(cmd->flags & DO_NOT_CAPTURE)) wctc4xxp_net_capture_cmd(wc, cmd); - if ((res=wctc4xxp_submit(wc->txd, cmd))) { - if (-EBUSY == res) { - /* Looks like we're out of room in the descriptor - * ring. We'll add this command to the pending list - * and the interrupt service routine will pull from - * this list as it clears up room in the descriptor - * ring. */ - wctc4xxp_remove_from_response_list(wc, cmd); - wctc4xxp_add_to_command_list(wc, cmd); - } else { - /* Unknown return value... */ - WARN_ON(1); - } - } else { + if (!(cmd->flags & DO_NOT_CAPTURE)) + wctc4xxp_net_capture_cmd(wc, cmd); + res = wctc4xxp_submit(wc->txd, cmd); + if (-EBUSY == res) { + /* Looks like we're out of room in the descriptor + * ring. We'll add this command to the pending list + * and the interrupt service routine will pull from + * this list as it clears up room in the descriptor + * ring. */ + wctc4xxp_remove_from_response_list(wc, cmd); + wctc4xxp_add_to_command_list(wc, cmd); + } else if (0 == res) { wctc4xxp_transmit_demand_poll(wc); + } else { + /* Unknown return value... */ + WARN_ON(1); } } -static int +static int wctc4xxp_transmit_cmd_and_wait(struct wcdte *wc, struct tcb *cmd) { cmd->flags |= DO_NOT_AUTO_FREE; @@ -1425,54 +1564,37 @@ wctc4xxp_transmit_cmd_and_wait(struct wcdte *wc, struct tcb *cmd) if (cmd->flags & DTE_CMD_TIMEOUT) { DTE_DEBUG(DTE_DEBUG_GENERAL, "Timeout waiting for command.\n"); return -EIO; - } + } return 0; } -static int wctc4xxp_create_channel_pair(struct wcdte *wc, - struct channel_pvt *cpvt, u8 simple, u8 complicated); -static int wctc4xxp_destroy_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt); +static int wctc4xxp_create_channel_pair(struct wcdte *wc, + struct channel_pvt *cpvt, u8 simple, u8 complicated); +static int wctc4xxp_destroy_channel_pair(struct wcdte *wc, + struct channel_pvt *cpvt); static int __wctc4xxp_setup_channels(struct wcdte *wc); -static int -__wctc4xxp_send_cmd(struct wcdte *wc, struct tcb *cmd) -{ - int ret = 0; - wctc4xxp_transmit_cmd(wc, cmd); - wait_for_completion(&cmd->complete); - if (cmd->flags & DTE_CMD_TIMEOUT) { - ret = -EIO; - } - free_cmd(cmd); - return ret; -} - -static void -wctc4xxp_init_state(struct channel_pvt *cpvt, encode_t encoder, - unsigned int channel, struct wcdte *wc) +static void +wctc4xxp_init_state(struct channel_pvt *cpvt, int encoder, + unsigned int channel, struct wcdte *wc) { memset(cpvt, 0, sizeof(*cpvt)); cpvt->encoder = encoder; cpvt->wc = wc; - cpvt->chan_in_num = INVALID; cpvt->chan_out_num = INVALID; - cpvt->ssrc = 0x78; - - cpvt->timeslot_in_num = channel* 2; - cpvt->timeslot_out_num = channel * 2; - - if (ENCODER == encoder) { - cpvt->timeslot_out_num++; - } else { - cpvt->timeslot_in_num++; - } + cpvt->timeslot_in_num = channel*2; + cpvt->timeslot_out_num = channel*2; + if (encoder) + ++cpvt->timeslot_out_num; + else + ++cpvt->timeslot_in_num; spin_lock_init(&cpvt->lock); INIT_LIST_HEAD(&cpvt->rx_queue); } -static unsigned int +static unsigned int wctc4xxp_getctl(struct wcdte *wc, unsigned int addr) { unsigned int val; @@ -1482,9 +1604,9 @@ wctc4xxp_getctl(struct wcdte *wc, unsigned int addr) return val; } -static void -wctc4xxp_cleanup_channel_private(struct wcdte *wc, struct - dahdi_transcoder_channel *dtc) +static void +wctc4xxp_cleanup_channel_private(struct wcdte *wc, + struct dahdi_transcoder_channel *dtc) { struct tcb *cmd, *temp; struct channel_pvt *cpvt = dtc->pvt; @@ -1503,7 +1625,7 @@ wctc4xxp_cleanup_channel_private(struct wcdte *wc, struct } static int -wctc4xxp_mark_channel_complement_built(struct wcdte *wc, +wctc4xxp_mark_channel_complement_built(struct wcdte *wc, struct dahdi_transcoder_channel *dtc) { int index; @@ -1514,17 +1636,17 @@ wctc4xxp_mark_channel_complement_built(struct wcdte *wc, BUG_ON(!cpvt); index = cpvt->timeslot_in_num/2; BUG_ON(index >= wc->numchannels); - if (cpvt->encoder == 1) { + if (cpvt->encoder) compl_dtc = &(wc->udecode->channels[index]); - } else { + else compl_dtc = &(wc->uencode->channels[index]); - } /* It shouldn't already have been built... */ WARN_ON(dahdi_tc_is_built(compl_dtc)); compl_dtc->built_fmts = dtc->dstfmt | dtc->srcfmt; compl_cpvt = compl_dtc->pvt; - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "dtc: %p is the complement to %p\n", compl_dtc, dtc); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "dtc: %p is the complement to %p\n", compl_dtc, dtc); compl_cpvt->chan_in_num = cpvt->chan_out_num; compl_cpvt->chan_out_num = cpvt->chan_in_num; dahdi_tc_set_built(compl_dtc); @@ -1533,7 +1655,7 @@ wctc4xxp_mark_channel_complement_built(struct wcdte *wc, return 0; } -static int +static int do_channel_allocate(struct dahdi_transcoder_channel *dtc) { struct channel_pvt *cpvt = dtc->pvt; @@ -1542,27 +1664,33 @@ do_channel_allocate(struct dahdi_transcoder_channel *dtc) u8 wctc4xxp_dstfmt; /* Digium Transcoder Engine Dest Format */ int res; +#ifndef DEBUG_WCTC4XXP down(&wc->chansem); +#else + if (down_interruptible(&wc->chansem)) + return -EINTR; +#endif /* Check again to see if the channel was built after grabbing the * channel semaphore, in case the previous holder of the semaphore * built this channel as a complement to itself. */ if (dahdi_tc_is_built(dtc)) { up(&wc->chansem); - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, - "Allocating channel %p which is already built.\n", dtc); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "Allocating channel %p which is already built.\n", dtc); return 0; } - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, - "Entering %s for channel %p.\n", __FUNCTION__, dtc); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "Entering %s for channel %p.\n", __func__, dtc); /* Anything on the rx queue now is old news... */ wctc4xxp_cleanup_channel_private(wc, dtc); - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Allocating a new channel: %p.\n", dtc); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "Allocating a new channel: %p.\n", dtc); wctc4xxp_srcfmt = wctc4xxp_dahdifmt_to_dtefmt(dtc->srcfmt); wctc4xxp_dstfmt = wctc4xxp_dahdifmt_to_dtefmt(dtc->dstfmt); - res = wctc4xxp_create_channel_pair(wc, cpvt, wctc4xxp_srcfmt, - wctc4xxp_dstfmt); + res = wctc4xxp_create_channel_pair(wc, cpvt, wctc4xxp_srcfmt, + wctc4xxp_dstfmt); if (res) { /* There was a problem creating the channel.... */ up(&wc->chansem); @@ -1574,7 +1702,8 @@ do_channel_allocate(struct dahdi_transcoder_channel *dtc) DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Channel %p has dstfmt=%x and srcfmt=%x\n", dtc, dtc->dstfmt, dtc->srcfmt); - /* Mark the channel complement (other half of encoder/decoder pair) as built */ + /* Mark the channel complement (other half of encoder/decoder pair) as + * built */ res = wctc4xxp_mark_channel_complement_built(wc, dtc); up(&wc->chansem); dahdi_transcoder_alert(dtc); @@ -1584,7 +1713,7 @@ do_channel_allocate(struct dahdi_transcoder_channel *dtc) static int wctc4xxp_operation_allocate(struct dahdi_transcoder_channel *dtc) { - struct wcdte *wc = ((struct channel_pvt*)(dtc->pvt))->wc; + struct wcdte *wc = ((struct channel_pvt *)(dtc->pvt))->wc; if (unlikely(test_bit(DTE_SHUTDOWN, &wc->flags))) { /* The shudown flags can also be set if there is a @@ -1593,8 +1722,8 @@ wctc4xxp_operation_allocate(struct dahdi_transcoder_channel *dtc) } if (dahdi_tc_is_built(dtc)) { - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, - "Allocating channel %p which is already built.\n", dtc); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "Allocating channel %p which is already built.\n", dtc); return 0; } return do_channel_allocate(dtc); @@ -1621,20 +1750,24 @@ wctc4xxp_operation_release(struct dahdi_transcoder_channel *dtc) return -EIO; } +#ifndef DEBUG_WCTC4XXP down(&wc->chansem); +#else + if (down_interruptible(&wc->chansem)) + return -EINTR; +#endif /* Remove any packets that are waiting on the outbound queue. */ wctc4xxp_cleanup_channel_private(wc, dtc); index = cpvt->timeslot_in_num/2; BUG_ON(index >= wc->numchannels); - if (ENCODER == cpvt->encoder) { + if (cpvt->encoder) compl_dtc = &(wc->udecode->channels[index]); - } else { + else compl_dtc = &(wc->uencode->channels[index]); - } BUG_ON(!compl_dtc); if (!dahdi_tc_is_built(compl_dtc)) { - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Releasing a channel that was never built.\n"); res = 0; goto error_exit; @@ -1645,9 +1778,10 @@ wctc4xxp_operation_release(struct dahdi_transcoder_channel *dtc) res = 0; goto error_exit; } - if ((res = wctc4xxp_destroy_channel_pair(wc, cpvt))) { + res = wctc4xxp_destroy_channel_pair(wc, cpvt); + if (res) goto error_exit; - } + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, "Releasing channel: %p\n", dtc); /* Mark this channel as not built */ dahdi_tc_clear_built(dtc); @@ -1665,7 +1799,7 @@ error_exit: return res; } -static inline struct tcb* +static inline struct tcb* get_ready_cmd(struct dahdi_transcoder_channel *dtc) { struct channel_pvt *cpvt = dtc->pvt; @@ -1673,20 +1807,19 @@ get_ready_cmd(struct dahdi_transcoder_channel *dtc) spin_lock_bh(&cpvt->lock); if (!list_empty(&cpvt->rx_queue)) { WARN_ON(!dahdi_tc_is_data_waiting(dtc)); - cmd = list_entry(cpvt->rx_queue.next, struct tcb, node); + cmd = list_entry(cpvt->rx_queue.next, struct tcb, node); list_del_init(&cmd->node); } else { cmd = NULL; } - if (list_empty(&cpvt->rx_queue)) { + if (list_empty(&cpvt->rx_queue)) dahdi_tc_clear_data_waiting(dtc); - } spin_unlock_bh(&cpvt->lock); return cmd; } /* Called with a buffer in which to copy a transcoded frame. */ -static ssize_t +static ssize_t wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos) { ssize_t ret; @@ -1707,30 +1840,35 @@ wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos) return -EIO; } - if (!(cmd = get_ready_cmd(dtc))) { + cmd = get_ready_cmd(dtc); + if (!cmd) { if (file->f_flags & O_NONBLOCK) { return -EAGAIN; } else { - ret = wait_event_interruptible(dtc->ready, - dahdi_tc_is_data_waiting(dtc)); + ret = wait_event_interruptible(dtc->ready, + dahdi_tc_is_data_waiting(dtc)); if (-ERESTARTSYS == ret) { /* Signal interrupted the wait */ return -EINTR; } else { /* List went not empty. */ cmd = get_ready_cmd(dtc); - } + } } } BUG_ON(!cmd); packet = cmd->data; - - payload_bytes = be16_to_cpu(packet->udphdr.len) - sizeof(struct rtphdr) - - sizeof(struct udphdr); + + payload_bytes = be16_to_cpu(packet->udphdr.len) - + sizeof(struct rtphdr) - sizeof(struct udphdr); if (count < payload_bytes) { - DTE_PRINTK(ERR, "Insufficient room to copy read data. Dropping packet.\n"); + if (printk_ratelimit()) { + DTE_PRINTK(ERR, + "Cannot copy %zd bytes into %zd byte user " \ + "buffer.\n", payload_bytes, count); + } free_cmd(cmd); return -EFBIG; } @@ -1744,15 +1882,15 @@ wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos) cpvt->last_dte_seqno = be16_to_cpu(packet->rtphdr.seqno); if (rtp_eseq != cpvt->last_dte_seqno) DTE_DEBUG(DTE_DEBUG_GENERAL, - "Bad seqno from DTE! [%04X][%d][%d][%d]\n", - be16_to_cpu(packet->rtphdr.seqno), + "Bad seqno from DTE! [%04X][%d][%d][%d]\n", + be16_to_cpu(packet->rtphdr.seqno), (be16_to_cpu(packet->udphdr.dest) - 0x5000), - be16_to_cpu(packet->rtphdr.seqno), + be16_to_cpu(packet->rtphdr.seqno), rtp_eseq); } if (unlikely(copy_to_user(frame, &packet->payload[0], payload_bytes))) { - DTE_PRINTK(ERR, "Failed to copy data in %s\n", __FUNCTION__); + DTE_PRINTK(ERR, "Failed to copy data in %s\n", __func__); free_cmd(cmd); return -EFAULT; } @@ -1762,9 +1900,10 @@ wctc4xxp_read(struct file *file, char __user *frame, size_t count, loff_t *ppos) return payload_bytes; } -/* Called with a frame in the srcfmt that is to be transcoded into the dstfmt. */ -static ssize_t -wctc4xxp_write(struct file *file, const char __user *frame, size_t count, loff_t *ppos) +/* Called with a frame in the srcfmt to be transcoded into the dstfmt. */ +static ssize_t +wctc4xxp_write(struct file *file, const char __user *frame, + size_t count, loff_t *ppos) { struct dahdi_transcoder_channel *dtc = file->private_data; struct channel_pvt *cpvt = dtc->pvt; @@ -1774,58 +1913,57 @@ wctc4xxp_write(struct file *file, const char __user *frame, size_t count, loff_t BUG_ON(!cpvt); BUG_ON(!wc); - if (unlikely(test_bit(DTE_SHUTDOWN, &wc->flags))) { - /* The shudown flags can also be set if there is a - * catastrophic failure. */ + if (unlikely(test_bit(DTE_SHUTDOWN, &wc->flags))) return -EIO; - } - if (!test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags)) { + if (!test_bit(DAHDI_TC_FLAG_CHAN_BUILT, &dtc->flags)) return -EAGAIN; - } if (count < 2) { - DTE_DEBUG(DTE_DEBUG_GENERAL, - "Cannot request to transcode a packet that is less than 2 bytes.\n"); + DTE_DEBUG(DTE_DEBUG_GENERAL, + "Cannot request to transcode a packet that is less than " \ + "2 bytes.\n"); return -EINVAL; } if (unlikely(count > SFRAME_SIZE - sizeof(struct rtp_packet))) { - DTE_DEBUG(DTE_DEBUG_GENERAL, + DTE_DEBUG(DTE_DEBUG_GENERAL, "Cannot transcode packet of %Zu bytes. This exceeds the " \ - "maximum size of %Zu bytes.\n", count, + "maximum size of %Zu bytes.\n", count, SFRAME_SIZE - sizeof(struct rtp_packet)); return -EINVAL; } if (DAHDI_FORMAT_G723_1 == dtc->srcfmt) { if ((G723_5K_BYTES != count) && (G723_6K_BYTES != count)) { - DTE_DEBUG(DTE_DEBUG_GENERAL, + DTE_DEBUG(DTE_DEBUG_GENERAL, "Trying to transcode packet into G723 format " \ "that is %Zu bytes instead of the expected " \ - "%d/%d bytes.\n", count, G723_5K_BYTES, G723_6K_BYTES); + "%d/%d bytes.\n", count, G723_5K_BYTES, + G723_6K_BYTES); return -EINVAL; } - cpvt->timestamp = G723_SAMPLES; + cpvt->timestamp += G723_SAMPLES; } else if (DAHDI_FORMAT_G723_1 == dtc->dstfmt) { cpvt->timestamp = G723_SAMPLES; } else { /* Same for ulaw and alaw */ - cpvt->timestamp = G729_SAMPLES; + cpvt->timestamp += G729_SAMPLES; } - if (!(cmd = wctc4xxp_create_rtp_cmd(wc, dtc, count))) { + cmd = wctc4xxp_create_rtp_cmd(wc, dtc, count); + if (!cmd) return -ENOMEM; - } /* Copy the data directly from user space into the command buffer. */ - if (copy_from_user(&((struct rtp_packet*)(cmd->data))->payload[0], frame, count)) { + if (copy_from_user(&((struct rtp_packet *)(cmd->data))->payload[0], + frame, count)) { DTE_PRINTK(ERR, "Failed to copy packet from userspace.\n"); free_cmd(cmd); return -EFAULT; } cpvt->seqno += 1; - DTE_DEBUG(DTE_DEBUG_RTP_TX, + DTE_DEBUG(DTE_DEBUG_RTP_TX, "Sending packet of %Zu byte on channel (%p).\n", count, dtc); wctc4xxp_transmit_cmd(wc, cmd); @@ -1834,12 +1972,13 @@ wctc4xxp_write(struct file *file, const char __user *frame, size_t count, loff_t return count; } -static void +static void wctc4xxp_send_ack(struct wcdte *wc, u8 seqno, __be16 channel) { struct tcb *cmd; struct csm_encaps_hdr *hdr; - if (!(cmd = __alloc_cmd(ALLOC_FLAGS, 0))) { + cmd = __alloc_cmd(ALLOC_FLAGS, 0); + if (!cmd) { WARN_ON(1); return; } @@ -1855,7 +1994,7 @@ wctc4xxp_send_ack(struct wcdte *wc, u8 seqno, __be16 channel) wctc4xxp_transmit_cmd(wc, cmd); } -static void +static void do_rx_response_packet(struct wcdte *wc, struct tcb *cmd) { const struct csm_encaps_hdr *listhdr; @@ -1865,7 +2004,8 @@ do_rx_response_packet(struct wcdte *wc, struct tcb *cmd) rxhdr = cmd->data; spin_lock_bh(&wc->cmd_list_lock); - list_for_each_entry_safe(pos, temp, &wc->waiting_for_response_list, node) { + list_for_each_entry_safe(pos, temp, + &wc->waiting_for_response_list, node) { listhdr = pos->data; if ((listhdr->function == rxhdr->function) && (listhdr->channel == rxhdr->channel)) { @@ -1880,7 +2020,7 @@ do_rx_response_packet(struct wcdte *wc, struct tcb *cmd) spin_unlock_bh(&wc->cmd_list_lock); } -static void +static void do_rx_ack_packet(struct wcdte *wc, struct tcb *cmd) { const struct csm_encaps_hdr *listhdr; @@ -1891,15 +2031,17 @@ do_rx_ack_packet(struct wcdte *wc, struct tcb *cmd) rxhdr = cmd->data; spin_lock_bh(&wc->cmd_list_lock); - list_for_each_entry_safe(pos, temp, &wc->waiting_for_response_list, node) { + list_for_each_entry_safe(pos, temp, + &wc->waiting_for_response_list, node) { listhdr = pos->data; if (cpu_to_be16(0xefed) == listhdr->ethhdr.h_proto) { wc->seq_num = (rxhdr->seq_num + 1) & 0xff; WARN_ON(!(pos->flags & DO_NOT_AUTO_FREE)); + WARN_ON(!(pos->flags & TX_COMPLETE)); list_del_init(&pos->node); WARN_ON(!(pos->flags & TX_COMPLETE)); complete(&pos->complete); - } else if ((listhdr->seq_num == rxhdr->seq_num) && + } else if ((listhdr->seq_num == rxhdr->seq_num) && (listhdr->channel == rxhdr->channel)) { if (pos->flags & __WAIT_FOR_RESPONSE) { pos->flags &= ~(__WAIT_FOR_ACK); @@ -1914,7 +2056,7 @@ do_rx_ack_packet(struct wcdte *wc, struct tcb *cmd) } } break; - } + } } spin_unlock_bh(&wc->cmd_list_lock); @@ -1922,7 +2064,7 @@ do_rx_ack_packet(struct wcdte *wc, struct tcb *cmd) free_cmd(cmd); } -static inline int +static inline int is_response(const struct csm_encaps_hdr *hdr) { return ((0x02 == hdr->type) || (0x04 == hdr->type)) ? 1 : 0; @@ -1942,7 +2084,7 @@ print_command(struct wcdte *wc, const struct tcb *cmd) DTE_PRINTK(DEBUG, "Failed print_command\n"); return; } - curlength = snprintf(buffer, BUFFER_SIZE, + curlength = snprintf(buffer, BUFFER_SIZE, "opcode: %04x seq: %02x control: %02x " "channel: %04x ", be16_to_cpu(hdr->op_code), hdr->seq_num, hdr->control, be16_to_cpu(hdr->channel)); @@ -1960,36 +2102,34 @@ print_command(struct wcdte *wc, const struct tcb *cmd) kfree(buffer); } -static void +static void receive_csm_encaps_packet(struct wcdte *wc, struct tcb *cmd) { const struct csm_encaps_hdr *hdr = cmd->data; if (!(hdr->control & MESSAGE_PACKET)) { - if (!(hdr->control & SUPPRESS_ACK)) { + if (!(hdr->control & SUPPRESS_ACK)) wctc4xxp_send_ack(wc, hdr->seq_num, hdr->channel); - } if (is_response(hdr)) { do_rx_response_packet(wc, cmd); } else if (0xc1 == hdr->type) { if (0x75 == hdr->class) { DTE_PRINTK(WARNING, - "Received alert (0x%04x) from dsp\n", + "Received alert (0x%04x) from dsp\n", le16_to_cpu(hdr->params[0])); } free_cmd(cmd); } else if (0xd4 == hdr->type) { if (hdr->params[0] != le16_to_cpu(0xffff)) { - DTE_PRINTK(WARNING, - "DTE Failed self test (%04x).\n", + DTE_PRINTK(WARNING, + "DTE Failed self test (%04x).\n", le16_to_cpu(hdr->params[0])); - } else if ((hdr->params[1] != le16_to_cpu(0x000c)) && - (hdr->params[1] != le16_to_cpu(0x010c))) - { - DTE_PRINTK(WARNING, - "Unexpected ERAM status (%04x).\n", + } else if ((hdr->params[1] != le16_to_cpu(0x000c)) && + (hdr->params[1] != le16_to_cpu(0x010c))) { + DTE_PRINTK(WARNING, + "Unexpected ERAM status (%04x).\n", le16_to_cpu(hdr->params[1])); } else { wctc4xxp_set_ready(wc); @@ -2001,7 +2141,8 @@ receive_csm_encaps_packet(struct wcdte *wc, struct tcb *cmd) print_command(wc, cmd); free_cmd(cmd); } else { - DTE_PRINTK(WARNING, "Unknown command type received. %02x\n", hdr->type); + DTE_PRINTK(WARNING, + "Unknown command type received. %02x\n", hdr->type); free_cmd(cmd); } } else { @@ -2009,7 +2150,7 @@ receive_csm_encaps_packet(struct wcdte *wc, struct tcb *cmd) } } -static void +static void queue_rtp_packet(struct wcdte *wc, struct tcb *cmd) { int index; @@ -2019,13 +2160,14 @@ queue_rtp_packet(struct wcdte *wc, struct tcb *cmd) index = (be16_to_cpu(packet->udphdr.dest) - 0x5000) / 2; if (unlikely(index >= wc->numchannels)) { - DTE_PRINTK(ERR, "Invalid channel number in response from DTE.\n"); + DTE_PRINTK(ERR, + "Invalid channel number in response from DTE.\n"); free_cmd(cmd); return; } switch (packet->rtphdr.type) { - case 0x00: + case 0x00: case 0x08: dtc = &(wc->udecode->channels[index]); break; @@ -2035,7 +2177,7 @@ queue_rtp_packet(struct wcdte *wc, struct tcb *cmd) break; default: DTE_PRINTK(ERR, "Unknown codec in packet (0x%02x).\n",\ - packet->rtphdr.type); + packet->rtphdr.type); free_cmd(cmd); return; } @@ -2049,18 +2191,18 @@ queue_rtp_packet(struct wcdte *wc, struct tcb *cmd) return; } -static inline void +static inline void wctc4xxp_receiveprep(struct wcdte *wc, struct tcb *cmd) { - const struct ethhdr *ethhdr = (const struct ethhdr*)(cmd->data); + const struct ethhdr *ethhdr = (const struct ethhdr *)(cmd->data); if (cpu_to_be16(ETH_P_IP) == ethhdr->h_proto) { queue_rtp_packet(wc, cmd); } else if (cpu_to_be16(ETH_P_CSM_ENCAPS) == ethhdr->h_proto) { receive_csm_encaps_packet(wc, cmd); } else { - DTE_PRINTK(WARNING, - "Unknown packet protocol recieved: %04x.\n", + DTE_PRINTK(WARNING, + "Unknown packet protocol recieved: %04x.\n", be16_to_cpu(ethhdr->h_proto)); free_cmd(cmd); } @@ -2094,9 +2236,8 @@ static inline void service_tx_ring(struct wcdte *wc) } spin_unlock_bh(&wc->cmd_list_lock); - if (cmd) { + if (cmd) wctc4xxp_transmit_cmd(wc, cmd); - } } } @@ -2105,7 +2246,6 @@ static inline void service_rx_ring(struct wcdte *wc) struct tcb *cmd; unsigned long flags; LIST_HEAD(local_list); - spin_lock_irqsave(&wc->rx_list_lock, flags); list_splice_init(&wc->rx_list, &local_list); spin_unlock_irqrestore(&wc->rx_list_lock, flags); @@ -2123,14 +2263,14 @@ static inline void service_rx_ring(struct wcdte *wc) wctc4xxp_receive_demand_poll(wc); } -static inline void service_dte(struct wcdte *wc) +static inline void service_dte(struct wcdte *wc) { service_tx_ring(wc); - service_rx_ring(wc); + service_rx_ring(wc); } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) static void deferred_work_func(void *param) { struct wcdte *wc = param; @@ -2156,7 +2296,7 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt) ints = __wctc4xxp_getctl(wc, 0x0028); ints &= wc->intmask; - + if (!ints) return IRQ_NONE; @@ -2186,13 +2326,16 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt) } reg |= RX_COMPLETE_INTERRUPT; } + #if DEFERRED_PROCESSING == WORKQUEUE schedule_work(&wc->deferred_work); #elif DEFERRED_PROCESSING == INTERRUPT -#error "You will need to change the locks if you want to run the processing in the interrupt handler." +#error "You will need to change the locks if you want to run the processing " \ + "in the interrupt handler." #else #error "Define a deferred processing function in kernel/wctc4xxp/wctc4xxp.h" #endif + __wctc4xxp_setctl(wc, 0x0028, reg); } else { if ((ints & 0x00008000) && debug) @@ -2215,9 +2358,6 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt) if ((ints & 0x00000008) && debug) DTE_PRINTK(INFO, "Jabber Timer Time-out INT\n"); - if ((ints & 0x00000004) && debug) - ; // printk("wcdte: Transmit Descriptor Unavailable INT\n"); - if ((ints & 0x00000002) && debug) DTE_PRINTK(INFO, "Transmit Processor Stopped INT\n"); @@ -2227,7 +2367,7 @@ DAHDI_IRQ_HANDLER(wctc4xxp_interrupt) return IRQ_HANDLED; } -static int +static int wctc4xxp_hardware_init(struct wcdte *wc) { /* Hardware stuff */ @@ -2235,16 +2375,15 @@ wctc4xxp_hardware_init(struct wcdte *wc) unsigned long newjiffies; u8 cache_line_size; const u32 DEFAULT_PCI_ACCESS = 0xfff80000; - + /* Enable I/O Access */ pci_read_config_dword(wc->pdev, 0x0004, ®); reg |= 0x00000007; pci_write_config_dword(wc->pdev, 0x0004, reg); - if (pci_read_config_byte(wc->pdev, 0x0c, &cache_line_size)) { - /* \todo Print an error message... */ + if (pci_read_config_byte(wc->pdev, 0x0c, &cache_line_size)) return -EIO; - } + switch (cache_line_size) { case 0x08: reg = DEFAULT_PCI_ACCESS | (0x1 << 14); @@ -2252,66 +2391,65 @@ wctc4xxp_hardware_init(struct wcdte *wc) case 0x10: reg = DEFAULT_PCI_ACCESS | (0x2 << 14); break; - case 0x20: + case 0x20: reg = DEFAULT_PCI_ACCESS | (0x3 << 14); break; default: reg = 0xfe584202; break; } - + reg |= ((wc->txd->padding / sizeof(u32)) << 2) & 0x7c; /* Reset the DTE... */ wctc4xxp_setctl(wc, 0x0000, reg | 1); newjiffies = jiffies + HZ; /* One second timeout */ /* ...and wait for it to come out of reset. */ - while(((wctc4xxp_getctl(wc,0x0000)) & 0x00000001) && (newjiffies > jiffies)) { + while (((wctc4xxp_getctl(wc, 0x0000)) & 0x00000001) && + (newjiffies > jiffies)) msleep(1); - } wctc4xxp_setctl(wc, 0x0000, reg); - + /* Configure watchdogs, access, etc */ wctc4xxp_setctl(wc, 0x0030, 0x00280048); - wctc4xxp_setctl(wc, 0x0078, 0x00000013 /* | (1 << 28) */); - + wctc4xxp_setctl(wc, 0x0078, 0x00000013); reg = wctc4xxp_getctl(wc, 0x00fc); wctc4xxp_setctl(wc, 0x00fc, (reg & ~0x7) | 0x7); - reg = wctc4xxp_getctl(wc, 0x00fc); - return 0; } -static void +static void wctc4xxp_setintmask(struct wcdte *wc, unsigned int intmask) { wc->intmask = intmask; wctc4xxp_setctl(wc, 0x0038, intmask); } -static void +static void wctc4xxp_enable_interrupts(struct wcdte *wc) { wctc4xxp_setintmask(wc, 0x000180c0); } -static void +static void wctc4xxp_start_dma(struct wcdte *wc) { int res; int i; u32 reg; struct tcb *cmd; - - for (i = 0; i < DRING_SIZE; ++i) { - if (!(cmd = alloc_cmd())) { + + for (i = 0; i < DRING_SIZE; ++i) { + cmd = alloc_cmd(); + if (!cmd) { WARN_ALWAYS(); return; } cmd->data_len = SFRAME_SIZE; - if ((res=wctc4xxp_submit(wc->rxd, cmd))) { + res = wctc4xxp_submit(wc->rxd, cmd); + if (res) { /* When we're starting the DMA, we should always be * able to fill the ring....so something is wrong * here. */ @@ -2326,14 +2464,14 @@ wctc4xxp_start_dma(struct wcdte *wc) /* Start receiver/transmitter */ reg = wctc4xxp_getctl(wc, 0x0030); - wctc4xxp_setctl(wc, 0x0030, reg | 0x00002002); /* Start XMT and RCD */ + wctc4xxp_setctl(wc, 0x0030, reg | 0x00002002); wctc4xxp_receive_demand_poll(wc); reg = wctc4xxp_getctl(wc, 0x0028); wctc4xxp_setctl(wc, 0x0028, reg); } -static void +static void wctc4xxp_stop_dma(struct wcdte *wc) { /* Disable interrupts and reset */ @@ -2350,13 +2488,13 @@ wctc4xxp_stop_dma(struct wcdte *wc) newjiffies = jiffies + HZ; /* One second timeout */ /* We'll wait here for the part to come out of reset */ - while(((wctc4xxp_getctl(wc,0x0000)) & 0x00000001) && (newjiffies > jiffies)) { - msleep(1); - } + while (((wctc4xxp_getctl(wc, 0x0000)) & 0x00000001) && + (newjiffies > jiffies)) + msleep(1); } -static void -wctc4xxp_disable_interrupts(struct wcdte *wc) +static void +wctc4xxp_disable_interrupts(struct wcdte *wc) { /* Disable interrupts */ wctc4xxp_setintmask(wc, 0x00000000); @@ -2369,7 +2507,7 @@ wctc4xxp_disable_interrupts(struct wcdte *wc) #define MDIO_ENB_IN 0x40000 #define MDIO_DATA_READ 0x80000 -static int +static int wctc4xxp_read_phy(struct wcdte *wc, int location) { int i; @@ -2378,28 +2516,33 @@ wctc4xxp_read_phy(struct wcdte *wc, int location) int retval = 0; /* Establish sync by sending at least 32 logic ones. */ - for (i = 32; i >= 0; i--) { - wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1); + for (i = 32; i >= 0; --i) { + wctc4xxp_setctl(wc, mdio_addr, + MDIO_ENB | MDIO_DATA_WRITE1); wctc4xxp_getctl(wc, mdio_addr); - wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK); + wctc4xxp_setctl(wc, mdio_addr, + MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK); wctc4xxp_getctl(wc, mdio_addr); } /* Shift the read command bits out. */ - for (i = 17; i >= 0; i--) { + for (i = 17; i >= 0; --i) { int dataval = (read_cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | dataval); wctc4xxp_getctl(wc, mdio_addr); - wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK); + wctc4xxp_setctl(wc, mdio_addr, + MDIO_ENB | dataval | MDIO_SHIFT_CLK); wctc4xxp_getctl(wc, mdio_addr); } /* Read the two transition, 16 data, and wire-idle bits. */ - for (i = 19; i > 0; i--) { + for (i = 19; i > 0; --i) { wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB_IN); wctc4xxp_getctl(wc, mdio_addr); - retval = (retval << 1) | ((wctc4xxp_getctl(wc, mdio_addr) & MDIO_DATA_READ) ? 1 : 0); + retval = (retval << 1) | + ((wctc4xxp_getctl(wc, mdio_addr) & MDIO_DATA_READ) ? + 1 : 0); wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK); wctc4xxp_getctl(wc, mdio_addr); } @@ -2407,7 +2550,7 @@ wctc4xxp_read_phy(struct wcdte *wc, int location) return retval; } -static void +static void wctc4xxp_write_phy(struct wcdte *wc, int location, int value) { int i; @@ -2415,22 +2558,24 @@ wctc4xxp_write_phy(struct wcdte *wc, int location, int value) long mdio_addr = 0x0048; /* Establish sync by sending 32 logic ones. */ - for (i = 32; i >= 0; i--) { + for (i = 32; i >= 0; --i) { wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1); wctc4xxp_getctl(wc, mdio_addr); - wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK); + wctc4xxp_setctl(wc, mdio_addr, + MDIO_ENB | MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK); wctc4xxp_getctl(wc, mdio_addr); } /* Shift the command bits out. */ - for (i = 31; i >= 0; i--) { + for (i = 31; i >= 0; --i) { int dataval = (cmd & (1 << i)) ? MDIO_DATA_WRITE1 : 0; wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | dataval); wctc4xxp_getctl(wc, mdio_addr); - wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB | dataval | MDIO_SHIFT_CLK); + wctc4xxp_setctl(wc, mdio_addr, + MDIO_ENB | dataval | MDIO_SHIFT_CLK); wctc4xxp_getctl(wc, mdio_addr); } /* Clear out extra bits. */ - for (i = 2; i > 0; i--) { + for (i = 2; i > 0; --i) { wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB_IN); wctc4xxp_getctl(wc, mdio_addr); wctc4xxp_setctl(wc, mdio_addr, MDIO_ENB_IN | MDIO_SHIFT_CLK); @@ -2446,7 +2591,7 @@ wctc4xxp_wait_for_link(struct wcdte *wc) unsigned int delay_count = 0; do { reg = wctc4xxp_getctl(wc, 0x00fc); - mdelay(2); + msleep(2); delay_count++; if (delay_count >= 5000) { @@ -2457,7 +2602,7 @@ wctc4xxp_wait_for_link(struct wcdte *wc) return 0; } -static int +static int wctc4xxp_load_firmware(struct wcdte *wc, const struct firmware *firmware) { unsigned int byteloc; @@ -2467,9 +2612,10 @@ wctc4xxp_load_firmware(struct wcdte *wc, const struct firmware *firmware) byteloc = 17; - if (!(cmd = alloc_cmd())) { + cmd = alloc_cmd(); + if (!cmd) return -ENOMEM; - } + if (MAX_FRAME_SIZE > cmd->data_len) { cmd->data = kmalloc(MAX_FRAME_SIZE, GFP_KERNEL); if (!(cmd->data)) { @@ -2480,7 +2626,8 @@ wctc4xxp_load_firmware(struct wcdte *wc, const struct firmware *firmware) } while (byteloc < (firmware->size-20)) { last_byteloc = byteloc; - length = (firmware->data[byteloc] << 8) | firmware->data[byteloc+1]; + length = (firmware->data[byteloc] << 8) | + firmware->data[byteloc+1]; byteloc += 2; cmd->data_len = length; BUG_ON(length > cmd->data_len); @@ -2494,7 +2641,7 @@ wctc4xxp_load_firmware(struct wcdte *wc, const struct firmware *firmware) DTE_PRINTK(ERR, "Failed to load firmware.\n"); return -EIO; } - } + } free_cmd(cmd); if (!wait_event_timeout(wc->waitq, wctc4xxp_is_ready(wc), 15*HZ)) { DTE_PRINTK(ERR, "Failed to boot firmware.\n"); @@ -2510,22 +2657,22 @@ wctc4xxp_turn_off_booted_led(struct wcdte *wc) int reg; /* Turn off auto negotiation */ wctc4xxp_write_phy(wc, 0, 0x2100); - DTE_DEBUG(DTE_DEBUG_GENERAL, "PHY register 0 = %X\n", + DTE_DEBUG(DTE_DEBUG_GENERAL, "PHY register 0 = %X\n", wctc4xxp_read_phy(wc, 0)); /* Set reset */ wctc4xxp_setctl(wc, 0x00A0, 0x04000000); /* Wait 4 ms to ensure processor reset */ - mdelay(4); + msleep(4); /* Clear reset */ wctc4xxp_setctl(wc, 0x00A0, 0x04080000); /* Wait for the ethernet link */ - if ((ret = wctc4xxp_wait_for_link(wc))) { + ret = wctc4xxp_wait_for_link(wc); + if (ret) return ret; - } /* Turn off booted LED */ wctc4xxp_setctl(wc, 0x00A0, 0x04084000); @@ -2537,174 +2684,138 @@ wctc4xxp_turn_off_booted_led(struct wcdte *wc) return ret; } -static void +static void wctc4xxp_turn_on_booted_led(struct wcdte *wc) { wctc4xxp_setctl(wc, 0x00A0, 0x04080000); } -static int +static int wctc4xxp_boot_processor(struct wcdte *wc, const struct firmware *firmware) { int ret; wctc4xxp_turn_off_booted_led(wc); - if ((ret = wctc4xxp_load_firmware(wc, firmware))) { + ret = wctc4xxp_load_firmware(wc, firmware); + if (ret) return ret; - } - + wctc4xxp_turn_on_booted_led(wc); DTE_DEBUG(DTE_DEBUG_GENERAL, "Successfully booted DTE processor.\n"); return 0; } -static int -wctc4xxp_create_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt, +static int +setup_half_channel(struct channel_pvt *pvt, struct tcb *cmd, u16 length) +{ + if (send_set_ip_hdr_channel_cmd(pvt, cmd)) + return -EIO; + if (send_voip_vceopt_cmd(pvt, cmd, length)) + return -EIO; + if (send_voip_tonectl_cmd(pvt, cmd)) + return -EIO; + if (send_voip_dtmfopt_cmd(pvt, cmd)) + return -EIO; + if (send_voip_indctrl_cmd(pvt, cmd)) + return -EIO; + return 0; +} + +static int +wctc4xxp_create_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt, u8 simple, u8 complicated) { - int res; - int length; - u8 chan1, chan2; - struct dahdi_transcoder_channel *dtc1, *dtc2; - struct channel_pvt *cpvt1, *cpvt2; - /* \todo what do these part variable names mean? */ - unsigned int timeslot; - unsigned int part2_id; + struct channel_pvt *encoder_pvt, *decoder_pvt; + u16 encoder_timeslot, decoder_timeslot; + u16 encoder_channel, decoder_channel; + u16 length; struct tcb *cmd; - const struct csm_encaps_hdr *hdr; - + cmd = alloc_cmd(); + if (!cmd) + return -ENOMEM; + BUG_ON(!wc || !cpvt); if (cpvt->encoder) { - timeslot = cpvt->timeslot_in_num; - part2_id = cpvt->timeslot_out_num; + encoder_timeslot = cpvt->timeslot_in_num; + decoder_timeslot = cpvt->timeslot_out_num; } else { u8 temp; - timeslot = cpvt->timeslot_out_num; - part2_id = cpvt->timeslot_in_num; + encoder_timeslot = cpvt->timeslot_out_num; + decoder_timeslot = cpvt->timeslot_in_num; temp = simple; simple = complicated; complicated = temp; } - length = (DTE_FORMAT_G729A == complicated) ? G729_LENGTH : - (DTE_FORMAT_G723_1 == complicated) ? G723_LENGTH : 0; - - if (!(cmd = wctc4xxp_create_channel_cmd(wc, timeslot))) { - return -ENOMEM; - } - if ((res=wctc4xxp_transmit_cmd_and_wait(wc, cmd))) { - free_cmd(cmd); - return res; - } - free_cmd(cmd); - - cmd = wctc4xxp_create_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, timeslot)); - if ((res=wctc4xxp_transmit_cmd_and_wait(wc,cmd))) { - free_cmd(cmd); - return res; - } - WARN_ON(!cmd->response); - hdr = (const struct csm_encaps_hdr*)cmd->response->data; - chan1 = le16_to_cpu(hdr->params[0]);; - free_cmd(cmd); - - if (!(cmd = wctc4xxp_create_channel_cmd(wc, part2_id))) { - return -ENOMEM; - } - if ((res = __wctc4xxp_send_cmd(wc, cmd))) { - return res; - } - cmd = wctc4xxp_create_cmd(wc, CMD_MSG_QUERY_CHANNEL(wc->seq_num++, part2_id)); - cmd->flags |= WAIT_FOR_RESPONSE; - if ((res=wctc4xxp_transmit_cmd_and_wait(wc,cmd))) { - return res; - } - WARN_ON(!cmd->response); - hdr = (const struct csm_encaps_hdr*)cmd->response->data; - chan2 = le16_to_cpu(hdr->params[0]);; - free_cmd(cmd); + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "DTE is using the following channels encoder_channel: " \ + "%d decoder_channel: %d\n", encoder_channel, decoder_channel); + + BUG_ON(encoder_timeslot/2 >= wc->numchannels); + BUG_ON(decoder_timeslot/2 >= wc->numchannels); + encoder_pvt = wc->uencode->channels[encoder_timeslot/2].pvt; + decoder_pvt = wc->udecode->channels[decoder_timeslot/2].pvt; + BUG_ON(!encoder_pvt); + BUG_ON(!decoder_pvt); + + /* First, let's create two channels, one for the simple -> complex + * encoder and another for the complex->simple decoder. */ + if (send_create_channel_cmd(wc, cmd, encoder_timeslot, + &encoder_channel)) + goto error_exit; - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, - "DTE is using the following channels chan1: %d chan2: %d\n", chan1, chan2); + if (send_create_channel_cmd(wc, cmd, decoder_timeslot, + &decoder_channel)) + goto error_exit; - BUG_ON(timeslot/2 >= wc->numchannels); - BUG_ON(part2_id/2 >= wc->numchannels); - dtc1 = &(wc->uencode->channels[timeslot/2]); - dtc2 = &(wc->udecode->channels[part2_id/2]); - cpvt1 = dtc1->pvt; - cpvt2 = dtc2->pvt; - BUG_ON(!cpvt1); - BUG_ON(!cpvt2); + length = (DTE_FORMAT_G729A == complicated) ? G729_LENGTH : + (DTE_FORMAT_G723_1 == complicated) ? G723_LENGTH : 0; - /* Configure complex channel */ - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt1->cmd_seqno++, chan1, part2_id, timeslot)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt1->cmd_seqno++, chan1, length, 0)))) { - return res; - } - /* Configure simple channel */ - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SET_IP_HDR_CHANNEL(cpvt2->cmd_seqno++, chan2, timeslot, part2_id)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VCEOPT(cpvt2->cmd_seqno++, chan2, length, 0)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt1->cmd_seqno++, chan1)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt1->cmd_seqno++, chan1)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_TONECTL(cpvt2->cmd_seqno++, chan2)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_DTMFOPT(cpvt2->cmd_seqno++, chan2)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt1->cmd_seqno++, chan1)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_INDCTRL(cpvt2->cmd_seqno++, chan2)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 1, chan1, chan2, complicated, simple)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt1->cmd_seqno++, chan1, complicated)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VOPENA(cpvt2->cmd_seqno++, chan2, simple)))) { - return res; - } + /* Now set all the default parameters for the encoder. */ + encoder_pvt->chan_in_num = encoder_channel; + encoder_pvt->chan_out_num = decoder_channel; + if (setup_half_channel(encoder_pvt, cmd, length)) + goto error_exit; - DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, - "DTE has completed setup and connected the two channels together.\n"); + /* And likewise for the decoder. */ + decoder_pvt->chan_in_num = decoder_channel; + decoder_pvt->chan_out_num = encoder_channel; + if (setup_half_channel(decoder_pvt, cmd, length)) + goto error_exit; + if (send_trans_connect_cmd(wc, cmd, 1, encoder_channel, + decoder_channel, complicated, simple)) + goto error_exit; + if (send_voip_vopena_cmd(encoder_pvt, cmd, complicated)) + goto error_exit; + if (send_voip_vopena_cmd(decoder_pvt, cmd, simple)) + goto error_exit; - /* Save off the channels returned from the DTE so we can use then when - * sending the RTP packets. */ - if (ENCODER == cpvt->encoder) { - cpvt->chan_in_num = chan1; - cpvt->chan_out_num = chan2; - } else { - cpvt->chan_out_num = chan1; - cpvt->chan_in_num = chan2; - } + DTE_DEBUG(DTE_DEBUG_CHANNEL_SETUP, + "DTE has completed setup and connected the " \ + "two channels together.\n"); + free_cmd(cmd); return 0; +error_exit: + free_cmd(cmd); + return -EIO; } -static int +static int wctc4xxp_destroy_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt) { struct dahdi_transcoder_channel *dtc1, *dtc2; - struct channel_pvt *cpvt1, *cpvt2; + struct channel_pvt *encoder_pvt, *decoder_pvt; int chan1, chan2, timeslot1, timeslot2; - int res; + struct tcb *cmd; + + cmd = alloc_cmd(); + if (!cmd) + return -ENOMEM; if (cpvt->encoder) { chan1 = cpvt->chan_in_num; @@ -2719,7 +2830,7 @@ wctc4xxp_destroy_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt) } if (timeslot1/2 >= wc->numchannels || timeslot2/2 >= wc->numchannels) { - DTE_PRINTK(WARNING, + DTE_PRINTK(WARNING, "Invalid channel numbers in %s. chan1:%d chan2: %d\n", __func__, timeslot1/2, timeslot2/2); return 0; @@ -2727,113 +2838,96 @@ wctc4xxp_destroy_channel_pair(struct wcdte *wc, struct channel_pvt *cpvt) dtc1 = &(wc->uencode->channels[timeslot1/2]); dtc2 = &(wc->udecode->channels[timeslot2/2]); - cpvt1 = dtc1->pvt; - cpvt2 = dtc2->pvt; - - /* Turn off both channels */ - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt1->cmd_seqno++, chan1)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_VOIP_VOPENA_CLOSE(cpvt2->cmd_seqno++, chan2)))) { - return res; - } - - /* Disconnect the channels */ - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_TRANS_CONNECT(wc->seq_num++, 0, chan1, chan2, 0, 0)))) { - return res; - } + encoder_pvt = dtc1->pvt; + decoder_pvt = dtc2->pvt; - /* Remove the channels */ - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan1)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_DESTROY_CHANNEL(wc->seq_num++, chan2)))) { - return res; - } + if (send_voip_vopena_close_cmd(encoder_pvt, cmd)) + goto error_exit; + if (send_voip_vopena_close_cmd(decoder_pvt, cmd)) + goto error_exit; + if (send_trans_connect_cmd(wc, cmd, 0, chan1, chan2, 0, 0)) + goto error_exit; + if (send_destroy_channel_cmd(wc, cmd, chan1)) + goto error_exit; + if (send_destroy_channel_cmd(wc, cmd, chan2)) + goto error_exit; + free_cmd(cmd); return 0; +error_exit: + free_cmd(cmd); + return -1; } -static int +static int __wctc4xxp_setup_channels(struct wcdte *wc) { - int res; struct tcb *cmd; + int tdm_bus; - if (!(cmd = alloc_cmd())) { + cmd = alloc_cmd(); + if (!cmd) return -ENOMEM; - } - __wctc4xxp_create_set_arm_clk_cmd(wc, cmd); - res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); - free_cmd(cmd); - if (res) { - return res; - } + if (send_set_arm_clk_cmd(wc, cmd)) + goto error_exit; - cmd = wctc4xxp_create_cmd(wc, CMD_MSG_SET_SPU_CLK(wc->seq_num++)); - res = wctc4xxp_transmit_cmd_and_wait(wc, cmd); - free_cmd(cmd); - if (res) { - return res; - } + if (send_set_spu_clk_cmd(wc, cmd)) + goto error_exit; - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_TDM_SELECT_BUS_MODE(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_TDM_ENABLE_BUS(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x03, 0x20, 0x00)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x04, 0x80, 0x04)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x05, 0x20, 0x08)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SUPVSR_SETUP_TDM_PARMS(wc->seq_num++, 0x06, 0x80, 0x0C)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SET_ETH_HEADER(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_IP_SERVICE_CONFIG(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_ARP_SERVICE_CONFIG(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_ICMP_SERVICE_CONFIG(wc->seq_num++)))) { - return res; - } + if (send_tdm_select_bus_mode_cmd(wc, cmd)) + goto error_exit; - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_DEVICE_SET_COUNTRY_CODE(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x02)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_IP_OPTIONS(wc->seq_num++)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_SPU_FEATURES_CONTROL(wc->seq_num++, 0x04)))) { - return res; - } - if ((res=wctc4xxp_send_cmd(wc, CMD_MSG_TDM_OPT(wc->seq_num++)))) { - return res; + for (tdm_bus = 0; tdm_bus < 4; ++tdm_bus) { + if (send_supvsr_setup_tdm_parms(wc, cmd, tdm_bus)) + goto error_exit; } + + if (send_set_eth_header_cmd(wc, cmd, src_mac, dst_mac)) + goto error_exit; + + if (send_ip_service_config_cmd(wc, cmd)) + goto error_exit; + + if (send_arp_service_config_cmd(wc, cmd)) + goto error_exit; + + if (send_icmp_service_config_cmd(wc, cmd)) + goto error_exit; + + if (send_device_set_country_code_cmd(wc, cmd)) + goto error_exit; + + if (send_spu_features_control_cmd(wc, cmd, 0x02)) + goto error_exit; + + if (send_ip_options_cmd(wc, cmd)) + goto error_exit; + + if (send_spu_features_control_cmd(wc, cmd, 0x04)) + goto error_exit; + + if (send_tdm_opt_cmd(wc, cmd)) + goto error_exit; + + free_cmd(cmd); return 0; +error_exit: + free_cmd(cmd); + return -1; } -static int +static int wctc4xxp_setup_channels(struct wcdte *wc) { int ret; - +#ifndef DEBUG_WCTC4XXP down(&wc->chansem); +#else + if (down_interruptible(&wc->chansem)) + return -EINTR; +#endif ret = __wctc4xxp_setup_channels(wc); up(&wc->chansem); @@ -2847,81 +2941,73 @@ static void wctc4xxp_setup_file_operations(struct file_operations *fops) fops->write = wctc4xxp_write; } -static int -initialize_channel_pvt(struct wcdte *wc, encode_t type, - struct channel_pvt **cpvt) +static int +initialize_channel_pvt(struct wcdte *wc, int encoder, + struct channel_pvt **cpvt) { int chan; - *cpvt = kmalloc(sizeof(struct channel_pvt) * wc->numchannels, GFP_KERNEL); - if (!(*cpvt)) { + *cpvt = kmalloc(sizeof(struct channel_pvt) * wc->numchannels, + GFP_KERNEL); + if (!(*cpvt)) return -ENOMEM; - } - for (chan = 0; chan < wc->numchannels; ++chan) { - wctc4xxp_init_state((*cpvt) + chan, type, chan, wc); - } + for (chan = 0; chan < wc->numchannels; ++chan) + wctc4xxp_init_state((*cpvt) + chan, encoder, chan, wc); return 0; } -static int -initialize_transcoder(struct wcdte *wc, unsigned int srcfmts, - unsigned int dstfmts, struct channel_pvt *pvts, - struct dahdi_transcoder **zt) +static int +initialize_transcoder(struct wcdte *wc, unsigned int srcfmts, + unsigned int dstfmts, struct channel_pvt *pvts, + struct dahdi_transcoder **zt) { int chan; *zt = dahdi_transcoder_alloc(wc->numchannels); - if (!(*zt)) { + if (!(*zt)) return -ENOMEM; - } (*zt)->srcfmts = srcfmts; (*zt)->dstfmts = dstfmts; (*zt)->allocate = wctc4xxp_operation_allocate; (*zt)->release = wctc4xxp_operation_release; wctc4xxp_setup_file_operations(&((*zt)->fops)); - for (chan = 0; chan < wc->numchannels; ++chan) { + for (chan = 0; chan < wc->numchannels; ++chan) (*zt)->channels[chan].pvt = &pvts[chan]; - } return 0; } static int initialize_encoders(struct wcdte *wc, unsigned int complexfmts) { int res; - if ((res = initialize_channel_pvt(wc, ENCODER, &wc->encoders))) { + res = initialize_channel_pvt(wc, 1, &wc->encoders); + if (res) return res; - } - if ((res = initialize_transcoder(wc, - DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW, - complexfmts, - wc->encoders, - &wc->uencode))) - { + + res = initialize_transcoder(wc, DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW, + complexfmts, wc->encoders, &wc->uencode); + if (res) return res; - } sprintf(wc->uencode->name, "DTE Encoder"); return res; } -static int +static int initialize_decoders(struct wcdte *wc, unsigned int complexfmts) { int res; - if ((res = initialize_channel_pvt(wc, DECODER, &wc->decoders))) { + res = initialize_channel_pvt(wc, 0, &wc->decoders); + if (res) return res; - } - if ((res = initialize_transcoder(wc, - complexfmts, + + res = initialize_transcoder(wc, complexfmts, DAHDI_FORMAT_ULAW | DAHDI_FORMAT_ALAW, - wc->decoders, - &wc->udecode))) - { + wc->decoders, &wc->udecode); + if (res) return res; - } sprintf(wc->udecode->name, "DTE Decoder"); return res; } -static void +static void wctc4xxp_send_commands(struct wcdte *wc, struct list_head *to_send) { struct tcb *cmd; @@ -2932,7 +3018,7 @@ wctc4xxp_send_commands(struct wcdte *wc, struct list_head *to_send) } } -static void +static void wctc4xxp_watchdog(unsigned long data) { struct wcdte *wc = (struct wcdte *)data; @@ -2940,30 +3026,34 @@ wctc4xxp_watchdog(unsigned long data) LIST_HEAD(cmds_to_retry); const int MAX_RETRIES = 5; - /* Check for any commands that have completed transmitted. */ service_tx_ring(wc); spin_lock(&wc->cmd_list_lock); /* Go through the list of messages that are waiting for responses from * the DTE, and complete or retry any that have timed out. */ - list_for_each_entry_safe(cmd, temp, &wc->waiting_for_response_list, node) { + list_for_each_entry_safe(cmd, temp, + &wc->waiting_for_response_list, node) { if (time_after(jiffies, cmd->timeout)) { if (++cmd->retries > MAX_RETRIES) { if (!(cmd->flags & TX_COMPLETE)) { set_bit(DTE_SHUTDOWN, &wc->flags); spin_unlock(&wc->cmd_list_lock); wctc4xxp_stop_dma(wc); - DTE_PRINTK(ERR, "Board malfunctioning. " \ - "Halting operation.\n"); + DTE_PRINTK(ERR, + "Board malfunctioning. " \ + "Halting operation.\n"); return; } - /* ERROR: We've retried the command and haven't - * received the ACK or the response. */ + /* ERROR: We've retried the command and + * haven't received the ACK or the response. + */ cmd->flags |= DTE_CMD_TIMEOUT; list_del_init(&cmd->node); + complete(&cmd->complete); } else if (cmd->flags & TX_COMPLETE) { /* Move this to the local list because we're - * going to resend it once we free the locks */ + * going to resend it once we free the locks + */ list_move_tail(&cmd->node, &cmds_to_retry); cmd->flags &= ~(TX_COMPLETE); } else { @@ -2972,12 +3062,13 @@ wctc4xxp_watchdog(unsigned long data) * off any lists, lets just reset the timeout * and tell the hardware to look for another * command . */ - DTE_PRINTK(WARNING, "Retrying command that was " \ - "still on descriptor list.\n"); + DTE_PRINTK(WARNING, + "Retrying command that was " \ + "still on descriptor list.\n"); cmd->timeout = jiffies + HZ/4; wctc4xxp_transmit_demand_poll(wc); } - } + } } spin_unlock(&wc->cmd_list_lock); @@ -3000,15 +3091,13 @@ wctc4xxp_add_to_device_list(struct wcdte *wc) /* Add the new entry before the one here */ list_add_tail(&wc->node, &cur->node); break; - } - else { + } else { ++pos; } } /* If we didn't already add the new entry to the list, add it now */ - if (list_empty(&wc->node)) { + if (list_empty(&wc->node)) list_add_tail(&wc->node, &wctc4xxp_list); - } spin_unlock(&wctc4xxp_list_lock); return pos; } @@ -3019,19 +3108,19 @@ struct wctc4xxp_desc { int flags; }; -static struct wctc4xxp_desc wctc400p = { +static struct wctc4xxp_desc wctc400p = { .short_name = "tc400b", - .long_name = "Wildcard TC400P+TC400M", - .flags = 0, + .long_name = "Wildcard TC400P+TC400M", + .flags = 0, }; -static struct wctc4xxp_desc wctce400 = { +static struct wctc4xxp_desc wctce400 = { .short_name = "tce400", - .long_name = "Wildcard TCE400+TC400M", + .long_name = "Wildcard TCE400+TC400M", .flags = 0, }; -static int __devinit +static int __devinit wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) { int res, reg, position_on_list; @@ -3053,14 +3142,14 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) * Setup the pure software constructs internal to this driver. * --------------------------------------------------------------- */ - if (!(wc = kmalloc(sizeof(*wc), GFP_KERNEL))) { + wc = kmalloc(sizeof(*wc), GFP_KERNEL); + if (!wc) return -ENOMEM; - } memset(wc, 0, sizeof(*wc)); position_on_list = wctc4xxp_add_to_device_list(wc); - snprintf(wc->board_name, sizeof(wc->board_name)-1, "%s%d", - d->short_name, position_on_list); + snprintf(wc->board_name, sizeof(wc->board_name)-1, "%s%d", + d->short_name, position_on_list); wc->iobase = pci_resource_start(pdev, 0); wc->pdev = pdev; wc->pos = position_on_list; @@ -3073,7 +3162,7 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) INIT_LIST_HEAD(&wc->cmd_list); INIT_LIST_HEAD(&wc->waiting_for_response_list); INIT_LIST_HEAD(&wc->rx_list); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20) INIT_WORK(&wc->deferred_work, deferred_work_func, wc); #else INIT_WORK(&wc->deferred_work, deferred_work_func); @@ -3083,7 +3172,7 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) /* Keep track of whether we need to free the region */ if (!request_region(wc->iobase, 0xff, wc->board_name)) { /* \todo put in error message. */ - DTE_PRINTK(WARNING, + DTE_PRINTK(WARNING, "Failed to reserve the I/O ports for this device.\n"); return -EIO; } @@ -3096,31 +3185,34 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) return -EIO; } - if (!(wc->txd = kmalloc(sizeof(*wc->txd), GFP_KERNEL))) { + wc->txd = kmalloc(sizeof(*wc->txd), GFP_KERNEL); + if (!wc->txd) { res = -ENOMEM; goto error_exit_swinit; } - if ((res = wctc4xxp_initialize_descriptor_ring(wc->pdev, wc->txd, - 0xe0800000, - DMA_TO_DEVICE))) { + res = wctc4xxp_initialize_descriptor_ring(wc->pdev, wc->txd, + 0xe0800000, DMA_TO_DEVICE); + if (res) goto error_exit_swinit; - } - if (!(wc->rxd = kmalloc(sizeof(*wc->rxd), GFP_KERNEL))) { + wc->rxd = kmalloc(sizeof(*wc->rxd), GFP_KERNEL); + if (!wc->rxd) { res = -ENOMEM; goto error_exit_swinit; } - if ((res = wctc4xxp_initialize_descriptor_ring(wc->pdev, wc->rxd, 0, - DMA_FROM_DEVICE))) { + res = wctc4xxp_initialize_descriptor_ring(wc->pdev, wc->rxd, 0, + DMA_FROM_DEVICE); + if (res) goto error_exit_swinit; - } #if defined(HOTPLUG_FIRMWARE) - if ((res = request_firmware(&firmware, tc400m_firmware, &wc->pdev->dev)) || - !firmware) { - DTE_PRINTK(ERR, "Firmware %s not available from userspace. (%d)\n", tc400m_firmware, res); + res = request_firmware(&firmware, tc400m_firmware, &wc->pdev->dev); + if (res || !firmware) { + DTE_PRINTK(ERR, + "Firmware %s not available from userspace. (%d)\n", + tc400m_firmware, res); goto error_exit_swinit; } #else @@ -3153,74 +3245,74 @@ wctc4xxp_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) wc->numchannels = min_numchannels; } - if ((res = initialize_encoders(wc, complexfmts))) { + res = initialize_encoders(wc, complexfmts); + if (res) goto error_exit_swinit; - } - if ((res = initialize_decoders(wc, complexfmts))) { + res = initialize_decoders(wc, complexfmts); + if (res) goto error_exit_swinit; - } - + if (DTE_DEBUG_NETWORK_IF & debug) { - if ((res = wctc4xxp_net_register(wc))) { + res = wctc4xxp_net_register(wc); + if (res) goto error_exit_swinit; - } } -# if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18) +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18) wc->watchdog.function = wctc4xxp_watchdog; wc->watchdog.data = (unsigned long)wc; init_timer(&wc->watchdog); # else - setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc); + setup_timer(&wc->watchdog, wctc4xxp_watchdog, (unsigned long)wc); # endif /* ------------------------------------------------------------------ * Load the firmware and start the DTE. * --------------------------------------------------------------- */ - if ((res = pci_enable_device(pdev))) { + res = pci_enable_device(pdev); + if (res) { DTE_PRINTK(ERR, "Failed to enable device.\n"); goto error_exit_swinit;; } pci_set_master(pdev); pci_set_drvdata(pdev, wc); - if ((res = request_irq(pdev->irq, wctc4xxp_interrupt, DAHDI_IRQ_SHARED, wc->board_name, wc))) { + res = request_irq(pdev->irq, wctc4xxp_interrupt, + DAHDI_IRQ_SHARED, wc->board_name, wc); + if (res) { DTE_PRINTK(ERR, "Unable to request IRQ %d\n", pdev->irq); - if (firmware != &embedded_firmware) { + if (firmware != &embedded_firmware) release_firmware(firmware); - } goto error_exit_hwinit; } - if ((res = wctc4xxp_hardware_init(wc))) { - if (firmware != &embedded_firmware) { + res = wctc4xxp_hardware_init(wc); + if (res) { + if (firmware != &embedded_firmware) release_firmware(firmware); - } goto error_exit_hwinit; } wctc4xxp_enable_interrupts(wc); wctc4xxp_start_dma(wc); res = wctc4xxp_boot_processor(wc, firmware); - if (firmware != &embedded_firmware) { + if (firmware != &embedded_firmware) release_firmware(firmware); - } - if (res) { + if (res) goto error_exit_hwinit; - } - if ((res = wctc4xxp_setup_channels(wc))) { + res = wctc4xxp_setup_channels(wc); + if (res) goto error_exit_hwinit; - } /* \todo Read firmware version directly from tc400b.*/ DTE_PRINTK(INFO, "(%s) Transcoder support LOADED " \ - "(firm ver = %d.%d)\n", wc->complexname, wctc4xxp_firmware_ver, + "(firm ver = %d.%d)\n", wc->complexname, wctc4xxp_firmware_ver, wctc4xxp_firmware_ver_minor); reg = wctc4xxp_getctl(wc, 0x00fc); - DTE_DEBUG(DTE_DEBUG_GENERAL, + DTE_DEBUG(DTE_DEBUG_GENERAL, "debug: (post-boot) Reg fc is %08x\n", reg); - + DTE_PRINTK(INFO, "Installed a Wildcard TC: %s \n", wc->variety); DTE_DEBUG(DTE_DEBUG_GENERAL, "Operating in DEBUG mode.\n"); dahdi_transcoder_register(wc->uencode); @@ -3235,20 +3327,20 @@ error_exit_hwinit: pci_set_drvdata(pdev, NULL); error_exit_swinit: wctc4xxp_net_unregister(wc); - if (wc->encoders) kfree(wc->encoders); - if (wc->decoders) kfree(wc->decoders); - if (wc->uencode) dahdi_transcoder_free(wc->uencode); - if (wc->udecode) dahdi_transcoder_free(wc->udecode); + kfree(wc->encoders); + kfree(wc->decoders); + if (wc->uencode) + dahdi_transcoder_free(wc->uencode); + if (wc->udecode) + dahdi_transcoder_free(wc->udecode); if (wc->txd) { - if (wc->txd->desc) { + if (wc->txd->desc) wctc4xxp_cleanup_descriptor_ring(wc->txd); - } kfree(wc->txd); } if (wc->rxd) { - if (wc->rxd && wc->rxd->desc) { + if (wc->rxd && wc->rxd->desc) wctc4xxp_cleanup_descriptor_ring(wc->rxd); - } kfree(wc->rxd); } release_region(wc->iobase, 0xff); @@ -3256,7 +3348,7 @@ error_exit_swinit: list_del(&wc->node); spin_unlock(&wctc4xxp_list_lock); kfree(wc); - return res; + return res; } static void wctc4xxp_cleanup_channels(struct wcdte *wc) @@ -3264,10 +3356,10 @@ static void wctc4xxp_cleanup_channels(struct wcdte *wc) int i; struct dahdi_transcoder_channel *dtc_en, *dtc_de; - for(i = 0; i < wc->numchannels; i++) { + for (i = 0; i < wc->numchannels; ++i) { dtc_en = &(wc->uencode->channels[i]); wctc4xxp_cleanup_channel_private(wc, dtc_en); - + dtc_de = &(wc->udecode->channels[i]); wctc4xxp_cleanup_channel_private(wc, dtc_de); } @@ -3300,31 +3392,33 @@ static void __devexit wctc4xxp_remove_one(struct pci_dev *pdev) wctc4xxp_net_unregister(wc); if (debug) { - for(i = 0; i < wc->numchannels; i++) { + for (i = 0; i < wc->numchannels; ++i) { dtc_en = &(wc->uencode->channels[i]); cpvt = dtc_en->pvt; - DTE_DEBUG(DTE_DEBUG_GENERAL, - "encoder[%d] snt = %d, rcv = %d [%d]\n", i, - atomic_read(&cpvt->stats.packets_sent), - atomic_read(&cpvt->stats.packets_received), - atomic_read(&cpvt->stats.packets_sent) - atomic_read(&cpvt->stats.packets_received)); + DTE_DEBUG(DTE_DEBUG_GENERAL, + "encoder[%d] snt = %d, rcv = %d [%d]\n", i, + atomic_read(&cpvt->stats.packets_sent), + atomic_read(&cpvt->stats.packets_received), + atomic_read(&cpvt->stats.packets_sent) - + atomic_read(&cpvt->stats.packets_received)); dtc_de = &(wc->udecode->channels[i]); cpvt = dtc_de->pvt; - DTE_DEBUG(DTE_DEBUG_GENERAL, - "decoder[%d] snt = %d, rcv = %d [%d]\n", i, - atomic_read(&cpvt->stats.packets_sent), - atomic_read(&cpvt->stats.packets_received), - atomic_read(&cpvt->stats.packets_sent) - atomic_read(&cpvt->stats.packets_received)); + DTE_DEBUG(DTE_DEBUG_GENERAL, + "decoder[%d] snt = %d, rcv = %d [%d]\n", i, + atomic_read(&cpvt->stats.packets_sent), + atomic_read(&cpvt->stats.packets_received), + atomic_read(&cpvt->stats.packets_sent) - + atomic_read(&cpvt->stats.packets_received)); } } - + /* Stop any DMA */ wctc4xxp_stop_dma(wc); /* In case hardware is still there */ wctc4xxp_disable_interrupts(wc); - + free_irq(pdev->irq, wc); /* There isn't anything that would run in the workqueue that will wait @@ -3337,11 +3431,13 @@ static void __devexit wctc4xxp_remove_one(struct pci_dev *pdev) release_region(wc->iobase, 0xff); spin_lock_bh(&wc->cmd_list_lock); if (wc->txd) { - if (wc->txd->desc) wctc4xxp_cleanup_descriptor_ring(wc->txd); + if (wc->txd->desc) + wctc4xxp_cleanup_descriptor_ring(wc->txd); kfree(wc->txd); } if (wc->rxd) { - if (wc->rxd && wc->rxd->desc) wctc4xxp_cleanup_descriptor_ring(wc->rxd); + if (wc->rxd && wc->rxd->desc) + wctc4xxp_cleanup_descriptor_ring(wc->rxd); kfree(wc->rxd); } spin_unlock_bh(&wc->cmd_list_lock); @@ -3358,8 +3454,10 @@ static void __devexit wctc4xxp_remove_one(struct pci_dev *pdev) } static struct pci_device_id wctc4xxp_pci_tbl[] = { - { 0xd161, 0x3400, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wctc400p }, /* Digium board */ - { 0xd161, 0x8004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (unsigned long) &wctce400 }, /* Digium board */ + { 0xd161, 0x3400, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) &wctc400p }, /* Digium board */ + { 0xd161, 0x8004, PCI_ANY_ID, PCI_ANY_ID, + 0, 0, (unsigned long) &wctce400 }, /* Digium board */ { 0 } }; @@ -3375,21 +3473,16 @@ static struct pci_driver wctc4xxp_driver = { static int __init wctc4xxp_init(void) { int res; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,23) - cmd_cache = kmem_cache_create(THIS_MODULE->name, sizeof(struct tcb), 0, -#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,22) - SLAB_HWCACHE_ALIGN | SLAB_STORE_USER, NULL, NULL); -#else - SLAB_HWCACHE_ALIGN, NULL, NULL); -#endif -#else - cmd_cache = kmem_cache_create(THIS_MODULE->name, sizeof(struct tcb), 0, - SLAB_HWCACHE_ALIGN, NULL); -#endif - - if (!cmd_cache) { +# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 23) + cmd_cache = kmem_cache_create(THIS_MODULE->name, sizeof(struct tcb), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); +# else + cmd_cache = kmem_cache_create(THIS_MODULE->name, sizeof(struct tcb), + 0, SLAB_HWCACHE_ALIGN, NULL); +# endif + + if (!cmd_cache) return -ENOMEM; - } spin_lock_init(&wctc4xxp_list_lock); INIT_LIST_HEAD(&wctc4xxp_list); res = dahdi_pci_module(&wctc4xxp_driver); |