forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/usb/host/xhci-dbgtty.c
....@@ -1,5 +1,5 @@
11 // SPDX-License-Identifier: GPL-2.0
2
-/**
2
+/*
33 * xhci-dbgtty.c - tty glue for xHCI debug capability
44 *
55 * Copyright (C) 2017 Intel Corporation
....@@ -13,6 +13,16 @@
1313
1414 #include "xhci.h"
1515 #include "xhci-dbgcap.h"
16
+
17
+static int dbc_tty_init(void);
18
+static void dbc_tty_exit(void);
19
+
20
+static struct tty_driver *dbc_tty_driver;
21
+
22
+static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc)
23
+{
24
+ return dbc->priv;
25
+}
1626
1727 static unsigned int
1828 dbc_send_packet(struct dbc_port *port, char *packet, unsigned int size)
....@@ -48,7 +58,7 @@
4858 list_del(&req->list_pool);
4959
5060 spin_unlock(&port->port_lock);
51
- status = dbc_ep_queue(port->out, req, GFP_ATOMIC);
61
+ status = dbc_ep_queue(req);
5262 spin_lock(&port->port_lock);
5363
5464 if (status) {
....@@ -80,7 +90,7 @@
8090 req->length = DBC_MAX_PACKET;
8191
8292 spin_unlock(&port->port_lock);
83
- status = dbc_ep_queue(port->in, req, GFP_ATOMIC);
93
+ status = dbc_ep_queue(req);
8494 spin_lock(&port->port_lock);
8595
8696 if (status) {
....@@ -91,11 +101,10 @@
91101 }
92102
93103 static void
94
-dbc_read_complete(struct xhci_hcd *xhci, struct dbc_request *req)
104
+dbc_read_complete(struct xhci_dbc *dbc, struct dbc_request *req)
95105 {
96106 unsigned long flags;
97
- struct xhci_dbc *dbc = xhci->dbc;
98
- struct dbc_port *port = &dbc->port;
107
+ struct dbc_port *port = dbc_to_port(dbc);
99108
100109 spin_lock_irqsave(&port->port_lock, flags);
101110 list_add_tail(&req->list_pool, &port->read_queue);
....@@ -103,11 +112,10 @@
103112 spin_unlock_irqrestore(&port->port_lock, flags);
104113 }
105114
106
-static void dbc_write_complete(struct xhci_hcd *xhci, struct dbc_request *req)
115
+static void dbc_write_complete(struct xhci_dbc *dbc, struct dbc_request *req)
107116 {
108117 unsigned long flags;
109
- struct xhci_dbc *dbc = xhci->dbc;
110
- struct dbc_port *port = &dbc->port;
118
+ struct dbc_port *port = dbc_to_port(dbc);
111119
112120 spin_lock_irqsave(&port->port_lock, flags);
113121 list_add(&req->list_pool, &port->write_pool);
....@@ -118,35 +126,36 @@
118126 case -ESHUTDOWN:
119127 break;
120128 default:
121
- xhci_warn(xhci, "unexpected write complete status %d\n",
129
+ dev_warn(dbc->dev, "unexpected write complete status %d\n",
122130 req->status);
123131 break;
124132 }
125133 spin_unlock_irqrestore(&port->port_lock, flags);
126134 }
127135
128
-static void xhci_dbc_free_req(struct dbc_ep *dep, struct dbc_request *req)
136
+static void xhci_dbc_free_req(struct dbc_request *req)
129137 {
130138 kfree(req->buf);
131
- dbc_free_request(dep, req);
139
+ dbc_free_request(req);
132140 }
133141
134142 static int
135
-xhci_dbc_alloc_requests(struct dbc_ep *dep, struct list_head *head,
136
- void (*fn)(struct xhci_hcd *, struct dbc_request *))
143
+xhci_dbc_alloc_requests(struct xhci_dbc *dbc, unsigned int direction,
144
+ struct list_head *head,
145
+ void (*fn)(struct xhci_dbc *, struct dbc_request *))
137146 {
138147 int i;
139148 struct dbc_request *req;
140149
141150 for (i = 0; i < DBC_QUEUE_SIZE; i++) {
142
- req = dbc_alloc_request(dep, GFP_ATOMIC);
151
+ req = dbc_alloc_request(dbc, direction, GFP_KERNEL);
143152 if (!req)
144153 break;
145154
146155 req->length = DBC_MAX_PACKET;
147156 req->buf = kmalloc(req->length, GFP_KERNEL);
148157 if (!req->buf) {
149
- xhci_dbc_free_req(dep, req);
158
+ dbc_free_request(req);
150159 break;
151160 }
152161
....@@ -158,14 +167,14 @@
158167 }
159168
160169 static void
161
-xhci_dbc_free_requests(struct dbc_ep *dep, struct list_head *head)
170
+xhci_dbc_free_requests(struct list_head *head)
162171 {
163172 struct dbc_request *req;
164173
165174 while (!list_empty(head)) {
166175 req = list_entry(head->next, struct dbc_request, list_pool);
167176 list_del(&req->list_pool);
168
- xhci_dbc_free_req(dep, req);
177
+ xhci_dbc_free_req(req);
169178 }
170179 }
171180
....@@ -279,63 +288,14 @@
279288 .unthrottle = dbc_tty_unthrottle,
280289 };
281290
282
-static struct tty_driver *dbc_tty_driver;
283
-
284
-int xhci_dbc_tty_register_driver(struct xhci_hcd *xhci)
285
-{
286
- int status;
287
- struct xhci_dbc *dbc = xhci->dbc;
288
-
289
- dbc_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
290
- TTY_DRIVER_DYNAMIC_DEV);
291
- if (IS_ERR(dbc_tty_driver)) {
292
- status = PTR_ERR(dbc_tty_driver);
293
- dbc_tty_driver = NULL;
294
- return status;
295
- }
296
-
297
- dbc_tty_driver->driver_name = "dbc_serial";
298
- dbc_tty_driver->name = "ttyDBC";
299
-
300
- dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
301
- dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL;
302
- dbc_tty_driver->init_termios = tty_std_termios;
303
- dbc_tty_driver->init_termios.c_cflag =
304
- B9600 | CS8 | CREAD | HUPCL | CLOCAL;
305
- dbc_tty_driver->init_termios.c_ispeed = 9600;
306
- dbc_tty_driver->init_termios.c_ospeed = 9600;
307
- dbc_tty_driver->driver_state = &dbc->port;
308
-
309
- tty_set_operations(dbc_tty_driver, &dbc_tty_ops);
310
-
311
- status = tty_register_driver(dbc_tty_driver);
312
- if (status) {
313
- xhci_err(xhci,
314
- "can't register dbc tty driver, err %d\n", status);
315
- put_tty_driver(dbc_tty_driver);
316
- dbc_tty_driver = NULL;
317
- }
318
-
319
- return status;
320
-}
321
-
322
-void xhci_dbc_tty_unregister_driver(void)
323
-{
324
- if (dbc_tty_driver) {
325
- tty_unregister_driver(dbc_tty_driver);
326
- put_tty_driver(dbc_tty_driver);
327
- dbc_tty_driver = NULL;
328
- }
329
-}
330
-
331
-static void dbc_rx_push(unsigned long _port)
291
+static void dbc_rx_push(struct tasklet_struct *t)
332292 {
333293 struct dbc_request *req;
334294 struct tty_struct *tty;
335295 unsigned long flags;
336296 bool do_push = false;
337297 bool disconnect = false;
338
- struct dbc_port *port = (void *)_port;
298
+ struct dbc_port *port = from_tasklet(port, t, push);
339299 struct list_head *queue = &port->read_queue;
340300
341301 spin_lock_irqsave(&port->port_lock, flags);
....@@ -418,17 +378,15 @@
418378 };
419379
420380 static void
421
-xhci_dbc_tty_init_port(struct xhci_hcd *xhci, struct dbc_port *port)
381
+xhci_dbc_tty_init_port(struct xhci_dbc *dbc, struct dbc_port *port)
422382 {
423383 tty_port_init(&port->port);
424384 spin_lock_init(&port->port_lock);
425
- tasklet_init(&port->push, dbc_rx_push, (unsigned long)port);
385
+ tasklet_setup(&port->push, dbc_rx_push);
426386 INIT_LIST_HEAD(&port->read_pool);
427387 INIT_LIST_HEAD(&port->read_queue);
428388 INIT_LIST_HEAD(&port->write_pool);
429389
430
- port->in = get_in_ep(xhci);
431
- port->out = get_out_ep(xhci);
432390 port->port.ops = &dbc_port_ops;
433391 port->n_read = 0;
434392 }
....@@ -440,66 +398,157 @@
440398 tty_port_destroy(&port->port);
441399 }
442400
443
-int xhci_dbc_tty_register_device(struct xhci_hcd *xhci)
401
+static int xhci_dbc_tty_register_device(struct xhci_dbc *dbc)
444402 {
445403 int ret;
446404 struct device *tty_dev;
447
- struct xhci_dbc *dbc = xhci->dbc;
448
- struct dbc_port *port = &dbc->port;
405
+ struct dbc_port *port = dbc_to_port(dbc);
449406
450
- xhci_dbc_tty_init_port(xhci, port);
407
+ if (port->registered)
408
+ return -EBUSY;
409
+
410
+ xhci_dbc_tty_init_port(dbc, port);
411
+
412
+ ret = kfifo_alloc(&port->write_fifo, DBC_WRITE_BUF_SIZE, GFP_KERNEL);
413
+ if (ret)
414
+ goto err_exit_port;
415
+
416
+ ret = xhci_dbc_alloc_requests(dbc, BULK_IN, &port->read_pool,
417
+ dbc_read_complete);
418
+ if (ret)
419
+ goto err_free_fifo;
420
+
421
+ ret = xhci_dbc_alloc_requests(dbc, BULK_OUT, &port->write_pool,
422
+ dbc_write_complete);
423
+ if (ret)
424
+ goto err_free_requests;
425
+
451426 tty_dev = tty_port_register_device(&port->port,
452427 dbc_tty_driver, 0, NULL);
453428 if (IS_ERR(tty_dev)) {
454429 ret = PTR_ERR(tty_dev);
455
- goto register_fail;
430
+ goto err_free_requests;
456431 }
457
-
458
- ret = kfifo_alloc(&port->write_fifo, DBC_WRITE_BUF_SIZE, GFP_KERNEL);
459
- if (ret)
460
- goto buf_alloc_fail;
461
-
462
- ret = xhci_dbc_alloc_requests(port->in, &port->read_pool,
463
- dbc_read_complete);
464
- if (ret)
465
- goto request_fail;
466
-
467
- ret = xhci_dbc_alloc_requests(port->out, &port->write_pool,
468
- dbc_write_complete);
469
- if (ret)
470
- goto request_fail;
471432
472433 port->registered = true;
473434
474435 return 0;
475436
476
-request_fail:
477
- xhci_dbc_free_requests(port->in, &port->read_pool);
478
- xhci_dbc_free_requests(port->out, &port->write_pool);
437
+err_free_requests:
438
+ xhci_dbc_free_requests(&port->read_pool);
439
+ xhci_dbc_free_requests(&port->write_pool);
440
+err_free_fifo:
479441 kfifo_free(&port->write_fifo);
480
-
481
-buf_alloc_fail:
482
- tty_unregister_device(dbc_tty_driver, 0);
483
-
484
-register_fail:
442
+err_exit_port:
485443 xhci_dbc_tty_exit_port(port);
486444
487
- xhci_err(xhci, "can't register tty port, err %d\n", ret);
445
+ dev_err(dbc->dev, "can't register tty port, err %d\n", ret);
488446
489447 return ret;
490448 }
491449
492
-void xhci_dbc_tty_unregister_device(struct xhci_hcd *xhci)
450
+static void xhci_dbc_tty_unregister_device(struct xhci_dbc *dbc)
493451 {
494
- struct xhci_dbc *dbc = xhci->dbc;
495
- struct dbc_port *port = &dbc->port;
452
+ struct dbc_port *port = dbc_to_port(dbc);
496453
454
+ if (!port->registered)
455
+ return;
497456 tty_unregister_device(dbc_tty_driver, 0);
498457 xhci_dbc_tty_exit_port(port);
499458 port->registered = false;
500459
501460 kfifo_free(&port->write_fifo);
502
- xhci_dbc_free_requests(get_out_ep(xhci), &port->read_pool);
503
- xhci_dbc_free_requests(get_out_ep(xhci), &port->read_queue);
504
- xhci_dbc_free_requests(get_in_ep(xhci), &port->write_pool);
461
+ xhci_dbc_free_requests(&port->read_pool);
462
+ xhci_dbc_free_requests(&port->read_queue);
463
+ xhci_dbc_free_requests(&port->write_pool);
464
+}
465
+
466
+static const struct dbc_driver dbc_driver = {
467
+ .configure = xhci_dbc_tty_register_device,
468
+ .disconnect = xhci_dbc_tty_unregister_device,
469
+};
470
+
471
+int xhci_dbc_tty_probe(struct xhci_hcd *xhci)
472
+{
473
+ struct xhci_dbc *dbc = xhci->dbc;
474
+ struct dbc_port *port;
475
+ int status;
476
+
477
+ /* dbc_tty_init will be called by module init() in the future */
478
+ status = dbc_tty_init();
479
+ if (status)
480
+ return status;
481
+
482
+ port = kzalloc(sizeof(*port), GFP_KERNEL);
483
+ if (!port) {
484
+ status = -ENOMEM;
485
+ goto out;
486
+ }
487
+
488
+ dbc->driver = &dbc_driver;
489
+ dbc->priv = port;
490
+
491
+
492
+ dbc_tty_driver->driver_state = port;
493
+
494
+ return 0;
495
+out:
496
+ /* dbc_tty_exit will be called by module_exit() in the future */
497
+ dbc_tty_exit();
498
+ return status;
499
+}
500
+
501
+/*
502
+ * undo what probe did, assume dbc is stopped already.
503
+ * we also assume tty_unregister_device() is called before this
504
+ */
505
+void xhci_dbc_tty_remove(struct xhci_dbc *dbc)
506
+{
507
+ struct dbc_port *port = dbc_to_port(dbc);
508
+
509
+ dbc->driver = NULL;
510
+ dbc->priv = NULL;
511
+ kfree(port);
512
+
513
+ /* dbc_tty_exit will be called by module_exit() in the future */
514
+ dbc_tty_exit();
515
+}
516
+
517
+static int dbc_tty_init(void)
518
+{
519
+ int ret;
520
+
521
+ dbc_tty_driver = tty_alloc_driver(1, TTY_DRIVER_REAL_RAW |
522
+ TTY_DRIVER_DYNAMIC_DEV);
523
+ if (IS_ERR(dbc_tty_driver))
524
+ return PTR_ERR(dbc_tty_driver);
525
+
526
+ dbc_tty_driver->driver_name = "dbc_serial";
527
+ dbc_tty_driver->name = "ttyDBC";
528
+
529
+ dbc_tty_driver->type = TTY_DRIVER_TYPE_SERIAL;
530
+ dbc_tty_driver->subtype = SERIAL_TYPE_NORMAL;
531
+ dbc_tty_driver->init_termios = tty_std_termios;
532
+ dbc_tty_driver->init_termios.c_cflag =
533
+ B9600 | CS8 | CREAD | HUPCL | CLOCAL;
534
+ dbc_tty_driver->init_termios.c_ispeed = 9600;
535
+ dbc_tty_driver->init_termios.c_ospeed = 9600;
536
+
537
+ tty_set_operations(dbc_tty_driver, &dbc_tty_ops);
538
+
539
+ ret = tty_register_driver(dbc_tty_driver);
540
+ if (ret) {
541
+ pr_err("Can't register dbc tty driver\n");
542
+ put_tty_driver(dbc_tty_driver);
543
+ }
544
+ return ret;
545
+}
546
+
547
+static void dbc_tty_exit(void)
548
+{
549
+ if (dbc_tty_driver) {
550
+ tty_unregister_driver(dbc_tty_driver);
551
+ put_tty_driver(dbc_tty_driver);
552
+ dbc_tty_driver = NULL;
553
+ }
505554 }