| .. | .. |
|---|
| 1 | | -/* SPDX-License-Identifier: GPL-2.0 */ |
|---|
| 2 | 1 | /* |
|---|
| 3 | 2 | * DHD debugability Linux os layer |
|---|
| 4 | 3 | * |
|---|
| 5 | | - * Copyright (C) 1999-2019, Broadcom Corporation |
|---|
| 6 | | - * |
|---|
| 4 | + * <<Broadcom-WL-IPTag/Open:>> |
|---|
| 5 | + * |
|---|
| 6 | + * Portions of this code are copyright (c) 2022 Cypress Semiconductor Corporation |
|---|
| 7 | + * |
|---|
| 8 | + * Copyright (C) 1999-2017, Broadcom Corporation |
|---|
| 9 | + * |
|---|
| 7 | 10 | * Unless you and Broadcom execute a separate written software license |
|---|
| 8 | 11 | * agreement governing use of this software, this software is licensed to you |
|---|
| 9 | 12 | * under the terms of the GNU General Public License version 2 (the "GPL"), |
|---|
| 10 | 13 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the |
|---|
| 11 | 14 | * following added to such license: |
|---|
| 12 | | - * |
|---|
| 15 | + * |
|---|
| 13 | 16 | * As a special exception, the copyright holders of this software give you |
|---|
| 14 | 17 | * permission to link this software with independent modules, and to copy and |
|---|
| 15 | 18 | * distribute the resulting executable under terms of your choice, provided that |
|---|
| .. | .. |
|---|
| 17 | 20 | * the license of that module. An independent module is a module which is not |
|---|
| 18 | 21 | * derived from this software. The special exception does not apply to any |
|---|
| 19 | 22 | * modifications of the software. |
|---|
| 20 | | - * |
|---|
| 23 | + * |
|---|
| 21 | 24 | * Notwithstanding the above, under no circumstances may you combine this |
|---|
| 22 | 25 | * software in any way with any other Broadcom software provided under a license |
|---|
| 23 | 26 | * other than the GPL, without Broadcom's express prior written consent. |
|---|
| 24 | 27 | * |
|---|
| 25 | | - * $Id: dhd_debug_linux.c 554441 2015-05-05 18:45:58Z $ |
|---|
| 28 | + * $Id: dhd_debug_linux.c 696754 2017-04-28 00:21:58Z $ |
|---|
| 26 | 29 | */ |
|---|
| 27 | 30 | |
|---|
| 28 | 31 | #include <typedefs.h> |
|---|
| 29 | 32 | #include <osl.h> |
|---|
| 30 | 33 | #include <bcmutils.h> |
|---|
| 31 | 34 | #include <bcmendian.h> |
|---|
| 32 | | -#ifndef CUSTOMER_IPCAM |
|---|
| 33 | | -#include <bcmpcie.h> |
|---|
| 34 | | -#endif |
|---|
| 35 | 35 | #include <dngl_stats.h> |
|---|
| 36 | 36 | #include <dhd.h> |
|---|
| 37 | 37 | #include <dhd_dbg.h> |
|---|
| .. | .. |
|---|
| 61 | 61 | {1, WIFI_EVENT_DRIVER_EAPOL_FRAME_RECEIVED, "DRIVER EAPOL RX"}, |
|---|
| 62 | 62 | {2, WIFI_EVENT_DRIVER_SCAN_REQUESTED, "SCAN_REQUESTED"}, |
|---|
| 63 | 63 | {2, WIFI_EVENT_DRIVER_SCAN_COMPLETE, "SCAN COMPELETE"}, |
|---|
| 64 | | - {3, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND, "SCAN RESULT FOUND"} |
|---|
| 64 | + {3, WIFI_EVENT_DRIVER_SCAN_RESULT_FOUND, "SCAN RESULT FOUND"}, |
|---|
| 65 | + {2, WIFI_EVENT_DRIVER_PNO_ADD, "PNO ADD"}, |
|---|
| 66 | + {2, WIFI_EVENT_DRIVER_PNO_REMOVE, "PNO REMOVE"}, |
|---|
| 67 | + {2, WIFI_EVENT_DRIVER_PNO_NETWORK_FOUND, "PNO NETWORK FOUND"}, |
|---|
| 68 | + {2, WIFI_EVENT_DRIVER_PNO_SCAN_REQUESTED, "PNO SCAN_REQUESTED"}, |
|---|
| 69 | + {1, WIFI_EVENT_DRIVER_PNO_SCAN_RESULT_FOUND, "PNO SCAN RESULT FOUND"}, |
|---|
| 70 | + {1, WIFI_EVENT_DRIVER_PNO_SCAN_COMPLETE, "PNO SCAN COMPELETE"} |
|---|
| 65 | 71 | }; |
|---|
| 66 | 72 | |
|---|
| 67 | 73 | static void |
|---|
| .. | .. |
|---|
| 72 | 78 | dbg_ring_send_sub_t ring_sub_send; |
|---|
| 73 | 79 | ndev = dhd_linux_get_primary_netdev(dhdp); |
|---|
| 74 | 80 | if (!ndev) |
|---|
| 81 | + return; |
|---|
| 82 | + if (!VALID_RING(ring_id)) |
|---|
| 75 | 83 | return; |
|---|
| 76 | 84 | if (ring_send_sub_cb[ring_id]) { |
|---|
| 77 | 85 | ring_sub_send = ring_send_sub_cb[ring_id]; |
|---|
| .. | .. |
|---|
| 95 | 103 | dbg_ring_poll_worker(struct work_struct *work) |
|---|
| 96 | 104 | { |
|---|
| 97 | 105 | struct delayed_work *d_work = to_delayed_work(work); |
|---|
| 106 | + bool sched = TRUE; |
|---|
| 107 | + dhd_dbg_ring_t *ring; |
|---|
| 108 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
|---|
| 109 | +#pragma GCC diagnostic push |
|---|
| 110 | +#pragma GCC diagnostic ignored "-Wcast-qual" |
|---|
| 111 | +#endif // endif |
|---|
| 98 | 112 | linux_dbgring_info_t *ring_info = |
|---|
| 99 | 113 | container_of(d_work, linux_dbgring_info_t, work); |
|---|
| 114 | +#if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) |
|---|
| 115 | +#pragma GCC diagnostic pop |
|---|
| 116 | +#endif // endif |
|---|
| 100 | 117 | dhd_pub_t *dhdp = ring_info->dhdp; |
|---|
| 101 | 118 | int ringid = ring_info->ring_id; |
|---|
| 102 | 119 | dhd_dbg_ring_status_t ring_status; |
|---|
| 103 | 120 | void *buf; |
|---|
| 104 | 121 | dhd_dbg_ring_entry_t *hdr; |
|---|
| 105 | 122 | uint32 buflen, rlen; |
|---|
| 123 | + unsigned long flags; |
|---|
| 106 | 124 | |
|---|
| 125 | + ring = &dhdp->dbg->dbg_rings[ringid]; |
|---|
| 126 | + DHD_DBG_RING_LOCK(ring->lock, flags); |
|---|
| 107 | 127 | dhd_dbg_get_ring_status(dhdp, ringid, &ring_status); |
|---|
| 108 | | - if (ring_status.written_bytes > ring_status.read_bytes) |
|---|
| 109 | | - buflen = ring_status.written_bytes - ring_status.read_bytes; |
|---|
| 110 | | - else if (ring_status.written_bytes < ring_status.read_bytes) |
|---|
| 111 | | - buflen = 0xFFFFFFFF + ring_status.written_bytes - |
|---|
| 112 | | - ring_status.read_bytes; |
|---|
| 113 | | - else |
|---|
| 128 | + |
|---|
| 129 | + if (ring->wp > ring->rp) { |
|---|
| 130 | + buflen = ring->wp - ring->rp; |
|---|
| 131 | + } else if (ring->wp < ring->rp) { |
|---|
| 132 | + buflen = ring->ring_size - ring->rp + ring->wp; |
|---|
| 133 | + } else { |
|---|
| 114 | 134 | goto exit; |
|---|
| 115 | | - buf = MALLOC(dhdp->osh, buflen); |
|---|
| 135 | + } |
|---|
| 136 | + |
|---|
| 137 | + if (buflen > ring->ring_size) { |
|---|
| 138 | + goto exit; |
|---|
| 139 | + } |
|---|
| 140 | + |
|---|
| 141 | + buf = MALLOCZ(dhdp->osh, buflen); |
|---|
| 116 | 142 | if (!buf) { |
|---|
| 117 | 143 | DHD_ERROR(("%s failed to allocate read buf\n", __FUNCTION__)); |
|---|
| 118 | | - return; |
|---|
| 144 | + sched = FALSE; |
|---|
| 145 | + goto exit; |
|---|
| 119 | 146 | } |
|---|
| 120 | | - rlen = dhd_dbg_ring_pull(dhdp, ringid, buf, buflen); |
|---|
| 147 | + |
|---|
| 148 | + rlen = dhd_dbg_pull_from_ring(dhdp, ringid, buf, buflen); |
|---|
| 149 | + |
|---|
| 150 | + if (!ring->sched_pull) { |
|---|
| 151 | + ring->sched_pull = TRUE; |
|---|
| 152 | + } |
|---|
| 153 | + |
|---|
| 121 | 154 | hdr = (dhd_dbg_ring_entry_t *)buf; |
|---|
| 122 | 155 | while (rlen > 0) { |
|---|
| 123 | 156 | ring_status.read_bytes += ENTRY_LENGTH(hdr); |
|---|
| 124 | 157 | /* offset fw ts to host ts */ |
|---|
| 125 | 158 | hdr->timestamp += ring_info->tsoffset; |
|---|
| 126 | 159 | debug_data_send(dhdp, ringid, hdr, ENTRY_LENGTH(hdr), |
|---|
| 127 | | - ring_status); |
|---|
| 160 | + ring_status); |
|---|
| 128 | 161 | rlen -= ENTRY_LENGTH(hdr); |
|---|
| 129 | | - hdr = (dhd_dbg_ring_entry_t *)((void *)hdr + ENTRY_LENGTH(hdr)); |
|---|
| 162 | + hdr = (dhd_dbg_ring_entry_t *)((char *)hdr + ENTRY_LENGTH(hdr)); |
|---|
| 130 | 163 | } |
|---|
| 131 | 164 | MFREE(dhdp->osh, buf, buflen); |
|---|
| 132 | 165 | |
|---|
| 133 | | - if (!ring_info->interval) |
|---|
| 134 | | - return; |
|---|
| 135 | | - dhd_dbg_get_ring_status(dhdp, ring_info->ring_id, &ring_status); |
|---|
| 136 | | - |
|---|
| 137 | 166 | exit: |
|---|
| 138 | | - if (ring_info->interval) { |
|---|
| 167 | + if (sched) { |
|---|
| 139 | 168 | /* retrigger the work at same interval */ |
|---|
| 140 | | - if (ring_status.written_bytes == ring_status.read_bytes) |
|---|
| 169 | + if ((ring_status.written_bytes == ring_status.read_bytes) && |
|---|
| 170 | + (ring_info->interval)) { |
|---|
| 141 | 171 | schedule_delayed_work(d_work, ring_info->interval); |
|---|
| 142 | | - else |
|---|
| 143 | | - schedule_delayed_work(d_work, 0); |
|---|
| 172 | + } |
|---|
| 144 | 173 | } |
|---|
| 174 | + |
|---|
| 175 | + DHD_DBG_RING_UNLOCK(ring->lock, flags); |
|---|
| 145 | 176 | |
|---|
| 146 | 177 | return; |
|---|
| 147 | 178 | } |
|---|
| .. | .. |
|---|
| 173 | 204 | int ret = BCME_OK; |
|---|
| 174 | 205 | int ring_id; |
|---|
| 175 | 206 | linux_dbgring_info_t *os_priv, *ring_info; |
|---|
| 176 | | - uint32 ms; |
|---|
| 177 | 207 | |
|---|
| 178 | 208 | ring_id = dhd_dbg_find_ring_id(dhdp, ring_name); |
|---|
| 179 | 209 | if (!VALID_RING(ring_id)) |
|---|
| .. | .. |
|---|
| 194 | 224 | return BCME_ERROR; |
|---|
| 195 | 225 | ring_info = &os_priv[ring_id]; |
|---|
| 196 | 226 | ring_info->log_level = log_level; |
|---|
| 197 | | - if (ring_id == FW_VERBOSE_RING_ID || ring_id == FW_EVENT_RING_ID) { |
|---|
| 198 | | - ring_info->tsoffset = local_clock(); |
|---|
| 199 | | - if (dhd_wl_ioctl_get_intiovar(dhdp, "rte_timesync", &ms, WLC_GET_VAR, |
|---|
| 200 | | - FALSE, 0)) |
|---|
| 201 | | - DHD_ERROR(("%s rte_timesync failed\n", __FUNCTION__)); |
|---|
| 202 | | - do_div(ring_info->tsoffset, 1000000); |
|---|
| 203 | | - ring_info->tsoffset -= ms; |
|---|
| 204 | | - } |
|---|
| 227 | + |
|---|
| 205 | 228 | if (time_intval == 0 || log_level == 0) { |
|---|
| 206 | 229 | ring_info->interval = 0; |
|---|
| 207 | 230 | cancel_delayed_work_sync(&ring_info->work); |
|---|
| 208 | 231 | } else { |
|---|
| 209 | 232 | ring_info->interval = msecs_to_jiffies(time_intval * MSEC_PER_SEC); |
|---|
| 233 | + cancel_delayed_work_sync(&ring_info->work); |
|---|
| 210 | 234 | schedule_delayed_work(&ring_info->work, ring_info->interval); |
|---|
| 211 | 235 | } |
|---|
| 212 | 236 | |
|---|
| .. | .. |
|---|
| 257 | 281 | if (!os_priv) |
|---|
| 258 | 282 | return BCME_ERROR; |
|---|
| 259 | 283 | |
|---|
| 260 | | - max_log_level = MAX(os_priv[FW_VERBOSE_RING_ID].log_level, |
|---|
| 261 | | - os_priv[FW_EVENT_RING_ID].log_level); |
|---|
| 284 | + max_log_level = os_priv[FW_VERBOSE_RING_ID].log_level; |
|---|
| 285 | + |
|---|
| 262 | 286 | if (max_log_level == SUPPRESS_LOG_LEVEL) { |
|---|
| 263 | 287 | /* suppress the logging in FW not to wake up host while device in suspend mode */ |
|---|
| 264 | 288 | ret = dhd_iovar(dhdp, 0, "logtrace", (char *)&enable, sizeof(enable), NULL, 0, |
|---|
| 265 | | - TRUE); |
|---|
| 289 | + TRUE); |
|---|
| 266 | 290 | if (ret < 0 && (ret != BCME_UNSUPPORTED)) { |
|---|
| 267 | 291 | DHD_ERROR(("logtrace is failed : %d\n", ret)); |
|---|
| 268 | 292 | } |
|---|
| .. | .. |
|---|
| 305 | 329 | { |
|---|
| 306 | 330 | int ret = BCME_OK, i; |
|---|
| 307 | 331 | dhd_dbg_ring_entry_t msg_hdr; |
|---|
| 308 | | - log_conn_event_t event_data; |
|---|
| 332 | + log_conn_event_t *event_data = (log_conn_event_t *)data; |
|---|
| 309 | 333 | linux_dbgring_info_t *os_priv, *ring_info = NULL; |
|---|
| 310 | 334 | |
|---|
| 311 | 335 | if (!VALID_RING(ring_id)) |
|---|
| 312 | 336 | return BCME_UNSUPPORTED; |
|---|
| 313 | | - |
|---|
| 314 | 337 | os_priv = dhd_dbg_get_priv(dhdp); |
|---|
| 315 | | - if (!os_priv) |
|---|
| 316 | | - return BCME_UNSUPPORTED; |
|---|
| 317 | 338 | |
|---|
| 318 | | - ring_info = &os_priv[ring_id]; |
|---|
| 339 | + if (os_priv) { |
|---|
| 340 | + ring_info = &os_priv[ring_id]; |
|---|
| 341 | + } else |
|---|
| 342 | + return BCME_NORESOURCE; |
|---|
| 319 | 343 | |
|---|
| 320 | 344 | memset(&msg_hdr, 0, sizeof(dhd_dbg_ring_entry_t)); |
|---|
| 321 | 345 | |
|---|
| .. | .. |
|---|
| 325 | 349 | msg_hdr.flags |= DBG_RING_ENTRY_FLAGS_HAS_BINARY; |
|---|
| 326 | 350 | msg_hdr.timestamp = local_clock(); |
|---|
| 327 | 351 | /* convert to ms */ |
|---|
| 328 | | - do_div(msg_hdr.timestamp, 1000000); |
|---|
| 329 | | - msg_hdr.len = sizeof(event_data); |
|---|
| 330 | | - event_data.event = *((uint16 *)(data)); |
|---|
| 352 | + msg_hdr.timestamp = DIV_U64_BY_U32(msg_hdr.timestamp, NSEC_PER_MSEC); |
|---|
| 353 | + msg_hdr.len = data_len; |
|---|
| 331 | 354 | /* filter the event for higher log level with current log level */ |
|---|
| 332 | 355 | for (i = 0; i < ARRAYSIZE(dhd_event_map); i++) { |
|---|
| 333 | | - if ((dhd_event_map[i].tag == event_data.event) && |
|---|
| 356 | + if ((dhd_event_map[i].tag == event_data->event) && |
|---|
| 334 | 357 | dhd_event_map[i].log_level > ring_info->log_level) { |
|---|
| 335 | 358 | return ret; |
|---|
| 336 | 359 | } |
|---|
| 337 | 360 | } |
|---|
| 338 | 361 | } |
|---|
| 339 | | - ret = dhd_dbg_ring_push(dhdp, ring_id, &msg_hdr, &event_data); |
|---|
| 362 | + ret = dhd_dbg_push_to_ring(dhdp, ring_id, &msg_hdr, event_data); |
|---|
| 340 | 363 | if (ret) { |
|---|
| 341 | 364 | DHD_ERROR(("%s : failed to push data into the ring (%d) with ret(%d)\n", |
|---|
| 342 | 365 | __FUNCTION__, ring_id, ret)); |
|---|
| .. | .. |
|---|
| 345 | 368 | return ret; |
|---|
| 346 | 369 | } |
|---|
| 347 | 370 | |
|---|
| 371 | +#ifdef DBG_PKT_MON |
|---|
| 372 | +int |
|---|
| 373 | +dhd_os_dbg_attach_pkt_monitor(dhd_pub_t *dhdp) |
|---|
| 374 | +{ |
|---|
| 375 | + return dhd_dbg_attach_pkt_monitor(dhdp, dhd_os_dbg_monitor_tx_pkts, |
|---|
| 376 | + dhd_os_dbg_monitor_tx_status, dhd_os_dbg_monitor_rx_pkts); |
|---|
| 377 | +} |
|---|
| 378 | + |
|---|
| 379 | +int |
|---|
| 380 | +dhd_os_dbg_start_pkt_monitor(dhd_pub_t *dhdp) |
|---|
| 381 | +{ |
|---|
| 382 | + return dhd_dbg_start_pkt_monitor(dhdp); |
|---|
| 383 | +} |
|---|
| 384 | + |
|---|
| 385 | +int |
|---|
| 386 | +dhd_os_dbg_monitor_tx_pkts(dhd_pub_t *dhdp, void *pkt, uint32 pktid) |
|---|
| 387 | +{ |
|---|
| 388 | + return dhd_dbg_monitor_tx_pkts(dhdp, pkt, pktid); |
|---|
| 389 | +} |
|---|
| 390 | + |
|---|
| 391 | +int |
|---|
| 392 | +dhd_os_dbg_monitor_tx_status(dhd_pub_t *dhdp, void *pkt, uint32 pktid, |
|---|
| 393 | + uint16 status) |
|---|
| 394 | +{ |
|---|
| 395 | + return dhd_dbg_monitor_tx_status(dhdp, pkt, pktid, status); |
|---|
| 396 | +} |
|---|
| 397 | + |
|---|
| 398 | +int |
|---|
| 399 | +dhd_os_dbg_monitor_rx_pkts(dhd_pub_t *dhdp, void *pkt) |
|---|
| 400 | +{ |
|---|
| 401 | + return dhd_dbg_monitor_rx_pkts(dhdp, pkt); |
|---|
| 402 | +} |
|---|
| 403 | + |
|---|
| 404 | +int |
|---|
| 405 | +dhd_os_dbg_stop_pkt_monitor(dhd_pub_t *dhdp) |
|---|
| 406 | +{ |
|---|
| 407 | + return dhd_dbg_stop_pkt_monitor(dhdp); |
|---|
| 408 | +} |
|---|
| 409 | + |
|---|
| 410 | +int |
|---|
| 411 | +dhd_os_dbg_monitor_get_tx_pkts(dhd_pub_t *dhdp, void __user *user_buf, |
|---|
| 412 | + uint16 req_count, uint16 *resp_count) |
|---|
| 413 | +{ |
|---|
| 414 | + return dhd_dbg_monitor_get_tx_pkts(dhdp, user_buf, req_count, resp_count); |
|---|
| 415 | +} |
|---|
| 416 | + |
|---|
| 417 | +int |
|---|
| 418 | +dhd_os_dbg_monitor_get_rx_pkts(dhd_pub_t *dhdp, void __user *user_buf, |
|---|
| 419 | + uint16 req_count, uint16 *resp_count) |
|---|
| 420 | +{ |
|---|
| 421 | + return dhd_dbg_monitor_get_rx_pkts(dhdp, user_buf, req_count, resp_count); |
|---|
| 422 | +} |
|---|
| 423 | + |
|---|
| 424 | +int |
|---|
| 425 | +dhd_os_dbg_detach_pkt_monitor(dhd_pub_t *dhdp) |
|---|
| 426 | +{ |
|---|
| 427 | + return dhd_dbg_detach_pkt_monitor(dhdp); |
|---|
| 428 | +} |
|---|
| 429 | +#endif /* DBG_PKT_MON */ |
|---|
| 430 | + |
|---|
| 348 | 431 | int |
|---|
| 349 | 432 | dhd_os_dbg_get_feature(dhd_pub_t *dhdp, int32 *features) |
|---|
| 350 | 433 | { |
|---|
| 351 | 434 | int ret = BCME_OK; |
|---|
| 352 | 435 | *features = 0; |
|---|
| 436 | +#ifdef DEBUGABILITY |
|---|
| 353 | 437 | *features |= DBG_MEMORY_DUMP_SUPPORTED; |
|---|
| 354 | 438 | if (FW_SUPPORTED(dhdp, logtrace)) { |
|---|
| 355 | 439 | *features |= DBG_CONNECT_EVENT_SUPPORTED; |
|---|
| .. | .. |
|---|
| 358 | 442 | if (FW_SUPPORTED(dhdp, hchk)) { |
|---|
| 359 | 443 | *features |= DBG_HEALTH_CHECK_SUPPORTED; |
|---|
| 360 | 444 | } |
|---|
| 445 | +#ifdef DBG_PKT_MON |
|---|
| 446 | + if (FW_SUPPORTED(dhdp, d11status)) { |
|---|
| 447 | + *features |= DBG_PACKET_FATE_SUPPORTED; |
|---|
| 448 | + } |
|---|
| 449 | +#endif /* DBG_PKT_MON */ |
|---|
| 450 | +#endif /* DEBUGABILITY */ |
|---|
| 361 | 451 | return ret; |
|---|
| 362 | 452 | } |
|---|
| 363 | 453 | |
|---|
| .. | .. |
|---|
| 367 | 457 | linux_dbgring_info_t *ring_info; |
|---|
| 368 | 458 | |
|---|
| 369 | 459 | ring_info = &((linux_dbgring_info_t *)os_priv)[ring_id]; |
|---|
| 370 | | - if (ring_info->interval != 0) |
|---|
| 371 | | - schedule_delayed_work(&ring_info->work, 0); |
|---|
| 460 | + cancel_delayed_work(&ring_info->work); |
|---|
| 461 | + schedule_delayed_work(&ring_info->work, 0); |
|---|
| 372 | 462 | } |
|---|
| 373 | 463 | |
|---|
| 374 | 464 | int |
|---|
| .. | .. |
|---|
| 405 | 495 | int ring_id; |
|---|
| 406 | 496 | /* free os_dbg data */ |
|---|
| 407 | 497 | os_priv = dhd_dbg_get_priv(dhdp); |
|---|
| 498 | + if (!os_priv) |
|---|
| 499 | + return; |
|---|
| 408 | 500 | /* abort pending any job */ |
|---|
| 409 | 501 | for (ring_id = DEBUG_RING_ID_INVALID + 1; ring_id < DEBUG_RING_ID_MAX; ring_id++) { |
|---|
| 410 | 502 | ring_info = &os_priv[ring_id]; |
|---|