Commit 14cee8e3 authored by David S. Miller's avatar David S. Miller

Merge branch 'isdn'

Tilman Schmidt says:

====================
Coverity patches for drivers/isdn

Here's a series of patches for the ISDN CAPI subsystem and the
Gigaset ISDN driver.
Patches 1 to 7 are specific fixes for Coverity warnings.
Patches 8 to 11 fix related problems with the handling of invalid
CAPI command codes I noticed while working on this.
Patch 12 fixes an unrelated problem I noticed during the subsequent
regression tests.
It would be great if these could still be merged.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f787d6c8 86f8ef2c
...@@ -506,7 +506,10 @@ static void send_message(capidrv_contr *card, _cmsg *cmsg) ...@@ -506,7 +506,10 @@ static void send_message(capidrv_contr *card, _cmsg *cmsg)
struct sk_buff *skb; struct sk_buff *skb;
size_t len; size_t len;
capi_cmsg2message(cmsg, cmsg->buf); if (capi_cmsg2message(cmsg, cmsg->buf)) {
printk(KERN_ERR "capidrv::send_message: parser failure\n");
return;
}
len = CAPIMSG_LEN(cmsg->buf); len = CAPIMSG_LEN(cmsg->buf);
skb = alloc_skb(len, GFP_ATOMIC); skb = alloc_skb(len, GFP_ATOMIC);
if (!skb) { if (!skb) {
...@@ -1578,7 +1581,12 @@ static _cmsg s_cmsg; ...@@ -1578,7 +1581,12 @@ static _cmsg s_cmsg;
static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb) static void capidrv_recv_message(struct capi20_appl *ap, struct sk_buff *skb)
{ {
capi_message2cmsg(&s_cmsg, skb->data); if (capi_message2cmsg(&s_cmsg, skb->data)) {
printk(KERN_ERR "capidrv: applid=%d: received invalid message\n",
ap->applid);
kfree_skb(skb);
return;
}
if (debugmode > 3) { if (debugmode > 3) {
_cdebbuf *cdb = capi_cmsg2str(&s_cmsg); _cdebbuf *cdb = capi_cmsg2str(&s_cmsg);
...@@ -1903,7 +1911,11 @@ static int capidrv_command(isdn_ctrl *c, capidrv_contr *card) ...@@ -1903,7 +1911,11 @@ static int capidrv_command(isdn_ctrl *c, capidrv_contr *card)
NULL, /* Useruserdata */ NULL, /* Useruserdata */
NULL /* Facilitydataarray */ NULL /* Facilitydataarray */
); );
capi_cmsg2message(&cmdcmsg, cmdcmsg.buf); if (capi_cmsg2message(&cmdcmsg, cmdcmsg.buf)) {
printk(KERN_ERR "capidrv-%d: capidrv_command: parser failure\n",
card->contrnr);
return -EINVAL;
}
plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP); plci_change_state(card, bchan->plcip, EV_PLCI_CONNECT_RESP);
send_message(card, &cmdcmsg); send_message(card, &cmdcmsg);
return 0; return 0;
...@@ -2090,7 +2102,11 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb) ...@@ -2090,7 +2102,11 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0) if (capidrv_add_ack(nccip, datahandle, doack ? (int)skb->len : -1) < 0)
return 0; return 0;
capi_cmsg2message(&sendcmsg, sendcmsg.buf); if (capi_cmsg2message(&sendcmsg, sendcmsg.buf)) {
printk(KERN_ERR "capidrv-%d: if_sendbuf: parser failure\n",
card->contrnr);
return -EINVAL;
}
msglen = CAPIMSG_LEN(sendcmsg.buf); msglen = CAPIMSG_LEN(sendcmsg.buf);
if (skb_headroom(skb) < msglen) { if (skb_headroom(skb) < msglen) {
struct sk_buff *nskb = skb_realloc_headroom(skb, msglen); struct sk_buff *nskb = skb_realloc_headroom(skb, msglen);
......
...@@ -207,9 +207,24 @@ static unsigned command_2_index(unsigned c, unsigned sc) ...@@ -207,9 +207,24 @@ static unsigned command_2_index(unsigned c, unsigned sc)
c = 0x9 + (c & 0x0f); c = 0x9 + (c & 0x0f);
else if (c == 0x41) else if (c == 0x41)
c = 0x9 + 0x1; c = 0x9 + 0x1;
if (c > 0x18)
c = 0x00;
return (sc & 3) * (0x9 + 0x9) + c; return (sc & 3) * (0x9 + 0x9) + c;
} }
/**
* capi_cmd2par() - find parameter string for CAPI 2.0 command/subcommand
* @cmd: command number
* @subcmd: subcommand number
*
* Return value: static string, NULL if command/subcommand unknown
*/
static unsigned char *capi_cmd2par(u8 cmd, u8 subcmd)
{
return cpars[command_2_index(cmd, subcmd)];
}
/*-------------------------------------------------------*/ /*-------------------------------------------------------*/
#define TYP (cdef[cmsg->par[cmsg->p]].typ) #define TYP (cdef[cmsg->par[cmsg->p]].typ)
#define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off) #define OFF (((u8 *)cmsg) + cdef[cmsg->par[cmsg->p]].off)
...@@ -302,7 +317,9 @@ unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg) ...@@ -302,7 +317,9 @@ unsigned capi_cmsg2message(_cmsg *cmsg, u8 *msg)
cmsg->m = msg; cmsg->m = msg;
cmsg->l = 8; cmsg->l = 8;
cmsg->p = 0; cmsg->p = 0;
cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)]; cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
if (!cmsg->par)
return 1; /* invalid command/subcommand */
pars_2_message(cmsg); pars_2_message(cmsg);
...@@ -375,7 +392,9 @@ unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg) ...@@ -375,7 +392,9 @@ unsigned capi_message2cmsg(_cmsg *cmsg, u8 *msg)
cmsg->p = 0; cmsg->p = 0;
byteTRcpy(cmsg->m + 4, &cmsg->Command); byteTRcpy(cmsg->m + 4, &cmsg->Command);
byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)]; cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
if (!cmsg->par)
return 1; /* invalid command/subcommand */
message_2_pars(cmsg); message_2_pars(cmsg);
...@@ -470,12 +489,17 @@ static char *mnames[] = ...@@ -470,12 +489,17 @@ static char *mnames[] =
* @cmd: command number * @cmd: command number
* @subcmd: subcommand number * @subcmd: subcommand number
* *
* Return value: static string, NULL if command/subcommand unknown * Return value: static string
*/ */
char *capi_cmd2str(u8 cmd, u8 subcmd) char *capi_cmd2str(u8 cmd, u8 subcmd)
{ {
return mnames[command_2_index(cmd, subcmd)]; char *result;
result = mnames[command_2_index(cmd, subcmd)];
if (result == NULL)
result = "INVALID_COMMAND";
return result;
} }
...@@ -625,6 +649,9 @@ static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m) ...@@ -625,6 +649,9 @@ static _cdebbuf *printstruct(_cdebbuf *cdb, u8 *m)
static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level) static _cdebbuf *protocol_message_2_pars(_cdebbuf *cdb, _cmsg *cmsg, int level)
{ {
if (!cmsg->par)
return NULL; /* invalid command/subcommand */
for (; TYP != _CEND; cmsg->p++) { for (; TYP != _CEND; cmsg->p++) {
int slen = 29 + 3 - level; int slen = 29 + 3 - level;
int i; int i;
...@@ -759,10 +786,10 @@ _cdebbuf *capi_message2str(u8 *msg) ...@@ -759,10 +786,10 @@ _cdebbuf *capi_message2str(u8 *msg)
cmsg->p = 0; cmsg->p = 0;
byteTRcpy(cmsg->m + 4, &cmsg->Command); byteTRcpy(cmsg->m + 4, &cmsg->Command);
byteTRcpy(cmsg->m + 5, &cmsg->Subcommand); byteTRcpy(cmsg->m + 5, &cmsg->Subcommand);
cmsg->par = cpars[command_2_index(cmsg->Command, cmsg->Subcommand)]; cmsg->par = capi_cmd2par(cmsg->Command, cmsg->Subcommand);
cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n", cdb = bufprint(cdb, "%-26s ID=%03d #0x%04x LEN=%04d\n",
mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], capi_cmd2str(cmsg->Command, cmsg->Subcommand),
((unsigned short *) msg)[1], ((unsigned short *) msg)[1],
((unsigned short *) msg)[3], ((unsigned short *) msg)[3],
((unsigned short *) msg)[0]); ((unsigned short *) msg)[0]);
...@@ -796,7 +823,7 @@ _cdebbuf *capi_cmsg2str(_cmsg *cmsg) ...@@ -796,7 +823,7 @@ _cdebbuf *capi_cmsg2str(_cmsg *cmsg)
cmsg->l = 8; cmsg->l = 8;
cmsg->p = 0; cmsg->p = 0;
cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n", cdb = bufprint(cdb, "%s ID=%03d #0x%04x LEN=%04d\n",
mnames[command_2_index(cmsg->Command, cmsg->Subcommand)], capi_cmd2str(cmsg->Command, cmsg->Subcommand),
((u16 *) cmsg->m)[1], ((u16 *) cmsg->m)[1],
((u16 *) cmsg->m)[3], ((u16 *) cmsg->m)[3],
((u16 *) cmsg->m)[0]); ((u16 *) cmsg->m)[0]);
......
...@@ -1184,7 +1184,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data) ...@@ -1184,7 +1184,7 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
* Return value: CAPI result code * Return value: CAPI result code
*/ */
int capi20_manufacturer(unsigned int cmd, void __user *data) int capi20_manufacturer(unsigned long cmd, void __user *data)
{ {
struct capi_ctr *ctr; struct capi_ctr *ctr;
int retval; int retval;
...@@ -1259,7 +1259,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data) ...@@ -1259,7 +1259,7 @@ int capi20_manufacturer(unsigned int cmd, void __user *data)
} }
default: default:
printk(KERN_ERR "kcapi: manufacturer command %d unknown.\n", printk(KERN_ERR "kcapi: manufacturer command %lu unknown.\n",
cmd); cmd);
break; break;
......
This diff is collapsed.
...@@ -604,14 +604,14 @@ void gigaset_handle_modem_response(struct cardstate *cs) ...@@ -604,14 +604,14 @@ void gigaset_handle_modem_response(struct cardstate *cs)
} }
EXPORT_SYMBOL_GPL(gigaset_handle_modem_response); EXPORT_SYMBOL_GPL(gigaset_handle_modem_response);
/* disconnect /* disconnect_nobc
* process closing of connection associated with given AT state structure * process closing of connection associated with given AT state structure
* without B channel
*/ */
static void disconnect(struct at_state_t **at_state_p) static void disconnect_nobc(struct at_state_t **at_state_p,
struct cardstate *cs)
{ {
unsigned long flags; unsigned long flags;
struct bc_state *bcs = (*at_state_p)->bcs;
struct cardstate *cs = (*at_state_p)->cs;
spin_lock_irqsave(&cs->lock, flags); spin_lock_irqsave(&cs->lock, flags);
++(*at_state_p)->seq_index; ++(*at_state_p)->seq_index;
...@@ -622,23 +622,44 @@ static void disconnect(struct at_state_t **at_state_p) ...@@ -622,23 +622,44 @@ static void disconnect(struct at_state_t **at_state_p)
gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE"); gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
cs->commands_pending = 1; cs->commands_pending = 1;
} }
spin_unlock_irqrestore(&cs->lock, flags);
if (bcs) { /* check for and deallocate temporary AT state */
/* B channel assigned: invoke hardware specific handler */ if (!list_empty(&(*at_state_p)->list)) {
cs->ops->close_bchannel(bcs);
/* notify LL */
if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
gigaset_isdn_hupD(bcs);
}
} else {
/* no B channel assigned: just deallocate */
spin_lock_irqsave(&cs->lock, flags);
list_del(&(*at_state_p)->list); list_del(&(*at_state_p)->list);
kfree(*at_state_p); kfree(*at_state_p);
*at_state_p = NULL; *at_state_p = NULL;
spin_unlock_irqrestore(&cs->lock, flags); }
spin_unlock_irqrestore(&cs->lock, flags);
}
/* disconnect_bc
* process closing of connection associated with given AT state structure
* and B channel
*/
static void disconnect_bc(struct at_state_t *at_state,
struct cardstate *cs, struct bc_state *bcs)
{
unsigned long flags;
spin_lock_irqsave(&cs->lock, flags);
++at_state->seq_index;
/* revert to selected idle mode */
if (!cs->cidmode) {
cs->at_state.pending_commands |= PC_UMMODE;
gig_dbg(DEBUG_EVENT, "Scheduling PC_UMMODE");
cs->commands_pending = 1;
}
spin_unlock_irqrestore(&cs->lock, flags);
/* invoke hardware specific handler */
cs->ops->close_bchannel(bcs);
/* notify LL */
if (bcs->chstate & (CHS_D_UP | CHS_NOTIFY_LL)) {
bcs->chstate &= ~(CHS_D_UP | CHS_NOTIFY_LL);
gigaset_isdn_hupD(bcs);
} }
} }
...@@ -646,7 +667,7 @@ static void disconnect(struct at_state_t **at_state_p) ...@@ -646,7 +667,7 @@ static void disconnect(struct at_state_t **at_state_p)
* get a free AT state structure: either one of those associated with the * get a free AT state structure: either one of those associated with the
* B channels of the Gigaset device, or if none of those is available, * B channels of the Gigaset device, or if none of those is available,
* a newly allocated one with bcs=NULL * a newly allocated one with bcs=NULL
* The structure should be freed by calling disconnect() after use. * The structure should be freed by calling disconnect_nobc() after use.
*/ */
static inline struct at_state_t *get_free_channel(struct cardstate *cs, static inline struct at_state_t *get_free_channel(struct cardstate *cs,
int cid) int cid)
...@@ -1057,7 +1078,7 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1057,7 +1078,7 @@ static void do_action(int action, struct cardstate *cs,
struct event_t *ev) struct event_t *ev)
{ {
struct at_state_t *at_state = *p_at_state; struct at_state_t *at_state = *p_at_state;
struct at_state_t *at_state2; struct bc_state *bcs2;
unsigned long flags; unsigned long flags;
int channel; int channel;
...@@ -1156,8 +1177,8 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1156,8 +1177,8 @@ static void do_action(int action, struct cardstate *cs,
break; break;
case ACT_RING: case ACT_RING:
/* get fresh AT state structure for new CID */ /* get fresh AT state structure for new CID */
at_state2 = get_free_channel(cs, ev->parameter); at_state = get_free_channel(cs, ev->parameter);
if (!at_state2) { if (!at_state) {
dev_warn(cs->dev, dev_warn(cs->dev,
"RING ignored: could not allocate channel structure\n"); "RING ignored: could not allocate channel structure\n");
break; break;
...@@ -1166,16 +1187,16 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1166,16 +1187,16 @@ static void do_action(int action, struct cardstate *cs,
/* initialize AT state structure /* initialize AT state structure
* note that bcs may be NULL if no B channel is free * note that bcs may be NULL if no B channel is free
*/ */
at_state2->ConState = 700; at_state->ConState = 700;
for (i = 0; i < STR_NUM; ++i) { for (i = 0; i < STR_NUM; ++i) {
kfree(at_state2->str_var[i]); kfree(at_state->str_var[i]);
at_state2->str_var[i] = NULL; at_state->str_var[i] = NULL;
} }
at_state2->int_var[VAR_ZCTP] = -1; at_state->int_var[VAR_ZCTP] = -1;
spin_lock_irqsave(&cs->lock, flags); spin_lock_irqsave(&cs->lock, flags);
at_state2->timer_expires = RING_TIMEOUT; at_state->timer_expires = RING_TIMEOUT;
at_state2->timer_active = 1; at_state->timer_active = 1;
spin_unlock_irqrestore(&cs->lock, flags); spin_unlock_irqrestore(&cs->lock, flags);
break; break;
case ACT_ICALL: case ACT_ICALL:
...@@ -1213,14 +1234,17 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1213,14 +1234,17 @@ static void do_action(int action, struct cardstate *cs,
case ACT_DISCONNECT: case ACT_DISCONNECT:
cs->cur_at_seq = SEQ_NONE; cs->cur_at_seq = SEQ_NONE;
at_state->cid = -1; at_state->cid = -1;
if (bcs && cs->onechannel && cs->dle) { if (!bcs) {
disconnect_nobc(p_at_state, cs);
} else if (cs->onechannel && cs->dle) {
/* Check for other open channels not needed: /* Check for other open channels not needed:
* DLE only used for M10x with one B channel. * DLE only used for M10x with one B channel.
*/ */
at_state->pending_commands |= PC_DLE0; at_state->pending_commands |= PC_DLE0;
cs->commands_pending = 1; cs->commands_pending = 1;
} else } else {
disconnect(p_at_state); disconnect_bc(at_state, cs, bcs);
}
break; break;
case ACT_FAKEDLE0: case ACT_FAKEDLE0:
at_state->int_var[VAR_ZDLE] = 0; at_state->int_var[VAR_ZDLE] = 0;
...@@ -1228,25 +1252,27 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1228,25 +1252,27 @@ static void do_action(int action, struct cardstate *cs,
/* fall through */ /* fall through */
case ACT_DLE0: case ACT_DLE0:
cs->cur_at_seq = SEQ_NONE; cs->cur_at_seq = SEQ_NONE;
at_state2 = &cs->bcs[cs->curchannel].at_state; bcs2 = cs->bcs + cs->curchannel;
disconnect(&at_state2); disconnect_bc(&bcs2->at_state, cs, bcs2);
break; break;
case ACT_ABORTHUP: case ACT_ABORTHUP:
cs->cur_at_seq = SEQ_NONE; cs->cur_at_seq = SEQ_NONE;
dev_warn(cs->dev, "Could not hang up.\n"); dev_warn(cs->dev, "Could not hang up.\n");
at_state->cid = -1; at_state->cid = -1;
if (bcs && cs->onechannel) if (!bcs)
disconnect_nobc(p_at_state, cs);
else if (cs->onechannel)
at_state->pending_commands |= PC_DLE0; at_state->pending_commands |= PC_DLE0;
else else
disconnect(p_at_state); disconnect_bc(at_state, cs, bcs);
schedule_init(cs, MS_RECOVER); schedule_init(cs, MS_RECOVER);
break; break;
case ACT_FAILDLE0: case ACT_FAILDLE0:
cs->cur_at_seq = SEQ_NONE; cs->cur_at_seq = SEQ_NONE;
dev_warn(cs->dev, "Error leaving DLE mode.\n"); dev_warn(cs->dev, "Error leaving DLE mode.\n");
cs->dle = 0; cs->dle = 0;
at_state2 = &cs->bcs[cs->curchannel].at_state; bcs2 = cs->bcs + cs->curchannel;
disconnect(&at_state2); disconnect_bc(&bcs2->at_state, cs, bcs2);
schedule_init(cs, MS_RECOVER); schedule_init(cs, MS_RECOVER);
break; break;
case ACT_FAILDLE1: case ACT_FAILDLE1:
...@@ -1275,14 +1301,14 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1275,14 +1301,14 @@ static void do_action(int action, struct cardstate *cs,
if (reinit_and_retry(cs, channel) < 0) { if (reinit_and_retry(cs, channel) < 0) {
dev_warn(cs->dev, dev_warn(cs->dev,
"Could not get a call ID. Cannot dial.\n"); "Could not get a call ID. Cannot dial.\n");
at_state2 = &cs->bcs[channel].at_state; bcs2 = cs->bcs + channel;
disconnect(&at_state2); disconnect_bc(&bcs2->at_state, cs, bcs2);
} }
break; break;
case ACT_ABORTCID: case ACT_ABORTCID:
cs->cur_at_seq = SEQ_NONE; cs->cur_at_seq = SEQ_NONE;
at_state2 = &cs->bcs[cs->curchannel].at_state; bcs2 = cs->bcs + cs->curchannel;
disconnect(&at_state2); disconnect_bc(&bcs2->at_state, cs, bcs2);
break; break;
case ACT_DIALING: case ACT_DIALING:
...@@ -1291,7 +1317,10 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1291,7 +1317,10 @@ static void do_action(int action, struct cardstate *cs,
break; break;
case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL procssng */ case ACT_ABORTACCEPT: /* hangup/error/timeout during ICALL procssng */
disconnect(p_at_state); if (bcs)
disconnect_bc(at_state, cs, bcs);
else
disconnect_nobc(p_at_state, cs);
break; break;
case ACT_ABORTDIAL: /* error/timeout during dial preparation */ case ACT_ABORTDIAL: /* error/timeout during dial preparation */
...@@ -1380,6 +1409,11 @@ static void do_action(int action, struct cardstate *cs, ...@@ -1380,6 +1409,11 @@ static void do_action(int action, struct cardstate *cs,
/* events from the LL */ /* events from the LL */
case ACT_DIAL: case ACT_DIAL:
if (!ev->ptr) {
*p_genresp = 1;
*p_resp_code = RSP_ERROR;
break;
}
start_dial(at_state, ev->ptr, ev->parameter); start_dial(at_state, ev->ptr, ev->parameter);
break; break;
case ACT_ACCEPT: case ACT_ACCEPT:
......
...@@ -497,6 +497,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb) ...@@ -497,6 +497,7 @@ static int send_cb(struct cardstate *cs, struct cmdbuf_t *cb)
static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
{ {
unsigned long flags; unsigned long flags;
int len;
gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
DEBUG_TRANSCMD : DEBUG_LOCKCMD, DEBUG_TRANSCMD : DEBUG_LOCKCMD,
...@@ -515,10 +516,11 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) ...@@ -515,10 +516,11 @@ static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
spin_unlock_irqrestore(&cs->cmdlock, flags); spin_unlock_irqrestore(&cs->cmdlock, flags);
spin_lock_irqsave(&cs->lock, flags); spin_lock_irqsave(&cs->lock, flags);
len = cb->len;
if (cs->connected) if (cs->connected)
tasklet_schedule(&cs->write_tasklet); tasklet_schedule(&cs->write_tasklet);
spin_unlock_irqrestore(&cs->lock, flags); spin_unlock_irqrestore(&cs->lock, flags);
return cb->len; return len;
} }
static int gigaset_write_room(struct cardstate *cs) static int gigaset_write_room(struct cardstate *cs)
......
...@@ -41,7 +41,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]); ...@@ -41,7 +41,7 @@ u16 capi20_get_manufacturer(u32 contr, u8 buf[CAPI_MANUFACTURER_LEN]);
u16 capi20_get_version(u32 contr, struct capi_version *verp); u16 capi20_get_version(u32 contr, struct capi_version *verp);
u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]); u16 capi20_get_serial(u32 contr, u8 serial[CAPI_SERIAL_LEN]);
u16 capi20_get_profile(u32 contr, struct capi_profile *profp); u16 capi20_get_profile(u32 contr, struct capi_profile *profp);
int capi20_manufacturer(unsigned int cmd, void __user *data); int capi20_manufacturer(unsigned long cmd, void __user *data);
#define CAPICTR_UP 0 #define CAPICTR_UP 0
#define CAPICTR_DOWN 1 #define CAPICTR_DOWN 1
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment