diff options
author | Tilman Schmidt <tilman@imap.cc> | 2010-07-05 14:18:43 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-07-07 16:57:51 -0700 |
commit | e3628dd176ba3ed329991ef042c29aae60617630 (patch) | |
tree | 77e47e95ba38276557702a5bfc8e319bc9100b7c /drivers/isdn/gigaset/bas-gigaset.c | |
parent | b3251d8045f87eec5d565603345d262cee134fa6 (diff) | |
download | op-kernel-dev-e3628dd176ba3ed329991ef042c29aae60617630.zip op-kernel-dev-e3628dd176ba3ed329991ef042c29aae60617630.tar.gz |
isdn/gigaset: avoid copying AT commands twice
Change the Gigaset driver's internal write_cmd interface to accept a
cmdbuf structure instead of a string. This avoids copying formatted
AT commands a second time.
Impact: optimization
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn/gigaset/bas-gigaset.c')
-rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 51 |
1 files changed, 11 insertions, 40 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 47a5ffe..2dab531 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -1913,65 +1913,41 @@ static int start_cbsend(struct cardstate *cs) * USB transmission is started if necessary. * parameters: * cs controller state structure - * buf command string to send - * len number of bytes to send (max. IF_WRITEBUF) - * wake_tasklet tasklet to run when transmission is completed - * (NULL if none) + * cb command buffer structure * return value: * number of bytes queued on success * error code < 0 on error */ -static int gigaset_write_cmd(struct cardstate *cs, - const unsigned char *buf, int len, - struct tasklet_struct *wake_tasklet) +static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb) { - struct cmdbuf_t *cb; unsigned long flags; int rc; gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? DEBUG_TRANSCMD : DEBUG_LOCKCMD, - "CMD Transmit", len, buf); - - if (len <= 0) { - /* nothing to do */ - rc = 0; - goto notqueued; - } + "CMD Transmit", cb->len, cb->buf); /* translate "+++" escape sequence sent as a single separate command * into "close AT channel" command for error recovery * The next command will reopen the AT channel automatically. */ - if (len == 3 && !memcmp(buf, "+++", 3)) { + if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) { + kfree(cb); rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); - goto notqueued; - } - - if (len > IF_WRITEBUF) - len = IF_WRITEBUF; - cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC); - if (!cb) { - dev_err(cs->dev, "%s: out of memory\n", __func__); - rc = -ENOMEM; - goto notqueued; + if (cb->wake_tasklet) + tasklet_schedule(cb->wake_tasklet); + return rc < 0 ? rc : cb->len; } - memcpy(cb->buf, buf, len); - cb->len = len; - cb->offset = 0; - cb->next = NULL; - cb->wake_tasklet = wake_tasklet; - spin_lock_irqsave(&cs->cmdlock, flags); cb->prev = cs->lastcmdbuf; if (cs->lastcmdbuf) cs->lastcmdbuf->next = cb; else { cs->cmdbuf = cb; - cs->curlen = len; + cs->curlen = cb->len; } - cs->cmdbytes += len; + cs->cmdbytes += cb->len; cs->lastcmdbuf = cb; spin_unlock_irqrestore(&cs->cmdlock, flags); @@ -1988,12 +1964,7 @@ static int gigaset_write_cmd(struct cardstate *cs, } rc = start_cbsend(cs); spin_unlock_irqrestore(&cs->lock, flags); - return rc < 0 ? rc : len; - -notqueued: /* request handled without queuing */ - if (wake_tasklet) - tasklet_schedule(wake_tasklet); - return rc; + return rc < 0 ? rc : cb->len; } /* gigaset_write_room |