diff options
author | Johan Hovold <jhovold@gmail.com> | 2013-08-13 13:27:36 +0200 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2013-08-14 13:51:01 -0700 |
commit | 2fcd1c9b327c23414a5215a0fa53df9d75871a46 (patch) | |
tree | cf53c724acf4e0810c7c5ab1425d16f7ac941c3d /drivers/usb/serial/keyspan.c | |
parent | 05986ba9b025ae7742744e1108bd59b1f6e8f443 (diff) | |
download | op-kernel-dev-2fcd1c9b327c23414a5215a0fa53df9d75871a46.zip op-kernel-dev-2fcd1c9b327c23414a5215a0fa53df9d75871a46.tar.gz |
USB: keyspan: fix serial DMA-buffer allocations
Make sure serial DMA-buffers are allocated separately from containing
structure to prevent potential memory corruption on non-cache-coherent
systems.
Signed-off-by: Johan Hovold <jhovold@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb/serial/keyspan.c')
-rw-r--r-- | drivers/usb/serial/keyspan.c | 40 |
1 files changed, 36 insertions, 4 deletions
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 5a97972..3d2ce56 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c @@ -56,17 +56,17 @@ struct keyspan_serial_private { const struct keyspan_device_details *device_details; struct urb *instat_urb; - char instat_buf[INSTAT_BUFLEN]; + char *instat_buf; /* added to support 49wg, where data from all 4 ports comes in on 1 EP and high-speed supported */ struct urb *indat_urb; - char indat_buf[INDAT49W_BUFLEN]; + char *indat_buf; /* XXX this one probably will need a lock */ struct urb *glocont_urb; - char glocont_buf[GLOCONT_BUFLEN]; - char ctrl_buf[8]; /* for EP0 control message */ + char *glocont_buf; + char *ctrl_buf; /* for EP0 control message */ }; struct keyspan_port_private { @@ -2313,6 +2313,22 @@ static int keyspan_startup(struct usb_serial *serial) return -ENOMEM; } + s_priv->instat_buf = kzalloc(INSTAT_BUFLEN, GFP_KERNEL); + if (!s_priv->instat_buf) + goto err_instat_buf; + + s_priv->indat_buf = kzalloc(INDAT49W_BUFLEN, GFP_KERNEL); + if (!s_priv->indat_buf) + goto err_indat_buf; + + s_priv->glocont_buf = kzalloc(GLOCONT_BUFLEN, GFP_KERNEL); + if (!s_priv->glocont_buf) + goto err_glocont_buf; + + s_priv->ctrl_buf = kzalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); + if (!s_priv->ctrl_buf) + goto err_ctrl_buf; + s_priv->device_details = d_details; usb_set_serial_data(serial, s_priv); @@ -2330,6 +2346,17 @@ static int keyspan_startup(struct usb_serial *serial) } return 0; + +err_ctrl_buf: + kfree(s_priv->glocont_buf); +err_glocont_buf: + kfree(s_priv->indat_buf); +err_indat_buf: + kfree(s_priv->instat_buf); +err_instat_buf: + kfree(s_priv); + + return -ENOMEM; } static void keyspan_disconnect(struct usb_serial *serial) @@ -2353,6 +2380,11 @@ static void keyspan_release(struct usb_serial *serial) usb_free_urb(s_priv->indat_urb); usb_free_urb(s_priv->glocont_urb); + kfree(s_priv->ctrl_buf); + kfree(s_priv->glocont_buf); + kfree(s_priv->indat_buf); + kfree(s_priv->instat_buf); + kfree(s_priv); } |