aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hovold <jhovold@gmail.com>2009-12-28 17:01:48 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2010-03-02 17:53:51 -0500
commit0954644bf5a5a2281746516ce0f5df988d504c31 (patch)
tree78e49914f5988e768f82928b8e53582e81ee9d55
parent52372ccb5a19d35b68b79118fafdced0c12f0ec9 (diff)
USB: cypress_m8: fix DMA buffer on stack
Cc: Lonnie Mendez <dignome@gmail.com> Signed-off-by: Johan Hovold <jhovold@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/usb/serial/cypress_m8.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index 60c200230bc8..1ce1a3a3e21a 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -344,7 +344,8 @@ static int cypress_serial_control(struct tty_struct *tty,
344{ 344{
345 int new_baudrate = 0, retval = 0, tries = 0; 345 int new_baudrate = 0, retval = 0, tries = 0;
346 struct cypress_private *priv; 346 struct cypress_private *priv;
347 __u8 feature_buffer[5]; 347 u8 *feature_buffer;
348 const unsigned int feature_len = 5;
348 unsigned long flags; 349 unsigned long flags;
349 350
350 dbg("%s", __func__); 351 dbg("%s", __func__);
@@ -354,6 +355,10 @@ static int cypress_serial_control(struct tty_struct *tty,
354 if (!priv->comm_is_ok) 355 if (!priv->comm_is_ok)
355 return -ENODEV; 356 return -ENODEV;
356 357
358 feature_buffer = kcalloc(feature_len, sizeof(u8), GFP_KERNEL);
359 if (!feature_buffer)
360 return -ENOMEM;
361
357 switch (cypress_request_type) { 362 switch (cypress_request_type) {
358 case CYPRESS_SET_CONFIG: 363 case CYPRESS_SET_CONFIG:
359 /* 0 means 'Hang up' so doesn't change the true bit rate */ 364 /* 0 means 'Hang up' so doesn't change the true bit rate */
@@ -370,7 +375,6 @@ static int cypress_serial_control(struct tty_struct *tty,
370 dbg("%s - baud rate is being sent as %d", 375 dbg("%s - baud rate is being sent as %d",
371 __func__, new_baudrate); 376 __func__, new_baudrate);
372 377
373 memset(feature_buffer, 0, sizeof(feature_buffer));
374 /* fill the feature_buffer with new configuration */ 378 /* fill the feature_buffer with new configuration */
375 *((u_int32_t *)feature_buffer) = new_baudrate; 379 *((u_int32_t *)feature_buffer) = new_baudrate;
376 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */ 380 feature_buffer[4] |= data_bits; /* assign data bits in 2 bit space ( max 3 ) */
@@ -394,15 +398,15 @@ static int cypress_serial_control(struct tty_struct *tty,
394 HID_REQ_SET_REPORT, 398 HID_REQ_SET_REPORT,
395 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 399 USB_DIR_OUT | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
396 0x0300, 0, feature_buffer, 400 0x0300, 0, feature_buffer,
397 sizeof(feature_buffer), 500); 401 feature_len, 500);
398 402
399 if (tries++ >= 3) 403 if (tries++ >= 3)
400 break; 404 break;
401 405
402 } while (retval != sizeof(feature_buffer) && 406 } while (retval != feature_len &&
403 retval != -ENODEV); 407 retval != -ENODEV);
404 408
405 if (retval != sizeof(feature_buffer)) { 409 if (retval != feature_len) {
406 dev_err(&port->dev, "%s - failed sending serial " 410 dev_err(&port->dev, "%s - failed sending serial "
407 "line settings - %d\n", __func__, retval); 411 "line settings - %d\n", __func__, retval);
408 cypress_set_dead(port); 412 cypress_set_dead(port);
@@ -422,30 +426,28 @@ static int cypress_serial_control(struct tty_struct *tty,
422 /* Not implemented for this device, 426 /* Not implemented for this device,
423 and if we try to do it we're likely 427 and if we try to do it we're likely
424 to crash the hardware. */ 428 to crash the hardware. */
425 return -ENOTTY; 429 retval = -ENOTTY;
430 goto out;
426 } 431 }
427 dbg("%s - retreiving serial line settings", __func__); 432 dbg("%s - retreiving serial line settings", __func__);
428 /* set initial values in feature buffer */
429 memset(feature_buffer, 0, sizeof(feature_buffer));
430
431 do { 433 do {
432 retval = usb_control_msg(port->serial->dev, 434 retval = usb_control_msg(port->serial->dev,
433 usb_rcvctrlpipe(port->serial->dev, 0), 435 usb_rcvctrlpipe(port->serial->dev, 0),
434 HID_REQ_GET_REPORT, 436 HID_REQ_GET_REPORT,
435 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS, 437 USB_DIR_IN | USB_RECIP_INTERFACE | USB_TYPE_CLASS,
436 0x0300, 0, feature_buffer, 438 0x0300, 0, feature_buffer,
437 sizeof(feature_buffer), 500); 439 feature_len, 500);
438 440
439 if (tries++ >= 3) 441 if (tries++ >= 3)
440 break; 442 break;
441 } while (retval != sizeof(feature_buffer) 443 } while (retval != feature_len
442 && retval != -ENODEV); 444 && retval != -ENODEV);
443 445
444 if (retval != sizeof(feature_buffer)) { 446 if (retval != feature_len) {
445 dev_err(&port->dev, "%s - failed to retrieve serial " 447 dev_err(&port->dev, "%s - failed to retrieve serial "
446 "line settings - %d\n", __func__, retval); 448 "line settings - %d\n", __func__, retval);
447 cypress_set_dead(port); 449 cypress_set_dead(port);
448 return retval; 450 goto out;
449 } else { 451 } else {
450 spin_lock_irqsave(&priv->lock, flags); 452 spin_lock_irqsave(&priv->lock, flags);
451 /* store the config in one byte, and later 453 /* store the config in one byte, and later
@@ -458,7 +460,8 @@ static int cypress_serial_control(struct tty_struct *tty,
458 spin_lock_irqsave(&priv->lock, flags); 460 spin_lock_irqsave(&priv->lock, flags);
459 ++priv->cmd_count; 461 ++priv->cmd_count;
460 spin_unlock_irqrestore(&priv->lock, flags); 462 spin_unlock_irqrestore(&priv->lock, flags);
461 463out:
464 kfree(feature_buffer);
462 return retval; 465 return retval;
463} /* cypress_serial_control */ 466} /* cypress_serial_control */
464 467