hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/thunderbolt/ctl.c
....@@ -1,8 +1,9 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /*
3
- * Thunderbolt Cactus Ridge driver - control channel and configuration commands
3
+ * Thunderbolt driver - control channel and configuration commands
44 *
55 * Copyright (c) 2014 Andreas Noever <andreas.noever@gmail.com>
6
+ * Copyright (C) 2018, Intel Corporation
67 */
78
89 #include <linux/crc32.h>
....@@ -218,6 +219,7 @@
218219 static struct tb_cfg_result decode_error(const struct ctl_pkg *response)
219220 {
220221 struct cfg_error_pkg *pkg = response->buffer;
222
+ struct tb_ctl *ctl = response->ctl;
221223 struct tb_cfg_result res = { 0 };
222224 res.response_route = tb_cfg_get_route(&pkg->header);
223225 res.response_port = 0;
....@@ -226,9 +228,13 @@
226228 if (res.err)
227229 return res;
228230
229
- WARN(pkg->zero1, "pkg->zero1 is %#x\n", pkg->zero1);
230
- WARN(pkg->zero2, "pkg->zero1 is %#x\n", pkg->zero1);
231
- WARN(pkg->zero3, "pkg->zero1 is %#x\n", pkg->zero1);
231
+ if (pkg->zero1)
232
+ tb_ctl_warn(ctl, "pkg->zero1 is %#x\n", pkg->zero1);
233
+ if (pkg->zero2)
234
+ tb_ctl_warn(ctl, "pkg->zero2 is %#x\n", pkg->zero2);
235
+ if (pkg->zero3)
236
+ tb_ctl_warn(ctl, "pkg->zero3 is %#x\n", pkg->zero3);
237
+
232238 res.err = 1;
233239 res.tb_error = pkg->error;
234240 res.response_port = pkg->port;
....@@ -265,9 +271,8 @@
265271 * Invalid cfg_space/offset/length combination in
266272 * cfg_read/cfg_write.
267273 */
268
- tb_ctl_WARN(ctl,
269
- "CFG_ERROR(%llx:%x): Invalid config space or offset\n",
270
- res->response_route, res->response_port);
274
+ tb_ctl_dbg(ctl, "%llx:%x: invalid config space or offset\n",
275
+ res->response_route, res->response_port);
271276 return;
272277 case TB_CFG_ERROR_NO_SUCH_PORT:
273278 /*
....@@ -281,6 +286,10 @@
281286 case TB_CFG_ERROR_LOOP:
282287 tb_ctl_WARN(ctl, "CFG_ERROR(%llx:%x): Route contains a loop\n",
283288 res->response_route, res->response_port);
289
+ return;
290
+ case TB_CFG_ERROR_LOCK:
291
+ tb_ctl_warn(ctl, "%llx:%x: downstream port is locked\n",
292
+ res->response_route, res->response_port);
284293 return;
285294 default:
286295 /* 5,6,7,9 and 11 are also valid error codes */
....@@ -387,7 +396,7 @@
387396
388397 static int tb_async_error(const struct ctl_pkg *pkg)
389398 {
390
- const struct cfg_error_pkg *error = (const struct cfg_error_pkg *)pkg;
399
+ const struct cfg_error_pkg *error = pkg->buffer;
391400
392401 if (pkg->frame.eof != TB_CFG_PKG_ERROR)
393402 return false;
....@@ -452,7 +461,7 @@
452461 "RX: checksum mismatch, dropping packet\n");
453462 goto rx;
454463 }
455
- /* Fall through */
464
+ fallthrough;
456465 case TB_CFG_PKG_ICM_EVENT:
457466 if (tb_ctl_handle_event(pkg->ctl, frame->eof, pkg, frame->size))
458467 goto rx;
....@@ -631,7 +640,7 @@
631640 ctl->rx_packets[i]->frame.callback = tb_ctl_rx_callback;
632641 }
633642
634
- tb_ctl_info(ctl, "control channel created\n");
643
+ tb_ctl_dbg(ctl, "control channel created\n");
635644 return ctl;
636645 err:
637646 tb_ctl_free(ctl);
....@@ -662,8 +671,7 @@
662671 tb_ctl_pkg_free(ctl->rx_packets[i]);
663672
664673
665
- if (ctl->frame_pool)
666
- dma_pool_destroy(ctl->frame_pool);
674
+ dma_pool_destroy(ctl->frame_pool);
667675 kfree(ctl);
668676 }
669677
....@@ -673,7 +681,7 @@
673681 void tb_ctl_start(struct tb_ctl *ctl)
674682 {
675683 int i;
676
- tb_ctl_info(ctl, "control channel starting...\n");
684
+ tb_ctl_dbg(ctl, "control channel starting...\n");
677685 tb_ring_start(ctl->tx); /* is used to ack hotplug packets, start first */
678686 tb_ring_start(ctl->rx);
679687 for (i = 0; i < TB_CTL_RX_PKG_COUNT; i++)
....@@ -702,25 +710,32 @@
702710 if (!list_empty(&ctl->request_queue))
703711 tb_ctl_WARN(ctl, "dangling request in request_queue\n");
704712 INIT_LIST_HEAD(&ctl->request_queue);
705
- tb_ctl_info(ctl, "control channel stopped\n");
713
+ tb_ctl_dbg(ctl, "control channel stopped\n");
706714 }
707715
708716 /* public interface, commands */
709717
710718 /**
711
- * tb_cfg_error() - send error packet
719
+ * tb_cfg_ack_plug() - Ack hot plug/unplug event
720
+ * @ctl: Control channel to use
721
+ * @route: Router that originated the event
722
+ * @port: Port where the hot plug/unplug happened
723
+ * @unplug: Ack hot plug or unplug
712724 *
713
- * Return: Returns 0 on success or an error code on failure.
725
+ * Call this as response for hot plug/unplug event to ack it.
726
+ * Returns %0 on success or an error code on failure.
714727 */
715
-int tb_cfg_error(struct tb_ctl *ctl, u64 route, u32 port,
716
- enum tb_cfg_error error)
728
+int tb_cfg_ack_plug(struct tb_ctl *ctl, u64 route, u32 port, bool unplug)
717729 {
718730 struct cfg_error_pkg pkg = {
719731 .header = tb_cfg_make_header(route),
720732 .port = port,
721
- .error = error,
733
+ .error = TB_CFG_ERROR_ACK_PLUG_EVENT,
734
+ .pg = unplug ? TB_CFG_ERROR_PG_HOT_UNPLUG
735
+ : TB_CFG_ERROR_PG_HOT_PLUG,
722736 };
723
- tb_ctl_info(ctl, "resetting error on %llx:%x.\n", route, port);
737
+ tb_ctl_dbg(ctl, "acking hot %splug event on %llx:%x\n",
738
+ unplug ? "un" : "", route, port);
724739 return tb_ctl_tx(ctl, &pkg, sizeof(pkg), TB_CFG_PKG_ERROR);
725740 }
726741
....@@ -930,6 +945,26 @@
930945 return res;
931946 }
932947
948
+static int tb_cfg_get_error(struct tb_ctl *ctl, enum tb_cfg_space space,
949
+ const struct tb_cfg_result *res)
950
+{
951
+ /*
952
+ * For unimplemented ports access to port config space may return
953
+ * TB_CFG_ERROR_INVALID_CONFIG_SPACE (alternatively their type is
954
+ * set to TB_TYPE_INACTIVE). In the former case return -ENODEV so
955
+ * that the caller can mark the port as disabled.
956
+ */
957
+ if (space == TB_CFG_PORT &&
958
+ res->tb_error == TB_CFG_ERROR_INVALID_CONFIG_SPACE)
959
+ return -ENODEV;
960
+
961
+ tb_cfg_print_error(ctl, res);
962
+
963
+ if (res->tb_error == TB_CFG_ERROR_LOCK)
964
+ return -EACCES;
965
+ return -EIO;
966
+}
967
+
933968 int tb_cfg_read(struct tb_ctl *ctl, void *buffer, u64 route, u32 port,
934969 enum tb_cfg_space space, u32 offset, u32 length)
935970 {
....@@ -942,12 +977,11 @@
942977
943978 case 1:
944979 /* Thunderbolt error, tb_error holds the actual number */
945
- tb_cfg_print_error(ctl, &res);
946
- return -EIO;
980
+ return tb_cfg_get_error(ctl, space, &res);
947981
948982 case -ETIMEDOUT:
949
- tb_ctl_warn(ctl, "timeout reading config space %u from %#x\n",
950
- space, offset);
983
+ tb_ctl_warn(ctl, "%llx: timeout reading config space %u from %#x\n",
984
+ route, space, offset);
951985 break;
952986
953987 default:
....@@ -969,12 +1003,11 @@
9691003
9701004 case 1:
9711005 /* Thunderbolt error, tb_error holds the actual number */
972
- tb_cfg_print_error(ctl, &res);
973
- return -EIO;
1006
+ return tb_cfg_get_error(ctl, space, &res);
9741007
9751008 case -ETIMEDOUT:
976
- tb_ctl_warn(ctl, "timeout writing config space %u to %#x\n",
977
- space, offset);
1009
+ tb_ctl_warn(ctl, "%llx: timeout writing config space %u to %#x\n",
1010
+ route, space, offset);
9781011 break;
9791012
9801013 default: