Commit 170ebf85 authored by Tilman Schmidt's avatar Tilman Schmidt Committed by David S. Miller

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: default avatarTilman Schmidt <tilman@imap.cc>
Tested-by: default avatarKolja Waschk <kawk@users.sourceforge.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 44c1d6f9
...@@ -46,6 +46,9 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); ...@@ -46,6 +46,9 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
#define IF_WRITEBUF 264 #define IF_WRITEBUF 264
/* interrupt pipe message size according to ibid. ch. 2.2 */
#define IP_MSGSIZE 3
/* Values for the Gigaset 307x */ /* Values for the Gigaset 307x */
#define USB_GIGA_VENDOR_ID 0x0681 #define USB_GIGA_VENDOR_ID 0x0681
#define USB_3070_PRODUCT_ID 0x0001 #define USB_3070_PRODUCT_ID 0x0001
...@@ -110,7 +113,7 @@ struct bas_cardstate { ...@@ -110,7 +113,7 @@ struct bas_cardstate {
unsigned char *rcvbuf; /* AT reply receive buffer */ unsigned char *rcvbuf; /* AT reply receive buffer */
struct urb *urb_int_in; /* URB for interrupt pipe */ struct urb *urb_int_in; /* URB for interrupt pipe */
unsigned char int_in_buf[3]; unsigned char *int_in_buf;
spinlock_t lock; /* locks all following */ spinlock_t lock; /* locks all following */
int basstate; /* bitmap (BS_*) */ int basstate; /* bitmap (BS_*) */
...@@ -657,7 +660,7 @@ static void read_int_callback(struct urb *urb) ...@@ -657,7 +660,7 @@ static void read_int_callback(struct urb *urb)
} }
/* drop incomplete packets even if the missing bytes wouldn't matter */ /* drop incomplete packets even if the missing bytes wouldn't matter */
if (unlikely(urb->actual_length < 3)) { if (unlikely(urb->actual_length < IP_MSGSIZE)) {
dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
urb->actual_length); urb->actual_length);
goto resubmit; goto resubmit;
...@@ -2127,6 +2130,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) ...@@ -2127,6 +2130,7 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
static void gigaset_freecshw(struct cardstate *cs) static void gigaset_freecshw(struct cardstate *cs)
{ {
/* timers, URBs and rcvbuf are disposed of in disconnect */ /* timers, URBs and rcvbuf are disposed of in disconnect */
kfree(cs->hw.bas->int_in_buf);
kfree(cs->hw.bas); kfree(cs->hw.bas);
cs->hw.bas = NULL; cs->hw.bas = NULL;
} }
...@@ -2140,6 +2144,12 @@ static int gigaset_initcshw(struct cardstate *cs) ...@@ -2140,6 +2144,12 @@ static int gigaset_initcshw(struct cardstate *cs)
pr_err("out of memory\n"); pr_err("out of memory\n");
return 0; return 0;
} }
ucs->int_in_buf = kmalloc(IP_MSGSIZE, GFP_KERNEL);
if (!ucs->int_in_buf) {
kfree(ucs);
pr_err("out of memory\n");
return 0;
}
ucs->urb_cmd_in = NULL; ucs->urb_cmd_in = NULL;
ucs->urb_cmd_out = NULL; ucs->urb_cmd_out = NULL;
...@@ -2292,7 +2302,7 @@ static int gigaset_probe(struct usb_interface *interface, ...@@ -2292,7 +2302,7 @@ static int gigaset_probe(struct usb_interface *interface,
usb_fill_int_urb(ucs->urb_int_in, udev, usb_fill_int_urb(ucs->urb_int_in, udev,
usb_rcvintpipe(udev, usb_rcvintpipe(udev,
(endpoint->bEndpointAddress) & 0x0f), (endpoint->bEndpointAddress) & 0x0f),
ucs->int_in_buf, 3, read_int_callback, cs, ucs->int_in_buf, IP_MSGSIZE, read_int_callback, cs,
endpoint->bInterval); endpoint->bInterval);
if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) { if ((rc = usb_submit_urb(ucs->urb_int_in, GFP_KERNEL)) != 0) {
dev_err(cs->dev, "could not submit interrupt URB: %s\n", dev_err(cs->dev, "could not submit interrupt URB: %s\n",
......
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