diff options
| -rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 118 |
1 files changed, 52 insertions, 66 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 63b629b1cdb2..b5e7f9c7d74e 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
| @@ -1853,20 +1853,24 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
| 1853 | { | 1853 | { |
| 1854 | struct cmdbuf_t *cb; | 1854 | struct cmdbuf_t *cb; |
| 1855 | unsigned long flags; | 1855 | unsigned long flags; |
| 1856 | int status; | 1856 | int rc; |
| 1857 | 1857 | ||
| 1858 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? | 1858 | gigaset_dbg_buffer(atomic_read(&cs->mstate) != MS_LOCKED ? |
| 1859 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, | 1859 | DEBUG_TRANSCMD : DEBUG_LOCKCMD, |
| 1860 | "CMD Transmit", len, buf); | 1860 | "CMD Transmit", len, buf); |
| 1861 | 1861 | ||
| 1862 | if (len <= 0) | 1862 | if (len <= 0) { |
| 1863 | return 0; /* nothing to do */ | 1863 | /* nothing to do */ |
| 1864 | rc = 0; | ||
| 1865 | goto notqueued; | ||
| 1866 | } | ||
| 1864 | 1867 | ||
| 1865 | if (len > IF_WRITEBUF) | 1868 | if (len > IF_WRITEBUF) |
| 1866 | len = IF_WRITEBUF; | 1869 | len = IF_WRITEBUF; |
| 1867 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { | 1870 | if (!(cb = kmalloc(sizeof(struct cmdbuf_t) + len, GFP_ATOMIC))) { |
| 1868 | dev_err(cs->dev, "%s: out of memory\n", __func__); | 1871 | dev_err(cs->dev, "%s: out of memory\n", __func__); |
| 1869 | return -ENOMEM; | 1872 | rc = -ENOMEM; |
| 1873 | goto notqueued; | ||
| 1870 | } | 1874 | } |
| 1871 | 1875 | ||
| 1872 | memcpy(cb->buf, buf, len); | 1876 | memcpy(cb->buf, buf, len); |
| @@ -1891,11 +1895,21 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
| 1891 | if (unlikely(!cs->connected)) { | 1895 | if (unlikely(!cs->connected)) { |
| 1892 | spin_unlock_irqrestore(&cs->lock, flags); | 1896 | spin_unlock_irqrestore(&cs->lock, flags); |
| 1893 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | 1897 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); |
| 1898 | /* flush command queue */ | ||
| 1899 | spin_lock_irqsave(&cs->cmdlock, flags); | ||
| 1900 | while (cs->cmdbuf != NULL) | ||
| 1901 | complete_cb(cs); | ||
| 1902 | spin_unlock_irqrestore(&cs->cmdlock, flags); | ||
| 1894 | return -ENODEV; | 1903 | return -ENODEV; |
| 1895 | } | 1904 | } |
| 1896 | status = start_cbsend(cs); | 1905 | rc = start_cbsend(cs); |
| 1897 | spin_unlock_irqrestore(&cs->lock, flags); | 1906 | spin_unlock_irqrestore(&cs->lock, flags); |
| 1898 | return status < 0 ? status : len; | 1907 | return rc < 0 ? rc : len; |
| 1908 | |||
| 1909 | notqueued: /* request handled without queuing */ | ||
| 1910 | if (wake_tasklet) | ||
| 1911 | tasklet_schedule(wake_tasklet); | ||
| 1912 | return rc; | ||
| 1899 | } | 1913 | } |
| 1900 | 1914 | ||
| 1901 | /* gigaset_write_room | 1915 | /* gigaset_write_room |
| @@ -1964,20 +1978,15 @@ static int gigaset_freebcshw(struct bc_state *bcs) | |||
| 1964 | 1978 | ||
| 1965 | /* kill URBs and tasklets before freeing - better safe than sorry */ | 1979 | /* kill URBs and tasklets before freeing - better safe than sorry */ |
| 1966 | atomic_set(&ubc->running, 0); | 1980 | atomic_set(&ubc->running, 0); |
| 1967 | for (i = 0; i < BAS_OUTURBS; ++i) | 1981 | gig_dbg(DEBUG_INIT, "%s: killing iso URBs", __func__); |
| 1968 | if (ubc->isoouturbs[i].urb) { | 1982 | for (i = 0; i < BAS_OUTURBS; ++i) { |
| 1969 | gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d", | 1983 | usb_kill_urb(ubc->isoouturbs[i].urb); |
| 1970 | __func__, i); | 1984 | usb_free_urb(ubc->isoouturbs[i].urb); |
| 1971 | usb_kill_urb(ubc->isoouturbs[i].urb); | 1985 | } |
| 1972 | usb_free_urb(ubc->isoouturbs[i].urb); | 1986 | for (i = 0; i < BAS_INURBS; ++i) { |
| 1973 | } | 1987 | usb_kill_urb(ubc->isoinurbs[i]); |
| 1974 | for (i = 0; i < BAS_INURBS; ++i) | 1988 | usb_free_urb(ubc->isoinurbs[i]); |
| 1975 | if (ubc->isoinurbs[i]) { | 1989 | } |
| 1976 | gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d", | ||
| 1977 | __func__, i); | ||
| 1978 | usb_kill_urb(ubc->isoinurbs[i]); | ||
| 1979 | usb_free_urb(ubc->isoinurbs[i]); | ||
| 1980 | } | ||
| 1981 | tasklet_kill(&ubc->sent_tasklet); | 1990 | tasklet_kill(&ubc->sent_tasklet); |
| 1982 | tasklet_kill(&ubc->rcvd_tasklet); | 1991 | tasklet_kill(&ubc->rcvd_tasklet); |
| 1983 | kfree(ubc->isooutbuf); | 1992 | kfree(ubc->isooutbuf); |
| @@ -2099,55 +2108,32 @@ static void freeurbs(struct cardstate *cs) | |||
| 2099 | struct bas_bc_state *ubc; | 2108 | struct bas_bc_state *ubc; |
| 2100 | int i, j; | 2109 | int i, j; |
| 2101 | 2110 | ||
| 2111 | gig_dbg(DEBUG_INIT, "%s: killing URBs", __func__); | ||
| 2102 | for (j = 0; j < 2; ++j) { | 2112 | for (j = 0; j < 2; ++j) { |
| 2103 | ubc = cs->bcs[j].hw.bas; | 2113 | ubc = cs->bcs[j].hw.bas; |
| 2104 | for (i = 0; i < BAS_OUTURBS; ++i) | 2114 | for (i = 0; i < BAS_OUTURBS; ++i) { |
| 2105 | if (ubc->isoouturbs[i].urb) { | 2115 | usb_kill_urb(ubc->isoouturbs[i].urb); |
| 2106 | usb_kill_urb(ubc->isoouturbs[i].urb); | 2116 | usb_free_urb(ubc->isoouturbs[i].urb); |
| 2107 | gig_dbg(DEBUG_INIT, | 2117 | ubc->isoouturbs[i].urb = NULL; |
| 2108 | "%s: isoc output URB %d/%d unlinked", | 2118 | } |
| 2109 | __func__, j, i); | 2119 | for (i = 0; i < BAS_INURBS; ++i) { |
| 2110 | usb_free_urb(ubc->isoouturbs[i].urb); | 2120 | usb_kill_urb(ubc->isoinurbs[i]); |
| 2111 | ubc->isoouturbs[i].urb = NULL; | 2121 | usb_free_urb(ubc->isoinurbs[i]); |
| 2112 | } | 2122 | ubc->isoinurbs[i] = NULL; |
| 2113 | for (i = 0; i < BAS_INURBS; ++i) | 2123 | } |
| 2114 | if (ubc->isoinurbs[i]) { | ||
| 2115 | usb_kill_urb(ubc->isoinurbs[i]); | ||
| 2116 | gig_dbg(DEBUG_INIT, | ||
| 2117 | "%s: isoc input URB %d/%d unlinked", | ||
| 2118 | __func__, j, i); | ||
| 2119 | usb_free_urb(ubc->isoinurbs[i]); | ||
| 2120 | ubc->isoinurbs[i] = NULL; | ||
| 2121 | } | ||
| 2122 | } | ||
| 2123 | if (ucs->urb_int_in) { | ||
| 2124 | usb_kill_urb(ucs->urb_int_in); | ||
| 2125 | gig_dbg(DEBUG_INIT, "%s: interrupt input URB unlinked", | ||
| 2126 | __func__); | ||
| 2127 | usb_free_urb(ucs->urb_int_in); | ||
| 2128 | ucs->urb_int_in = NULL; | ||
| 2129 | } | ||
| 2130 | if (ucs->urb_cmd_out) { | ||
| 2131 | usb_kill_urb(ucs->urb_cmd_out); | ||
| 2132 | gig_dbg(DEBUG_INIT, "%s: command output URB unlinked", | ||
| 2133 | __func__); | ||
| 2134 | usb_free_urb(ucs->urb_cmd_out); | ||
| 2135 | ucs->urb_cmd_out = NULL; | ||
| 2136 | } | ||
| 2137 | if (ucs->urb_cmd_in) { | ||
| 2138 | usb_kill_urb(ucs->urb_cmd_in); | ||
| 2139 | gig_dbg(DEBUG_INIT, "%s: command input URB unlinked", | ||
| 2140 | __func__); | ||
| 2141 | usb_free_urb(ucs->urb_cmd_in); | ||
| 2142 | ucs->urb_cmd_in = NULL; | ||
| 2143 | } | ||
| 2144 | if (ucs->urb_ctrl) { | ||
| 2145 | usb_kill_urb(ucs->urb_ctrl); | ||
| 2146 | gig_dbg(DEBUG_INIT, "%s: control output URB unlinked", | ||
| 2147 | __func__); | ||
| 2148 | usb_free_urb(ucs->urb_ctrl); | ||
| 2149 | ucs->urb_ctrl = NULL; | ||
| 2150 | } | 2124 | } |
| 2125 | usb_kill_urb(ucs->urb_int_in); | ||
| 2126 | usb_free_urb(ucs->urb_int_in); | ||
| 2127 | ucs->urb_int_in = NULL; | ||
| 2128 | usb_kill_urb(ucs->urb_cmd_out); | ||
| 2129 | usb_free_urb(ucs->urb_cmd_out); | ||
| 2130 | ucs->urb_cmd_out = NULL; | ||
| 2131 | usb_kill_urb(ucs->urb_cmd_in); | ||
| 2132 | usb_free_urb(ucs->urb_cmd_in); | ||
| 2133 | ucs->urb_cmd_in = NULL; | ||
| 2134 | usb_kill_urb(ucs->urb_ctrl); | ||
| 2135 | usb_free_urb(ucs->urb_ctrl); | ||
| 2136 | ucs->urb_ctrl = NULL; | ||
| 2151 | } | 2137 | } |
| 2152 | 2138 | ||
| 2153 | /* gigaset_probe | 2139 | /* gigaset_probe |
