aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/isdn/gigaset/bas-gigaset.c
diff options
context:
space:
mode:
authorTilman Schmidt <tilman@imap.cc>2010-07-05 10:18:43 -0400
committerDavid S. Miller <davem@davemloft.net>2010-07-07 19:57:51 -0400
commite3628dd176ba3ed329991ef042c29aae60617630 (patch)
tree77e47e95ba38276557702a5bfc8e319bc9100b7c /drivers/isdn/gigaset/bas-gigaset.c
parentb3251d8045f87eec5d565603345d262cee134fa6 (diff)
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.c51
1 files changed, 11 insertions, 40 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 47a5ffec55a3..2dab5313913b 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)
1913 * USB transmission is started if necessary. 1913 * USB transmission is started if necessary.
1914 * parameters: 1914 * parameters:
1915 * cs controller state structure 1915 * cs controller state structure
1916 * buf command string to send 1916 * cb command buffer structure
1917 * len number of bytes to send (max. IF_WRITEBUF)
1918 * wake_tasklet tasklet to run when transmission is completed
1919 * (NULL if none)
1920 * return value: 1917 * return value:
1921 * number of bytes queued on success 1918 * number of bytes queued on success
1922 * error code < 0 on error 1919 * error code < 0 on error
1923 */ 1920 */
1924static int gigaset_write_cmd(struct cardstate *cs, 1921static int gigaset_write_cmd(struct cardstate *cs, struct cmdbuf_t *cb)
1925 const unsigned char *buf, int len,
1926 struct tasklet_struct *wake_tasklet)
1927{ 1922{
1928 struct cmdbuf_t *cb;
1929 unsigned long flags; 1923 unsigned long flags;
1930 int rc; 1924 int rc;
1931 1925
1932 gigaset_dbg_buffer(cs->mstate != MS_LOCKED ? 1926 gigaset_dbg_buffer(cs->mstate != MS_LOCKED ?
1933 DEBUG_TRANSCMD : DEBUG_LOCKCMD, 1927 DEBUG_TRANSCMD : DEBUG_LOCKCMD,
1934 "CMD Transmit", len, buf); 1928 "CMD Transmit", cb->len, cb->buf);
1935
1936 if (len <= 0) {
1937 /* nothing to do */
1938 rc = 0;
1939 goto notqueued;
1940 }
1941 1929
1942 /* translate "+++" escape sequence sent as a single separate command 1930 /* translate "+++" escape sequence sent as a single separate command
1943 * into "close AT channel" command for error recovery 1931 * into "close AT channel" command for error recovery
1944 * The next command will reopen the AT channel automatically. 1932 * The next command will reopen the AT channel automatically.
1945 */ 1933 */
1946 if (len == 3 && !memcmp(buf, "+++", 3)) { 1934 if (cb->len == 3 && !memcmp(cb->buf, "+++", 3)) {
1935 kfree(cb);
1947 rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT); 1936 rc = req_submit(cs->bcs, HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT);
1948 goto notqueued; 1937 if (cb->wake_tasklet)
1949 } 1938 tasklet_schedule(cb->wake_tasklet);
1950 1939 return rc < 0 ? rc : cb->len;
1951 if (len > IF_WRITEBUF)
1952 len = IF_WRITEBUF;
1953 cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC);
1954 if (!cb) {
1955 dev_err(cs->dev, "%s: out of memory\n", __func__);
1956 rc = -ENOMEM;
1957 goto notqueued;
1958 } 1940 }
1959 1941
1960 memcpy(cb->buf, buf, len);
1961 cb->len = len;
1962 cb->offset = 0;
1963 cb->next = NULL;
1964 cb->wake_tasklet = wake_tasklet;
1965
1966 spin_lock_irqsave(&cs->cmdlock, flags); 1942 spin_lock_irqsave(&cs->cmdlock, flags);
1967 cb->prev = cs->lastcmdbuf; 1943 cb->prev = cs->lastcmdbuf;
1968 if (cs->lastcmdbuf) 1944 if (cs->lastcmdbuf)
1969 cs->lastcmdbuf->next = cb; 1945 cs->lastcmdbuf->next = cb;
1970 else { 1946 else {
1971 cs->cmdbuf = cb; 1947 cs->cmdbuf = cb;
1972 cs->curlen = len; 1948 cs->curlen = cb->len;
1973 } 1949 }
1974 cs->cmdbytes += len; 1950 cs->cmdbytes += cb->len;
1975 cs->lastcmdbuf = cb; 1951 cs->lastcmdbuf = cb;
1976 spin_unlock_irqrestore(&cs->cmdlock, flags); 1952 spin_unlock_irqrestore(&cs->cmdlock, flags);
1977 1953
@@ -1988,12 +1964,7 @@ static int gigaset_write_cmd(struct cardstate *cs,
1988 } 1964 }
1989 rc = start_cbsend(cs); 1965 rc = start_cbsend(cs);
1990 spin_unlock_irqrestore(&cs->lock, flags); 1966 spin_unlock_irqrestore(&cs->lock, flags);
1991 return rc < 0 ? rc : len; 1967 return rc < 0 ? rc : cb->len;
1992
1993notqueued: /* request handled without queuing */
1994 if (wake_tasklet)
1995 tasklet_schedule(wake_tasklet);
1996 return rc;
1997} 1968}
1998 1969
1999/* gigaset_write_room 1970/* gigaset_write_room