aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/serial/mct_u232.c55
-rw-r--r--drivers/usb/serial/mct_u232.h2
2 files changed, 46 insertions, 11 deletions
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index cd009cb280a5..86503831ad3f 100644
--- a/drivers/usb/serial/mct_u232.c
+++ b/drivers/usb/serial/mct_u232.c
@@ -75,6 +75,7 @@
75#include <linux/module.h> 75#include <linux/module.h>
76#include <linux/spinlock.h> 76#include <linux/spinlock.h>
77#include <linux/uaccess.h> 77#include <linux/uaccess.h>
78#include <asm/unaligned.h>
78#include <linux/usb.h> 79#include <linux/usb.h>
79#include <linux/usb/serial.h> 80#include <linux/usb/serial.h>
80#include "mct_u232.h" 81#include "mct_u232.h"
@@ -231,19 +232,22 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial,
231static int mct_u232_set_baud_rate(struct tty_struct *tty, 232static int mct_u232_set_baud_rate(struct tty_struct *tty,
232 struct usb_serial *serial, struct usb_serial_port *port, speed_t value) 233 struct usb_serial *serial, struct usb_serial_port *port, speed_t value)
233{ 234{
234 __le32 divisor; 235 unsigned int divisor;
235 int rc; 236 int rc;
236 unsigned char zero_byte = 0; 237 unsigned char *buf;
237 unsigned char cts_enable_byte = 0; 238 unsigned char cts_enable_byte = 0;
238 speed_t speed; 239 speed_t speed;
239 240
240 divisor = cpu_to_le32(mct_u232_calculate_baud_rate(serial, value, 241 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
241 &speed)); 242 if (buf == NULL)
243 return -ENOMEM;
242 244
245 divisor = mct_u232_calculate_baud_rate(serial, value, &speed);
246 put_unaligned_le32(cpu_to_le32(divisor), buf);
243 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 247 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
244 MCT_U232_SET_BAUD_RATE_REQUEST, 248 MCT_U232_SET_BAUD_RATE_REQUEST,
245 MCT_U232_SET_REQUEST_TYPE, 249 MCT_U232_SET_REQUEST_TYPE,
246 0, 0, &divisor, MCT_U232_SET_BAUD_RATE_SIZE, 250 0, 0, buf, MCT_U232_SET_BAUD_RATE_SIZE,
247 WDR_TIMEOUT); 251 WDR_TIMEOUT);
248 if (rc < 0) /*FIXME: What value speed results */ 252 if (rc < 0) /*FIXME: What value speed results */
249 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n", 253 dev_err(&port->dev, "Set BAUD RATE %d failed (error = %d)\n",
@@ -269,10 +273,11 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
269 a device which is not asserting 'CTS'. 273 a device which is not asserting 'CTS'.
270 */ 274 */
271 275
276 buf[0] = 0;
272 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 277 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
273 MCT_U232_SET_UNKNOWN1_REQUEST, 278 MCT_U232_SET_UNKNOWN1_REQUEST,
274 MCT_U232_SET_REQUEST_TYPE, 279 MCT_U232_SET_REQUEST_TYPE,
275 0, 0, &zero_byte, MCT_U232_SET_UNKNOWN1_SIZE, 280 0, 0, buf, MCT_U232_SET_UNKNOWN1_SIZE,
276 WDR_TIMEOUT); 281 WDR_TIMEOUT);
277 if (rc < 0) 282 if (rc < 0)
278 dev_err(&port->dev, "Sending USB device request code %d " 283 dev_err(&port->dev, "Sending USB device request code %d "
@@ -284,30 +289,40 @@ static int mct_u232_set_baud_rate(struct tty_struct *tty,
284 289
285 dbg("set_baud_rate: send second control message, data = %02X", 290 dbg("set_baud_rate: send second control message, data = %02X",
286 cts_enable_byte); 291 cts_enable_byte);
292 buf[0] = cts_enable_byte;
287 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 293 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
288 MCT_U232_SET_CTS_REQUEST, 294 MCT_U232_SET_CTS_REQUEST,
289 MCT_U232_SET_REQUEST_TYPE, 295 MCT_U232_SET_REQUEST_TYPE,
290 0, 0, &cts_enable_byte, MCT_U232_SET_CTS_SIZE, 296 0, 0, buf, MCT_U232_SET_CTS_SIZE,
291 WDR_TIMEOUT); 297 WDR_TIMEOUT);
292 if (rc < 0) 298 if (rc < 0)
293 dev_err(&port->dev, "Sending USB device request code %d " 299 dev_err(&port->dev, "Sending USB device request code %d "
294 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc); 300 "failed (error = %d)\n", MCT_U232_SET_CTS_REQUEST, rc);
295 301
302 kfree(buf);
296 return rc; 303 return rc;
297} /* mct_u232_set_baud_rate */ 304} /* mct_u232_set_baud_rate */
298 305
299static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr) 306static int mct_u232_set_line_ctrl(struct usb_serial *serial, unsigned char lcr)
300{ 307{
301 int rc; 308 int rc;
309 unsigned char *buf;
310
311 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
312 if (buf == NULL)
313 return -ENOMEM;
314
315 buf[0] = lcr;
302 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 316 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
303 MCT_U232_SET_LINE_CTRL_REQUEST, 317 MCT_U232_SET_LINE_CTRL_REQUEST,
304 MCT_U232_SET_REQUEST_TYPE, 318 MCT_U232_SET_REQUEST_TYPE,
305 0, 0, &lcr, MCT_U232_SET_LINE_CTRL_SIZE, 319 0, 0, buf, MCT_U232_SET_LINE_CTRL_SIZE,
306 WDR_TIMEOUT); 320 WDR_TIMEOUT);
307 if (rc < 0) 321 if (rc < 0)
308 dev_err(&serial->dev->dev, 322 dev_err(&serial->dev->dev,
309 "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc); 323 "Set LINE CTRL 0x%x failed (error = %d)\n", lcr, rc);
310 dbg("set_line_ctrl: 0x%x", lcr); 324 dbg("set_line_ctrl: 0x%x", lcr);
325 kfree(buf);
311 return rc; 326 return rc;
312} /* mct_u232_set_line_ctrl */ 327} /* mct_u232_set_line_ctrl */
313 328
@@ -315,23 +330,31 @@ static int mct_u232_set_modem_ctrl(struct usb_serial *serial,
315 unsigned int control_state) 330 unsigned int control_state)
316{ 331{
317 int rc; 332 int rc;
318 unsigned char mcr = MCT_U232_MCR_NONE; 333 unsigned char mcr;
334 unsigned char *buf;
335
336 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
337 if (buf == NULL)
338 return -ENOMEM;
319 339
340 mcr = MCT_U232_MCR_NONE;
320 if (control_state & TIOCM_DTR) 341 if (control_state & TIOCM_DTR)
321 mcr |= MCT_U232_MCR_DTR; 342 mcr |= MCT_U232_MCR_DTR;
322 if (control_state & TIOCM_RTS) 343 if (control_state & TIOCM_RTS)
323 mcr |= MCT_U232_MCR_RTS; 344 mcr |= MCT_U232_MCR_RTS;
324 345
346 buf[0] = mcr;
325 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), 347 rc = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
326 MCT_U232_SET_MODEM_CTRL_REQUEST, 348 MCT_U232_SET_MODEM_CTRL_REQUEST,
327 MCT_U232_SET_REQUEST_TYPE, 349 MCT_U232_SET_REQUEST_TYPE,
328 0, 0, &mcr, MCT_U232_SET_MODEM_CTRL_SIZE, 350 0, 0, buf, MCT_U232_SET_MODEM_CTRL_SIZE,
329 WDR_TIMEOUT); 351 WDR_TIMEOUT);
330 if (rc < 0) 352 if (rc < 0)
331 dev_err(&serial->dev->dev, 353 dev_err(&serial->dev->dev,
332 "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc); 354 "Set MODEM CTRL 0x%x failed (error = %d)\n", mcr, rc);
333 dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr); 355 dbg("set_modem_ctrl: state=0x%x ==> mcr=0x%x", control_state, mcr);
334 356
357 kfree(buf);
335 return rc; 358 return rc;
336} /* mct_u232_set_modem_ctrl */ 359} /* mct_u232_set_modem_ctrl */
337 360
@@ -339,17 +362,27 @@ static int mct_u232_get_modem_stat(struct usb_serial *serial,
339 unsigned char *msr) 362 unsigned char *msr)
340{ 363{
341 int rc; 364 int rc;
365 unsigned char *buf;
366
367 buf = kmalloc(MCT_U232_MAX_SIZE, GFP_KERNEL);
368 if (buf == NULL) {
369 *msr = 0;
370 return -ENOMEM;
371 }
342 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), 372 rc = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
343 MCT_U232_GET_MODEM_STAT_REQUEST, 373 MCT_U232_GET_MODEM_STAT_REQUEST,
344 MCT_U232_GET_REQUEST_TYPE, 374 MCT_U232_GET_REQUEST_TYPE,
345 0, 0, msr, MCT_U232_GET_MODEM_STAT_SIZE, 375 0, 0, buf, MCT_U232_GET_MODEM_STAT_SIZE,
346 WDR_TIMEOUT); 376 WDR_TIMEOUT);
347 if (rc < 0) { 377 if (rc < 0) {
348 dev_err(&serial->dev->dev, 378 dev_err(&serial->dev->dev,
349 "Get MODEM STATus failed (error = %d)\n", rc); 379 "Get MODEM STATus failed (error = %d)\n", rc);
350 *msr = 0; 380 *msr = 0;
381 } else {
382 *msr = buf[0];
351 } 383 }
352 dbg("get_modem_stat: 0x%x", *msr); 384 dbg("get_modem_stat: 0x%x", *msr);
385 kfree(buf);
353 return rc; 386 return rc;
354} /* mct_u232_get_modem_stat */ 387} /* mct_u232_get_modem_stat */
355 388
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h
index 07b6bec31dc8..7417d5ce1e23 100644
--- a/drivers/usb/serial/mct_u232.h
+++ b/drivers/usb/serial/mct_u232.h
@@ -73,6 +73,8 @@
73#define MCT_U232_SET_CTS_REQUEST 12 73#define MCT_U232_SET_CTS_REQUEST 12
74#define MCT_U232_SET_CTS_SIZE 1 74#define MCT_U232_SET_CTS_SIZE 1
75 75
76#define MCT_U232_MAX_SIZE 4 /* of MCT_XXX_SIZE */
77
76/* 78/*
77 * Baud rate (divisor) 79 * Baud rate (divisor)
78 * Actually, there are two of them, MCT website calls them "Philips solution" 80 * Actually, there are two of them, MCT website calls them "Philips solution"