diff options
author | Tilman Schmidt <tilman@imap.cc> | 2009-03-19 02:44:23 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-03-19 02:44:23 -0400 |
commit | 170ebf85160dd128e1c4206cc197cce7d1424705 (patch) | |
tree | 43686daef9a1aa3a535c9c2f4c57f5ce1e3fd31c /drivers/isdn | |
parent | 44c1d6f99d4c86638bffabf0b7a232d0fe7ae574 (diff) |
bas_gigaset: correctly allocate USB interrupt transfer buffer
Every USB transfer buffer has to be allocated individually by kmalloc.
Impact: bugfix, no functional change
Signed-off-by: Tilman Schmidt <tilman@imap.cc>
Tested-by: Kolja Waschk <kawk@users.sourceforge.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/gigaset/bas-gigaset.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 18dd8aacbe8d..831ddce1467b 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -46,6 +46,9 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
46 | /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ | 46 | /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ |
47 | #define IF_WRITEBUF 264 | 47 | #define IF_WRITEBUF 264 |
48 | 48 | ||
49 | /* interrupt pipe message size according to ibid. ch. 2.2 */ | ||
50 | #define IP_MSGSIZE 3 | ||
51 | |||
49 | /* Values for the Gigaset 307x */ | 52 | /* Values for the Gigaset 307x */ |
50 | #define USB_GIGA_VENDOR_ID 0x0681 | 53 | #define USB_GIGA_VENDOR_ID 0x0681 |
51 | #define USB_3070_PRODUCT_ID 0x0001 | 54 | #define USB_3070_PRODUCT_ID 0x0001 |
@@ -110,7 +113,7 @@ struct bas_cardstate { | |||
110 | unsigned char *rcvbuf; /* AT reply receive buffer */ | 113 | unsigned char *rcvbuf; /* AT reply receive buffer */ |
111 | 114 | ||
112 | struct urb *urb_int_in; /* URB for interrupt pipe */ | 115 | struct urb *urb_int_in; /* URB for interrupt pipe */ |
113 | unsigned char int_in_buf[3]; | 116 | unsigned char *int_in_buf; |
114 | 117 | ||
115 | spinlock_t lock; /* locks all following */ | 118 | spinlock_t lock; /* locks all following */ |
116 | int basstate; /* bitmap (BS_*) */ | 119 | int basstate; /* bitmap (BS_*) */ |
@@ -657,7 +660,7 @@ static void read_int_callback(struct urb *urb) | |||
657 | } | 660 | } |
658 | 661 | ||
659 | /* drop incomplete packets even if the missing bytes wouldn't matter */ | 662 | /* drop incomplete packets even if the missing bytes wouldn't matter */ |
660 | if (unlikely(urb->actual_length < 3)) { | 663 | if (unlikely(urb->actual_length < IP_MSGSIZE)) { |
661 | dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", | 664 | dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", |
662 | urb->actual_length); | 665 | urb->actual_length); |
663 | goto resubmit; | 666 | goto resubmit; |
@@ -2127,6 +2130,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
2127 | static void gigaset_freecshw(struct cardstate *cs) | 2130 | static void gigaset_freecshw(struct cardstate *cs) |
2128 | { | 2131 | { |
2129 | /* timers, URBs and rcvbuf are disposed of in disconnect */ | 2132 | /* timers, URBs and rcvbuf are disposed of in disconnect */ |
2133 | kfree(cs->hw.bas->int_in_buf); | ||
2130 | kfree(cs->hw.bas); | 2134 | kfree(cs->hw.bas); |
2131 | cs->hw.bas = NULL; | 2135 | cs->hw.bas = NULL; |
2132 | } | 2136 | } |
@@ -2140,6 +2144,12 @@ static int gigaset_initcshw(struct cardstate *cs) | |||
2140 | pr_err("out of memory\n"); | 2144 | pr_err("out of memory\n"); |
2141 | return 0; | 2145 | return 0; |
2142 | } | 2146 | } |
2147 | ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL); | ||
2148 | if (!ucs->int_in_buf) { | ||
2149 | kfree(ucs); | ||
2150 | pr_err("out of memory\n"); | ||
2151 | return 0; | ||
2152 | } | ||
2143 | 2153 | ||
2144 | ucs->urb_cmd_in = NULL; | 2154 | ucs->urb_cmd_in = NULL; |
2145 | ucs->urb_cmd_out = NULL; | 2155 | ucs->urb_cmd_out = NULL; |
@@ -2292,7 +2302,7 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2292 | usb_fill_int_urb(ucs->urb_int_in, udev, | 2302 | usb_fill_int_urb(ucs->urb_int_in, udev, |
2293 | usb_rcvintpipe(udev, | 2303 | usb_rcvintpipe(udev, |
2294 | (endpoint->bEndpointAddress) & 0x0f), | 2304 | (endpoint->bEndpointAddress) & 0x0f), |
2295 | ucs->int_in_buf, 3, read_int_callback, cs, | 2305 | ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs, |
2296 | endpoint->bInterval); | 2306 | endpoint->bInterval); |
2297 | if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { | 2307 | if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { |
2298 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", | 2308 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", |