diff options
Diffstat (limited to 'drivers/isdn/gigaset')
-rw-r--r-- | drivers/isdn/gigaset/Kconfig | 1 | ||||
-rw-r--r-- | drivers/isdn/gigaset/common.c | 31 | ||||
-rw-r--r-- | drivers/isdn/gigaset/ev-layer.c | 124 | ||||
-rw-r--r-- | drivers/isdn/gigaset/gigaset.h | 9 | ||||
-rw-r--r-- | drivers/isdn/gigaset/interface.c | 60 |
5 files changed, 97 insertions, 128 deletions
diff --git a/drivers/isdn/gigaset/Kconfig b/drivers/isdn/gigaset/Kconfig index b18a92c3218..dde5e09e626 100644 --- a/drivers/isdn/gigaset/Kconfig +++ b/drivers/isdn/gigaset/Kconfig @@ -1,5 +1,6 @@ menuconfig ISDN_DRV_GIGASET tristate "Siemens Gigaset support" + depends on TTY select CRC_CCITT select BITREVERSE help diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 6849a11a1b2..7c7814497e3 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c @@ -467,11 +467,6 @@ void gigaset_freecs(struct cardstate *cs) mutex_lock(&cs->mutex); - if (!cs->bcs) - goto f_cs; - if (!cs->inbuf) - goto f_bcs; - spin_lock_irqsave(&cs->lock, flags); cs->running = 0; spin_unlock_irqrestore(&cs->lock, flags); /* event handler and timer are @@ -507,17 +502,16 @@ void gigaset_freecs(struct cardstate *cs) gig_dbg(DEBUG_INIT, "clearing at_state"); clear_at_state(&cs->at_state); dealloc_temp_at_states(cs); + clear_events(cs); tty_port_destroy(&cs->port); /* fall through */ case 0: /* error in basic setup */ - clear_events(cs); gig_dbg(DEBUG_INIT, "freeing inbuf"); kfree(cs->inbuf); + kfree(cs->bcs); } -f_bcs: gig_dbg(DEBUG_INIT, "freeing bcs[]"); - kfree(cs->bcs); -f_cs: gig_dbg(DEBUG_INIT, "freeing cs"); + mutex_unlock(&cs->mutex); free_cs(cs); } @@ -687,19 +681,6 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, return NULL; } - gig_dbg(DEBUG_INIT, "allocating bcs[0..%d]", channels - 1); - cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); - if (!cs->bcs) { - pr_err("out of memory\n"); - goto error; - } - gig_dbg(DEBUG_INIT, "allocating inbuf"); - cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); - if (!cs->inbuf) { - pr_err("out of memory\n"); - goto error; - } - cs->cs_init = 0; cs->channels = channels; cs->onechannel = onechannel; @@ -729,6 +710,12 @@ struct cardstate *gigaset_initcs(struct gigaset_driver *drv, int channels, cs->mode = M_UNKNOWN; cs->mstate = MS_UNINITIALIZED; + cs->bcs = kmalloc(channels * sizeof(struct bc_state), GFP_KERNEL); + cs->inbuf = kmalloc(sizeof(struct inbuf_t), GFP_KERNEL); + if (!cs->bcs || !cs->inbuf) { + pr_err("out of memory\n"); + goto error; + } ++cs->cs_init; gig_dbg(DEBUG_INIT, "setting up at_state"); diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index 2e6963dc740..7459b127ddd 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c @@ -351,10 +351,11 @@ struct reply_t gigaset_tab_cid[] = static const struct resp_type_t { - unsigned char *response; - int resp_code; - int type; -} resp_type[] = + char *response; + int resp_code; + int type; +} +resp_type[] = { {"OK", RSP_OK, RT_NOTHING}, {"ERROR", RSP_ERROR, RT_NOTHING}, @@ -374,11 +375,12 @@ static const struct resp_type_t { }; static const struct zsau_resp_t { - unsigned char *str; - int code; -} zsau_resp[] = + char *str; + int code; +} +zsau_resp[] = { - {"OUTGOING_CALL_PROCEEDING", ZSAU_OUTGOING_CALL_PROCEEDING}, + {"OUTGOING_CALL_PROCEEDING", ZSAU_PROCEEDING}, {"CALL_DELIVERED", ZSAU_CALL_DELIVERED}, {"ACTIVE", ZSAU_ACTIVE}, {"DISCONNECT_IND", ZSAU_DISCONNECT_IND}, @@ -434,7 +436,7 @@ void gigaset_handle_modem_response(struct cardstate *cs) len = cs->cbytes; if (!len) { /* ignore additional LFs/CRs (M10x config mode or cx100) */ - gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[len]); + gig_dbg(DEBUG_MCMD, "skipped EOL [%02X]", cs->respdata[0]); return; } cs->respdata[len] = 0; @@ -707,27 +709,29 @@ static void schedule_init(struct cardstate *cs, int state) cs->commands_pending = 1; } -/* Add "AT" to a command, add the cid, dle encode it, send the result to the - hardware. */ -static void send_command(struct cardstate *cs, const char *cmd, int cid, - int dle, gfp_t kmallocflags) +/* send an AT command + * adding the "AT" prefix, cid and DLE encapsulation as appropriate + */ +static void send_command(struct cardstate *cs, const char *cmd, + struct at_state_t *at_state) { + int cid = at_state->cid; struct cmdbuf_t *cb; size_t buflen; buflen = strlen(cmd) + 12; /* DLE ( A T 1 2 3 4 5 <cmd> DLE ) \0 */ - cb = kmalloc(sizeof(struct cmdbuf_t) + buflen, kmallocflags); + cb = kmalloc(sizeof(struct cmdbuf_t) + buflen, GFP_ATOMIC); if (!cb) { dev_err(cs->dev, "%s: out of memory\n", __func__); return; } if (cid > 0 && cid <= 65535) cb->len = snprintf(cb->buf, buflen, - dle ? "\020(AT%d%s\020)" : "AT%d%s", + cs->dle ? "\020(AT%d%s\020)" : "AT%d%s", cid, cmd); else cb->len = snprintf(cb->buf, buflen, - dle ? "\020(AT%s\020)" : "AT%s", + cs->dle ? "\020(AT%s\020)" : "AT%s", cmd); cb->offset = 0; cb->next = NULL; @@ -886,7 +890,7 @@ static void finish_shutdown(struct cardstate *cs) gigaset_isdn_stop(cs); } - /* The rest is done by cleanup_cs () in user mode. */ + /* The rest is done by cleanup_cs() in process context. */ cs->cmd_result = -ENODEV; cs->waiting = 0; @@ -976,10 +980,9 @@ exit: } static void handle_icall(struct cardstate *cs, struct bc_state *bcs, - struct at_state_t **p_at_state) + struct at_state_t *at_state) { int retval; - struct at_state_t *at_state = *p_at_state; retval = gigaset_isdn_icall(at_state); switch (retval) { @@ -1176,7 +1179,7 @@ static void do_action(int action, struct cardstate *cs, spin_unlock_irqrestore(&cs->lock, flags); break; case ACT_ICALL: - handle_icall(cs, bcs, p_at_state); + handle_icall(cs, bcs, at_state); break; case ACT_FAILSDOWN: dev_warn(cs->dev, "Could not shut down the device.\n"); @@ -1264,7 +1267,7 @@ static void do_action(int action, struct cardstate *cs, cs->commands_pending = 1; break; } - /* fall through */ + /* bad cid: fall through */ case ACT_FAILCID: cs->cur_at_seq = SEQ_NONE; channel = cs->curchannel; @@ -1339,7 +1342,6 @@ static void do_action(int action, struct cardstate *cs, *p_resp_code = RSP_ERROR; break; } - /*at_state->getstring = 1;*/ cs->gotfwver = 0; break; case ACT_GOTVER: @@ -1471,7 +1473,6 @@ static void process_event(struct cardstate *cs, struct event_t *ev) int rcode; int genresp = 0; int resp_code = RSP_ERROR; - int sendcid; struct at_state_t *at_state; int index; int curact; @@ -1499,7 +1500,6 @@ static void process_event(struct cardstate *cs, struct event_t *ev) at_state->ConState, ev->type); bcs = at_state->bcs; - sendcid = at_state->cid; /* Setting the pointer to the dial array */ rep = at_state->replystruct; @@ -1510,10 +1510,12 @@ static void process_event(struct cardstate *cs, struct event_t *ev) || !at_state->timer_active) { ev->type = RSP_NONE; /* old timeout */ gig_dbg(DEBUG_EVENT, "old timeout"); - } else if (!at_state->waiting) - gig_dbg(DEBUG_EVENT, "timeout occurred"); - else - gig_dbg(DEBUG_EVENT, "stopped waiting"); + } else { + if (at_state->waiting) + gig_dbg(DEBUG_EVENT, "stopped waiting"); + else + gig_dbg(DEBUG_EVENT, "timeout occurred"); + } } spin_unlock_irqrestore(&cs->lock, flags); @@ -1561,45 +1563,40 @@ static void process_event(struct cardstate *cs, struct event_t *ev) do_action(rep->action[curact], cs, bcs, &at_state, &p_command, &genresp, &resp_code, ev); if (!at_state) - break; /* may be freed after disconnect */ + /* at_state destroyed by disconnect */ + return; } - if (at_state) { - /* Jump to the next con-state regarding the array */ - if (rep->new_ConState >= 0) - at_state->ConState = rep->new_ConState; + /* Jump to the next con-state regarding the array */ + if (rep->new_ConState >= 0) + at_state->ConState = rep->new_ConState; - if (genresp) { - spin_lock_irqsave(&cs->lock, flags); + if (genresp) { + spin_lock_irqsave(&cs->lock, flags); + at_state->timer_expires = 0; + at_state->timer_active = 0; + spin_unlock_irqrestore(&cs->lock, flags); + gigaset_add_event(cs, at_state, resp_code, NULL, 0, NULL); + } else { + /* Send command to modem if not NULL... */ + if (p_command) { + if (cs->connected) + send_command(cs, p_command, at_state); + else + gigaset_add_event(cs, at_state, RSP_NODEV, + NULL, 0, NULL); + } + + spin_lock_irqsave(&cs->lock, flags); + if (!rep->timeout) { at_state->timer_expires = 0; at_state->timer_active = 0; - spin_unlock_irqrestore(&cs->lock, flags); - gigaset_add_event(cs, at_state, resp_code, - NULL, 0, NULL); - } else { - /* Send command to modem if not NULL... */ - if (p_command) { - if (cs->connected) - send_command(cs, p_command, - sendcid, cs->dle, - GFP_ATOMIC); - else - gigaset_add_event(cs, at_state, - RSP_NODEV, - NULL, 0, NULL); - } - - spin_lock_irqsave(&cs->lock, flags); - if (!rep->timeout) { - at_state->timer_expires = 0; - at_state->timer_active = 0; - } else if (rep->timeout > 0) { /* new timeout */ - at_state->timer_expires = rep->timeout * 10; - at_state->timer_active = 1; - ++at_state->timer_index; - } - spin_unlock_irqrestore(&cs->lock, flags); + } else if (rep->timeout > 0) { /* new timeout */ + at_state->timer_expires = rep->timeout * 10; + at_state->timer_active = 1; + ++at_state->timer_index; } + spin_unlock_irqrestore(&cs->lock, flags); } } @@ -1693,6 +1690,11 @@ static void process_command_flags(struct cardstate *cs) for (i = 0; i < cs->channels; ++i) { bcs = cs->bcs + i; if (bcs->at_state.pending_commands & PC_HUP) { + if (cs->dle) { + cs->curchannel = bcs->channel; + schedule_sequence(cs, &cs->at_state, SEQ_DLE0); + return; + } bcs->at_state.pending_commands &= ~PC_HUP; if (bcs->at_state.pending_commands & PC_CID) { /* not yet dialing: PC_NOCID is sufficient */ diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 8e2fc8f31d1..eb63a0f7a02 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h @@ -111,11 +111,10 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, /* connection state */ #define ZSAU_NONE 0 -#define ZSAU_DISCONNECT_IND 4 -#define ZSAU_OUTGOING_CALL_PROCEEDING 1 #define ZSAU_PROCEEDING 1 #define ZSAU_CALL_DELIVERED 2 #define ZSAU_ACTIVE 3 +#define ZSAU_DISCONNECT_IND 4 #define ZSAU_NULL 5 #define ZSAU_DISCONNECT_REQ 6 #define ZSAU_UNKNOWN -1 @@ -183,18 +182,22 @@ void gigaset_dbg_buffer(enum debuglevel level, const unsigned char *msg, #define AT_NUM 7 /* variables in struct at_state_t */ +/* - numeric */ #define VAR_ZSAU 0 #define VAR_ZDLE 1 #define VAR_ZCTP 2 +/* total number */ #define VAR_NUM 3 - +/* - string */ #define STR_NMBR 0 #define STR_ZCPN 1 #define STR_ZCON 2 #define STR_ZBC 3 #define STR_ZHLC 4 +/* total number */ #define STR_NUM 5 +/* event types */ #define EV_TIMEOUT -105 #define EV_IF_VER -106 #define EV_PROC_CIDMODE -107 diff --git a/drivers/isdn/gigaset/interface.c b/drivers/isdn/gigaset/interface.c index 67abf3ff45e..e2b539675b6 100644 --- a/drivers/isdn/gigaset/interface.c +++ b/drivers/isdn/gigaset/interface.c @@ -112,36 +112,6 @@ static int if_config(struct cardstate *cs, int *arg) } /*** the terminal driver ***/ -/* stolen from usbserial and some other tty drivers */ - -static int if_open(struct tty_struct *tty, struct file *filp); -static void if_close(struct tty_struct *tty, struct file *filp); -static int if_ioctl(struct tty_struct *tty, - unsigned int cmd, unsigned long arg); -static int if_write_room(struct tty_struct *tty); -static int if_chars_in_buffer(struct tty_struct *tty); -static void if_throttle(struct tty_struct *tty); -static void if_unthrottle(struct tty_struct *tty); -static void if_set_termios(struct tty_struct *tty, struct ktermios *old); -static int if_tiocmget(struct tty_struct *tty); -static int if_tiocmset(struct tty_struct *tty, - unsigned int set, unsigned int clear); -static int if_write(struct tty_struct *tty, - const unsigned char *buf, int count); - -static const struct tty_operations if_ops = { - .open = if_open, - .close = if_close, - .ioctl = if_ioctl, - .write = if_write, - .write_room = if_write_room, - .chars_in_buffer = if_chars_in_buffer, - .set_termios = if_set_termios, - .throttle = if_throttle, - .unthrottle = if_unthrottle, - .tiocmget = if_tiocmget, - .tiocmset = if_tiocmset, -}; static int if_open(struct tty_struct *tty, struct file *filp) { @@ -164,7 +134,7 @@ static int if_open(struct tty_struct *tty, struct file *filp) if (cs->port.count == 1) { tty_port_tty_set(&cs->port, tty); - tty->low_latency = 1; + cs->port.low_latency = 1; } mutex_unlock(&cs->mutex); @@ -355,7 +325,7 @@ done: static int if_write_room(struct tty_struct *tty) { struct cardstate *cs = tty->driver_data; - int retval = -ENODEV; + int retval; gig_dbg(DEBUG_IF, "%u: %s()", cs->minor_index, __func__); @@ -498,6 +468,20 @@ out: mutex_unlock(&cs->mutex); } +static const struct tty_operations if_ops = { + .open = if_open, + .close = if_close, + .ioctl = if_ioctl, + .write = if_write, + .write_room = if_write_room, + .chars_in_buffer = if_chars_in_buffer, + .set_termios = if_set_termios, + .throttle = if_throttle, + .unthrottle = if_unthrottle, + .tiocmget = if_tiocmget, + .tiocmset = if_tiocmset, +}; + /* wakeup tasklet for the write operation */ static void if_wake(unsigned long data) @@ -562,16 +546,8 @@ void gigaset_if_free(struct cardstate *cs) void gigaset_if_receive(struct cardstate *cs, unsigned char *buffer, size_t len) { - struct tty_struct *tty = tty_port_tty_get(&cs->port); - - if (tty == NULL) { - gig_dbg(DEBUG_IF, "receive on closed device"); - return; - } - - tty_insert_flip_string(tty, buffer, len); - tty_flip_buffer_push(tty); - tty_kref_put(tty); + tty_insert_flip_string(&cs->port, buffer, len); + tty_flip_buffer_push(&cs->port); } EXPORT_SYMBOL_GPL(gigaset_if_receive); |