diff --git a/drivers/char/ts0710.h b/drivers/char/ts0710.h index d85db6f..5b676d4 100644 --- a/drivers/char/ts0710.h +++ b/drivers/char/ts0710.h @@ -185,16 +185,7 @@ typedef struct { __u8 value[0]; } __attribute__ ((packed)) mcc_short_frame; -typedef struct { - mcc_type type; - long_length length; - __u8 value[0]; -} __attribute__ ((packed)) mcc_long_frame_head; -typedef struct { - mcc_long_frame_head h; - __u8 value[0]; -} __attribute__ ((packed)) mcc_long_frame; /* MSC-command */ typedef struct { @@ -215,87 +206,13 @@ typedef struct { __u8 len:4; } __attribute__ ((packed)) brk_sigs; + typedef struct { - short_frame_head s_head; - mcc_short_frame_head mcc_s_head; address_field dlci; __u8 v24_sigs; - //brk_sigs break_signals; - __u8 fcs; -} __attribute__ ((packed)) msc_msg; - -#if 0 -/* conflict with termios.h */ -/* RPN command */ -#define B2400 0 -#define B4800 1 -#define B7200 2 -#define B9600 3 -#define B19200 4 -#define B38400 5 -#define B57600 6 -#define B115200 7 -#define D230400 8 -#endif +} __attribute__ ((packed)) msc_t; + -/* -typedef struct{ - __u8 bit_rate:1; - __u8 data_bits:1; - __u8 stop_bit:1; - __u8 parity:1; - __u8 parity_type:1; - __u8 xon_u8:1; - __u8 xoff_u8:1; - __u8 res1:1; - __u8 xon_input:1; - __u8 xon_output:1; - __u8 rtr_input:1; - __u8 rtr_output:1; - __u8 rtc_input:1; - __u8 rtc_output:1; - __u8 res2:2; -} __attribute__((packed)) parameter_mask; - -typedef struct{ - __u8 bit_rate; - __u8 data_bits:2; - __u8 stop_bit:1; - __u8 parity:1; - __u8 parity_type:2; - __u8 res1:2; - __u8 xon_input:1; - __u8 xon_output:1; - __u8 rtr_input:1; - __u8 rtr_output:1; - __u8 rtc_input:1; - __u8 rtc_output:1; - __u8 res2:2; - __u8 xon_u8; - __u8 xoff_u8; - parameter_mask pm; -} __attribute__((packed)) rpn_values; - -typedef struct{ - short_frame_head s_head; - mcc_short_frame_head mcc_s_head; - address_field dlci; - rpn_values rpn_val; - __u8 fcs; -} __attribute__((packed)) rpn_msg; -*/ - -/* RLS-command */ -/* -typedef struct{ - short_frame_head s_head; - mcc_short_frame_head mcc_s_head; - address_field dlci; - __u8 error:4; - __u8 res:4; - __u8 fcs; -} __attribute__((packed)) rls_msg; -*/ /* PN-command */ typedef struct { @@ -315,6 +232,22 @@ typedef struct { __u8 fcs; } __attribute__ ((packed)) pn_msg; +/* PN-command */ +typedef struct { + __u8 dlci:6; + __u8 res1:2; + __u8 frame_type:4; + __u8 credit_flow:4; + __u8 prior:6; + __u8 res2:2; + __u8 ack_timer; + __u8 frame_sizel; + __u8 frame_sizeh; + __u8 max_nbrof_retrans; + __u8 credits; + __u8 fcs; +} __attribute__ ((packed)) pn_t; + /* NSC-command */ typedef struct { short_frame_head s_head; @@ -327,15 +260,13 @@ typedef struct { #error Only littel-endianess supported now! #endif -enum { - REJECTED = 0, - DISCONNECTED, - CONNECTING, - NEGOTIATING, - CONNECTED, - DISCONNECTING, - FLOW_STOPPED -}; +#define REJECTED 0 +#define DISCONNECTED (1<<0) +#define CONNECTING (1<<1) +#define NEGOTIATING (1<<2) +#define CONNECTED (1<<3) +#define DISCONNECTING (1<<4) +#define FLOW_STOPPED (1<<5) enum ts0710_events { CONNECT_IND, @@ -364,3 +295,38 @@ typedef struct { dlci_struct dlci[TS0710_MAX_CHN]; } ts0710_con; + +#define valid_dlci(x) ( (x>0) && (x0) && (x #include -#define USB_FOR_MUX - -#ifndef USB_FOR_MUX #include -#endif #include #include @@ -69,112 +65,21 @@ #include #include #include +#include #include #include #include #include -#ifdef USB_FOR_MUX #include "ts0710_mux_usb.h" -#endif #include "ts0710.h" #include "ts0710_mux.h" -#define TS0710MUX_GPRS_SESSION_MAX 2 -#define TS0710MUX_MAJOR 250 -#define TS0710MUX_MINOR_START 0 - - static int NR_MUXS; - - /*#define TS0710MUX_TIME_OUT 30 *//* 300ms */ -#define TS0710MUX_TIME_OUT 250 /* 2500ms, for BP UART hardware flow control AP UART */ - -#define TS0710MUX_IO_DLCI_FC_ON 0x54F2 -#define TS0710MUX_IO_DLCI_FC_OFF 0x54F3 -#define TS0710MUX_IO_FC_ON 0x54F4 -#define TS0710MUX_IO_FC_OFF 0x54F5 - -#define TS0710MUX_MAX_BUF_SIZE 2048 - -#define TS0710MUX_SEND_BUF_OFFSET 10 -#define TS0710MUX_SEND_BUF_SIZE (DEF_TS0710_MTU + TS0710MUX_SEND_BUF_OFFSET + 34) -#define TS0710MUX_RECV_BUF_SIZE TS0710MUX_SEND_BUF_SIZE - -/*For BP UART problem Begin*/ -#ifdef TS0710SEQ2 -#define ACK_SPACE 66 /* 6 * 11(ACK frame size) */ -#else -#define ACK_SPACE 42 /* 6 * 7(ACK frame size) */ -#endif -/*For BP UART problem End*/ - - /*#define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE)*//* For BP UART problem */ -#define TS0710MUX_SERIAL_BUF_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + ACK_SPACE) /* For BP UART problem: ACK_SPACE */ - -#define TS0710MUX_MAX_TOTAL_FRAME_SIZE (DEF_TS0710_MTU + TS0710_MAX_HDR_SIZE + FLAG_SIZE) -#define TS0710MUX_MAX_CHARS_IN_BUF 65535 -#define TS0710MUX_THROTTLE_THRESHOLD DEF_TS0710_MTU - -#define TEST_PATTERN_SIZE 250 - -#define CMDTAG 0x55 -#define DATATAG 0xAA - -#define ACK 0x4F /*For BP UART problem */ - -/*For BP UART problem Begin*/ -#ifdef TS0710SEQ2 -#define FIRST_BP_SEQ_OFFSET 1 /*offset from start flag */ -#define SECOND_BP_SEQ_OFFSET 2 /*offset from start flag */ -#define FIRST_AP_SEQ_OFFSET 3 /*offset from start flag */ -#define SECOND_AP_SEQ_OFFSET 4 /*offset from start flag */ -#define SLIDE_BP_SEQ_OFFSET 5 /*offset from start flag */ -#define SEQ_FIELD_SIZE 5 -#else -#define SLIDE_BP_SEQ_OFFSET 1 /*offset from start flag */ -#define SEQ_FIELD_SIZE 1 -#endif - -#define ADDRESS_FIELD_OFFSET (1 + SEQ_FIELD_SIZE) /*offset from start flag */ -/*For BP UART problem End*/ - -#ifndef UNUSED_PARAM -#define UNUSED_PARAM(v) (void)(v) -#endif - -#define TS0710MUX_GPRS1_DLCI 7 -#define TS0710MUX_GPRS2_DLCI 8 - -#define TS0710MUX_GPRS1_RECV_COUNT_IDX 0 -#define TS0710MUX_GPRS1_SEND_COUNT_IDX 1 -#define TS0710MUX_GPRS2_RECV_COUNT_IDX 2 -#define TS0710MUX_GPRS2_SEND_COUNT_IDX 3 -#define TS0710MUX_COUNT_MAX_IDX 3 -#define TS0710MUX_COUNT_IDX_NUM (TS0710MUX_COUNT_MAX_IDX + 1) - -static volatile int mux_data_count[TS0710MUX_COUNT_IDX_NUM] = { 0, 0, 0, 0 }; -static volatile int mux_data_count2[TS0710MUX_COUNT_IDX_NUM] = { 0, 0, 0, 0 }; -static struct semaphore mux_data_count_mutex[TS0710MUX_COUNT_IDX_NUM]; -static volatile __u8 post_recv_count_flag = 0; - -/*PROC file*/ -struct proc_dir_entry *gprs_proc_file = NULL; -ssize_t file_proc_read(struct file *file, char *buf, size_t size, - loff_t * ppos); -ssize_t file_proc_write(struct file *file, const char *buf, size_t count, - loff_t * ppos); -struct file_operations file_proc_operations = { - read:file_proc_read, - write:file_proc_write, -}; -typedef struct { - int recvBytes; - int sentBytes; -} gprs_bytes; +static struct tty_struct *ipc_tty; typedef struct { @@ -182,12 +87,7 @@ typedef struct { __u8 datatty; } dlci_tty; - -static __u8 *tty2dlci; static __u8 *iscmdtty; -static dlci_tty *dlci2tty; - - typedef struct { volatile __u8 buf[TS0710MUX_SEND_BUF_SIZE]; @@ -198,8 +98,14 @@ typedef struct { volatile __u8 dummy; /* Allignment to 4*n bytes */ } mux_send_struct; +struct mux_data { + int collected; + int frame; + int seq; + const u8 *data +}; + /* Bit number in flags of mux_send_struct */ -#define BUF_BUSY 0 struct mux_recv_packet_tag { __u8 *data; @@ -219,7 +125,6 @@ struct mux_recv_struct_tag { }; typedef struct mux_recv_struct_tag mux_recv_struct; -#define RECV_RUNNING 0 static unsigned long mux_recv_flags = 0; static mux_send_struct *mux_send_info[23]; @@ -233,28 +138,7 @@ static mux_recv_struct *mux_recv_queue = NULL; // Local for 2.6? static struct tty_driver *mux_driver; -#ifdef USB_FOR_MUX -#define COMM_FOR_MUX_DRIVER usb_for_mux_driver -#define COMM_FOR_MUX_TTY usb_for_mux_tty -#define COMM_MUX_DISPATCHER usb_mux_dispatcher -#define COMM_MUX_SENDER usb_mux_sender -#else -#define COMM_FOR_MUX_DRIVER serial_for_mux_driver -#define COMM_FOR_MUX_TTY serial_for_mux_tty -#define COMM_MUX_DISPATCHER serial_mux_dispatcher -#define COMM_MUX_SENDER serial_mux_sender - -extern struct list_head *tq_serial_for_mux; -#endif - -extern struct tty_driver *COMM_FOR_MUX_DRIVER; -extern struct tty_struct *COMM_FOR_MUX_TTY; -extern void (*COMM_MUX_DISPATCHER) (struct tty_struct * tty); -extern void (*COMM_MUX_SENDER) (void); - static struct work_struct send_tqueue; -static struct work_struct receive_tqueue; -static struct work_struct post_recv_tqueue; static struct tty_struct *mux_table[23]; static struct ktermios *mux_termios[23]; @@ -266,277 +150,37 @@ static volatile short int mux_tty[23]; #define min(a,b) ( (a)<(b) ? (a):(b) ) #endif -static int get_count(__u8 idx); -static int set_count(__u8 idx, int count); -static int add_count(__u8 idx, int count); - -static int send_ua(ts0710_con * ts0710, __u8 dlci); -static int send_dm(ts0710_con * ts0710, __u8 dlci); -static int send_sabm(ts0710_con * ts0710, __u8 dlci); -static int send_disc(ts0710_con * ts0710, __u8 dlci); static void queue_uih(mux_send_struct * send_info, __u16 len, ts0710_con * ts0710, __u8 dlci); -static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size, - __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr); -static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr); static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr); -static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum); static __u8 crc_calc(__u8 * data, __u32 length); static void create_crctable(__u8 table[]); +static __u8 crctable[256]; static void mux_sched_send(void); -static __u8 crctable[256]; static ts0710_con ts0710_connection; -/* -static rpn_values rpn_val; -*/ - -static int valid_dlci(__u8 dlci) -{ - if ((dlci < TS0710_MAX_CHN) && (dlci > 0)) - return 1; - else - return 0; -} - -#ifdef TS0710DEBUG - -#ifdef PRINT_OUTPUT_PRINTK -#define TS0710_DEBUG(fmt, arg...) printk(KERN_INFO "MUX " __FUNCTION__ ": " fmt "\n" , ## arg) -#else -#include "ezxlog.h" -static __u8 strDebug[256]; -#define TS0710_DEBUG(fmt, arg...) ({ snprintf(strDebug, sizeof(strDebug), "MUX " __FUNCTION__ ": " fmt "\n" , ## arg); \ - /*printk("%s", strDebug)*/ezxlogk("MX", strDebug, strlen(strDebug)); }) -#endif /* End #ifdef PRINT_OUTPUT_PRINTK */ - -#else -#define TS0710_DEBUG(fmt...) -#endif /* End #ifdef TS0710DEBUG */ - -#ifdef TS0710LOG -static unsigned char g_tbuf[TS0710MUX_MAX_BUF_SIZE]; -#ifdef PRINT_OUTPUT_PRINTK -#define TS0710_LOG(fmt, arg...) printk(fmt, ## arg) -#define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg) -#else -#include "ezxlog.h" -static __u8 strLog[256]; -#define TS0710_LOG(fmt, arg...) ({ snprintf(strLog, sizeof(strLog), fmt, ## arg); \ - /*printk("%s", strLog)*/ezxlogk("MX", strLog, strlen(strLog)); }) -#define TS0710_PRINTK(fmt, arg...) ({ printk(fmt, ## arg); \ - TS0710_LOG(fmt, ## arg); }) -#endif /* End #ifdef PRINT_OUTPUT_PRINTK */ - -#else -#define TS0710_LOG(fmt...) -#define TS0710_PRINTK(fmt, arg...) printk(fmt, ## arg) -#endif /* End #ifdef TS0710LOG */ - -#ifdef TS0710DEBUG -static void TS0710_DEBUGHEX(__u8 * buf, int len) -{ - static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE]; - - int i; - int c; - - if (len <= 0) { - return; - } - c = 0; - for (i = 0; (i < len) && (c < (TS0710MUX_MAX_BUF_SIZE - 3)); i++) { - sprintf(&tbuf[c], "%02x ", buf[i]); - c += 3; - } - tbuf[c] = 0; - -#ifdef PRINT_OUTPUT_PRINTK - TS0710_DEBUG("%s", tbuf); -#else - /*printk("%s\n", tbuf) */ ezxlogk("MX", tbuf, c); -#endif -} -static void TS0710_DEBUGSTR(__u8 * buf, int len) +static void basic_dump(__u8 * buf, int len) { - static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE]; - - if (len <= 0) { - return; - } - - if (len > (TS0710MUX_MAX_BUF_SIZE - 1)) { - len = (TS0710MUX_MAX_BUF_SIZE - 1); - } - - memcpy(tbuf, buf, len); - tbuf[len] = 0; + len+=2; -#ifdef PRINT_OUTPUT_PRINTK - /* 0x00 byte in the string pointed by tbuf may truncate the print result */ - TS0710_DEBUG("%s", tbuf); -#else - /*printk("%s\n", tbuf) */ ezxlogk("MX", tbuf, len); -#endif -} -#else -#define TS0710_DEBUGHEX(buf, len) -#define TS0710_DEBUGSTR(buf, len) -#endif /* End #ifdef TS0710DEBUG */ + buf[0] = MUX_BASIC_FLAG_SEQ; + buf[len - 1] = MUX_BASIC_FLAG_SEQ; -#ifdef TS0710LOG -static void TS0710_LOGSTR_FRAME(__u8 send, __u8 * data, int len) -{ - short_frame *short_pkt; - long_frame *long_pkt; - __u8 *uih_data_start; - __u32 uih_len; - __u8 dlci; - int pos; - - if (len <= 0) { - return; - } - - pos = 0; - if (send) { - pos += sprintf(&g_tbuf[pos], "<"); - short_pkt = (short_frame *) (data + 1); /*For BP UART problem */ - } else { - /*For BP UART problem */ - /*pos += sprintf(&g_tbuf[pos], ">"); */ - pos += sprintf(&g_tbuf[pos], ">%d ", *(data + SLIDE_BP_SEQ_OFFSET)); /*For BP UART problem */ - -#ifdef TS0710SEQ2 - pos += sprintf(&g_tbuf[pos], "%02x %02x %02x %02x ", *(data + FIRST_BP_SEQ_OFFSET), *(data + SECOND_BP_SEQ_OFFSET), *(data + FIRST_AP_SEQ_OFFSET), *(data + SECOND_AP_SEQ_OFFSET)); /*For BP UART problem */ -#endif - - short_pkt = (short_frame *) (data + ADDRESS_FIELD_OFFSET); /*For BP UART problem */ - } - - /*For BP UART problem */ - /*short_pkt = (short_frame *)(data + 1); */ - - dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d; - switch (CLR_PF(short_pkt->h.control)) { - case SABM: - pos += sprintf(&g_tbuf[pos], "C SABM %d ::", dlci); - break; - case UA: - pos += sprintf(&g_tbuf[pos], "C UA %d ::", dlci); - break; - case DM: - pos += sprintf(&g_tbuf[pos], "C DM %d ::", dlci); - break; - case DISC: - pos += sprintf(&g_tbuf[pos], "C DISC %d ::", dlci); - break; - - /*For BP UART problem Begin */ - case ACK: - pos += sprintf(&g_tbuf[pos], "C ACK %d ", short_pkt->data[0]); - -#ifdef TS0710SEQ2 - pos += sprintf(&g_tbuf[pos], "%02x %02x %02x %02x ", short_pkt->data[1], short_pkt->data[2], short_pkt->data[3], short_pkt->data[4]); /*For BP UART problem */ -#endif - - pos += sprintf(&g_tbuf[pos], "::"); - break; - /*For BP UART problem End */ - - case UIH: - if (!dlci) { - pos += sprintf(&g_tbuf[pos], "C MCC %d ::", dlci); - } else { - - if ((short_pkt->h.length.ea) == 0) { - long_pkt = (long_frame *) short_pkt; - uih_len = GET_LONG_LENGTH(long_pkt->h.length); - uih_data_start = long_pkt->h.data; - } else { - uih_len = short_pkt->h.length.len; - uih_data_start = short_pkt->data; - } - switch (*uih_data_start) { - case CMDTAG: - pos += - sprintf(&g_tbuf[pos], "I %d A %d ::", dlci, - uih_len); - break; - case DATATAG: - default: - pos += - sprintf(&g_tbuf[pos], "I %d D %d ::", dlci, - uih_len); - break; - } - - } - break; - default: - pos += sprintf(&g_tbuf[pos], "N!!! %d ::", dlci); - break; - } + printk("dump (%d):",len); + + int i; + for(i=0;i (sizeof(g_tbuf) - pos - 1)) { - len = (sizeof(g_tbuf) - pos - 1); - } + printk(" \n"); - memcpy(&g_tbuf[pos], data, len); - pos += len; - g_tbuf[pos] = 0; -#ifdef PRINT_OUTPUT_PRINTK - /* 0x00 byte in the string pointed by g_tbuf may truncate the print result */ - TS0710_LOG("%s\n", g_tbuf); -#else - /*printk("%s\n", g_tbuf) */ ezxlogk("MX", g_tbuf, pos); -#endif } -#else -#define TS0710_LOGSTR_FRAME(send, data, len) -#endif -#ifdef TS0710SIG -#define my_for_each_task(p) \ - for ((p) = current; ((p) = (p)->next_task) != current; ) - -static void TS0710_SIG2APLOGD(void) -{ - struct task_struct *p; - static __u8 sig = 0; - - if (sig) { - return; - } - - read_lock(&tasklist_lock); - my_for_each_task(p) { - if (strncmp(p->comm, "aplogd", 6) == 0) { - sig = 1; - if (send_sig(SIGUSR2, p, 1) == 0) { - TS0710_PRINTK - ("MUX: success to send SIGUSR2 to aplogd!\n"); - } else { - TS0710_PRINTK - ("MUX: failure to send SIGUSR2 to aplogd!\n"); - } - break; - } - } - read_unlock(&tasklist_lock); - - if (!sig) { - TS0710_PRINTK("MUX: not found aplogd!\n"); - } -} -#else -#define TS0710_SIG2APLOGD() -#endif static int basic_write(ts0710_con * ts0710, __u8 * buf, int len) { @@ -544,55 +188,21 @@ static int basic_write(ts0710_con * ts0710, __u8 * buf, int len) UNUSED_PARAM(ts0710); - buf[0] = TS0710_BASIC_FLAG; - buf[len + 1] = TS0710_BASIC_FLAG; - - if ((COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)) { - TS0710_PRINTK - ("MUX basic_write: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n"); - -#ifndef USB_FOR_MUX - TS0710_PRINTK - ("MUX basic_write: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n"); - TS0710_SIG2APLOGD(); -#endif - - return -1; - } + len+=2; - TS0710_LOGSTR_FRAME(1, buf, len + 2); - TS0710_DEBUGHEX(buf, len + 2); + buf[0] = MUX_BASIC_FLAG_SEQ; + buf[len - 1] = MUX_BASIC_FLAG_SEQ; - res = COMM_FOR_MUX_DRIVER->ops->write(COMM_FOR_MUX_TTY, buf, len + 2); + res = ipc_tty->ops->write(ipc_tty, buf, len); - if (res != len + 2) { - TS0710_PRINTK("MUX basic_write: Write Error!\n"); + if (res != len) { + TS0710_PRINTK("MUX basic_write: Write Error! %d\n",res); return -1; } - return len + 2; -} - -/* Functions for the crc-check and calculation */ - -#define CRC_VALID 0xcf - -static __u32 crc_check(__u8 * data, __u32 length, __u8 check_sum) -{ - __u8 fcs = 0xff; + basic_dump(buf,len); - while (length--) { - fcs = crctable[fcs ^ *data++]; - } - fcs = crctable[fcs ^ check_sum]; - TS0710_DEBUG("fcs : %d\n", fcs); - if (fcs == (uint) 0xcf) { /*CRC_VALID) */ - TS0710_DEBUG("crc_check: CRC check OK\n"); - return 0; - } else { - TS0710_PRINTK("MUX crc_check: CRC check failed\n"); - return 1; - } + return len; } /* Calculates the checksum according to the ts0710 specification */ @@ -670,27 +280,10 @@ static void ts0710_reset_con(void) static void ts0710_init(void) { create_crctable(crctable); + fcs_init(); ts0710_reset_con(); - /* Set the values in the rpn octets */ -/* - rpn_val.bit_rate = 7; - rpn_val.data_bits = 3; - rpn_val.stop_bit = 0; - rpn_val.parity = 0; - rpn_val.parity_type = 0; - rpn_val.res1 = 0; - rpn_val.xon_input = 0; - rpn_val.xon_output = 0; - rpn_val.rtr_input = 0; - rpn_val.rtr_output = 0; - rpn_val.rtc_input = 0; - rpn_val.rtc_output = 0; - rpn_val.res2 = 0; - rpn_val.xon_u8 = 0x11; - rpn_val.xoff_u8 = 0x13; - memset(&rpn_val.pm, 0 , 2); *//* Set the mask to zero */ } static void ts0710_upon_disconnect(void) @@ -710,88 +303,158 @@ static void ts0710_upon_disconnect(void) /* Sending packet functions */ +/* See TS 07.10's Section 5.2.1.6 */ +static u_int8_t fcs_table[0x100]; +static void fcs_init(void) +{ + int i, bit; + u_int8_t reg, nreg; + + for (i = 0; i < 0x100; i ++) { + for (reg = bit = 0; bit < 8; bit ++, reg = nreg) { + nreg = reg >> 1; + if (((i >> bit) ^ reg) & 1) + nreg ^= 0xe0; /* x^8 + x^2 + x + 1 */ + } + + fcs_table[i] = reg; + } +} + +/* Computes the FCS checksum for a chunk of data. */ +static u_int8_t mux_fcs_compute(const u_int8_t payload[], int len) +{ + u_int8_t gen_reg; + + gen_reg = ~0; + while (len --) + gen_reg = fcs_table[gen_reg ^ *(payload ++)]; + + return ~gen_reg; +} + +/* Returns 1 if the given chunk of data has a correct FCS appended. */ +static int mux_fcs_check(const u_int8_t payload[], int len) +{ + return mux_fcs_compute(payload, len + 1) == 0xcf; +} + +/* See TS 07.10's Section 5.2.1 */ +static int mux_send_frame(__u8 dlci, int initiator, + enum mux_frametype frametype, const __u8 data[], int len +) +{ + + __u8 framebuf[2048]; + int pos = 0; + int pf, crc_len, res; + int cr = initiator & 0x1; + + // FIXME: bitmask? + switch(frametype){ + case MUX_UIH: + case ACK: + pf = 0; + crc_len = len; + break; + case MUX_UI: + pf = 0; + crc_len = 0; + break; + default: + pf = 1; + crc_len = 0; + } + + //if (dlc->muxer->option == mux_option_basic) + framebuf[pos ++] = MUX_BASIC_FLAG_SEQ; + //else + // framebuf[pos ++] = MUX_ADVANCED_FLAG_SEQ; + + /* Address field. */ + framebuf[pos ++] = MUX_EA | (cr << 1) | (dlci << 2); + + /* Control field. */ + framebuf[pos ++] = frametype | (pf << 4); + + /* Length indicator. */ + //if (dlc->muxer->option == mux_option_basic) { + if (len & ~0x7f) { + framebuf[pos ++] = 0 | ((len & 0x7f) << 1); + framebuf[pos ++] = len >> 7; + } else + framebuf[pos ++] = 1 | (len << 1); + //} + + /* Information field. */ + if (len) + memcpy(&framebuf[pos], data, len); + pos += len; + + framebuf[pos ++] = mux_fcs_compute(framebuf + 1, pos - 1 - crc_len); + + //if (dlc->muxer->option == mux_option_advanced) + // pos = mux_frame_escape(framebuf + 1, pos - 1) + 1; + + //if (dlc->muxer->option == mux_option_basic) + framebuf[pos ++] = MUX_BASIC_FLAG_SEQ; + //else + // framebuf[pos ++] = MUX_ADVANCED_FLAG_SEQ; + + /* + if (port->write(port, (const char *) framebuf, pos) < pos) + return -EIO; + else + return 0; + + */ + + + int iter; + + printk("sending frame\n"); + for(iter=0;iterops->write(ipc_tty, framebuf, pos); + //printk("ipc tty: %d written\n",res); + if (res != pos) { + TS0710_PRINTK("mux_send_frame error %d\n",res); + return -1; + } + + + return 0; + + +} + /* Creates a UA packet and puts it at the beginning of the pkt pointer */ -static int send_ua(ts0710_con * ts0710, __u8 dlci) +static void send_ua(ts0710_con * ts0710, __u8 dlci) { - __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE]; - short_frame *ua; - - TS0710_DEBUG("send_ua: Creating UA packet to DLCI %d\n", dlci); - - ua = (short_frame *) (buf + 1); - ua->h.addr.ea = 1; - ua->h.addr.cr = ((~(ts0710->initiator)) & 0x1); - ua->h.addr.d = (dlci) & 0x1; - ua->h.addr.server_chn = (dlci) >> 0x1; - ua->h.control = SET_PF(UA); - ua->h.length.ea = 1; - ua->h.length.len = 0; - ua->data[0] = crc_calc((__u8 *) ua, SHORT_CRC_CHECK); - - return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE); + mux_send_frame(dlci, !ts0710->initiator, MUX_UA, 0, 0); } /* Creates a DM packet and puts it at the beginning of the pkt pointer */ -static int send_dm(ts0710_con * ts0710, __u8 dlci) +static void send_dm(ts0710_con * ts0710, __u8 dlci) { - __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE]; - short_frame *dm; - - TS0710_DEBUG("send_dm: Creating DM packet to DLCI %d\n", dlci); - - dm = (short_frame *) (buf + 1); - dm->h.addr.ea = 1; - dm->h.addr.cr = ((~(ts0710->initiator)) & 0x1); - dm->h.addr.d = dlci & 0x1; - dm->h.addr.server_chn = dlci >> 0x1; - dm->h.control = SET_PF(DM); - dm->h.length.ea = 1; - dm->h.length.len = 0; - dm->data[0] = crc_calc((__u8 *) dm, SHORT_CRC_CHECK); - - return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE); + mux_send_frame(dlci, !ts0710->initiator, MUX_DM, 0, 0); } -static int send_sabm(ts0710_con * ts0710, __u8 dlci) +static void send_sabm(ts0710_con * ts0710, __u8 dlci) { - __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE]; - short_frame *sabm; - - TS0710_DEBUG("send_sabm: Creating SABM packet to DLCI %d\n", dlci); - - sabm = (short_frame *) (buf + 1); - sabm->h.addr.ea = 1; - sabm->h.addr.cr = ((ts0710->initiator) & 0x1); - sabm->h.addr.d = dlci & 0x1; - sabm->h.addr.server_chn = dlci >> 0x1; - sabm->h.control = SET_PF(SABM); - sabm->h.length.ea = 1; - sabm->h.length.len = 0; - sabm->data[0] = crc_calc((__u8 *) sabm, SHORT_CRC_CHECK); - - return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE); + mux_send_frame(dlci, ts0710->initiator, MUX_SABM, 0, 0); } -static int send_disc(ts0710_con * ts0710, __u8 dlci) +static void send_disc(ts0710_con * ts0710, __u8 dlci) { - __u8 buf[sizeof(short_frame) + FCS_SIZE + FLAG_SIZE]; - short_frame *disc; - - TS0710_DEBUG("send_disc: Creating DISC packet to DLCI %d\n", dlci); - - disc = (short_frame *) (buf + 1); - disc->h.addr.ea = 1; - disc->h.addr.cr = ((ts0710->initiator) & 0x1); - disc->h.addr.d = dlci & 0x1; - disc->h.addr.server_chn = dlci >> 0x1; - disc->h.control = SET_PF(DISC); - disc->h.length.ea = 1; - disc->h.length.len = 0; - disc->data[0] = crc_calc((__u8 *) disc, SHORT_CRC_CHECK); - - return basic_write(ts0710, buf, sizeof(short_frame) + FCS_SIZE); + mux_send_frame(dlci, !ts0710->initiator, MUX_DISC, 0, 0); } static void queue_uih(mux_send_struct * send_info, __u16 len, @@ -828,303 +491,89 @@ static void queue_uih(mux_send_struct * send_info, __u16 len, /* Turns on the ts0710 flow control */ -static int ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr) +static void ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr) { - __u8 buf[30]; - mcc_short_frame *mcc_pkt; - short_frame *uih_pkt; - __u32 size; - - size = sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE; - uih_pkt = (short_frame *) (buf + 1); - set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), - ts0710->initiator); - uih_pkt->data[sizeof(mcc_short_frame)] = - crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK); - mcc_pkt = (mcc_short_frame *) (uih_pkt->data); - - mcc_pkt->h.type.ea = EA; - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = FCON; - mcc_pkt->h.length.ea = EA; - mcc_pkt->h.length.len = 0; - - return basic_write(ts0710, buf, size); + mux_send_uih(ts0710, cr, FCON, 0, 0); } /* Turns off the ts0710 flow control */ -static int ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr) +static void ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr) { - __u8 buf[30]; - mcc_short_frame *mcc_pkt; - short_frame *uih_pkt; - __u32 size; - - size = (sizeof(short_frame) + sizeof(mcc_short_frame) + FCS_SIZE); - uih_pkt = (short_frame *) (buf + 1); - set_uih_hdr(uih_pkt, CTRL_CHAN, sizeof(mcc_short_frame), - ts0710->initiator); - uih_pkt->data[sizeof(mcc_short_frame)] = - crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK); - mcc_pkt = (mcc_short_frame *) (uih_pkt->data); - - mcc_pkt->h.type.ea = 1; - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = FCOFF; - mcc_pkt->h.length.ea = 1; - mcc_pkt->h.length.len = 0; - - return basic_write(ts0710, buf, size); + mux_send_uih(ts0710, cr, FCOFF, 0, 0); } -/* -static int ts0710_rpn_msg(ts0710_con *ts0710, __u8 cr, __u8 dlci, __u8 req) -{ - char buf[100]; - rpn_msg* rpn_pkt; - __u32 fsize; - __u32 psize; - - fsize = sizeof(rpn_msg); - - if (req) { - fsize -= sizeof(rpn_values); - } - - psize = (fsize - sizeof(short_frame) - FCS_SIZE); - rpn_pkt = (rpn_msg *) buf; +/* Sends an PN-messages and sets the not negotiable parameters to their + default values in ts0710 */ - set_uih_hdr((short_frame *) rpn_pkt, CTRL_CHAN, psize, ts0710->initiator); +static void send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size, + __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr) +{ + + __u8 data[8]; + pn_t *send = (pn_t*)data; - rpn_pkt->fcs = crc_calc((__u8*) rpn_pkt, SHORT_CRC_CHECK); + send->res1 = 0; + send->res2 = 0; + send->dlci = dlci; + send->frame_type = 0; + send->credit_flow = credit_flow; + send->prior = prior; + send->ack_timer = 0; - rpn_pkt->mcc_s_head.type.ea = EA; - rpn_pkt->mcc_s_head.type.cr = cr; - rpn_pkt->mcc_s_head.type.type = RPN; - rpn_pkt->mcc_s_head.length.ea = EA; + send->frame_sizel = frame_size & 0xFF; + send->frame_sizeh = frame_size >> 8; - rpn_pkt->dlci.ea = EA; - rpn_pkt->dlci.cr = 1; - rpn_pkt->dlci.d = dlci & 1; - rpn_pkt->dlci.server_chn = (dlci >> 1); + send->credits = credits; + send->max_nbrof_retrans = 0; - if (req) { - rpn_pkt->mcc_s_head.length.len = 1; - rpn_pkt->rpn_val.bit_rate = rpn_pkt->fcs; - } else { - rpn_pkt->mcc_s_head.length.len = 8; - memcpy(&(rpn_pkt->rpn_val), &rpn_val, sizeof(rpn_values)); - } - return basic_write(ts0710, buf, fsize); -} -*/ -/* -static int ts0710_rls_msg(ts0710_con *ts0710, __u8 cr, __u8 dlci, __u8 err_code) -{ - char buf[100]; - rls_msg *rls_pkt; - __u32 fsize; - __u32 psize; - - fsize = sizeof(rls_msg); - psize = fsize - sizeof(short_frame) - FCS_SIZE; - rls_pkt = (rls_msg *) buf; - - set_uih_hdr((short_frame *) rls_pkt, CTRL_CHAN, psize, ts0710->initiator); - rls_pkt->fcs = crc_calc((__u8*) rls_pkt, SHORT_CRC_CHECK); - - rls_pkt->mcc_s_head.type.ea = EA; - rls_pkt->mcc_s_head.type.cr = cr; - rls_pkt->mcc_s_head.type.type = RLS; - rls_pkt->mcc_s_head.length.ea = EA; - rls_pkt->mcc_s_head.length.len = 2; - - rls_pkt->dlci.ea = EA; - rls_pkt->dlci.cr = 1; - rls_pkt->dlci.d = dlci & 1; - rls_pkt->dlci.server_chn = dlci >> 1; - rls_pkt->error = err_code; - rls_pkt->res = 0; - - return basic_write(ts0710, buf, fsize); + mux_send_uih(ts0710, cr, PN, data, 8); } -*/ -/* Sends an PN-messages and sets the not negotiable parameters to their - default values in ts0710 */ +/* Send a Not supported command - command, which needs 3 bytes */ -static int send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size, - __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr) +static void send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr) { - __u8 buf[30]; - pn_msg *pn_pkt; - __u32 size; - TS0710_DEBUG - ("send_pn_msg: DLCI 0x%02x, prior:0x%02x, frame_size:%d, credit_flow:%x, credits:%d, cr:%x\n", - dlci, prior, frame_size, credit_flow, credits, cr); - - size = sizeof(pn_msg); - pn_pkt = (pn_msg *) (buf + 1); - - set_uih_hdr((void *)pn_pkt, CTRL_CHAN, - size - (sizeof(short_frame) + FCS_SIZE), ts0710->initiator); - pn_pkt->fcs = crc_calc((__u8 *) pn_pkt, SHORT_CRC_CHECK); - - pn_pkt->mcc_s_head.type.ea = 1; - pn_pkt->mcc_s_head.type.cr = cr; - pn_pkt->mcc_s_head.type.type = PN; - pn_pkt->mcc_s_head.length.ea = 1; - pn_pkt->mcc_s_head.length.len = 8; - - pn_pkt->res1 = 0; - pn_pkt->res2 = 0; - pn_pkt->dlci = dlci; - pn_pkt->frame_type = 0; - pn_pkt->credit_flow = credit_flow; - pn_pkt->prior = prior; - pn_pkt->ack_timer = 0; - SET_PN_MSG_FRAME_SIZE(pn_pkt, frame_size); - pn_pkt->credits = credits; - pn_pkt->max_nbrof_retrans = 0; - - return basic_write(ts0710, buf, size); + mux_send_uih(ts0710, cr, NSC, &cmd, 1); } -/* Send a Not supported command - command, which needs 3 bytes */ - -static int send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr) +static void mux_send_uih(ts0710_con * ts0710, __u8 cr,__u8 type, __u8 *data, int len) { - __u8 buf[30]; - nsc_msg *nsc_pkt; - __u32 size; + __u8 *send = kmalloc(len+2,GFP_KERNEL); - size = sizeof(nsc_msg); - nsc_pkt = (nsc_msg *) (buf + 1); + mcc_short_frame_head *head = send; + head->type.ea = 1; + head->type.cr = cr; + head->type.type = type; + head->length.ea = 1; + head->length.len = len; - set_uih_hdr((void *)nsc_pkt, CTRL_CHAN, - sizeof(nsc_msg) - sizeof(short_frame) - FCS_SIZE, - ts0710->initiator); + if (len) + memcpy(send+2,data,len); - nsc_pkt->fcs = crc_calc((__u8 *) nsc_pkt, SHORT_CRC_CHECK); + mux_send_frame(CTRL_CHAN, ts0710->initiator, MUX_UIH, send, len+2); - nsc_pkt->mcc_s_head.type.ea = 1; - nsc_pkt->mcc_s_head.type.cr = cr; - nsc_pkt->mcc_s_head.type.type = NSC; - nsc_pkt->mcc_s_head.length.ea = 1; - nsc_pkt->mcc_s_head.length.len = 1; + kfree(send); - nsc_pkt->command_type.ea = 1; - nsc_pkt->command_type.cr = cmd.cr; - nsc_pkt->command_type.type = cmd.type; - return basic_write(ts0710, buf, size); } static int ts0710_msc_msg(ts0710_con * ts0710, __u8 value, __u8 cr, __u8 dlci) { - __u8 buf[30]; - msc_msg *msc_pkt; - __u32 size; - - size = sizeof(msc_msg); - msc_pkt = (msc_msg *) (buf + 1); - - set_uih_hdr((void *)msc_pkt, CTRL_CHAN, - sizeof(msc_msg) - sizeof(short_frame) - FCS_SIZE, - ts0710->initiator); + __u8 buf[2]; + msc_t *send = (msc_t*) buf; - msc_pkt->fcs = crc_calc((__u8 *) msc_pkt, SHORT_CRC_CHECK); + send->dlci.ea = 1; + send->dlci.cr = 1; + send->dlci.d = dlci & 1; + send->dlci.server_chn = (dlci >> 1) & 0x1f; - msc_pkt->mcc_s_head.type.ea = 1; - msc_pkt->mcc_s_head.type.cr = cr; - msc_pkt->mcc_s_head.type.type = MSC; - msc_pkt->mcc_s_head.length.ea = 1; - msc_pkt->mcc_s_head.length.len = 2; + send->v24_sigs = value; - msc_pkt->dlci.ea = 1; - msc_pkt->dlci.cr = 1; - msc_pkt->dlci.d = dlci & 1; - msc_pkt->dlci.server_chn = (dlci >> 1) & 0x1f; + mux_send_uih(ts0710, cr, MSC, buf, 2); - msc_pkt->v24_sigs = value; - - return basic_write(ts0710, buf, size); -} - -static int ts0710_test_msg(ts0710_con * ts0710, __u8 * test_pattern, __u32 len, - __u8 cr, __u8 * f_buf /*Frame buf */ ) -{ - __u32 size; - - if (len > SHORT_PAYLOAD_SIZE) { - long_frame *uih_pkt; - mcc_long_frame *mcc_pkt; - - size = - (sizeof(long_frame) + sizeof(mcc_long_frame) + len + - FCS_SIZE); - uih_pkt = (long_frame *) (f_buf + 1); - - set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN, len + - sizeof(mcc_long_frame), ts0710->initiator); - uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] = - crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK); - mcc_pkt = (mcc_long_frame *) uih_pkt->data; - - mcc_pkt->h.type.ea = EA; - /* cr tells whether it is a commmand (1) or a response (0) */ - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = TEST; - SET_LONG_LENGTH(mcc_pkt->h.length, len); - memcpy(mcc_pkt->value, test_pattern, len); - } else if (len > (SHORT_PAYLOAD_SIZE - sizeof(mcc_short_frame))) { - long_frame *uih_pkt; - mcc_short_frame *mcc_pkt; - - /* Create long uih packet and short mcc packet */ - size = - (sizeof(long_frame) + sizeof(mcc_short_frame) + len + - FCS_SIZE); - uih_pkt = (long_frame *) (f_buf + 1); - - set_uih_hdr((short_frame *) uih_pkt, CTRL_CHAN, - len + sizeof(mcc_short_frame), ts0710->initiator); - uih_pkt->data[GET_LONG_LENGTH(uih_pkt->h.length)] = - crc_calc((__u8 *) uih_pkt, LONG_CRC_CHECK); - mcc_pkt = (mcc_short_frame *) uih_pkt->data; - - mcc_pkt->h.type.ea = EA; - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = TEST; - mcc_pkt->h.length.ea = EA; - mcc_pkt->h.length.len = len; - memcpy(mcc_pkt->value, test_pattern, len); - } else { - short_frame *uih_pkt; - mcc_short_frame *mcc_pkt; - - size = - (sizeof(short_frame) + sizeof(mcc_short_frame) + len + - FCS_SIZE); - uih_pkt = (short_frame *) (f_buf + 1); - - set_uih_hdr((void *)uih_pkt, CTRL_CHAN, len - + sizeof(mcc_short_frame), ts0710->initiator); - uih_pkt->data[uih_pkt->h.length.len] = - crc_calc((__u8 *) uih_pkt, SHORT_CRC_CHECK); - mcc_pkt = (mcc_short_frame *) uih_pkt->data; - - mcc_pkt->h.type.ea = EA; - mcc_pkt->h.type.cr = cr; - mcc_pkt->h.type.type = TEST; - mcc_pkt->h.length.ea = EA; - mcc_pkt->h.length.len = len; - memcpy(mcc_pkt->value, test_pattern, len); - - } - return basic_write(ts0710, f_buf, size); + return 0; } static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr) @@ -1147,116 +596,19 @@ static void set_uih_hdr(short_frame * uih_pkt, __u8 dlci, __u32 len, __u8 cr) void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) { - __u8 *tbuf = NULL; mcc_short_frame *mcc_short_pkt; int j; - if (longpkt) { - mcc_short_pkt = - (mcc_short_frame *) (((long_frame *) data)->data); - } else { - mcc_short_pkt = - (mcc_short_frame *) (((short_frame *) data)->data); - } - - switch (mcc_short_pkt->h.type.type) { - case TEST: - if (mcc_short_pkt->h.type.cr == MCC_RSP) { - TS0710_DEBUG("Received test command response\n"); - - if (ts0710->be_testing) { - if ((mcc_short_pkt->h.length.ea) == 0) { - mcc_long_frame *mcc_long_pkt; - mcc_long_pkt = - (mcc_long_frame *) mcc_short_pkt; - if (GET_LONG_LENGTH - (mcc_long_pkt->h.length) != - TEST_PATTERN_SIZE) { - ts0710->test_errs = - TEST_PATTERN_SIZE; - TS0710_DEBUG - ("Err: received test pattern is %d bytes long, not expected %d\n", - GET_LONG_LENGTH - (mcc_long_pkt->h.length), - TEST_PATTERN_SIZE); - } else { - ts0710->test_errs = 0; - for (j = 0; - j < TEST_PATTERN_SIZE; - j++) { - if (mcc_long_pkt-> - value[j] != - (j & 0xFF)) { - (ts0710-> - test_errs)++; - } - } - } - - } else { - -#if TEST_PATTERN_SIZE < 128 - if (mcc_short_pkt->h.length.len != - TEST_PATTERN_SIZE) { -#endif - - ts0710->test_errs = - TEST_PATTERN_SIZE; - TS0710_DEBUG - ("Err: received test pattern is %d bytes long, not expected %d\n", - mcc_short_pkt->h.length. - len, TEST_PATTERN_SIZE); - -#if TEST_PATTERN_SIZE < 128 - } else { - ts0710->test_errs = 0; - for (j = 0; - j < TEST_PATTERN_SIZE; - j++) { - if (mcc_short_pkt-> - value[j] != - (j & 0xFF)) { - (ts0710-> - test_errs)++; - } - } - } -#endif - - } - - ts0710->be_testing = 0; /* Clear the flag */ - wake_up_interruptible(&ts0710->test_wait); - } else { - TS0710_DEBUG - ("Err: shouldn't or late to get test cmd response\n"); - } - } else { - tbuf = (__u8 *) kmalloc(len + 32, GFP_ATOMIC); - if (!tbuf) { - break; - } + if (longpkt) + mcc_short_pkt = (mcc_short_frame *) (((long_frame *) data)->data); + else + mcc_short_pkt = (mcc_short_frame *) (((short_frame *) data)->data); - if ((mcc_short_pkt->h.length.ea) == 0) { - mcc_long_frame *mcc_long_pkt; - mcc_long_pkt = (mcc_long_frame *) mcc_short_pkt; - ts0710_test_msg(ts0710, mcc_long_pkt->value, - GET_LONG_LENGTH(mcc_long_pkt->h. - length), - MCC_RSP, tbuf); - } else { - ts0710_test_msg(ts0710, mcc_short_pkt->value, - mcc_short_pkt->h.length.len, - MCC_RSP, tbuf); - } - kfree(tbuf); - } - break; + switch (mcc_short_pkt->h.type.type) { case FCON: /*Flow control on command */ - TS0710_PRINTK - ("MUX Received Flow control(all channels) on command\n"); + TS0710_PRINTK ("MUX Received Flow control(all channels) on command\n"); if (mcc_short_pkt->h.type.cr == MCC_CMD) { ts0710->dlci[0].state = CONNECTED; ts0710_fcon_msg(ts0710, MCC_RSP); @@ -1265,8 +617,7 @@ void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) break; case FCOFF: /*Flow control off command */ - TS0710_PRINTK - ("MUX Received Flow control(all channels) off command\n"); + TS0710_PRINTK ("MUX Received Flow control(all channels) off command\n"); if (mcc_short_pkt->h.type.cr == MCC_CMD) { for (j = 0; j < TS0710_MAX_CHN; j++) { ts0710->dlci[j].state = FLOW_STOPPED; @@ -1288,39 +639,22 @@ void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) send_dm(ts0710, dlci); break; } + if (mcc_short_pkt->h.type.cr == MCC_CMD) { TS0710_DEBUG("Received Modem status command\n"); - if (v24_sigs & 2) { - if (ts0710->dlci[dlci].state == - CONNECTED) { - TS0710_LOG - ("MUX Received Flow off on dlci %d\n", - dlci); - ts0710->dlci[dlci].state = - FLOW_STOPPED; - } - } else { - if (ts0710->dlci[dlci].state == - FLOW_STOPPED) { - ts0710->dlci[dlci].state = - CONNECTED; - TS0710_LOG - ("MUX Received Flow on on dlci %d\n", - dlci); - mux_sched_send(); - } + if ((v24_sigs & 2) && (ts0710->dlci[dlci].state == CONNECTED)) { + TS0710_LOG ("MUX Received Flow off on dlci %d\n", dlci); + ts0710->dlci[dlci].state = FLOW_STOPPED; + + } else if (MUX_STOPPED(ts0710,dlci)) { + ts0710->dlci[dlci].state = CONNECTED; + TS0710_LOG ("MUX Received Flow on on dlci %d\n", dlci); + mux_sched_send(); } ts0710_msc_msg(ts0710, v24_sigs, MCC_RSP, dlci); -/* - if (!(ts0710->dlci[dlci].initiated) && !(ts0710->dlci[dlci].initiator)) { - ts0710_msc_msg(ts0710, EA | RTR | RTC | DV, MCC_CMD, dlci); - ts0710->dlci[dlci].initiated = 1; - } -*/ } else { - TS0710_DEBUG - ("Received Modem status response\n"); + TS0710_DEBUG ("Received Modem status response\n"); if (v24_sigs & 2) { TS0710_DEBUG("Flow stop accepted\n"); @@ -1329,47 +663,6 @@ void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) break; } - /* case RPN: *//*Remote port negotiation command */ - -/* { - __u8 dlci; - - dlci = (mcc_short_pkt->value[0]) >> 2; - - if (mcc_short_pkt->h.type.cr == MCC_CMD) { - if (mcc_short_pkt->h.length.len == 1) { - TS0710_DEBUG("Received Remote port negotiation command\n"); - ts0710_rpn_msg(ts0710, MCC_RSP, dlci, 0); - } else { -*/ - /* Accept the other sides settings (accept all for now) */ -/* TS0710_DEBUG("Received Remote port negotiation respons\n"); - memcpy(&rpn_val, &mcc_short_pkt->value[1], 8); - ts0710_rpn_msg(ts0710, MCC_RSP, dlci, 0); -*/ - /* Zero the parametermask after response */ -/* memset(&rpn_val.pm, 0, 2); - } - } - break; - } -*/ -/* - case RLS: *//*Remote line status */ -/* { - __u8 dlci; - __u8 err_code; - - TS0710_DEBUG("Received Remote line status\n"); - if (mcc_short_pkt->h.type.cr == MCC_CMD) { - dlci = mcc_short_pkt->value[0] >> 2; - err_code = mcc_short_pkt->value[1]; - - ts0710_rls_msg(ts0710, MCC_RSP, dlci, err_code); - } - break; - } -*/ case PN: /*DLC parameter negotiation */ { __u8 dlci; @@ -1379,36 +672,27 @@ void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) pn_pkt = (pn_msg *) data; dlci = pn_pkt->dlci; frame_size = GET_PN_MSG_FRAME_SIZE(pn_pkt); - TS0710_DEBUG - ("Received DLC parameter negotiation, PN\n"); + TS0710_DEBUG ("Received DLC parameter negotiation, PN\n"); + if (pn_pkt->mcc_s_head.type.cr == MCC_CMD) { TS0710_DEBUG("received PN command with:\n"); TS0710_DEBUG("Frame size:%d\n", frame_size); - frame_size = - min(frame_size, ts0710->dlci[dlci].mtu); - send_pn_msg(ts0710, pn_pkt->prior, frame_size, - 0, 0, dlci, MCC_RSP); + frame_size = min(frame_size, ts0710->dlci[dlci].mtu); + send_pn_msg(ts0710, pn_pkt->prior, frame_size, 0, 0, dlci, MCC_RSP); ts0710->dlci[dlci].mtu = frame_size; - TS0710_DEBUG("process_mcc : mtu set to %d\n", - ts0710->dlci[dlci].mtu); + TS0710_DEBUG("process_mcc : mtu set to %d\n", ts0710->dlci[dlci].mtu); } else { TS0710_DEBUG("received PN response with:\n"); TS0710_DEBUG("Frame size:%d\n", frame_size); - frame_size = - min(frame_size, ts0710->dlci[dlci].mtu); + frame_size = min(frame_size, ts0710->dlci[dlci].mtu); ts0710->dlci[dlci].mtu = frame_size; - TS0710_DEBUG - ("process_mcc : mtu set on dlci:%d to %d\n", - dlci, ts0710->dlci[dlci].mtu); if (ts0710->dlci[dlci].state == NEGOTIATING) { ts0710->dlci[dlci].state = CONNECTING; - wake_up_interruptible(&ts0710-> - dlci[dlci]. - open_wait); + wake_up_interruptible(&ts0710-> dlci[dlci]. open_wait); } } break; @@ -1425,39 +709,15 @@ void process_mcc(__u8 * data, __u32 len, ts0710_con * ts0710, int longpkt) } } -static mux_recv_packet *get_mux_recv_packet(__u32 size) -{ - mux_recv_packet *recv_packet; - - TS0710_DEBUG("Enter into get_mux_recv_packet"); - - recv_packet = - (mux_recv_packet *) kmalloc(sizeof(mux_recv_packet), GFP_ATOMIC); - if (!recv_packet) { - return 0; - } - - recv_packet->data = (__u8 *) kmalloc(size, GFP_ATOMIC); - if (!(recv_packet->data)) { - kfree(recv_packet); - return 0; - } - recv_packet->length = 0; - recv_packet->next = 0; - return recv_packet; -} static void free_mux_recv_packet(mux_recv_packet * recv_packet) { - TS0710_DEBUG("Enter into free_mux_recv_packet"); - - if (!recv_packet) { + if (!recv_packet) return; - } - if (recv_packet->data) { + if (recv_packet->data) kfree(recv_packet->data); - } + kfree(recv_packet); } @@ -1465,9 +725,8 @@ static void free_mux_recv_struct(mux_recv_struct * recv_info) { mux_recv_packet *recv_packet1, *recv_packet2; - if (!recv_info) { + if (!recv_info) return; - } recv_packet1 = recv_info->mux_packet; while (recv_packet1) { @@ -1489,159 +748,85 @@ static inline void add_post_recv_queue(mux_recv_struct ** head, static void ts0710_flow_on(__u8 dlci, ts0710_con * ts0710) { int i; - __u8 cmdtty; - __u8 datatty; struct tty_struct *tty; mux_recv_struct *recv_info; - if ((ts0710->dlci[0].state != CONNECTED) - && (ts0710->dlci[0].state != FLOW_STOPPED)) { + if (!(ts0710->dlci[0].state) & (CONNECTED | FLOW_STOPPED)) return; - } else if ((ts0710->dlci[dlci].state != CONNECTED) - && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { + + if (!(ts0710->dlci[dlci].state) & (CONNECTED | FLOW_STOPPED)) return; - } - if (!(ts0710->dlci[dlci].flow_control)) { + if (!(ts0710->dlci[dlci].flow_control)) return; - } - cmdtty = dlci2tty[dlci].cmdtty; - datatty = dlci2tty[dlci].datatty; - if (cmdtty != datatty) { - /* Check AT cmd tty */ - tty = mux_table[cmdtty]; - if (mux_tty[cmdtty] && tty) { - if (test_bit(TTY_THROTTLED, &tty->flags)) { - return; - } - } - recv_info = mux_recv_info[cmdtty]; - if (mux_recv_info_flags[cmdtty] && recv_info) { - if (recv_info->total) { - return; - } - } + ts0710_msc_msg(ts0710, EA | RTC | RTR | DV, MCC_CMD, dlci); + + ts0710->dlci[dlci].flow_control = 0; - /* Check data tty */ - tty = mux_table[datatty]; - if (mux_tty[datatty] && tty) { - if (test_bit(TTY_THROTTLED, &tty->flags)) { - return; - } - } - recv_info = mux_recv_info[datatty]; - if (mux_recv_info_flags[datatty] && recv_info) { - if (recv_info->total) { - return; - } - } - } - for (i = 0; i < 3; i++) { - if (ts0710_msc_msg(ts0710, EA | RTC | RTR | DV, MCC_CMD, dlci) < - 0) { - continue; - } else { - TS0710_LOG("MUX send Flow on on dlci %d\n", dlci); - ts0710->dlci[dlci].flow_control = 0; - break; - } - } } static void ts0710_flow_off(struct tty_struct *tty, __u8 dlci, - ts0710_con * ts0710) + ts0710_con * ts0710) { + int i; - if (test_and_set_bit(TTY_THROTTLED, &tty->flags)) { + TS0710_PRINTK("TS0710: flow off\n"); + + if (test_and_set_bit(TTY_THROTTLED, &tty->flags)) return; - } - if ((ts0710->dlci[0].state != CONNECTED) - && (ts0710->dlci[0].state != FLOW_STOPPED)) { + + if ((ts0710->dlci[0].state != CONNECTED) && (ts0710->dlci[0].state != FLOW_STOPPED)) return; - } else if ((ts0710->dlci[dlci].state != CONNECTED) - && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { + + if ((ts0710->dlci[dlci].state != CONNECTED) + && (ts0710->dlci[dlci].state != FLOW_STOPPED)) return; - } - if (ts0710->dlci[dlci].flow_control) { + + if (ts0710->dlci[dlci].flow_control) return; - } + for (i = 0; i < 3; i++) { - if (ts0710_msc_msg - (ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, dlci) < 0) { + if (ts0710_msc_msg (ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, dlci) < 0) continue; - } else { - TS0710_LOG("MUX send Flow off on dlci %d\n", dlci); - ts0710->dlci[dlci].flow_control = 1; - break; - } + + TS0710_LOG("MUX send Flow off on dlci %d\n", dlci); + ts0710->dlci[dlci].flow_control = 1; + break; } } -int ts0710_recv_data(ts0710_con * ts0710, char *data, int len) +void ts0710_recv_data_server(ts0710_con * ts0710, short_frame *short_pkt, int len) { - short_frame *short_pkt; - long_frame *long_pkt; - __u8 *uih_data_start; - __u32 uih_len; - __u8 dlci; - __u8 be_connecting; -#ifdef TS0710DEBUG - unsigned long t; -#endif - short_pkt = (short_frame *) data; +__u8 be_connecting; +__u8 *uih_data_start; + __u32 uih_len; + long_frame *long_pkt; - dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d; switch (CLR_PF(short_pkt->h.control)) { case SABM: TS0710_DEBUG("SABM-packet received\n"); -/*For BP UART problem - if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) ) - break; -*/ - - if (!dlci) { TS0710_DEBUG("server channel == 0\n"); ts0710->dlci[0].state = CONNECTED; TS0710_DEBUG("sending back UA - control channel\n"); - send_ua(ts0710, dlci); + send_ua(ts0710, 0); wake_up_interruptible(&ts0710->dlci[0].open_wait); - } else if (valid_dlci(dlci)) { - - TS0710_DEBUG("Incomming connect on channel %d\n", dlci); - - TS0710_DEBUG("sending UA, dlci %d\n", dlci); - send_ua(ts0710, dlci); - - ts0710->dlci[dlci].state = CONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - - } else { - TS0710_DEBUG("invalid dlci %d, sending DM\n", dlci); - send_dm(ts0710, dlci); - } break; case UA: TS0710_DEBUG("UA packet received\n"); -/*For BP UART problem - if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) ) - break; -*/ - - if (!dlci) { TS0710_DEBUG("server channel == 0\n"); if (ts0710->dlci[0].state == CONNECTING) { @@ -1654,39 +839,12 @@ int ts0710_recv_data(ts0710_con * ts0710, char *data, int len) TS0710_DEBUG (" Something wrong receiving UA packet\n"); } - } else if (valid_dlci(dlci)) { - TS0710_DEBUG("Incomming UA on channel %d\n", dlci); - - if (ts0710->dlci[dlci].state == CONNECTING) { - ts0710->dlci[dlci].state = CONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci]. - open_wait); - } else if (ts0710->dlci[dlci].state == DISCONNECTING) { - ts0710->dlci[dlci].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci]. - open_wait); - wake_up_interruptible(&ts0710->dlci[dlci]. - close_wait); - ts0710_reset_dlci(dlci); - } else { - TS0710_DEBUG - (" Something wrong receiving UA packet\n"); - } - } else { - TS0710_DEBUG("invalid dlci %d\n", dlci); - } break; case DM: TS0710_DEBUG("DM packet received\n"); -/*For BP UART problem - if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) ) - break; -*/ - - if (!dlci) { TS0710_DEBUG("server channel == 0\n"); if (ts0710->dlci[0].state == CONNECTING) { @@ -1698,383 +856,259 @@ int ts0710_recv_data(ts0710_con * ts0710, char *data, int len) if (be_connecting) { ts0710->dlci[0].state = REJECTED; } - } else if (valid_dlci(dlci)) { - TS0710_DEBUG("Incomming DM on channel %d\n", dlci); - - if (ts0710->dlci[dlci].state == CONNECTING) { - ts0710->dlci[dlci].state = REJECTED; - } else { - ts0710->dlci[dlci].state = DISCONNECTED; - } - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - wake_up_interruptible(&ts0710->dlci[dlci].close_wait); - ts0710_reset_dlci(dlci); - } else { - TS0710_DEBUG("invalid dlci %d\n", dlci); - } break; case DISC: TS0710_DEBUG("DISC packet received\n"); -/*For BP UART problem - if( crc_check((__u8*) short_pkt, SHORT_CRC_CHECK, short_pkt->data[0]) ) - break; -*/ - - if (!dlci) { TS0710_DEBUG("server channel == 0\n"); - send_ua(ts0710, dlci); + send_ua(ts0710, 0); TS0710_DEBUG("DISC, sending back UA\n"); ts0710_upon_disconnect(); - } else if (valid_dlci(dlci)) { - TS0710_DEBUG("Incomming DISC on channel %d\n", dlci); - - send_ua(ts0710, dlci); - TS0710_DEBUG("DISC, sending back UA\n"); - - ts0710->dlci[dlci].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci].open_wait); - wake_up_interruptible(&ts0710->dlci[dlci].close_wait); - ts0710_reset_dlci(dlci); - } else { - TS0710_DEBUG("invalid dlci %d\n", dlci); - } break; case UIH: TS0710_DEBUG("UIH packet received\n"); - if ((dlci >= TS0710_MAX_CHN)) { - TS0710_DEBUG("invalid dlci %d\n", dlci); - send_dm(ts0710, dlci); - break; - } - if (GET_PF(short_pkt->h.control)) { - TS0710_LOG - ("MUX Error %s: UIH packet with P/F set, discard it!\n", + TS0710_LOG ("MUX Error %s: UIH packet with P/F set, discard it!\n", __FUNCTION__); break; } - if ((ts0710->dlci[dlci].state != CONNECTED) - && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { - TS0710_LOG - ("MUX Error %s: DLCI %d not connected, discard it!\n", - __FUNCTION__, dlci); - send_dm(ts0710, dlci); - break; - } + // FIXME: connected and flow if ((short_pkt->h.length.ea) == 0) { TS0710_DEBUG("Long UIH packet received\n"); - long_pkt = (long_frame *) data; + long_pkt = (long_frame *) short_pkt; uih_len = GET_LONG_LENGTH(long_pkt->h.length); uih_data_start = long_pkt->h.data; TS0710_DEBUG("long packet length %d\n", uih_len); -/*For BP UART problem - if (crc_check(data, LONG_CRC_CHECK, *(uih_data_start + uih_len))) - break; -*/ } else { TS0710_DEBUG("Short UIH pkt received\n"); uih_len = short_pkt->h.length.len; uih_data_start = short_pkt->data; -/*For BP UART problem - if (crc_check(data, SHORT_CRC_CHECK, *(uih_data_start + uih_len))) - break; -*/ } - if (dlci == 0) { TS0710_DEBUG("UIH on serv_channel 0\n"); - process_mcc(data, len, ts0710, + process_mcc(short_pkt, len, ts0710, !(short_pkt->h.length.ea)); - } else if (valid_dlci(dlci)) { - /* do tty dispatch */ - __u8 tag; - __u8 tty_idx; - struct tty_struct *tty; - __u8 queue_data; - __u8 post_recv; - __u8 flow_control; - mux_recv_struct *recv_info; - int recv_room; - mux_recv_packet *recv_packet, *recv_packet2; - - TS0710_DEBUG("UIH on channel %d\n", dlci); - - if (uih_len > ts0710->dlci[dlci].mtu) { - TS0710_PRINTK - ("MUX Error: DLCI:%d, uih_len:%d is bigger than mtu:%d, discard data!\n", - dlci, uih_len, ts0710->dlci[dlci].mtu); - break; - } - tag = *uih_data_start; - uih_data_start++; - uih_len--; + break; - if (!uih_len) { - break; - } + default: + TS0710_DEBUG("illegal packet\n"); + break; + } - switch (tag) { - case CMDTAG: - tty_idx = dlci2tty[dlci].cmdtty; - TS0710_DEBUG("CMDTAG on DLCI:%d, /dev/mux%d\n", - dlci, tty_idx); - TS0710_DEBUGSTR(uih_data_start, uih_len); - if (!(iscmdtty[tty_idx])) { - TS0710_PRINTK - ("MUX Error: %s: Wrong CMDTAG on DLCI:%d, /dev/mux%d\n", - __FUNCTION__, dlci, tty_idx); - } - break; - case DATATAG: - default: - tty_idx = dlci2tty[dlci].datatty; - TS0710_DEBUG - ("NON-CMDTAG on DLCI:%d, /dev/mux%d\n", - dlci, tty_idx); - if (iscmdtty[tty_idx]) { - TS0710_PRINTK - ("MUX Error: %s: Wrong NON-CMDTAG on DLCI:%d, /dev/mux%d\n", - __FUNCTION__, dlci, tty_idx); - } - break; - } - tty = mux_table[tty_idx]; - if ((!mux_tty[tty_idx]) || (!tty)) { - TS0710_PRINTK - ("MUX: No application waiting for, discard it! /dev/mux%d\n", - tty_idx); - } else { /* Begin processing received data */ - if ((!mux_recv_info_flags[tty_idx]) - || (!mux_recv_info[tty_idx])) { - TS0710_PRINTK - ("MUX Error: No mux_recv_info, discard it! /dev/mux%d\n", - tty_idx); - break; - } +} - recv_info = mux_recv_info[tty_idx]; - if (recv_info->total > 8192) { - TS0710_PRINTK - ("MUX : discard data for tty_idx:%d, recv_info->total > 8192 \n", - tty_idx); - break; - } +void process_uih(ts0710_con * ts0710, char *data, int len, __u8 dlci){ - queue_data = 0; - post_recv = 0; - flow_control = 0; - recv_room = 65535; - if (tty->receive_room) - recv_room = tty->receive_room; - - if (test_bit(TTY_THROTTLED, &tty->flags)) { - queue_data = 1; - } else { - if (recv_info->total) { - queue_data = 1; - post_recv = 1; - } else if (recv_room < uih_len) { - queue_data = 1; - flow_control = 1; - } - - if ((recv_room - - (uih_len + recv_info->total)) < - ts0710->dlci[dlci].mtu) { - flow_control = 1; - } - } + short_frame *short_pkt = (short_frame *) data; + long_frame *long_pkt; + __u8 *uih_data_start; + __u32 uih_len; + __u8 tag; + __u8 tty_idx; + struct tty_struct *tty; + __u8 queue_data; + __u8 post_recv; + __u8 flow_control; + mux_recv_struct *recv_info; + int recv_room; + mux_recv_packet *recv_packet, *recv_packet2; - if (!queue_data) { - /* Put received data into read buffer of tty */ - TS0710_DEBUG - ("Put received data into read buffer of /dev/mux%d", - tty_idx); -#ifdef TS0710DEBUG - t = jiffies; -#endif + if ((ts0710->dlci[dlci].state != CONNECTED) + && (ts0710->dlci[dlci].state != FLOW_STOPPED)) { + TS0710_LOG ("MUX Error %s: DLCI %d not connected, discard it!\n", + __FUNCTION__, dlci); + send_dm(ts0710, dlci); + return; + } - (tty->ldisc.ops->receive_buf) (tty, - uih_data_start, - NULL, - uih_len); + if ((short_pkt->h.length.ea) == 0) { + TS0710_DEBUG("Long UIH packet received\n"); + long_pkt = (long_frame *) data; + uih_len = GET_LONG_LENGTH(long_pkt->h.length); + uih_data_start = long_pkt->h.data; + TS0710_DEBUG("long packet length %d\n", uih_len); -#ifdef TS0710DEBUG - TS0710_DEBUG - ("tty->ldisc.ops->receive_buf take ticks: %lu", - (jiffies - t)); -#endif + } else { + TS0710_DEBUG("Short UIH pkt received\n"); + uih_len = short_pkt->h.length.len; + uih_data_start = short_pkt->data; - } else { /* Queue data */ - - TS0710_DEBUG - ("Put received data into recv queue of /dev/mux%d", - tty_idx); - if (recv_info->total) { - /* recv_info is already linked into mux_recv_queue */ - - recv_packet = - get_mux_recv_packet - (uih_len); - if (!recv_packet) { - TS0710_PRINTK - ("MUX %s: no memory\n", - __FUNCTION__); - break; - } - - memcpy(recv_packet->data, - uih_data_start, uih_len); - recv_packet->length = uih_len; - recv_info->total += uih_len; - recv_packet->next = NULL; - - if (!(recv_info->mux_packet)) { - recv_info->mux_packet = - recv_packet; - } else { - recv_packet2 = - recv_info-> - mux_packet; - while (recv_packet2-> - next) { - recv_packet2 = - recv_packet2-> - next; - } - recv_packet2->next = - recv_packet; - } /* End if( !(recv_info->mux_packet) ) */ - } else { /* recv_info->total == 0 */ - if (uih_len > - TS0710MUX_RECV_BUF_SIZE) { - TS0710_PRINTK - ("MUX Error: tty_idx:%d, uih_len == %d is too big\n", - tty_idx, uih_len); - uih_len = - TS0710MUX_RECV_BUF_SIZE; - } - memcpy(recv_info->data, - uih_data_start, uih_len); - recv_info->length = uih_len; - recv_info->total = uih_len; - - add_post_recv_queue - (&mux_recv_queue, - recv_info); - } /* End recv_info->total == 0 */ - } /* End Queue data */ - - if (flow_control) { - /* Do something for flow control */ - ts0710_flow_off(tty, dlci, ts0710); - } + } - if (tty_idx == - dlci2tty[TS0710MUX_GPRS1_DLCI].datatty) { - if (add_count - (TS0710MUX_GPRS1_RECV_COUNT_IDX, - uih_len) < 0) { - post_recv_count_flag = 1; - post_recv = 1; - mux_data_count2 - [TS0710MUX_GPRS1_RECV_COUNT_IDX] - += uih_len; - } - } else if (tty_idx == - dlci2tty[TS0710MUX_GPRS2_DLCI]. - datatty) { - if (add_count - (TS0710MUX_GPRS2_RECV_COUNT_IDX, - uih_len) < 0) { - post_recv_count_flag = 1; - post_recv = 1; - mux_data_count2 - [TS0710MUX_GPRS2_RECV_COUNT_IDX] - += uih_len; - } - } - if (post_recv) - schedule_work(&post_recv_tqueue); - } /* End processing received data */ - } else { - TS0710_DEBUG("invalid dlci %d\n", dlci); + TS0710_DEBUG("UIH on channel %d\n", dlci); + + if (uih_len > ts0710->dlci[dlci].mtu) { + TS0710_PRINTK + ("MUX Error: DLCI:%d, uih_len:%d is bigger than mtu:%d, discard data!\n", + dlci, uih_len, ts0710->dlci[dlci].mtu); + return; + } + + tag = *uih_data_start; + uih_data_start++; + uih_len--; + + if (!uih_len) + return; + + + printk("uih tag %x on dlci %d\n",tag,dlci); + + tty_idx = dlci-1; + tty = mux_table[tty_idx]; + + if ((!mux_tty[tty_idx]) || (!tty)) { + TS0710_PRINTK + ("MUX: No application waiting for, discard it! /dev/mux%d\n", + tty_idx); + return; + + } + + if ((!mux_recv_info_flags[tty_idx]) + || (!mux_recv_info[tty_idx])) { + TS0710_PRINTK + ("MUX Error: No mux_recv_info, discard it! /dev/mux%d\n", + tty_idx); + return; + } + + recv_info = mux_recv_info[tty_idx]; + if (recv_info->total > 8192) { + TS0710_PRINTK + ("MUX : discard data for tty_idx:%d, recv_info->total > 8192 \n", + tty_idx); + return; + } + + queue_data = 0; + post_recv = 0; + flow_control = 0; + recv_room = 65535; + if (tty->receive_room) + recv_room = tty->receive_room; + + if (recv_info->total) + post_recv = 1; + + + if ((recv_room - (uih_len + recv_info->total)) < + ts0710->dlci[dlci].mtu) { + flow_control = 1; + } + + + tty->ldisc.ops->receive_buf(tty, uih_data_start, NULL, uih_len); + + + if (flow_control) + ts0710_flow_off(tty, dlci, ts0710); + +} + +void ts0710_recv_data(ts0710_con * ts0710, char *data, int len) +{ + short_frame *short_pkt; + long_frame *long_pkt; + __u8 *uih_data_start; + __u32 uih_len; + __u8 dlci; + __u8 be_connecting; + + short_pkt = (short_frame *) data; + + dlci = short_pkt->h.addr.server_chn << 1 | short_pkt->h.addr.d; + if (!dlci) + return ts0710_recv_data_server(ts0710, short_pkt, len); + + switch (CLR_PF(short_pkt->h.control)) { + case SABM: + + TS0710_PRINTK("Incomming connect on channel %d\n", dlci); + + send_ua(ts0710, dlci); + + ts0710->dlci[dlci].state = CONNECTED; + wake_up_interruptible(&ts0710->dlci[dlci].open_wait); + + + break; + + case UA: + + TS0710_DEBUG("Incomming UA on channel %d\n", dlci); + + if (ts0710->dlci[dlci].state == CONNECTING) { + ts0710->dlci[dlci].state = CONNECTED; + wake_up_interruptible(&ts0710->dlci[dlci]. + open_wait); + } else if (ts0710->dlci[dlci].state == DISCONNECTING) { + ts0710->dlci[dlci].state = DISCONNECTED; + wake_up_interruptible(&ts0710->dlci[dlci]. + open_wait); + wake_up_interruptible(&ts0710->dlci[dlci]. + close_wait); + ts0710_reset_dlci(dlci); } + + break; + + case DM: + + TS0710_DEBUG("Incomming DM on channel %d\n", dlci); + + if (ts0710->dlci[dlci].state == CONNECTING) + ts0710->dlci[dlci].state = REJECTED; + else + ts0710->dlci[dlci].state = DISCONNECTED; + + wake_up_interruptible(&ts0710->dlci[dlci].open_wait); + wake_up_interruptible(&ts0710->dlci[dlci].close_wait); + ts0710_reset_dlci(dlci); + + + break; + + case DISC: + + send_ua(ts0710, dlci); + + ts0710->dlci[dlci].state = DISCONNECTED; + wake_up_interruptible(&ts0710->dlci[dlci].open_wait); + wake_up_interruptible(&ts0710->dlci[dlci].close_wait); + ts0710_reset_dlci(dlci); + + + break; + + case UIH: + + process_uih(ts0710, data,len, dlci); + break; default: - TS0710_DEBUG("illegal packet\n"); + TS0710_PRINTK("illegal packet\n"); break; } return 0; } -/* -int ts0710_send_data(ts0710_con *ts0710, __u8 dlci, __u8 *data, __u32 count) -{ - __u32 c, total = 0; - __u8 tag, first; - - if( ts0710->dlci[0].state == FLOW_STOPPED ){ - TS0710_DEBUG("Flow stopped on all channels, returning zero\n"); -*/ -/* - return -EFLOWSTOPPED; - } else if( ts0710->dlci[dlci].state == FLOW_STOPPED ){ - TS0710_DEBUG("Flow stopped, returning zero\n"); -*/ -/* - return -EFLOWSTOPPED; - } else if( ts0710->dlci[dlci].state == CONNECTED ){ - - TS0710_DEBUG("trying to send %d bytes\n", count); - tag = *data; - first = 1; -*/ - /* The first byte is always a Cmd/Data tag */ -/* - while( count > 1 ){ - - c = min(count, ts0710->dlci[dlci].mtu); - if( queue_uih(data, c, ts0710, dlci) <= 0 ) { - break; - } - - total += (c - 1); - data += (c - 1); - *data = tag; - count -= (c - 1); - - if( first ) { - first = 0; - total++; - } - } - TS0710_DEBUG("sent %d bytes\n", total); - return total; - } else { - TS0710_DEBUG("DLCI %d not connected\n", dlci); - return -EDISCONNECTED; - } -} -*/ - /* Close ts0710 channel */ static void ts0710_close_channel(__u8 dlci) { @@ -2090,40 +1124,38 @@ static void ts0710_close_channel(__u8 dlci) } else if (ts0710->dlci[dlci].state == DISCONNECTING) { /* Reentry */ return; - } else { - ts0710->dlci[dlci].state = DISCONNECTING; - try = 3; - while (try--) { - t = jiffies; - send_disc(ts0710, dlci); - interruptible_sleep_on_timeout(&ts0710->dlci[dlci]. - close_wait, - TS0710MUX_TIME_OUT); - if (ts0710->dlci[dlci].state == DISCONNECTED) { - break; - } else if (signal_pending(current)) { - TS0710_PRINTK - ("MUX DLCI %d Send DISC got signal!\n", - dlci); - break; - } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { - TS0710_PRINTK - ("MUX DLCI %d Send DISC timeout!\n", dlci); - continue; - } + } + + ts0710->dlci[dlci].state = DISCONNECTING; + try = 3; + while (try--) { + t = jiffies; + send_disc(ts0710, dlci); + interruptible_sleep_on_timeout(&ts0710->dlci[dlci]. + close_wait, + TS0710MUX_TIME_OUT); + if (ts0710->dlci[dlci].state == DISCONNECTED) { + break; + } else if (signal_pending(current)) { + TS0710_PRINTK ("MUX DLCI %d Send DISC got signal!\n", dlci); + break; + } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { + TS0710_PRINTK ("MUX DLCI %d Send DISC timeout!\n", dlci); + continue; } + } - if (ts0710->dlci[dlci].state != DISCONNECTED) { - if (dlci == 0) { /* Control Channel */ - ts0710_upon_disconnect(); - } else { /* Other Channel */ - ts0710->dlci[dlci].state = DISCONNECTED; - wake_up_interruptible(&ts0710->dlci[dlci]. - close_wait); - ts0710_reset_dlci(dlci); - } + if (ts0710->dlci[dlci].state != DISCONNECTED) { + if (dlci == 0) { /* Control Channel */ + ts0710_upon_disconnect(); + } else { /* Other Channel */ + ts0710->dlci[dlci].state = DISCONNECTED; + wake_up_interruptible(&ts0710->dlci[dlci]. + close_wait); + ts0710_reset_dlci(dlci); } } + } int ts0710_open_channel(__u8 dlci) @@ -2135,8 +1167,7 @@ int ts0710_open_channel(__u8 dlci) retval = -ENODEV; if (dlci == 0) { // control channel - if ((ts0710->dlci[0].state == CONNECTED) - || (ts0710->dlci[0].state == FLOW_STOPPED)) { + if (ts0710->dlci[0].state & ( CONNECTED | FLOW_STOPPED )) { return 0; } else if (ts0710->dlci[0].state == CONNECTING) { /* Reentry */ @@ -2161,9 +1192,7 @@ int ts0710_open_channel(__u8 dlci) DISCONNECTED) { break; } else if (signal_pending(current)) { - TS0710_PRINTK - ("MUX DLCI:%d Wait for connecting got signal!\n", - dlci); + TS0710_PRINTK ("MUX DLCI:%d Wait for connecting got signal!\n", dlci); retval = -EAGAIN; break; } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { @@ -2187,36 +1216,29 @@ int ts0710_open_channel(__u8 dlci) ts0710->initiator = 1; ts0710->dlci[0].state = CONNECTING; ts0710->dlci[0].initiator = 1; - try = 10; - while (try--) { - t = jiffies; - send_sabm(ts0710, 0); - interruptible_sleep_on_timeout(&ts0710->dlci[0]. - open_wait, - TS0710MUX_TIME_OUT); - if ((ts0710->dlci[0].state == CONNECTED) - || (ts0710->dlci[0].state == - FLOW_STOPPED)) { - retval = 0; - break; - } else if (ts0710->dlci[0].state == REJECTED) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM got rejected!\n", - dlci); - retval = -EREJECTED; - break; - } else if (signal_pending(current)) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM got signal!\n", - dlci); - retval = -EAGAIN; - break; - } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM timeout!\n", - dlci); - continue; - } + + t = jiffies; + send_sabm(ts0710, 0); + interruptible_sleep_on_timeout(&ts0710->dlci[0]. + open_wait, + TS0710MUX_TIME_OUT); + if ((ts0710->dlci[0].state == CONNECTED) + || (ts0710->dlci[0].state == + FLOW_STOPPED)) { + retval = 0; + } else if (ts0710->dlci[0].state == REJECTED) { + TS0710_PRINTK + ("MUX DLCI:%d Send SABM got rejected!\n", + dlci); + retval = -EREJECTED; + } else if (signal_pending(current)) { + TS0710_PRINTK ("MUX DLCI:%d Send SABM got signal!\n", dlci); + retval = -EAGAIN; + } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { + TS0710_PRINTK + ("MUX DLCI:%d Send SABM timeout!\n", + dlci); + retval -ENODEV; } if (ts0710->dlci[0].state == CONNECTING) { @@ -2234,43 +1256,21 @@ int ts0710_open_channel(__u8 dlci) } else if ((ts0710->dlci[dlci].state == NEGOTIATING) || (ts0710->dlci[dlci].state == CONNECTING)) { /* Reentry */ - try = 8; - while (try--) { - t = jiffies; - interruptible_sleep_on_timeout(&ts0710-> - dlci[dlci]. - open_wait, - TS0710MUX_TIME_OUT); - if ((ts0710->dlci[dlci].state == CONNECTED) - || (ts0710->dlci[dlci].state == - FLOW_STOPPED)) { - retval = 0; - break; - } else if (ts0710->dlci[dlci].state == REJECTED) { - retval = -EREJECTED; - break; - } else if (ts0710->dlci[dlci].state == - DISCONNECTED) { - break; - } else if (signal_pending(current)) { - TS0710_PRINTK - ("MUX DLCI:%d Wait for connecting got signal!\n", - dlci); - retval = -EAGAIN; - break; - } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { - TS0710_PRINTK - ("MUX DLCI:%d Wait for connecting timeout!\n", - dlci); - continue; - } else - if ((ts0710->dlci[dlci].state == - NEGOTIATING) - || (ts0710->dlci[dlci].state == - CONNECTING)) { - continue; - } - } + + t = jiffies; + interruptible_sleep_on_timeout(&ts0710-> + dlci[dlci]. + open_wait, + TS0710MUX_TIME_OUT); + if ((ts0710->dlci[dlci].state == CONNECTED) + || (ts0710->dlci[dlci].state == + FLOW_STOPPED)) { + retval = 0; + } else if (ts0710->dlci[dlci].state == REJECTED) { + retval = -EREJECTED; + } else if (signal_pending(current)) { + retval = -EAGAIN; + } if ((ts0710->dlci[dlci].state == NEGOTIATING) || (ts0710->dlci[dlci].state == CONNECTING)) { @@ -2283,68 +1283,47 @@ int ts0710_open_channel(__u8 dlci) } else { ts0710->dlci[dlci].state = NEGOTIATING; ts0710->dlci[dlci].initiator = 1; - try = 3; - while (try--) { + + t = jiffies; + send_pn_msg(ts0710, 7, ts0710->dlci[dlci].mtu, + 0, 0, dlci, 1); + interruptible_sleep_on_timeout(&ts0710-> + dlci[dlci]. + open_wait, + TS0710MUX_TIME_OUT); + if (signal_pending(current)) { + TS0710_PRINTK + ("MUX DLCI:%d Send pn_msg got signal!\n", + dlci); + retval = -EAGAIN; + } + + if (ts0710->dlci[dlci].state == CONNECTING) { + t = jiffies; - send_pn_msg(ts0710, 7, ts0710->dlci[dlci].mtu, - 0, 0, dlci, 1); + send_sabm(ts0710, dlci); interruptible_sleep_on_timeout(&ts0710-> - dlci[dlci]. + dlci + [dlci]. open_wait, TS0710MUX_TIME_OUT); - if (ts0710->dlci[dlci].state == CONNECTING) { - break; - } else if (signal_pending(current)) { + if ((ts0710->dlci[dlci].state == + CONNECTED) + || (ts0710->dlci[dlci].state == + FLOW_STOPPED)) { + retval = 0; + } else if (ts0710->dlci[dlci].state == + REJECTED) { TS0710_PRINTK - ("MUX DLCI:%d Send pn_msg got signal!\n", + ("MUX DLCI:%d Send SABM got rejected!\n", dlci); - retval = -EAGAIN; - break; - } else if ((jiffies - t) >= TS0710MUX_TIME_OUT) { + retval = -EREJECTED; + } else if (signal_pending(current)) { TS0710_PRINTK - ("MUX DLCI:%d Send pn_msg timeout!\n", + ("MUX DLCI:%d Send SABM got signal!\n", dlci); - continue; - } - } - - if (ts0710->dlci[dlci].state == CONNECTING) { - try = 3; - while (try--) { - t = jiffies; - send_sabm(ts0710, dlci); - interruptible_sleep_on_timeout(&ts0710-> - dlci - [dlci]. - open_wait, - TS0710MUX_TIME_OUT); - if ((ts0710->dlci[dlci].state == - CONNECTED) - || (ts0710->dlci[dlci].state == - FLOW_STOPPED)) { - retval = 0; - break; - } else if (ts0710->dlci[dlci].state == - REJECTED) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM got rejected!\n", - dlci); - retval = -EREJECTED; - break; - } else if (signal_pending(current)) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM got signal!\n", - dlci); - retval = -EAGAIN; - break; - } else if ((jiffies - t) >= - TS0710MUX_TIME_OUT) { - TS0710_PRINTK - ("MUX DLCI:%d Send SABM timeout!\n", - dlci); - continue; - } - } + retval = -EAGAIN; + } } if ((ts0710->dlci[dlci].state == NEGOTIATING) @@ -2357,107 +1336,9 @@ int ts0710_open_channel(__u8 dlci) return retval; } -static int ts0710_exec_test_cmd(void) -{ - ts0710_con *ts0710 = &ts0710_connection; - __u8 *f_buf; /* Frame buffer */ - __u8 *d_buf; /* Data buffer */ - int retval = -EFAULT; - int j; - unsigned long t; - - if (ts0710->be_testing) { - /* Reentry */ - t = jiffies; - interruptible_sleep_on_timeout(&ts0710->test_wait, - 3 * TS0710MUX_TIME_OUT); - if (ts0710->be_testing == 0) { - if (ts0710->test_errs == 0) { - retval = 0; - } else { - retval = -EFAULT; - } - } else if (signal_pending(current)) { - TS0710_DEBUG - ("Wait for Test_cmd response got signal!\n"); - retval = -EAGAIN; - } else if ((jiffies - t) >= 3 * TS0710MUX_TIME_OUT) { - TS0710_DEBUG("Wait for Test_cmd response timeout!\n"); - retval = -EFAULT; - } - } else { - ts0710->be_testing = 1; /* Set the flag */ - - f_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL); - d_buf = (__u8 *) kmalloc(TEST_PATTERN_SIZE + 32, GFP_KERNEL); - if ((!f_buf) || (!d_buf)) { - if (f_buf) { - kfree(f_buf); - } - if (d_buf) { - kfree(d_buf); - } - - ts0710->be_testing = 0; /* Clear the flag */ - ts0710->test_errs = TEST_PATTERN_SIZE; - wake_up_interruptible(&ts0710->test_wait); - return -ENOMEM; - } - - for (j = 0; j < TEST_PATTERN_SIZE; j++) { - d_buf[j] = j & 0xFF; - } - - t = jiffies; - ts0710_test_msg(ts0710, d_buf, TEST_PATTERN_SIZE, MCC_CMD, - f_buf); - interruptible_sleep_on_timeout(&ts0710->test_wait, - 2 * TS0710MUX_TIME_OUT); - if (ts0710->be_testing == 0) { - if (ts0710->test_errs == 0) { - retval = 0; - } else { - retval = -EFAULT; - } - } else if (signal_pending(current)) { - TS0710_DEBUG("Send Test_cmd got signal!\n"); - retval = -EAGAIN; - } else if ((jiffies - t) >= 2 * TS0710MUX_TIME_OUT) { - TS0710_DEBUG("Send Test_cmd timeout!\n"); - ts0710->test_errs = TEST_PATTERN_SIZE; - retval = -EFAULT; - } - - ts0710->be_testing = 0; /* Clear the flag */ - wake_up_interruptible(&ts0710->test_wait); - - /* Release buffer */ - if (f_buf) { - kfree(f_buf); - } - if (d_buf) { - kfree(d_buf); - } - } - - return retval; -} - static void mux_sched_send(void) { - -#ifdef USB_FOR_MUX - schedule_work(&send_tqueue); -#else - if (!tq_serial_for_mux) { - TS0710_PRINTK("MUX Error: %s: tq_serial_for_mux == 0\n", - __FUNCTION__); - return; - } schedule_work(&send_tqueue); - mark_bh(SERIAL_BH); -#endif - } /**************************** @@ -2469,61 +1350,48 @@ static void mux_close(struct tty_struct *tty, struct file *filp) ts0710_con *ts0710 = &ts0710_connection; int line; __u8 dlci; - __u8 cmdtty; - __u8 datatty; UNUSED_PARAM(filp); - if (!tty) { - return; - } line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) return; - } + if (mux_tty[line] > 0) mux_tty[line]--; - dlci = tty2dlci[line]; - cmdtty = dlci2tty[dlci].cmdtty; - datatty = dlci2tty[dlci].datatty; - if ((mux_tty[cmdtty] == 0) && (mux_tty[datatty] == 0)) { - if (dlci == 1) { - ts0710_close_channel(0); - TS0710_PRINTK - ("MUX mux_close: tapisrv might be down!!! Close DLCI 1\n"); - TS0710_SIG2APLOGD(); - } + dlci = line+1; + if (mux_tty[line] == 0) ts0710_close_channel(dlci); - } - if (mux_tty[line] == 0) { - if ((mux_send_info_flags[line]) - && (mux_send_info[line]) - /*&& (mux_send_info[line]->filled == 0) */ - ) { - mux_send_info_flags[line] = 0; - kfree(mux_send_info[line]); - mux_send_info[line] = 0; - TS0710_DEBUG("Free mux_send_info for /dev/mux%d", line); - } - if ((mux_recv_info_flags[line]) - && (mux_recv_info[line]) - && (mux_recv_info[line]->total == 0)) { - mux_recv_info_flags[line] = 0; - free_mux_recv_struct(mux_recv_info[line]); - mux_recv_info[line] = 0; - TS0710_DEBUG("Free mux_recv_info for /dev/mux%d", line); - } + if (mux_tty[line] != 0) + return; - ts0710_flow_on(dlci, ts0710); - schedule_work(&post_recv_tqueue); + if ((mux_send_info_flags[line]) && (mux_send_info[line])) + { + mux_send_info_flags[line] = 0; + kfree(mux_send_info[line]); + mux_send_info[line] = 0; + TS0710_DEBUG("Free mux_send_info for /dev/mux%d\n", line); + } - wake_up_interruptible(&tty->read_wait); - wake_up_interruptible(&tty->write_wait); - tty->packet = 0; + if ((mux_recv_info_flags[line]) + && (mux_recv_info[line]) + && (mux_recv_info[line]->total == 0)) { + mux_recv_info_flags[line] = 0; + free_mux_recv_struct(mux_recv_info[line]); + mux_recv_info[line] = 0; + TS0710_DEBUG("Free mux_recv_info for /dev/mux%d\n", line); } + + ts0710_flow_on(dlci, ts0710); + //schedule_work(&post_recv_tqueue); + + wake_up_interruptible(&tty->read_wait); + wake_up_interruptible(&tty->write_wait); + tty->packet = 0; + } static void mux_throttle(struct tty_struct *tty) @@ -2533,19 +1401,15 @@ static void mux_throttle(struct tty_struct *tty) int i; __u8 dlci; - if (!tty) { - return; - } - line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) return; - } + TS0710_DEBUG("Enter into %s, minor number is: %d\n", __FUNCTION__, line); - dlci = tty2dlci[line]; + dlci = line+1; if ((ts0710->dlci[0].state != CONNECTED) && (ts0710->dlci[0].state != FLOW_STOPPED)) { return; @@ -2577,13 +1441,9 @@ static void mux_unthrottle(struct tty_struct *tty) __u8 dlci; mux_recv_struct *recv_info; - if (!tty) { - return; - } line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) return; - } if ((!mux_recv_info_flags[line]) || (!mux_recv_info[line])) { return; @@ -2593,11 +1453,11 @@ static void mux_unthrottle(struct tty_struct *tty) line); recv_info = mux_recv_info[line]; - dlci = tty2dlci[line]; + dlci = line+1; if (recv_info->total) { recv_info->post_unthrottle = 1; - schedule_work(&post_recv_tqueue); + //schedule_work(&post_recv_tqueue); } else { ts0710_flow_on(dlci, ts0710); } @@ -2612,26 +1472,16 @@ static int mux_chars_in_buffer(struct tty_struct *tty) mux_send_struct *send_info; retval = TS0710MUX_MAX_CHARS_IN_BUF; - if (!tty) { - goto out; - } + line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) { goto out; } - dlci = tty2dlci[line]; - if (ts0710->dlci[0].state == FLOW_STOPPED) { - TS0710_DEBUG - ("Flow stopped on all channels, returning MAX chars in buffer\n"); - goto out; - } else if (ts0710->dlci[dlci].state == FLOW_STOPPED) { - TS0710_DEBUG("Flow stopped, returning MAX chars in buffer\n"); - goto out; - } else if (ts0710->dlci[dlci].state != CONNECTED) { - TS0710_DEBUG("DLCI %d not connected\n", dlci); + dlci = line+1; + + if (! MUX_USABLE(ts0710,dlci)) goto out; - } if (!(mux_send_info_flags[line])) { goto out; @@ -2654,21 +1504,7 @@ static int mux_chars_in_serial_buffer(struct tty_struct *tty) { UNUSED_PARAM(tty); - if ((COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)) { - TS0710_PRINTK - ("MUX %s: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n", - __FUNCTION__); - -#ifndef USB_FOR_MUX - TS0710_PRINTK - ("MUX %s: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n", - __FUNCTION__); - TS0710_SIG2APLOGD(); -#endif - - return 0; - } - return COMM_FOR_MUX_DRIVER->ops->chars_in_buffer(COMM_FOR_MUX_TTY); + return ipc_tty->ops->chars_in_buffer(ipc_tty); } static int mux_write(struct tty_struct *tty, @@ -2680,21 +1516,31 @@ static int mux_write(struct tty_struct *tty, mux_send_struct *send_info; __u8 *d_buf; __u16 c; - __u8 post_recv; if (count <= 0) { return 0; } - if (!tty) { - return 0; - } + printk("write data to lowlevel driver:\n"); + int i; + for(i=0;iinitiator, CMDTAG, send, count+1); + + printk("sending correct\n"); line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) - return -ENODEV; - dlci = tty2dlci[line]; + dlci = line+1; if (ts0710->dlci[0].state == FLOW_STOPPED) { TS0710_DEBUG ("Flow stopped on all channels, returning zero /dev/mux%d\n", @@ -2703,88 +1549,64 @@ static int mux_write(struct tty_struct *tty, } else if (ts0710->dlci[dlci].state == FLOW_STOPPED) { TS0710_DEBUG("Flow stopped, returning zero /dev/mux%d\n", line); return 0; - } else if (ts0710->dlci[dlci].state == CONNECTED) { - - if (!(mux_send_info_flags[line])) { - TS0710_PRINTK - ("MUX Error: mux_write: mux_send_info_flags[%d] == 0\n", - line); - return -ENODEV; - } - send_info = mux_send_info[line]; - if (!send_info) { - TS0710_PRINTK - ("MUX Error: mux_write: mux_send_info[%d] == 0\n", - line); - return -ENODEV; - } - - c = min(count, (ts0710->dlci[dlci].mtu - 1)); - if (c <= 0) { - return 0; - } - - if (test_and_set_bit(BUF_BUSY, &send_info->flags)) - return 0; - - if (send_info->filled) { - clear_bit(BUF_BUSY, &send_info->flags); - return 0; - } - - d_buf = ((__u8 *) send_info->buf) + TS0710MUX_SEND_BUF_OFFSET; - memcpy(&d_buf[1], buf, c); + } else if (ts0710->dlci[dlci].state != CONNECTED) { + TS0710_PRINTK("MUX mux_write: DLCI %d not connected\n", dlci); + return -EDISCONNECTED; + } + if (!(mux_send_info_flags[line])) { + TS0710_PRINTK + ("MUX Error: mux_write: mux_send_info_flags[%d] == 0\n", + line); + return -ENODEV; + } + send_info = mux_send_info[line]; + if (!send_info) { + TS0710_PRINTK + ("MUX Error: mux_write: mux_send_info[%d] == 0\n", + line); + return -ENODEV; + } - TS0710_DEBUG("Prepare to send %d bytes from /dev/mux%d", c, - line); - if (iscmdtty[line]) { - TS0710_DEBUGSTR(&d_buf[1], c); - TS0710_DEBUG("CMDTAG"); - d_buf[0] = CMDTAG; - } else { - TS0710_DEBUG("DATATAG"); - d_buf[0] = DATATAG; - } + c = (count, (ts0710->dlci[dlci].mtu - 1)); + if (c <= 0) { + return 0; + } - TS0710_DEBUGHEX(d_buf, c + 1); + if (test_and_set_bit(BUF_BUSY, &send_info->flags)) + return 0; - send_info->frame = d_buf; - queue_uih(send_info, c + 1, ts0710, dlci); - send_info->filled = 1; + if (send_info->filled) { clear_bit(BUF_BUSY, &send_info->flags); + return 0; + } - post_recv = 0; - if (dlci == TS0710MUX_GPRS1_DLCI) { - if (add_count - (TS0710MUX_GPRS1_SEND_COUNT_IDX, c) < 0) { - post_recv_count_flag = 1; - post_recv = 1; - mux_data_count2[TS0710MUX_GPRS1_SEND_COUNT_IDX] - += c; - } - } else if (dlci == TS0710MUX_GPRS2_DLCI) { - if (add_count - (TS0710MUX_GPRS2_SEND_COUNT_IDX, c) < 0) { - post_recv_count_flag = 1; - post_recv = 1; - mux_data_count2[TS0710MUX_GPRS2_SEND_COUNT_IDX] - += c; - } - } + d_buf = ((__u8 *) send_info->buf) + TS0710MUX_SEND_BUF_OFFSET; + memcpy(&d_buf[1], buf, c); - if (post_recv) - schedule_work(&post_recv_tqueue); + TS0710_DEBUG("Prepare to send %d bytes from /dev/mux%d\n", c, + line); - if (mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY) == 0) { - /* Sending bottom half should be - run after return from this function */ - mux_sched_send(); - } - return c; + if (iscmdtty[line]) { + TS0710_DEBUG("send CMDTAG\n"); + d_buf[0] = CMDTAG; } else { - TS0710_PRINTK("MUX mux_write: DLCI %d not connected\n", dlci); - return -EDISCONNECTED; + TS0710_DEBUG("send DATATAG\n"); + d_buf[0] = DATATAG; + } + + + send_info->frame = d_buf; + queue_uih(send_info, c + 1, ts0710, dlci); + send_info->filled = 1; + clear_bit(BUF_BUSY, &send_info->flags); + + if (mux_chars_in_serial_buffer(ipc_tty) == 0) { + /* Sending bottom half should be + run after return from this function */ + mux_sched_send(); } + return c; + } static int mux_write_room(struct tty_struct *tty) @@ -2796,15 +1618,13 @@ static int mux_write_room(struct tty_struct *tty) mux_send_struct *send_info; retval = 0; - if (!tty) { - goto out; - } + line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) goto out; - } + - dlci = tty2dlci[line]; + dlci = line+1; if (ts0710->dlci[0].state == FLOW_STOPPED) { TS0710_DEBUG("Flow stopped on all channels, returning ZERO\n"); goto out; @@ -2816,111 +1636,30 @@ static int mux_write_room(struct tty_struct *tty) goto out; } - if (!(mux_send_info_flags[line])) { + if (!(mux_send_info_flags[line])) goto out; - } + send_info = mux_send_info[line]; - if (!send_info) { + if (!send_info) goto out; - } - if (send_info->filled) { + + if (send_info->filled) goto out; - } - + retval = ts0710->dlci[dlci].mtu - 1; out: return retval; } -static int mux_ioctl(struct tty_struct *tty, struct file *file, - unsigned int cmd, unsigned long arg) -{ - ts0710_con *ts0710 = &ts0710_connection; - int line; - __u8 dlci; - - UNUSED_PARAM(file); - UNUSED_PARAM(arg); - - if (!tty) { - return -EIO; - } - line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { - return -ENODEV; - } - - dlci = tty2dlci[line]; - switch (cmd) { - case TS0710MUX_IO_MSC_HANGUP: - if (ts0710_msc_msg(ts0710, EA | RTR | DV, MCC_CMD, dlci) < 0) { - return -EAGAIN; - } else { - return 0; - } - - case TS0710MUX_IO_TEST_CMD: - return ts0710_exec_test_cmd(); -/* - case TS0710MUX_IO_DLCI_FC_ON: - if( line == 0 ) { - break; - } - if( ts0710_msc_msg(ts0710, EA | RTC | RTR | DV, MCC_CMD, (__u8)line) < 0) { - return -EAGAIN; - } else { - return 0; - } - - case TS0710MUX_IO_DLCI_FC_OFF: - if( line == 0 ) { - break; - } - if( ts0710_msc_msg(ts0710, EA | FC | RTC | RTR | DV, MCC_CMD, (__u8)line) < 0) { - return -EAGAIN; - } else { - return 0; - } - - case TS0710MUX_IO_FC_ON: - if( line != 0 ) { - break; - } - if( ts0710_fcon_msg(ts0710, MCC_CMD) < 0) { - return -EAGAIN; - } else { - return 0; - } - - case TS0710MUX_IO_FC_OFF: - if( line != 0 ) { - break; - } - if( ts0710_fcoff_msg(ts0710, MCC_CMD) < 0) { - return -EAGAIN; - } else { - return 0; - } -*/ - default: - break; - } - return -ENOIOCTLCMD; -} - static void mux_flush_buffer(struct tty_struct *tty) { int line; - if (!tty) { - return; - } - line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) return; - } + TS0710_PRINTK("MUX %s: line is:%d\n", __FUNCTION__, line); @@ -2940,19 +1679,6 @@ static void mux_flush_buffer(struct tty_struct *tty) (tty->ldisc.ops->write_wakeup) (tty); } -/* - if( (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0) ) { - TS0710_PRINTK("MUX %s: (COMM_FOR_MUX_DRIVER == 0) || (COMM_FOR_MUX_TTY == 0)\n", __FUNCTION__); - -#ifndef USB_FOR_MUX - TS0710_PRINTK("MUX %s: tapisrv might be down!!! (serial_for_mux_driver == 0) || (serial_for_mux_tty == 0)\n", __FUNCTION__); - TS0710_SIG2APLOGD(); -#endif - - return; - } - return COMM_FOR_MUX_DRIVER->flush_buffer(COMM_FOR_MUX_TTY); -*/ } static int mux_open(struct tty_struct *tty, struct file *filp) @@ -2960,42 +1686,22 @@ static int mux_open(struct tty_struct *tty, struct file *filp) int retval; int line; __u8 dlci; - __u8 cmdtty; - __u8 datatty; mux_send_struct *send_info; mux_recv_struct *recv_info; UNUSED_PARAM(filp); retval = -ENODEV; - if ((COMM_FOR_MUX_DRIVER == NULL) || (COMM_FOR_MUX_TTY == NULL)) { - -#ifdef USB_FOR_MUX - TS0710_PRINTK("MUX: please install and open IPC-USB first\n"); -#else - TS0710_PRINTK("MUX: please install and open ttyS0 first\n"); -#endif - - goto out; - } - if (!tty) { - goto out; - } line = tty->index; - if ((line < 0) || (line >= NR_MUXS)) { + if (MUX_INVALID(line)) goto out; - } -#ifdef TS0710SERVER - /* do nothing as a server */ - mux_tty[line]++; - retval = 0; -#else + + mux_tty[line]++; - dlci = tty2dlci[line]; + dlci = line+1; mux_table[line] = tty; -/* if( dlci == 1 ) { */ /* Open server channel 0 first */ if ((retval = ts0710_open_channel(0)) != 0) { TS0710_PRINTK("MUX: Can't connect server channel 0!\n"); @@ -3004,7 +1710,6 @@ static int mux_open(struct tty_struct *tty, struct file *filp) mux_tty[line]--; goto out; } -/* } */ /* Allocate memory first. As soon as connection has been established, MUX may receive */ if (mux_send_info_flags[line] == 0) { @@ -3051,9 +1756,7 @@ static int mux_open(struct tty_struct *tty, struct file *filp) } /* Now establish DLCI connection */ - cmdtty = dlci2tty[dlci].cmdtty; - datatty = dlci2tty[dlci].datatty; - if ((mux_tty[cmdtty] > 0) || (mux_tty[datatty] > 0)) { + if (mux_tty[dlci-1] > 0) { if ((retval = ts0710_open_channel(dlci)) != 0) { TS0710_PRINTK("MUX: Can't connected channel %d!\n", dlci); @@ -3076,7 +1779,6 @@ static int mux_open(struct tty_struct *tty, struct file *filp) retval = 0; -#endif out: return retval; } @@ -3086,506 +1788,84 @@ void mux_dispatcher(struct tty_struct *tty) { UNUSED_PARAM(tty); - schedule_work(&receive_tqueue); + //schedule_work(&receive_tqueue); } -/*For BP UART problem Begin*/ -#ifdef TS0710SEQ2 -static int send_ack(ts0710_con * ts0710, __u8 seq_num, __u8 bp_seq1, - __u8 bp_seq2) -#else -static int send_ack(ts0710_con * ts0710, __u8 seq_num) -#endif -{ - __u8 buf[20]; - short_frame *ack; - -#ifdef TS0710SEQ2 - static __u16 ack_seq = 0; -#endif - ack = (short_frame *) (buf + 1); - ack->h.addr.ea = 1; - ack->h.addr.cr = ((ts0710->initiator) & 0x1); - ack->h.addr.d = 0; - ack->h.addr.server_chn = 0; - ack->h.control = ACK; - ack->h.length.ea = 1; - -#ifdef TS0710SEQ2 - ack->h.length.len = 5; - ack->data[0] = seq_num; - ack->data[1] = bp_seq1; - ack->data[2] = bp_seq2; - ack->data[3] = (ack_seq & 0xFF); - ack->data[4] = (ack_seq >> 8) & 0xFF; - ack_seq++; - ack->data[5] = crc_calc((__u8 *) ack, SHORT_CRC_CHECK); -#else - ack->h.length.len = 1; - ack->data[0] = seq_num; - ack->data[1] = crc_calc((__u8 *) ack, SHORT_CRC_CHECK); -#endif +static void send_ack(ts0710_con * ts0710, __u8 seq_num) +{ + mux_send_frame(CTRL_CHAN, ts0710->initiator, ACK, &seq_num, 1); - return basic_write(ts0710, buf, - (sizeof(short_frame) + FCS_SIZE + - ack->h.length.len)); } +static void ts_ldisc_rx(struct tty_struct *tty, const u8 *data, char *flags, int count) -/*For BP UART problem End*/ - -static void receive_worker(struct work_struct *work) { - struct tty_struct *tty = COMM_FOR_MUX_TTY; - int count, tbuf_free, tbuf_read; - static unsigned char tbuf[TS0710MUX_MAX_BUF_SIZE]; - static unsigned char *tbuf_ptr = &tbuf[0]; - static unsigned char *start_flag = 0; - unsigned char *search, *to, *from; + static __u8 expect_seq = 0; + int framelen; short_frame *short_pkt; long_frame *long_pkt; - static int framelen = -1; - /*For BP UART problem Begin */ - static __u8 expect_seq = 0; - __u32 crc_error; - __u8 *uih_data_start; - __u32 uih_len; - /*For BP UART problem End */ - - UNUSED_PARAM(work); - - if (!tty) - return; - - while (1) { - tbuf_free = TS0710MUX_MAX_BUF_SIZE - (tbuf_ptr - tbuf); - TS0710_PRINTK("Reading max %i bytes from ts0710_mux_usb inbuf.\n", tbuf_free); - tbuf_read = get_from_inbuf_list(tbuf_ptr, tbuf_free); - if (tbuf_read == 0) { - break; - } else { - TS0710_PRINTK("Read %i bytes.\n", tbuf_read); - }; - tbuf_ptr += tbuf_read; - }; - - count = (tbuf_ptr - tbuf); - - // Should be impossible? - //if (count > (TS0710MUX_MAX_BUF_SIZE - (tbuf_ptr - tbuf))) { - // TS0710_PRINTK - // ("MUX receive_worker: !!!!! Exceed buffer boundary !!!!!\n"); - // count = (TS0710MUX_MAX_BUF_SIZE - (tbuf_ptr - tbuf)); - //} - -#ifdef USB_FOR_MUX - TS0710_DEBUG("Received following bytes from IPC-USB"); -#else - TS0710_DEBUG("Received following bytes from UART"); -#endif - TS0710_DEBUGHEX(tbuf, count); - - //gets updated above - //tbuf_ptr += count; - search = &tbuf[0]; + struct mux_data *disc_data = (struct mux_data*)tty->disc_data; - if (test_and_set_bit(RECV_RUNNING, &mux_recv_flags)) { - schedule_work(&receive_tqueue); - return; - } + if (disc_data->frame) { + framelen = disc_data->frame; + } else { + short_pkt = (short_frame *) (data + ADDRESS_FIELD_OFFSET); - if ((start_flag != 0) && (framelen != -1)) { - if ((tbuf_ptr - start_flag) < framelen) { - clear_bit(RECV_RUNNING, &mux_recv_flags); - return; + if (short_pkt->h.length.ea == 1) { + framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1 + SEQ_FIELD_SIZE; + } else { + long_pkt = (long_frame *) (data + ADDRESS_FIELD_OFFSET); + framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH(long_pkt->h.length) + 2 + SEQ_FIELD_SIZE; } } - while (1) { - if (start_flag == 0) { /* Frame Start Flag not found */ - framelen = -1; - while (search < tbuf_ptr) { - if (*search == TS0710_BASIC_FLAG) { - start_flag = search; - break; - } -#ifdef TS0710LOG - else { - TS0710_LOG(">S %02x %c\n", *search, - *search); - } -#endif - - search++; - } - - if (start_flag == 0) { - tbuf_ptr = &tbuf[0]; - break; - } - } else { /* Frame Start Flag found */ - /* 1 start flag + 1 address + 1 control + 1 or 2 length + lengths data + 1 FCS + 1 end flag */ - /* For BP UART problem 1 start flag + 1 seq_num + 1 address + ...... */ - /*if( (framelen == -1) && ((tbuf_ptr - start_flag) > TS0710_MAX_HDR_SIZE) ) */ - if ((framelen == -1) && ((tbuf_ptr - start_flag) > (TS0710_MAX_HDR_SIZE + SEQ_FIELD_SIZE))) { /*For BP UART problem */ - /*short_pkt = (short_frame *) (start_flag + 1); */ - short_pkt = (short_frame *) (start_flag + ADDRESS_FIELD_OFFSET); /*For BP UART problem */ - if (short_pkt->h.length.ea == 1) { /* short frame */ - /*framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1; */ - framelen = TS0710_MAX_HDR_SIZE + short_pkt->h.length.len + 1 + SEQ_FIELD_SIZE; /*For BP UART problem */ - } else { /* long frame */ - /*long_pkt = (long_frame *) (start_flag + 1); */ - long_pkt = (long_frame *) (start_flag + ADDRESS_FIELD_OFFSET); /*For BP UART problem */ - /*framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH( long_pkt->h.length ) + 2; */ - framelen = TS0710_MAX_HDR_SIZE + GET_LONG_LENGTH(long_pkt->h.length) + 2 + SEQ_FIELD_SIZE; /*For BP UART problem */ - } - - /*if( framelen > TS0710MUX_MAX_TOTAL_FRAME_SIZE ) { */ - if (framelen > (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE)) { /*For BP UART problem */ - TS0710_LOGSTR_FRAME(0, start_flag, - (tbuf_ptr - - start_flag)); - TS0710_PRINTK - ("MUX Error: %s: frame length:%d is bigger than Max total frame size:%d\n", - /*__FUNCTION__, framelen, TS0710MUX_MAX_TOTAL_FRAME_SIZE);*/ - __FUNCTION__, framelen, (TS0710MUX_MAX_TOTAL_FRAME_SIZE + SEQ_FIELD_SIZE)); /*For BP UART problem */ - search = start_flag + 1; - start_flag = 0; - framelen = -1; - continue; - } - } - - if ((framelen != -1) - && ((tbuf_ptr - start_flag) >= framelen)) { - if (*(start_flag + framelen - 1) == TS0710_BASIC_FLAG) { /* OK, We got one frame */ - - /*For BP UART problem Begin */ - TS0710_LOGSTR_FRAME(0, start_flag, - framelen); - TS0710_DEBUGHEX(start_flag, framelen); - - short_pkt = - (short_frame *) (start_flag + - ADDRESS_FIELD_OFFSET); - if ((short_pkt->h.length.ea) == 0) { - long_pkt = - (long_frame *) (start_flag + - ADDRESS_FIELD_OFFSET); - uih_len = - GET_LONG_LENGTH(long_pkt->h. - length); - uih_data_start = - long_pkt->h.data; - - crc_error = - crc_check((__u8 - *) (start_flag + - SLIDE_BP_SEQ_OFFSET), - LONG_CRC_CHECK + - 1, - *(uih_data_start + - uih_len)); - } else { - uih_len = - short_pkt->h.length.len; - uih_data_start = - short_pkt->data; - - crc_error = - crc_check((__u8 - *) (start_flag + - SLIDE_BP_SEQ_OFFSET), - SHORT_CRC_CHECK + - 1, - *(uih_data_start + - uih_len)); - } - - if (!crc_error) { - if (expect_seq == - *(start_flag + - SLIDE_BP_SEQ_OFFSET)) { - expect_seq++; - if (expect_seq >= 4) { - expect_seq = 0; - } -#ifdef TS0710SEQ2 - send_ack - (&ts0710_connection, - expect_seq, - *(start_flag + - FIRST_BP_SEQ_OFFSET), - *(start_flag + - SECOND_BP_SEQ_OFFSET)); -#else - send_ack - (&ts0710_connection, - expect_seq); -#endif - - ts0710_recv_data - (&ts0710_connection, - start_flag + - ADDRESS_FIELD_OFFSET, - framelen - 2 - - SEQ_FIELD_SIZE); - } else { - -#ifdef TS0710DEBUG - if (* - (start_flag + - SLIDE_BP_SEQ_OFFSET) - != 0x9F) { -#endif - - TS0710_LOG - ("MUX sequence number %d is not expected %d, discard data!\n", - * - (start_flag - + - SLIDE_BP_SEQ_OFFSET), - expect_seq); - -#ifdef TS0710SEQ2 - send_ack - (&ts0710_connection, - expect_seq, - * - (start_flag - + - FIRST_BP_SEQ_OFFSET), - * - (start_flag - + - SECOND_BP_SEQ_OFFSET)); -#else - send_ack - (&ts0710_connection, - expect_seq); -#endif - -#ifdef TS0710DEBUG - } else { - *(uih_data_start - + uih_len) = - 0; - TS0710_PRINTK - ("MUX bp log: %s\n", - uih_data_start); - } -#endif - - } - } else { /* crc_error */ - search = start_flag + 1; - start_flag = 0; - framelen = -1; - continue; - } /*End if(!crc_error) */ - - /*For BP UART problem End */ - -/*For BP UART problem - TS0710_LOGSTR_FRAME(0, start_flag, framelen); - TS0710_DEBUGHEX(start_flag, framelen); - ts0710_recv_data(&ts0710_connection, start_flag + 1, framelen - 2); -*/ - search = start_flag + framelen; - } else { - TS0710_LOGSTR_FRAME(0, start_flag, - framelen); - TS0710_DEBUGHEX(start_flag, framelen); - TS0710_PRINTK - ("MUX: Lost synchronization!\n"); - search = start_flag + 1; - } - - start_flag = 0; - framelen = -1; - continue; - } - - if (start_flag != &tbuf[0]) { - to = tbuf; - from = start_flag; - count = tbuf_ptr - start_flag; - while (count--) { - *to++ = *from++; - } - tbuf_ptr -= (start_flag - tbuf); - start_flag = tbuf; - } - break; - } /* End Frame Start Flag found */ - } /* End while(1) */ + if(!disc_data->data) + disc_data->data = kzalloc(framelen, GFP_KERNEL); - clear_bit(RECV_RUNNING, &mux_recv_flags); -} + memcpy(disc_data->data + disc_data->collected,data,count); -static void post_recv_worker(struct work_struct *work) -{ - ts0710_con *ts0710 = &ts0710_connection; - int tty_idx; - struct tty_struct *tty; - __u8 post_recv; - __u8 flow_control; - __u8 dlci; - mux_recv_struct *recv_info, *recv_info2, *post_recv_q; - int recv_room; - mux_recv_packet *recv_packet, *recv_packet2; - __u8 j; - UNUSED_PARAM(work); + if ((disc_data->collected + count) < framelen) { + disc_data->frame = framelen; + disc_data->seq = expect_seq; + disc_data->collected += count; - if (test_and_set_bit(RECV_RUNNING, &mux_recv_flags)) { - schedule_work(&post_recv_tqueue); return; - } - - TS0710_DEBUG("Enter into post_recv_worker"); - - post_recv = 0; - if (!mux_recv_queue) { - goto out; - } + } - post_recv_q = NULL; - recv_info2 = mux_recv_queue; - while ((recv_info = recv_info2)) { - recv_info2 = recv_info->next; + disc_data->collected = 0; + disc_data->frame = 0; + data = disc_data->data; - if (!(recv_info->total)) { - TS0710_PRINTK - ("MUX Error: %s: Should not get here, recv_info->total == 0 \n", - __FUNCTION__); - continue; + + if (expect_seq == *(data + SLIDE_BP_SEQ_OFFSET)) { + expect_seq++; + if (expect_seq >= 4) { + expect_seq = 0; } - tty_idx = recv_info->no_tty; - dlci = tty2dlci[tty_idx]; - tty = mux_table[tty_idx]; - if ((!mux_tty[tty_idx]) || (!tty)) { - TS0710_PRINTK - ("MUX: No application waiting for, free recv_info! tty_idx:%d\n", - tty_idx); - mux_recv_info_flags[tty_idx] = 0; - free_mux_recv_struct(mux_recv_info[tty_idx]); - mux_recv_info[tty_idx] = 0; - ts0710_flow_on(dlci, ts0710); - continue; - } + send_ack (&ts0710_connection, expect_seq); - TS0710_DEBUG("/dev/mux%d recv_info->total is: %d", tty_idx, - recv_info->total); + ts0710_recv_data (&ts0710_connection, + data + ADDRESS_FIELD_OFFSET, + framelen - 2 - SEQ_FIELD_SIZE + ); - if (test_bit(TTY_THROTTLED, &tty->flags)) { - add_post_recv_queue(&post_recv_q, recv_info); - continue; - } + } else { - flow_control = 0; - recv_packet2 = recv_info->mux_packet; - while (recv_info->total) { - recv_room = 65535; - if (tty->receive_room) - recv_room = tty->receive_room; + printk("seq miss! expect %d, got %d\n", + expect_seq, + *(data + SLIDE_BP_SEQ_OFFSET) + ); + } - if (recv_info->length) { - if (recv_room < recv_info->length) { - flow_control = 1; - break; - } - /* Put queued data into read buffer of tty */ - TS0710_DEBUG - ("Put queued recv data into read buffer of /dev/mux%d", - tty_idx); - TS0710_DEBUGHEX(recv_info->data, - recv_info->length); - (tty->ldisc.ops->receive_buf) (tty, recv_info->data, - NULL, - recv_info->length); - recv_info->total -= recv_info->length; - recv_info->length = 0; - } else { /* recv_info->length == 0 */ - if ((recv_packet = recv_packet2)) { - recv_packet2 = recv_packet->next; - - if (recv_room < recv_packet->length) { - flow_control = 1; - recv_info->mux_packet = - recv_packet; - break; - } - - /* Put queued data into read buffer of tty */ - TS0710_DEBUG - ("Put queued recv data into read buffer of /dev/mux%d", - tty_idx); - TS0710_DEBUGHEX(recv_packet->data, - recv_packet->length); - (tty->ldisc.ops->receive_buf) (tty, - recv_packet-> - data, NULL, - recv_packet-> - length); - recv_info->total -= recv_packet->length; - free_mux_recv_packet(recv_packet); - } else { - TS0710_PRINTK - ("MUX Error: %s: Should not get here, recv_info->total is:%u \n", - __FUNCTION__, recv_info->total); - } - } /* End recv_info->length == 0 */ - } /* End while( recv_info->total ) */ + kfree(disc_data->data); + disc_data->data = NULL; - if (!(recv_info->total)) { - /* Important clear */ - recv_info->mux_packet = 0; - if (recv_info->post_unthrottle) { - /* Do something for post_unthrottle */ - ts0710_flow_on(dlci, ts0710); - recv_info->post_unthrottle = 0; - } - } else { - add_post_recv_queue(&post_recv_q, recv_info); - - if (flow_control) { - /* Do something for flow control */ - if (recv_info->post_unthrottle) { - set_bit(TTY_THROTTLED, &tty->flags); - recv_info->post_unthrottle = 0; - } else { - ts0710_flow_off(tty, dlci, ts0710); - } - } /* End if( flow_control ) */ - } - } /* End while( (recv_info = recv_info2) ) */ - - mux_recv_queue = post_recv_q; - - out: - if (post_recv_count_flag) { - post_recv_count_flag = 0; - for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) { - if (mux_data_count2[j] > 0) { - if (add_count(j, mux_data_count2[j]) == 0) { - mux_data_count2[j] = 0; - } else { - post_recv_count_flag = 1; - post_recv = 1; - } - } - } /* End for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) */ - } - /* End if( post_recv_count_flag ) */ - if (post_recv) - schedule_work(&post_recv_tqueue); - clear_bit(RECV_RUNNING, &mux_recv_flags); } /* mux sender, call from serial.c transmit_chars() */ @@ -3595,10 +1875,10 @@ void mux_sender(void) int chars; __u8 idx; - chars = mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY); + chars = mux_chars_in_serial_buffer(ipc_tty); if (!chars) { /* chars == 0 */ - TS0710_LOG("<[]\n"); + TS0710_DEBUG("<[]\n"); mux_sched_send(); return; } @@ -3627,14 +1907,13 @@ static void send_worker(struct work_struct *work) UNUSED_PARAM(work); - TS0710_DEBUG("Enter into send_worker"); + TS0710_DEBUG("Enter into send_worker\n"); mux_send_info_idx = NR_MUXS; - if (ts0710->dlci[0].state == FLOW_STOPPED) { - TS0710_DEBUG("Flow stopped on all channels\n"); + if (MUX_ALL_STOPPED(ts0710)) return; - } + for (j = 0; j < NR_MUXS; j++) { @@ -3651,20 +1930,20 @@ static void send_worker(struct work_struct *work) continue; } - dlci = tty2dlci[j]; - if (ts0710->dlci[dlci].state == FLOW_STOPPED) { - TS0710_DEBUG("Flow stopped on channel DLCI: %d\n", - dlci); + dlci = j+1; + + if (MUX_STOPPED(ts0710,dlci)) continue; - } else if (ts0710->dlci[dlci].state != CONNECTED) { + + if (! MUX_CONNECTED(ts0710,dlci)) { TS0710_DEBUG("DLCI %d not connected\n", dlci); send_info->filled = 0; continue; } - chars = mux_chars_in_serial_buffer(COMM_FOR_MUX_TTY); + chars = mux_chars_in_serial_buffer(ipc_tty); if (send_info->length <= (TS0710MUX_SERIAL_BUF_SIZE - chars)) { - TS0710_DEBUG("Send queued UIH for /dev/mux%d", j); + TS0710_DEBUG("Send queued UIH for /dev/mux%d\n", j); basic_write(ts0710, (__u8 *) send_info->frame, send_info->length); send_info->length = 0; @@ -3702,15 +1981,12 @@ static void send_worker(struct work_struct *work) continue; } - dlci = tty2dlci[j]; - if (ts0710->dlci[dlci].state == FLOW_STOPPED) { - TS0710_DEBUG("Flow stopped on channel DLCI: %d\n", - dlci); + dlci = j+1; + if (MUX_STOPPED(ts0710,dlci)) continue; - } else if (ts0710->dlci[dlci].state != CONNECTED) { - TS0710_DEBUG("DLCI %d not connected\n", dlci); + + if (! MUX_CONNECTED(ts0710,dlci)) continue; - } if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.ops->write_wakeup) { @@ -3730,119 +2006,64 @@ static void send_worker(struct work_struct *work) } /* End for() loop */ } -static int get_count(__u8 idx) +static int ts_ldisc_open(struct tty_struct *tty) { - int ret; + struct mux_data* disc_data; + printk("ts line %x\n",tty); - if (idx > TS0710MUX_COUNT_MAX_IDX) { - TS0710_PRINTK("MUX get_count: invalid idx: %d!\n", idx); - return -1; - } + tty->receive_room = 65536; - down(&mux_data_count_mutex[idx]); - ret = mux_data_count[idx]; - up(&mux_data_count_mutex[idx]); + disc_data = kzalloc(sizeof(struct mux_data),GFP_KERNEL); - return ret; -} + disc_data->collected = 0; + disc_data->frame = 0; + disc_data->data = NULL; -static int set_count(__u8 idx, int count) -{ - if (idx > TS0710MUX_COUNT_MAX_IDX) { - TS0710_PRINTK("MUX set_count: invalid idx: %d!\n", idx); - return -1; - } - if (count < 0) { - TS0710_PRINTK("MUX set_count: invalid count: %d!\n", count); - return -1; - } + tty->disc_data = disc_data; - down(&mux_data_count_mutex[idx]); - mux_data_count[idx] = count; - up(&mux_data_count_mutex[idx]); + + ipc_tty = tty; return 0; } -static int add_count(__u8 idx, int count) +static void ts_ldisc_close(struct tty_struct *tty) { - if (idx > TS0710MUX_COUNT_MAX_IDX) { - TS0710_PRINTK("MUX add_count: invalid idx: %d!\n", idx); - return -1; - } - if (count <= 0) { - TS0710_PRINTK("MUX add_count: invalid count: %d!\n", count); - return -1; - } + printk("ts close line %x\n",tty); + ipc_tty = 0; - if (down_trylock(&mux_data_count_mutex[idx])) - return -1; - mux_data_count[idx] += count; - up(&mux_data_count_mutex[idx]); - - return 0; } -ssize_t file_proc_read(struct file * file, char *buf, size_t size, - loff_t * ppos) +static void ts_ldisc_wake(struct tty_struct *tty) { - gprs_bytes gprsData[TS0710MUX_GPRS_SESSION_MAX]; - int bufLen = sizeof(gprs_bytes) * TS0710MUX_GPRS_SESSION_MAX; - - UNUSED_PARAM(file); - UNUSED_PARAM(size); - UNUSED_PARAM(ppos); - - gprsData[0].recvBytes = get_count(TS0710MUX_GPRS1_RECV_COUNT_IDX); - gprsData[0].sentBytes = get_count(TS0710MUX_GPRS1_SEND_COUNT_IDX); - gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].recvBytes = - get_count(TS0710MUX_GPRS2_RECV_COUNT_IDX); - gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].sentBytes = - get_count(TS0710MUX_GPRS2_SEND_COUNT_IDX); - - if(copy_to_user(buf, gprsData, bufLen)) - return -EFAULT; - - return bufLen; + printk("ts wake %x\n",tty); } -ssize_t file_proc_write(struct file * file, const char *buf, size_t count, - loff_t * ppos) +static ssize_t ts_ldisc_read(struct tty_struct *tty, struct file *file, + unsigned char __user *buf, size_t nr) { - gprs_bytes gprsData[TS0710MUX_GPRS_SESSION_MAX]; - int bufLen = sizeof(gprs_bytes) * TS0710MUX_GPRS_SESSION_MAX; - - UNUSED_PARAM(file); - UNUSED_PARAM(count); - UNUSED_PARAM(ppos); - - memset(gprsData, 0, bufLen); - - if(copy_from_user(gprsData, buf, bufLen)) - return -EFAULT; - - set_count(TS0710MUX_GPRS1_RECV_COUNT_IDX, gprsData[0].recvBytes); - set_count(TS0710MUX_GPRS1_SEND_COUNT_IDX, gprsData[0].sentBytes); - set_count(TS0710MUX_GPRS2_RECV_COUNT_IDX, - gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].recvBytes); - set_count(TS0710MUX_GPRS2_SEND_COUNT_IDX, - gprsData[TS0710MUX_GPRS_SESSION_MAX - 1].sentBytes); + return 0; +} - return bufLen; +static ssize_t ts_ldisc_write(struct tty_struct *tty, struct file *file, + const unsigned char *data, size_t count) +{ + return 0; } -static void gprs_proc_init(void) +static int ts_ldisc_ioctl(struct tty_struct *tty, struct file * file, + unsigned int cmd, unsigned long arg) { - gprs_proc_file = - create_proc_entry("gprsbytes", S_IRUSR | S_IWUSR, NULL); - gprs_proc_file->proc_fops = &file_proc_operations; + return -1; } -static void gprs_proc_exit(void) +static unsigned int ts_ldisc_poll(struct tty_struct *tty, + struct file *filp, poll_table *wait) { - remove_proc_entry("gprsbytes", gprs_proc_file); + return 0; } + struct tty_operations mux_ops={ .open = mux_open, .close = mux_close, @@ -3852,83 +2073,44 @@ struct tty_operations mux_ops={ .chars_in_buffer = mux_chars_in_buffer, .throttle = mux_throttle, .unthrottle = mux_unthrottle, - .ioctl = mux_ioctl, +}; + +static struct tty_ldisc_ops ts_ldisc = { + .owner = THIS_MODULE, + .magic = TTY_LDISC_MAGIC, + .name = "ts07.10", + .open = ts_ldisc_open, + .close = ts_ldisc_close, + .read = ts_ldisc_read, + .write = ts_ldisc_write, + .ioctl = ts_ldisc_ioctl, + .poll = ts_ldisc_poll, + .receive_buf = ts_ldisc_rx, + .write_wakeup = ts_ldisc_wake, }; -static __u8 tty2dlci_gen1[16] = - { 1, 2, 3, 4, 5, 6, 7, 8, 6, 7, 8, 9, 10, 11, 12, 13 }; static __u8 iscmdtty_gen1[16] = { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0 }; -static dlci_tty dlci2tty_gen1[] = { {0, 0}, /* DLCI 0 */ - {0, 0}, /* DLCI 1 */ - {1, 1}, /* DLCI 2 */ - {2, 2}, /* DLCI 3 */ - {3, 3}, /* DLCI 4 */ - {4, 4}, /* DLCI 5 */ - {5, 8}, /* DLCI 6 */ - {6, 9}, /* DLCI 7 */ - {7, 10}, /* DLCI 8 */ - {11, 11}, /* DLCI 9 */ - {12, 12}, /* DLCI 10 */ - {13, 13}, /* DLCI 11 */ - {14, 14}, /* DLCI 12 */ - {15, 15} - }; /* DLCI 13 */ - -static __u8 tty2dlci_gen2[ 23 ] = - { 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 }; static __u8 iscmdtty_gen2[ 23 ] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; -static dlci_tty dlci2tty_gen2[] = { {0, 0}, /* DLCI 0 */ - {0, 0}, /* DLCI 1 */ - {1, 1}, /* DLCI 2 */ - {2, 2}, /* DLCI 3 */ - {3, 3}, /* DLCI 4 */ - {4, 4}, /* DLCI 5 */ - {10, 10}, /* DLCI 6 */ - {5, 11}, /* DLCI 7 */ - {6, 12}, /* DLCI 8 */ - {7, 13}, /* DLCI 9 */ - {8, 14}, /* DLCI 10 */ - {9, 15}, /* DLCI 11 */ - {16, 16}, /* DLCI 12 */ - {17, 17}, /* DLCI 13 */ - {18, 18}, /* DLCI 14 */ - {19, 19}, /* DLCI 15 */ - {20, 20}, /* DLCI 16 */ - {21, 21}, /* DLCI 17 */ - {22, 22} }; /* DLCI 18 */ - static int __init mux_init(void) { __u8 j; - if (COMM_FOR_MUX_DRIVER == NULL) { - -#ifdef USB_FOR_MUX - panic("please install IPC-USB first\n"); -#else - panic("please install ttyS0 first\n"); -#endif - - } - if(machine_is_ezx_a1200()||machine_is_ezx_e6()){ - NR_MUXS=23; - tty2dlci=tty2dlci_gen2; - iscmdtty=iscmdtty_gen2; - dlci2tty=dlci2tty_gen2; - mux_send_info_idx=23; + NR_MUXS=23; + iscmdtty=iscmdtty_gen2; + mux_send_info_idx=23; }else{ - NR_MUXS=16; - tty2dlci=tty2dlci_gen1; - iscmdtty=iscmdtty_gen1; - dlci2tty=dlci2tty_gen1; - mux_send_info_idx=16; + NR_MUXS=16; + iscmdtty=iscmdtty_gen1; + mux_send_info_idx=16; } + + TS0710_PRINTK("initializing mux with %d channels\n",NR_MUXS); ts0710_init(); @@ -3943,16 +2125,7 @@ static int __init mux_init(void) mux_recv_queue = NULL; mux_recv_flags = 0; - for (j = 0; j < TS0710MUX_COUNT_IDX_NUM; j++) { - mux_data_count[j] = 0; - mux_data_count2[j] = 0; - init_MUTEX(&mux_data_count_mutex[j]); - } - post_recv_count_flag = 0; - INIT_WORK(&send_tqueue, send_worker); - INIT_WORK(&receive_tqueue, receive_worker); - INIT_WORK(&post_recv_tqueue, post_recv_worker); mux_driver = alloc_tty_driver(NR_MUXS); if (!mux_driver) @@ -3991,11 +2164,8 @@ static int __init mux_init(void) for (j=0; j= NR_MUXS) ) +#define MUX_ALL_STOPPED(x) (x->dlci[0].state == FLOW_STOPPED) +#define MUX_STOPPED(x,n) (x->dlci[n].state == FLOW_STOPPED) +#define MUX_CONNECTED(x,n) (x->dlci[n].state == CONNECTED) +#define MUX_STOPPED_FULL(x,n) (MUX_ALL_STOPPED(x) || MUX_STOPPED(x,n)) +#define MUX_USABLE(x,n) (MUX_CONNECTED(x,n) && !MUX_STOPPED_FULL(x,n)) + +static void fcs_init(void); + +static void send_sabm(ts0710_con * ts0710, __u8 dlci); +static void send_dm(ts0710_con * ts0710, __u8 dlci); +static void send_disc(ts0710_con * ts0710, __u8 dlci); +static void send_ua(ts0710_con * ts0710, __u8 dlci); +static void send_pn_msg(ts0710_con * ts0710, __u8 prior, __u32 frame_size, + __u8 credit_flow, __u8 credits, __u8 dlci, __u8 cr); + +static void send_nsc_msg(ts0710_con * ts0710, mcc_type cmd, __u8 cr); +static void mux_send_uih(ts0710_con * ts0710, __u8 cr,__u8 type, __u8 *data, int len); +static void ts0710_fcoff_msg(ts0710_con * ts0710, __u8 cr); +static void ts0710_fcon_msg(ts0710_con * ts0710, __u8 cr); +static void send_ack(ts0710_con * ts0710, __u8 seq_num); diff --git a/drivers/char/ts0710_mux_usb.c b/drivers/char/ts0710_mux_usb.c index da3ee92..575a653 100644 --- a/drivers/char/ts0710_mux_usb.c +++ b/drivers/char/ts0710_mux_usb.c @@ -35,7 +35,9 @@ #include #include #include -#include +#include +#include +#include #include #include #include @@ -50,56 +52,21 @@ #include "ts0710_mux_usb.h" -/*Macro defined for this driver*/ -#define DRIVER_VERSION "1.0alpha1" -#define DRIVER_AUTHOR "Motorola / Harald Welte " -#define DRIVER_DESC "USB IPC Driver (TS07.10 lowlevel)" -#define MOTO_IPC_VID 0x22b8 -#define MOTO_IPC_PID 0x3006 -#define IBUF_SIZE 32 /*urb size*/ -#define IPC_USB_XMIT_SIZE 1024 -#define IPC_URB_SIZE 32 -#define IPC_USB_WRITE_INIT 0 -#define IPC_USB_WRITE_XMIT 1 -#define IPC_USB_PROBE_READY 3 -#define IPC_USB_PROBE_NOT_READY 4 -#define DBG_MAX_BUF_SIZE 1024 -#define ICL_EVENT_INTERVAL (HZ) -#undef BVD_DEBUG - -#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) -#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) -#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) -/*End defined macro*/ - /*global values defined*/ -static struct usb_driver usb_ipc_driver; static struct timer_list ipcusb_timer; -static struct timer_list suspend_timer; -static struct timer_list wakeup_timer; static struct tty_struct ipcusb_tty; /* the coresponding tty struct, we just use flip buffer here. */ -static struct tty_driver ipcusb_tty_driver; /* the coresponding tty driver, we just use write and chars in buff here*/ +static struct tty_driver *ipcusb_tty_driver; /* the coresponding tty driver, we just use write and chars in buff here*/ struct tty_driver *usb_for_mux_driver = NULL; struct tty_struct *usb_for_mux_tty = NULL; -void (*usb_mux_dispatcher)(struct tty_struct *tty) = NULL; void (*usb_mux_sender)(void) = NULL; -void (*ipcusb_ap_to_bp)(unsigned char*, int) = NULL; -void (*ipcusb_bp_to_ap)(unsigned char*, int) = NULL; EXPORT_SYMBOL(usb_for_mux_driver); EXPORT_SYMBOL(usb_for_mux_tty); -EXPORT_SYMBOL(usb_mux_dispatcher); EXPORT_SYMBOL(usb_mux_sender); -EXPORT_SYMBOL(ipcusb_ap_to_bp); -EXPORT_SYMBOL(ipcusb_bp_to_ap); -static int sumbit_times = 0; -static int callback_times = 0; -//static unsigned long last_jiff = 0; -/*end global values defined*/ -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); +static struct usb_ipc_tty *ipc; + +//#define BVD_DEBUG #ifdef BVD_DEBUG #define bvd_dbg(format, arg...) printk(__FILE__ ": " format "\n" , ## arg) #else @@ -116,23 +83,15 @@ typedef struct { struct ipc_usb_data { u_int8_t write_finished_flag; u_int8_t write_flag, - ipc_flag, - suspend_flag; + ipc_flag; struct usb_device *ipc_dev; struct urb readurb_mux, writeurb_mux, writeurb_dsplog; char *obuf, *ibuf; - int writesize; /* max packet size for the - output bulk endpoint * - transfer buffers */ - struct circ_buf xmit; /* write cric bufffer */ struct list_head in_buf_list; spinlock_t in_buf_lock; - char bulk_in_ep_mux, - bulk_out_ep_mux, - bulk_in_ep_dsplog; unsigned int ifnum; struct tasklet_struct bh, @@ -165,75 +124,7 @@ static void bvd_dbg_hex(__u8 *buf, int len) #define bvd_dbg_hex(buf, len) #endif -static int unlink_urbs(struct urb *urb) -{ - unsigned long flags; - int retval; - - spin_lock_irqsave(&bvd_ipc->lock, flags); - - retval = usb_unlink_urb(urb); - if (retval != -EINPROGRESS && retval != 0) - printk("unlink urb err, %d", retval); - - spin_unlock_irqrestore(&bvd_ipc->lock, flags); - return retval; -} - -static void append_to_inbuf_list(struct urb *urb) -{ - buf_list_t *inbuf; - int count = urb->actual_length; - - // we are called from interrupt context. - inbuf = kmalloc(sizeof(buf_list_t), GFP_ATOMIC); - if (!inbuf) { - printk("append_to_inbuf_list: (%d) out of memory!\n", - sizeof(buf_list_t)); - return; - } - - inbuf->size = count; - inbuf->body = kmalloc(sizeof(char)*count, GFP_ATOMIC); - if (!inbuf->body) { - kfree(inbuf); - printk("append_to_inbuf_list: (%d) out of memory!\n", - sizeof(char)*count); - return; - } - memcpy(inbuf->body, (unsigned char*)urb->transfer_buffer, count); - spin_lock(&bvd_ipc->in_buf_lock); - list_add_tail(&inbuf->list, &bvd_ipc->in_buf_list); - spin_unlock(&bvd_ipc->in_buf_lock); -} - -int get_from_inbuf_list(const unsigned char *buf, int dst_count) -{ - int ret = 0; - spin_lock(&bvd_ipc->in_buf_lock); - if (!(list_empty(&bvd_ipc->in_buf_list))) { - int src_count; - buf_list_t *inbuf; - struct list_head *ptr; - - ptr = bvd_ipc->in_buf_list.next; - inbuf = list_entry(ptr, buf_list_t, list); - src_count = inbuf->size; - if (dst_count >= src_count) { - memcpy((unsigned char *)buf, inbuf->body, src_count); - ret = src_count; - list_del(ptr); - kfree(inbuf->body); - kfree(inbuf); - } else { - bvd_dbg("get_from_inbuf_list: not enough space in destination buffer"); - } - } - spin_unlock(&bvd_ipc->in_buf_lock); - return ret; -} -EXPORT_SYMBOL(get_from_inbuf_list); static void ipcusb_timeout(unsigned long data) { @@ -263,9 +154,6 @@ static void ipcusb_timeout(unsigned long data) } spin_unlock(&bvd_ipc->in_buf_lock); - if (usb_mux_dispatcher) - usb_mux_dispatcher(tty); /**call Liu changhui's func.**/ - spin_lock(&bvd_ipc->in_buf_lock); if (list_empty(&bvd_ipc->in_buf_list)) { urb->actual_length = 0; @@ -283,88 +171,63 @@ static void ipcusb_timeout(unsigned long data) static void usb_ipc_read_bulk(struct urb *urb) { int count = urb->actual_length; - struct tty_struct *tty = &ipcusb_tty; + struct tty_struct *tty = ipc->tty; - bvd_dbg("usb_ipc_read_bulk: begining!"); if (urb->status) - printk("nonzero read bulk status received: %d\n", urb->status); + printk("read bulk status received: %d, len %d\n", + urb->status, count + ); - bvd_dbg("usb_ipc_read_bulk: urb->actual_length=%d", urb->actual_length); - bvd_dbg("usb_ipc_read_bulk: urb->transfer_buffer:"); + if (!count) + return; bvd_dbg_hex((unsigned char*)urb->transfer_buffer, urb->actual_length); - if (count > 0 && ((*ipcusb_bp_to_ap) != NULL)) - (*ipcusb_bp_to_ap)(urb->transfer_buffer, urb->actual_length); + bvd_dbg("usb_ipc_read_bulk: inserting buffer into in_buf_list"); - if (count > 0) { - bvd_dbg("usb_ipc_read_bulk: inserting buffer into in_buf_list"); - bvd_ipc->suspend_flag = 1; - append_to_inbuf_list(urb); - if (usb_mux_dispatcher) - usb_mux_dispatcher(tty); /* call Liu changhui's func. */ + /* + printk("tty %x\n",tty); + printk("tty->ldisc %x\n",tty->ldisc); + printk("&tty->ldisc %x\n",&tty->ldisc); + printk("tty->ldisc.ops %x\n",tty->ldisc.ops); + //printk("tty->ldisc.ops->receive_buf %x\n",tty->ldisc.ops->receive_buf); + printk("buffer %x\n",urb->transfer_buffer); + printk("len %d\n",urb->actual_length); */ - urb->actual_length = 0; - urb->dev = bvd_ipc->ipc_dev; - if (usb_submit_urb(urb, GFP_ATOMIC)) - bvd_dbg("failed resubmitting read urb"); - bvd_dbg("usb_ipc_read_bulk: resubmited read urb"); - } + tty->ldisc.ops->receive_buf( + tty, (unsigned char*)urb->transfer_buffer, + NULL,urb->actual_length + ); + + urb->actual_length = 0; + urb->dev = bvd_ipc->ipc_dev; + if (usb_submit_urb(urb, GFP_ATOMIC)) + bvd_dbg("failed resubmitting read urb"); - bvd_dbg("usb_ipc_read_bulk: completed!!!"); } static void usb_ipc_write_bulk(struct urb *urb) { - callback_times++; bvd_ipc->write_finished_flag = 1; - bvd_dbg("usb_ipc_write_bulk: begining!"); - //printk("%s: write_finished_flag=%d\n", __FUNCTION__, bvd_ipc->write_finished_flag); - if (urb->status) printk("nonzero write bulk status received: %d\n", urb->status); if (usb_mux_sender) - usb_mux_sender(); /**call Liu changhui's func**/ + usb_mux_sender(); - //printk("usb_ipc_write_bulk: mark ipcusb_softint!\n"); tasklet_schedule(&bvd_ipc->bh); - - bvd_dbg("usb_ipc_write_bulk: finished!"); } -static void wakeup_timeout(unsigned long data) -{ -// GPSR(GPIO_MCU_INT_SW) = GPIO_bit(GPIO_MCU_INT_SW); - bvd_dbg("wakup_timeout: send GPIO_MCU_INT_SW signal!"); -} - -static void suspend_timeout(unsigned long data) -{ - if (bvd_ipc->suspend_flag == 1) { - bvd_ipc->suspend_flag = 0; - mod_timer(&suspend_timer, jiffies+(5000*HZ/1000)); - bvd_dbg("suspend_timeout: add the suspend timer again"); - } else { - unlink_urbs(&bvd_ipc->readurb_mux); -// UHCRHPS3 = 0x4; -// mdelay(40); -// bvd_dbg("suspend_timeout: send SUSPEND signal! UHCRHPS3=0x%x", -// UHCRHPS3); - } -} static void ipcusb_xmit_data(void) { int c, count = IPC_URB_SIZE; - int result = 0; int buf_flag = 0; int buf_num = 0; - //printk("%s: sumbit_times=%d, callback_times=%d\n", __FUNCTION__, sumbit_times, callback_times); if (bvd_ipc->write_finished_flag == 0) return; @@ -385,87 +248,39 @@ static void ipcusb_xmit_data(void) buf_num += c; } - if (buf_num == 0) { - bvd_dbg("ipcusb_xmit_data: buf_num=%d, add suspend_timer", - buf_num); - bvd_ipc->suspend_flag = 0; - mod_timer(&suspend_timer, jiffies+(5000*HZ/1000)); - } + if (!buf_flag) + return; bvd_dbg("ipcusb_xmit_data: buf_num=%d", buf_num); bvd_dbg("ipcusb_xmit_data: bvd_ipc->obuf: "); - bvd_dbg_hex((bvd_ipc->obuf)-buf_num, buf_num); - if (buf_flag) { - bvd_ipc->writeurb_mux.transfer_buffer_length = buf_num; - bvd_dbg("ipcusb_xmit_data: copy data to write urb finished! "); - - /* if ((UHCRHPS3 & 0x4) == 0x4) */{ - static int ret; - int time = 0; - - - /* Resume BP */ -// UHCRHPS3 = 0x8; -// mdelay(40); - bvd_dbg("ipcusb_xmit_data: Send RESUME signal! UHCRHPS3=0x%x", - UHCRHPS3); - /*send IN token*/ - bvd_ipc->readurb_mux.actual_length = 0; - bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev; - if ((ret = usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC))) - printk("ipcusb_xmit_data: usb_submit_urb(read mux bulk)" - "failed! status=%d\n", ret); - bvd_dbg("ipcusb_xmit_data: Send a IN token successfully!"); - } + bvd_ipc->writeurb_mux.transfer_buffer_length = buf_num; + ezx_wake_bp(); - sumbit_times++; - bvd_ipc->write_finished_flag = 0; - //printk("%s: clear write_finished_flag:%d\n", __FUNCTION__, bvd_ipc->write_finished_flag); - bvd_ipc->writeurb_mux.dev = bvd_ipc->ipc_dev; - if ((result = usb_submit_urb(&bvd_ipc->writeurb_mux, GFP_ATOMIC))) - warn("ipcusb_xmit_data: funky result! result=%d\n", result); + bvd_ipc->write_finished_flag = 0; - bvd_dbg("ipcusb_xmit_data: usb_submit_urb finished! result:%d", result); + bvd_ipc->writeurb_mux.dev = bvd_ipc->ipc_dev; + usb_submit_urb(&bvd_ipc->writeurb_mux, GFP_ATOMIC); - } } -static void usbipc_bh_func(unsigned long param) +static void usbipc_bh_bp_func(unsigned long param) { - ipcusb_xmit_data(); -} + if (bvd_ipc->ipc_flag =! IPC_USB_PROBE_READY) + return; + + /*send a IN token*/ + bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev; + usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC); -//extern void get_halted_bit(void); -static void usbipc_bh_bp_func(unsigned long param) -{ -// if ((UHCRHPS3 & 0x4) == 0x4) { -// UHCRHPS3 = 0x8; -// mdelay(40); -// bvd_dbg("ipcusb_softint_send_readurb: Send RESUME signal! " -// "UHCRHPS3=0x%x", UHCRHPS3); -// } - if (bvd_ipc->ipc_flag == IPC_USB_PROBE_READY) { - //get_halted_bit(); - - /*send a IN token*/ - bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev; - if (usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC)) { - bvd_dbg("ipcusb_softint_send_readurb: " - "usb_submit_urb(read mux bulk) failed!"); - } - bvd_dbg("ipcusb_softint_send_readurb: Send a IN token successfully!"); - bvd_ipc->suspend_flag = 0; - bvd_dbg("ipcusb_softint_send_readurb: add suspend_timer"); - mod_timer(&suspend_timer, jiffies+(5000*HZ/1000)); - } } static int usb_ipc_write(struct tty_struct *tty, const unsigned char *buf, int count) { + printk("usb_ipc_write\n"); int c, ret = 0; bvd_dbg("usb_ipc_write: count=%d, buf: ", count); @@ -474,11 +289,6 @@ static int usb_ipc_write(struct tty_struct *tty, if (count <= 0) return 0; - if (*ipcusb_ap_to_bp != NULL) - (*ipcusb_ap_to_bp)((unsigned char *)buf, count); - - bvd_ipc->suspend_flag = 1; - if ((bvd_ipc->ipc_flag == IPC_USB_PROBE_READY) && (bvd_ipc->xmit.head == bvd_ipc->xmit.tail)) { bvd_dbg("usb_ipc_write: set write_flag"); @@ -514,17 +324,85 @@ static int usb_ipc_write(struct tty_struct *tty, return ret; } +static int usb_ipc_write_room(struct tty_struct *tty) { + return IPC_USB_XMIT_SIZE; +} + static int usb_ipc_chars_in_buffer(struct tty_struct *tty) { - return CIRC_CNT(bvd_ipc->xmit.head, bvd_ipc->xmit.tail, IPC_USB_XMIT_SIZE); + return 0;//CIRC_CNT(bvd_ipc->xmit.head, bvd_ipc->xmit.tail, IPC_USB_XMIT_SIZE); +} + +static int usb_ipc_open(struct tty_struct *tty, struct file *file) +{ + + printk("open: %x, %x\n",tty,ipc); + + int index; + + /* initialize the pointer in case something fails */ + tty->driver_data = NULL; + + /* get the serial object associated with this tty pointer */ + index = tty->index; + + if (ipc == NULL) { + + printk("alloc\n"); + /* first time accessing this device, let's create it */ + ipc = kmalloc(sizeof(*ipc), GFP_KERNEL); + if (!ipc) + return -ENOMEM; + + ipc->open_count = 0; + } + + printk("after alloc\n"); + + + /* save our structure within the tty structure */ + tty->driver_data = ipc; + ipc->tty = tty; + ipc->open_count++; + + + if (ipc->open_count == 1) { + printk("opened first time\n"); + } + + printk("ipc opened %d times\n",ipc->open_count); + + printk("tty %x %x\n",ipc->tty,tty); + printk("&tty->ldisc %x\n",&tty->ldisc); + printk("tty->ldisc.ops %x\n",tty->ldisc.ops); + + + return 0; + +} + +static void usb_ipc_close(struct tty_struct *tty, struct file *file) { + + if (!ipc) + return; + + if (!ipc->open_count) + return; + + ipc->open_count--; + + if (ipc->open_count <= 0) { + printk("closed last time\n"); + } + + } -static int is_probed=0; void usb_send_readurb(void) { - //printk("usb_send_readurb: begining!UHCRHPS3=0x%x, usbh_finished_resume=%d\n", UHCRHPS3, usbh_finished_resume); - if(!is_probed) + if (bvd_ipc->ipc_flag != IPC_USB_PROBE_READY) return; + tasklet_schedule(&bvd_ipc->bh_bp); } @@ -535,8 +413,8 @@ static int usb_ipc_probe(struct usb_interface *intf, struct usb_config_descriptor *ipccfg; struct usb_interface_descriptor *interface; struct usb_endpoint_descriptor *endpoint; - int ep_cnt, readsize, writesize; - char have_bulk_in_mux, have_bulk_out_mux; + int ep_cnt, size_in, size_out; + char ep_in, ep_out; bvd_dbg("usb_ipc_probe: vendor id 0x%x, device id 0x%x", usbdev->descriptor.idVendor, usbdev->descriptor.idProduct); @@ -559,13 +437,13 @@ static int usb_ipc_probe(struct usb_interface *intf, /* After this point we can be a little noisy about what we are trying * to configure, hehe. */ if (usbdev->descriptor.bNumConfigurations != 1) { - info("usb_ipc_probe: Only one device configuration " + printk("usb_ipc_probe: Only one device configuration " "is supported."); return -1; } if (usbdev->config[0].desc.bNumInterfaces != 3) { - info("usb_ipc_probe: Only three device interfaces are " + printk("usb_ipc_probe: Only three device interfaces are " "supported."); return -1; } @@ -576,67 +454,58 @@ static int usb_ipc_probe(struct usb_interface *intf, bvd_dbg("usb_ipc_probe: Number of Endpoints:%d", (int) interface->bNumEndpoints); if (interface->bNumEndpoints != 2) { - info("usb_ipc_probe: Only two endpoints supported."); + printk("usb_ipc_probe: Only two endpoints supported got %d\n.", + interface->bNumEndpoints + ); return -1; } - ep_cnt = have_bulk_in_mux = have_bulk_out_mux = 0; - readsize = writesize = 0; + ep_cnt = ep_in = ep_out = 0; + size_in = size_out = 0; while (ep_cnt < interface->bNumEndpoints) { endpoint = &intf->cur_altsetting->endpoint[ep_cnt].desc; - bvd_dbg("usb_ipc_probe: endpoint[%i] is: %x", ep_cnt, - endpoint->bEndpointAddress); - - if (!have_bulk_in_mux && IS_EP_BULK_IN(*endpoint)) { - bvd_dbg("usb_ipc_probe: bEndpointAddress(IN) is: %x ", - endpoint->bEndpointAddress); - have_bulk_in_mux = endpoint->bEndpointAddress; - readsize = endpoint->wMaxPacketSize; - bvd_dbg("usb_ipc_probe: readsize=%d", readsize); - ep_cnt++; - continue; - } - if (!have_bulk_out_mux && IS_EP_BULK_OUT(*endpoint)) { - bvd_dbg("usb_ipc_probe: bEndpointAddress(OUT) is: %x ", - endpoint->bEndpointAddress); - have_bulk_out_mux = endpoint->bEndpointAddress; - writesize = endpoint->wMaxPacketSize; - bvd_dbg("usb_ipc_probe: writesize=%d", writesize); - ep_cnt++; - continue; - } + switch(endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { + case USB_DIR_IN: + printk("in\n"); + ep_in = endpoint->bEndpointAddress; + size_in = endpoint->wMaxPacketSize; + break; + case USB_DIR_OUT: + printk("out\n"); + ep_out = endpoint->bEndpointAddress; + size_out = endpoint->wMaxPacketSize; + break; + default: + printk("wtf is this? %d\n",ep_cnt); - info("usb_ipc_probe: Undetected endpoint ^_^ "); - /* Shouldn't ever get here unless we have something weird */ - return -1; + } + + + ep_cnt++; + + printk("usb_ipc_probe: Undetected endpoint\n"); } - /* Perform a quick check to make sure that everything worked as it - * should have. */ + printk("endpoints: %x/%x, sizes: %d/%d\n", + ep_in, ep_out, size_in, size_out + ); - switch (interface->bNumEndpoints) { - case 2: - if (!have_bulk_in_mux || !have_bulk_out_mux) { - info("usb_ipc_probe: Two bulk endpoints required."); - return -1; - } - break; - default: - info("usb_ipc_probe: Endpoint determination failed ^_^ "); + if (! (ep_in && ep_out) ) { + printk("usb_ipc_probe: Two bulk endpoints required."); return -1; } - + /* Ok, now initialize all the relevant values */ - if (!(bvd_ipc->obuf = (char *)kmalloc(writesize, GFP_KERNEL))) { + if (!(bvd_ipc->obuf = (char *)kmalloc(size_out, GFP_KERNEL))) { err("usb_ipc_probe: Not enough memory for the output buffer."); kfree(bvd_ipc); return -1; } bvd_dbg("usb_ipc_probe: obuf address:%p", bvd_ipc->obuf); - if (!(bvd_ipc->ibuf = (char *)kmalloc(readsize, GFP_KERNEL))) { + if (!(bvd_ipc->ibuf = (char *)kmalloc(size_in, GFP_KERNEL))) { err("usb_ipc_probe: Not enough memory for the input buffer."); kfree(bvd_ipc->obuf); kfree(bvd_ipc); @@ -644,52 +513,44 @@ static int usb_ipc_probe(struct usb_interface *intf, } bvd_dbg("usb_ipc_probe: ibuf address:%p", bvd_ipc->ibuf); - bvd_ipc->ipc_flag = IPC_USB_PROBE_READY; bvd_ipc->write_finished_flag = 1; - bvd_ipc->suspend_flag = 1; - bvd_ipc->bulk_in_ep_mux= have_bulk_in_mux; - bvd_ipc->bulk_out_ep_mux= have_bulk_out_mux; bvd_ipc->ipc_dev = usbdev; - bvd_ipc->writesize = writesize; INIT_LIST_HEAD(&bvd_ipc->in_buf_list); bvd_ipc->in_buf_lock = SPIN_LOCK_UNLOCKED; - bvd_ipc->bh.func = usbipc_bh_func; + bvd_ipc->bh.func = ipcusb_xmit_data; bvd_ipc->bh.data = (unsigned long) bvd_ipc; bvd_ipc->bh_bp.func = usbipc_bh_bp_func; bvd_ipc->bh_bp.data = (unsigned long) bvd_ipc; - bvd_dbg("after assignements"); + /*Build a write urb*/ usb_init_urb(&bvd_ipc->writeurb_mux); usb_fill_bulk_urb(&bvd_ipc->writeurb_mux, usbdev, - usb_sndbulkpipe(bvd_ipc->ipc_dev, - bvd_ipc->bulk_out_ep_mux), - bvd_ipc->obuf, writesize, usb_ipc_write_bulk, + usb_sndbulkpipe(usbdev, ep_out), + bvd_ipc->obuf, size_out, usb_ipc_write_bulk, bvd_ipc); - //bvd_ipc->writeurb_mux.transfer_flags |= USB_ASYNC_UNLINK; + bvd_dbg("after write urb"); /*Build a read urb and send a IN token first time*/ usb_init_urb(&bvd_ipc->readurb_mux); usb_fill_bulk_urb(&bvd_ipc->readurb_mux, usbdev, - usb_rcvbulkpipe(usbdev, bvd_ipc->bulk_in_ep_mux), - bvd_ipc->ibuf, readsize, usb_ipc_read_bulk, bvd_ipc); - //bvd_ipc->readurb_mux.transfer_flags |= USB_ASYNC_UNLINK; + usb_rcvbulkpipe(usbdev, ep_in), + bvd_ipc->ibuf, size_in, usb_ipc_read_bulk, bvd_ipc); + bvd_dbg("after read urb"); - //usb_driver_claim_interface(&usb_ipc_driver, intf, bvd_ipc); bvd_dbg("after claim interface"); - //usb_driver_claim_interface(&usb_ipc_driver, &ipccfg->interface[1], bvd_ipc); - // a2590c: dsplog is not supported by this driver - // usb_driver_claim_interface(&usb_ipc_driver, - // &ipccfg->interface[2], bvd_ipc); /*send a IN token first time*/ bvd_ipc->readurb_mux.dev = bvd_ipc->ipc_dev; bvd_dbg("after assignement"); + usb_set_intfdata(intf, bvd_ipc); + bvd_ipc->ipc_flag = IPC_USB_PROBE_READY; + if (usb_submit_urb(&bvd_ipc->readurb_mux, GFP_ATOMIC)) printk("usb_ipc_prob: usb_submit_urb(read mux bulk) failed!\n"); @@ -700,40 +561,21 @@ static int usb_ipc_probe(struct usb_interface *intf, tasklet_schedule(&bvd_ipc->bh); } - printk("usb_ipc_probe: completed probe!\n"); - usb_set_intfdata(intf, &bvd_ipc); - is_probed=1; return 0; } static void usb_ipc_disconnect(struct usb_interface *intf) { - //struct usb_device *usbdev = interface_to_usbdev(intf); - struct ipc_usb_data *bvd_ipc_disconnect = usb_get_intfdata(intf); - - - printk("usb_ipc_disconnect. bvd_ipc_disconnect address: %p\n", bvd_ipc_disconnect); - - //FIXME: Memory leak? -// if ((UHCRHPS3 & 0x4) == 0) - // usb_unlink_urb(&bvd_ipc_disconnect->readurb_mux); - - //usb_unlink_urb(&bvd_ipc_disconnect->writeurb_mux); - - bvd_ipc_disconnect->ipc_flag = IPC_USB_PROBE_NOT_READY; - kfree(bvd_ipc_disconnect->ibuf); - kfree(bvd_ipc_disconnect->obuf); - //usb_driver_release_interface(&usb_ipc_driver, - // bvd_ipc_disconnect->ipc_dev->actconfig->interface[0]); - //usb_driver_release_interface(&usb_ipc_driver, - // bvd_ipc_disconnect->ipc_dev->actconfig->interface[1]); + usb_unlink_urb(&bvd_ipc->writeurb_mux); + usb_unlink_urb(&bvd_ipc->readurb_mux); - //a2590c: dsplog interface is not supported by this driver - //usb_driver_release_interface(&usb_ipc_driver, &bvd_ipc_disconnect->ipc_dev->actconfig->interface[2]); + bvd_ipc->ipc_flag = IPC_USB_PROBE_NOT_READY; + kfree(bvd_ipc->ibuf); + kfree(bvd_ipc->obuf); - bvd_ipc_disconnect->ipc_dev = NULL; + bvd_ipc->ipc_dev = NULL; usb_set_intfdata(intf, NULL); @@ -746,14 +588,17 @@ static struct usb_device_id usb_ipc_id_table[] = { }; static struct usb_driver usb_ipc_driver = { - .name = "usb ipc", + .name = "usb_ipc", .probe = usb_ipc_probe, .disconnect = usb_ipc_disconnect, .id_table = usb_ipc_id_table, }; struct tty_operations ipc_tty_ops={ + .open = usb_ipc_open, + .close = usb_ipc_close, .write = usb_ipc_write, + .write_room = usb_ipc_write_room, .chars_in_buffer = usb_ipc_chars_in_buffer, }; @@ -762,6 +607,7 @@ static int __init usb_ipc_init(void) int result; bvd_dbg("init usb_ipc"); + /*init the related mux interface*/ if (!(bvd_ipc = kzalloc(sizeof(struct ipc_usb_data), GFP_KERNEL))) { err("usb_ipc_init: Out of memory."); @@ -782,32 +628,46 @@ static int __init usb_ipc_init(void) spin_lock_init(&bvd_ipc->lock); spin_lock_init(&bvd_ipc->in_buf_lock); + ipcusb_tty_driver = alloc_tty_driver(1); + ipcusb_tty_driver->owner = THIS_MODULE; + ipcusb_tty_driver->driver_name = "Neptune IPC"; + ipcusb_tty_driver->name = "ttyIPC"; + ipcusb_tty_driver->major = 251; + ipcusb_tty_driver->minor_start = 0; + ipcusb_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, + ipcusb_tty_driver->subtype = SERIAL_TYPE_NORMAL, + ipcusb_tty_driver->init_termios = tty_std_termios; + ipcusb_tty_driver->init_termios.c_cflag = B38400 | CS8 | CREAD; + ipcusb_tty_driver->flags = TTY_DRIVER_RESET_TERMIOS | TTY_DRIVER_REAL_RAW; - tty_set_operations(&ipcusb_tty_driver,&ipc_tty_ops); + tty_set_operations(ipcusb_tty_driver,&ipc_tty_ops); + if (tty_register_driver(ipcusb_tty_driver)) + printk("oops. cant register ipc tty\n"); - usb_for_mux_driver = &ipcusb_tty_driver; + printk("registering ipc tty dev %x\n",ipcusb_tty_driver); + if ( tty_register_device(ipcusb_tty_driver, 0, NULL)) + printk("oops cant register ipc tty dev\n"); + + usb_for_mux_driver = ipcusb_tty_driver; usb_for_mux_tty = &ipcusb_tty; /* register driver at the USB subsystem */ - // this was called before bvd_ipc was allocated result = usb_register(&usb_ipc_driver); if (result < 0) { err ("usb ipc driver could not be registered"); return result; } + ipc = NULL; + /* init timers for ipcusb read process and usb suspend */ init_timer(&ipcusb_timer); ipcusb_timer.function = ipcusb_timeout; - init_timer(&suspend_timer); - suspend_timer.function = suspend_timeout; + printk("USB Host(Bulverde) IPC driver registered.\n"); + printk(DRIVER_VERSION ":" DRIVER_DESC "\n"); - init_timer(&wakeup_timer); - wakeup_timer.function = wakeup_timeout; - info("USB Host(Bulverde) IPC driver registered."); - info(DRIVER_VERSION ":" DRIVER_DESC); return 0; } @@ -820,9 +680,13 @@ static void __exit usb_ipc_exit(void) kfree(bvd_ipc); usb_deregister(&usb_ipc_driver); - info("USB Host(Bulverde) IPC driver deregistered."); + printk("USB Host(Bulverde) IPC driver deregistered.\n"); } module_init(usb_ipc_init); module_exit(usb_ipc_exit); EXPORT_SYMBOL(usb_send_readurb); + +MODULE_AUTHOR(DRIVER_AUTHOR); +MODULE_DESCRIPTION(DRIVER_DESC); +MODULE_LICENSE("GPL"); diff --git a/drivers/char/ts0710_mux_usb.h b/drivers/char/ts0710_mux_usb.h index 8921227..73972b1 100644 --- a/drivers/char/ts0710_mux_usb.h +++ b/drivers/char/ts0710_mux_usb.h @@ -28,5 +28,30 @@ extern struct tty_struct *usb_for_mux_tty; extern void (*usb_mux_dispatcher)(struct tty_struct *tty); extern void (*usb_mux_sender)(void); -extern int get_from_inbuf_list(const unsigned char *buf, int dst_count); +struct usb_ipc_tty { + struct tty_struct *tty; /* pointer to the tty for this device */ + int open_count; /* number of times this port has been opened */ + struct timer_list *timer; + +}; + +#define DRIVER_VERSION "1.0alpha1" +#define DRIVER_AUTHOR "Motorola / Harald Welte " +#define DRIVER_DESC "USB IPC Driver (TS07.10 lowlevel)" +#define MOTO_IPC_VID 0x22b8 +#define MOTO_IPC_PID 0x3006 +#define IBUF_SIZE 32 /*urb size*/ +#define IPC_USB_XMIT_SIZE 1024 +#define IPC_URB_SIZE 32 +#define IPC_USB_WRITE_INIT 0 +#define IPC_USB_WRITE_XMIT 1 +#define IPC_USB_PROBE_READY 3 +#define IPC_USB_PROBE_NOT_READY 4 +#define DBG_MAX_BUF_SIZE 1024 +#define ICL_EVENT_INTERVAL (HZ) + + +#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0) +#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) +#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)