Skip to content

Commit 74f2664

Browse files
himadricsjhovold
authored andcommitted
USB: serial: ch314: use usb_control_msg_recv()
usb_control_msg_recv() is a new wrapper function for usb_control_msg() that has error checks for short reads. This function also accepts data buffer on stack. Hence use this function to simplify error handling for short reads. Short reads will now get reported as -EREMOTEIO with no indication of how short the transfer was. Signed-off-by: Himadri Pandya <[email protected]> Link: https://lore.kernel.org/r/[email protected] [ johan: fix quirk-detection breakage, style changes ] Signed-off-by: Johan Hovold <[email protected]>
1 parent c8345c0 commit 74f2664

File tree

1 file changed

+26
-59
lines changed

1 file changed

+26
-59
lines changed

drivers/usb/serial/ch341.c

Lines changed: 26 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,11 @@ static int ch341_control_in(struct usb_device *dev,
131131
dev_dbg(&dev->dev, "%s - (%02x,%04x,%04x,%u)\n", __func__,
132132
request, value, index, bufsize);
133133

134-
r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request,
135-
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
136-
value, index, buf, bufsize, DEFAULT_TIMEOUT);
137-
if (r < (int)bufsize) {
138-
if (r >= 0) {
139-
dev_err(&dev->dev,
140-
"short control message received (%d < %u)\n",
141-
r, bufsize);
142-
r = -EIO;
143-
}
144-
134+
r = usb_control_msg_recv(dev, 0, request,
135+
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
136+
value, index, buf, bufsize, DEFAULT_TIMEOUT,
137+
GFP_KERNEL);
138+
if (r) {
145139
dev_err(&dev->dev, "failed to receive control message: %d\n",
146140
r);
147141
return r;
@@ -287,56 +281,48 @@ static int ch341_set_handshake(struct usb_device *dev, u8 control)
287281
static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv)
288282
{
289283
const unsigned int size = 2;
290-
char *buffer;
284+
u8 buffer[2];
291285
int r;
292286
unsigned long flags;
293287

294-
buffer = kmalloc(size, GFP_KERNEL);
295-
if (!buffer)
296-
return -ENOMEM;
297-
298288
r = ch341_control_in(dev, CH341_REQ_READ_REG, 0x0706, 0, buffer, size);
299-
if (r < 0)
300-
goto out;
289+
if (r)
290+
return r;
301291

302292
spin_lock_irqsave(&priv->lock, flags);
303293
priv->msr = (~(*buffer)) & CH341_BITS_MODEM_STAT;
304294
spin_unlock_irqrestore(&priv->lock, flags);
305295

306-
out: kfree(buffer);
307-
return r;
296+
return 0;
308297
}
309298

310299
/* -------------------------------------------------------------------------- */
311300

312301
static int ch341_configure(struct usb_device *dev, struct ch341_private *priv)
313302
{
314303
const unsigned int size = 2;
315-
char *buffer;
304+
u8 buffer[2];
316305
int r;
317306

318-
buffer = kmalloc(size, GFP_KERNEL);
319-
if (!buffer)
320-
return -ENOMEM;
321-
322307
/* expect two bytes 0x27 0x00 */
323308
r = ch341_control_in(dev, CH341_REQ_READ_VERSION, 0, 0, buffer, size);
324-
if (r < 0)
325-
goto out;
309+
if (r)
310+
return r;
326311
dev_dbg(&dev->dev, "Chip version: 0x%02x\n", buffer[0]);
327312

328313
r = ch341_control_out(dev, CH341_REQ_SERIAL_INIT, 0, 0);
329314
if (r < 0)
330-
goto out;
315+
return r;
331316

332317
r = ch341_set_baudrate_lcr(dev, priv, priv->baud_rate, priv->lcr);
333318
if (r < 0)
334-
goto out;
319+
return r;
335320

336321
r = ch341_set_handshake(dev, priv->mcr);
322+
if (r < 0)
323+
return r;
337324

338-
out: kfree(buffer);
339-
return r;
325+
return 0;
340326
}
341327

342328
static int ch341_detect_quirks(struct usb_serial_port *port)
@@ -345,40 +331,27 @@ static int ch341_detect_quirks(struct usb_serial_port *port)
345331
struct usb_device *udev = port->serial->dev;
346332
const unsigned int size = 2;
347333
unsigned long quirks = 0;
348-
char *buffer;
334+
u8 buffer[2];
349335
int r;
350336

351-
buffer = kmalloc(size, GFP_KERNEL);
352-
if (!buffer)
353-
return -ENOMEM;
354-
355337
/*
356338
* A subset of CH34x devices does not support all features. The
357339
* prescaler is limited and there is no support for sending a RS232
358340
* break condition. A read failure when trying to set up the latter is
359341
* used to detect these devices.
360342
*/
361-
r = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), CH341_REQ_READ_REG,
362-
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
363-
CH341_REG_BREAK, 0, buffer, size, DEFAULT_TIMEOUT);
343+
r = usb_control_msg_recv(udev, 0, CH341_REQ_READ_REG,
344+
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN,
345+
CH341_REG_BREAK, 0, &buffer, size,
346+
DEFAULT_TIMEOUT, GFP_KERNEL);
364347
if (r == -EPIPE) {
365348
dev_info(&port->dev, "break control not supported, using simulated break\n");
366349
quirks = CH341_QUIRK_LIMITED_PRESCALER | CH341_QUIRK_SIMULATE_BREAK;
367350
r = 0;
368-
goto out;
369-
}
370-
371-
if (r != size) {
372-
if (r >= 0)
373-
r = -EIO;
351+
} else if (r) {
374352
dev_err(&port->dev, "failed to read break control: %d\n", r);
375-
goto out;
376353
}
377354

378-
r = 0;
379-
out:
380-
kfree(buffer);
381-
382355
if (quirks) {
383356
dev_dbg(&port->dev, "enabling quirk flags: 0x%02lx\n", quirks);
384357
priv->quirks |= quirks;
@@ -647,23 +620,19 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
647620
struct ch341_private *priv = usb_get_serial_port_data(port);
648621
int r;
649622
uint16_t reg_contents;
650-
uint8_t *break_reg;
623+
uint8_t break_reg[2];
651624

652625
if (priv->quirks & CH341_QUIRK_SIMULATE_BREAK) {
653626
ch341_simulate_break(tty, break_state);
654627
return;
655628
}
656629

657-
break_reg = kmalloc(2, GFP_KERNEL);
658-
if (!break_reg)
659-
return;
660-
661630
r = ch341_control_in(port->serial->dev, CH341_REQ_READ_REG,
662631
ch341_break_reg, 0, break_reg, 2);
663-
if (r < 0) {
632+
if (r) {
664633
dev_err(&port->dev, "%s - USB control read error (%d)\n",
665634
__func__, r);
666-
goto out;
635+
return;
667636
}
668637
dev_dbg(&port->dev, "%s - initial ch341 break register contents - reg1: %x, reg2: %x\n",
669638
__func__, break_reg[0], break_reg[1]);
@@ -684,8 +653,6 @@ static void ch341_break_ctl(struct tty_struct *tty, int break_state)
684653
if (r < 0)
685654
dev_err(&port->dev, "%s - USB control write error (%d)\n",
686655
__func__, r);
687-
out:
688-
kfree(break_reg);
689656
}
690657

691658
static int ch341_tiocmset(struct tty_struct *tty,

0 commit comments

Comments
 (0)