From patchwork Sun Jan 14 22:36:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bernard Metzler X-Patchwork-Id: 10162885 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 104D660390 for ; Sun, 14 Jan 2018 22:36:41 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id F09112887E for ; Sun, 14 Jan 2018 22:36:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E5337288F9; Sun, 14 Jan 2018 22:36:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D3F452887E for ; Sun, 14 Jan 2018 22:36:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752817AbeANWgg (ORCPT ); Sun, 14 Jan 2018 17:36:36 -0500 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:38786 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752995AbeANWge (ORCPT ); Sun, 14 Jan 2018 17:36:34 -0500 Received: from pps.filterd (m0098396.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.22/8.16.0.22) with SMTP id w0EMXwpd031192 for ; Sun, 14 Jan 2018 17:36:33 -0500 Received: from e06smtp13.uk.ibm.com (e06smtp13.uk.ibm.com [195.75.94.109]) by mx0a-001b2d01.pphosted.com with ESMTP id 2fg01g4447-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Sun, 14 Jan 2018 17:36:33 -0500 Received: from localhost by e06smtp13.uk.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Sun, 14 Jan 2018 22:36:31 -0000 Received: from b06cxnps3074.portsmouth.uk.ibm.com (9.149.109.194) by e06smtp13.uk.ibm.com (192.168.101.143) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Sun, 14 Jan 2018 22:36:29 -0000 Received: from d06av25.portsmouth.uk.ibm.com (d06av25.portsmouth.uk.ibm.com [9.149.105.61]) by b06cxnps3074.portsmouth.uk.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id w0EMaSaw56295528; Sun, 14 Jan 2018 22:36:28 GMT Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 290E411C050; Sun, 14 Jan 2018 22:30:15 +0000 (GMT) Received: from d06av25.portsmouth.uk.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0016311C04C; Sun, 14 Jan 2018 22:30:15 +0000 (GMT) Received: from zac27.zurich.ibm.com (unknown [9.4.233.128]) by d06av25.portsmouth.uk.ibm.com (Postfix) with ESMTP; Sun, 14 Jan 2018 22:30:14 +0000 (GMT) From: Bernard Metzler To: linux-rdma@vger.kernel.org Cc: Bernard Metzler Subject: [PATCH v3 12/13] SoftiWarp debugging code Date: Sun, 14 Jan 2018 17:36:02 -0500 X-Mailer: git-send-email 2.13.6 In-Reply-To: <20180114223603.19961-1-bmt@zurich.ibm.com> References: <20180114223603.19961-1-bmt@zurich.ibm.com> X-TM-AS-GCONF: 00 x-cbid: 18011422-0012-0000-0000-000005A3979C X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 18011422-0013-0000-0000-0000191F0366 Message-Id: <20180114223603.19961-13-bmt@zurich.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:, , definitions=2018-01-14_14:, , signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 malwarescore=0 suspectscore=1 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 impostorscore=0 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1709140000 definitions=main-1801140321 Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Signed-off-by: Bernard Metzler --- drivers/infiniband/sw/siw/siw_debug.c | 463 ++++++++++++++++++++++++++++++++++ drivers/infiniband/sw/siw/siw_debug.h | 87 +++++++ 2 files changed, 550 insertions(+) create mode 100644 drivers/infiniband/sw/siw/siw_debug.c create mode 100644 drivers/infiniband/sw/siw/siw_debug.h diff --git a/drivers/infiniband/sw/siw/siw_debug.c b/drivers/infiniband/sw/siw/siw_debug.c new file mode 100644 index 000000000000..7cad480ea7a6 --- /dev/null +++ b/drivers/infiniband/sw/siw/siw_debug.c @@ -0,0 +1,463 @@ +/* + * Software iWARP device driver + * + * Authors: Bernard Metzler + * Fredy Neeser + * + * Copyright (c) 2008-2017, IBM Corporation + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of IBM nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "siw.h" +#include "siw_cm.h" +#include "siw_obj.h" + +#define FDENTRY(f) (f->f_path.dentry) + +static struct dentry *siw_debugfs; + +static ssize_t siw_show_qps(struct file *f, char __user *buf, size_t space, + loff_t *ppos) +{ + struct siw_device *sdev = FDENTRY(f)->d_inode->i_private; + struct list_head *pos, *tmp; + char *kbuf = NULL; + int len = 0, n, num_qp; + + if (*ppos) + goto out; + + kbuf = kmalloc(space, GFP_KERNEL); + if (!kbuf) + goto out; + + num_qp = atomic_read(&sdev->num_qp); + if (!num_qp) + goto out; + + len = snprintf(kbuf, space, "%s: %d QPs\n", sdev->base_dev.name, + num_qp); + if (len > space) { + len = space; + goto out; + } + space -= len; + n = snprintf(kbuf + len, space, + "%-15s%-6s%-6s%-5s%-5s%-5s%-5s%-5s%-20s%s\n", + "QP-ID", "State", "Ref's", "SQ", "RQ", "IRQ", "ORQ", + "s/r", "Sock", "CEP"); + + if (n > space) { + len += space; + goto out; + } + len += n; + space -= n; + + list_for_each_safe(pos, tmp, &sdev->qp_list) { + struct siw_qp *qp = list_entry(pos, struct siw_qp, devq); + + n = snprintf(kbuf + len, space, + "%-15d%-6d%-6d%-5d%-5d%-5d%-5d%d/%-3d0x%-18p0x%-18p\n", + QP_ID(qp), + qp->attrs.state, + refcount_read(&qp->hdr.ref), + qp->attrs.sq_size, + qp->attrs.rq_size, + qp->attrs.irq_size, + qp->attrs.orq_size, + tx_wqe(qp) ? 1 : 0, + rx_wqe(qp) ? 1 : 0, + qp->attrs.llp_stream_handle, + qp->cep); + if (n < space) { + len += n; + space -= n; + } else { + len += space; + break; + } + } +out: + if (len) + len = simple_read_from_buffer(buf, len, ppos, kbuf, len); + + kfree(kbuf); + + return len; +}; + +static ssize_t siw_show_mrs(struct file *f, char __user *buf, size_t space, + loff_t *ppos) +{ + struct siw_device *sdev = FDENTRY(f)->d_inode->i_private; + struct list_head *pos, *tmp; + char *kbuf = NULL; + int len = 0, n, num_mr; + + if (*ppos) + goto out; + + kbuf = kmalloc(space, GFP_KERNEL); + if (!kbuf) + goto out; + + num_mr = atomic_read(&sdev->num_mr); + if (!num_mr) + goto out; + + len = snprintf(kbuf, space, "%s: %d MRs\n", sdev->base_dev.name, + num_mr); + if (len > space) { + len = space; + goto out; + } + space -= len; + + n = snprintf(kbuf + len, space, + "%-15s%-18s%-8s%-8s%-22s%-8s%-9s\n", + "MEM-ID", "PD", "STag", "Type", "size", "Ref's", "State"); + + if (n > space) { + len += space; + goto out; + } + len += n; + space -= n; + + list_for_each_safe(pos, tmp, &sdev->mr_list) { + struct siw_mr *mr = list_entry(pos, struct siw_mr, devq); + + n = snprintf(kbuf + len, space, + "%-15d%-18p0x%-8x%-8s0x%-20llx%-8d%-9s\n", + OBJ_ID(&mr->mem), mr->pd, mr->mem.hdr.id, + mr->mem_obj ? mr->mem.is_pbl ? "PBL":"UMEM":"KVA", + mr->mem.len, + refcount_read(&mr->mem.hdr.ref), + mr->mem.stag_valid ? "valid" : "invalid"); + if (n < space) { + len += n; + space -= n; + } else { + len += space; + break; + } + } +out: + if (len) + len = simple_read_from_buffer(buf, len, ppos, kbuf, len); + + kfree(kbuf); + + return len; +} + +static ssize_t siw_show_ceps(struct file *f, char __user *buf, size_t space, + loff_t *ppos) +{ + struct siw_device *sdev = FDENTRY(f)->d_inode->i_private; + struct list_head *pos, *tmp; + char *kbuf = NULL; + int len = 0, n, num_cep; + + if (*ppos) + goto out; + + kbuf = kmalloc(space, GFP_KERNEL); + if (!kbuf) + goto out; + + num_cep = atomic_read(&sdev->num_cep); + if (!num_cep) + goto out; + + len = snprintf(kbuf, space, "%s: %d CEPs\n", sdev->base_dev.name, + num_cep); + if (len > space) { + len = space; + goto out; + } + space -= len; + + n = snprintf(kbuf + len, space, + "%-20s%-6s%-6s%-9s%-5s%-3s%-4s%-21s%-9s\n", + "CEP", "State", "Ref's", "QP-ID", "LQ", "LC", "U", "Sock", + "CM-ID"); + + if (n > space) { + len += space; + goto out; + } + len += n; + space -= n; + + list_for_each_safe(pos, tmp, &sdev->cep_list) { + struct siw_cep *cep = list_entry(pos, struct siw_cep, devq); + + n = snprintf(kbuf + len, space, + "0x%-18p%-6d%-6d%-9d%-5s%-3s%-4d0x%-18p 0x%-16p\n", + cep, cep->state, + refcount_read(&cep->ref), + cep->qp ? QP_ID(cep->qp) : -1, + list_empty(&cep->listenq) ? "n" : "y", + cep->listen_cep ? "y" : "n", + cep->in_use, + cep->llp.sock, + cep->cm_id); + if (n < space) { + len += n; + space -= n; + } else { + len += space; + break; + } + } +out: + if (len) + len = simple_read_from_buffer(buf, len, ppos, kbuf, len); + + kfree(kbuf); + + return len; +} + +static ssize_t siw_show_stats(struct file *f, char __user *buf, size_t space, + loff_t *ppos) +{ + struct siw_device *sdev = FDENTRY(f)->d_inode->i_private; + char *kbuf = NULL; + int len = 0; + + if (*ppos) + goto out; + + kbuf = kmalloc(space, GFP_KERNEL); + if (!kbuf) + goto out; + + len = snprintf(kbuf, space, "Allocated SIW Objects:\n" + "Device %s (%s):\t" + "%s: %d, %s %d, %s: %d, %s: %d, %s: %d, %s: %d, %s: %d\n", + sdev->base_dev.name, + sdev->netdev->flags & IFF_UP ? "IFF_UP" : "IFF_DOWN", + "CXs", atomic_read(&sdev->num_ctx), + "PDs", atomic_read(&sdev->num_pd), + "QPs", atomic_read(&sdev->num_qp), + "CQs", atomic_read(&sdev->num_cq), + "SRQs", atomic_read(&sdev->num_srq), + "MRs", atomic_read(&sdev->num_mr), + "CEPs", atomic_read(&sdev->num_cep)); + if (len > space) + len = space; +out: + if (len) + len = simple_read_from_buffer(buf, len, ppos, kbuf, len); + + kfree(kbuf); + return len; +} + +static const struct file_operations siw_qp_debug_fops = { + .owner = THIS_MODULE, + .read = siw_show_qps +}; + +static const struct file_operations siw_mr_debug_fops = { + .owner = THIS_MODULE, + .read = siw_show_mrs +}; + +static const struct file_operations siw_cep_debug_fops = { + .owner = THIS_MODULE, + .read = siw_show_ceps +}; + +static const struct file_operations siw_stats_debug_fops = { + .owner = THIS_MODULE, + .read = siw_show_stats +}; + +void siw_debugfs_add_device(struct siw_device *sdev) +{ + struct dentry *entry; + + if (!siw_debugfs) + return; + + sdev->debugfs = debugfs_create_dir(sdev->base_dev.name, siw_debugfs); + if (sdev->debugfs) { + entry = debugfs_create_file("qp", 0400, sdev->debugfs, + (void *)sdev, &siw_qp_debug_fops); + if (!entry) + siw_dbg(sdev, "could not create 'qp' entry\n"); + + entry = debugfs_create_file("cep", 0400, sdev->debugfs, + (void *)sdev, &siw_cep_debug_fops); + if (!entry) + siw_dbg(sdev, "could not create 'cep' entry\n"); + + entry = debugfs_create_file("mr", 0400, sdev->debugfs, + (void *)sdev, &siw_mr_debug_fops); + if (!entry) + siw_dbg(sdev, "could not create 'qp' entry\n"); + + entry = debugfs_create_file("stats", 0400, sdev->debugfs, + (void *)sdev, + &siw_stats_debug_fops); + if (!entry) + siw_dbg(sdev, "could not create 'stats' entry\n"); + } +} + +void siw_debugfs_del_device(struct siw_device *sdev) +{ + debugfs_remove_recursive(sdev->debugfs); + sdev->debugfs = NULL; +} + +void siw_debug_init(void) +{ + siw_debugfs = debugfs_create_dir("siw", NULL); + + if (!siw_debugfs || siw_debugfs == ERR_PTR(-ENODEV)) { + pr_warn("SIW: could not init debugfs\n"); + siw_debugfs = NULL; + } +} + +void siw_debugfs_delete(void) +{ + debugfs_remove_recursive(siw_debugfs); + siw_debugfs = NULL; +} + +void siw_print_hdr(union iwarp_hdr *hdr, int qp_id, char *msg) +{ + enum rdma_opcode op = __rdmap_opcode(&hdr->ctrl); + u16 mpa_len = be16_to_cpu(hdr->ctrl.mpa_len); + + switch (op) { + + case RDMAP_RDMA_WRITE: + pr_info("siw: [QP %d]: %s(WRITE, DDP len %d): %08x %016llx\n", + qp_id, msg, ddp_data_len(op, mpa_len), + hdr->rwrite.sink_stag, hdr->rwrite.sink_to); + break; + + case RDMAP_RDMA_READ_REQ: + pr_info("siw: [QP %d]: %s(RREQ, DDP len %d): %08x %08x %08x %08x %016llx %08x %08x %016llx\n", + qp_id, msg, + ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->rreq.ddp_qn), + be32_to_cpu(hdr->rreq.ddp_msn), + be32_to_cpu(hdr->rreq.ddp_mo), + be32_to_cpu(hdr->rreq.sink_stag), + be64_to_cpu(hdr->rreq.sink_to), + be32_to_cpu(hdr->rreq.read_size), + be32_to_cpu(hdr->rreq.source_stag), + be64_to_cpu(hdr->rreq.source_to)); + + break; + + case RDMAP_RDMA_READ_RESP: + pr_info("siw: [QP %d]: %s(RRESP, DDP len %d): %08x %016llx\n", + qp_id, msg, ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->rresp.sink_stag), + be64_to_cpu(hdr->rresp.sink_to)); + break; + + case RDMAP_SEND: + pr_info("siw: [QP %d]: %s(SEND, DDP len %d): %08x %08x %08x\n", + qp_id, msg, ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->send.ddp_qn), + be32_to_cpu(hdr->send.ddp_msn), + be32_to_cpu(hdr->send.ddp_mo)); + break; + + case RDMAP_SEND_INVAL: + pr_info("siw: [QP %d]: %s(S_INV, DDP len %d): %08x %08x %08x %08x\n", + qp_id, msg, ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->send_inv.inval_stag), + be32_to_cpu(hdr->send_inv.ddp_qn), + be32_to_cpu(hdr->send_inv.ddp_msn), + be32_to_cpu(hdr->send_inv.ddp_mo)); + break; + + case RDMAP_SEND_SE: + pr_info("siw: [QP %d]: %s(S_SE, DDP len %d): %08x %08x %08x\n", + qp_id, msg, ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->send.ddp_qn), + be32_to_cpu(hdr->send.ddp_msn), + be32_to_cpu(hdr->send.ddp_mo)); + break; + + case RDMAP_SEND_SE_INVAL: + pr_info("siw: [QP %d]: %s(S_SE_INV, DDP len %d): %08x %08x %08x %08x\n", + qp_id, msg, ddp_data_len(op, mpa_len), + be32_to_cpu(hdr->send_inv.inval_stag), + be32_to_cpu(hdr->send_inv.ddp_qn), + be32_to_cpu(hdr->send_inv.ddp_msn), + be32_to_cpu(hdr->send_inv.ddp_mo)); + break; + + case RDMAP_TERMINATE: + pr_info("siw: [QP %d]: %s(TERM, DDP len %d):\n", qp_id, msg, + ddp_data_len(op, mpa_len)); + break; + + default: + pr_info("siw: [QP %d]: %s (undefined opcode %d)", qp_id, msg, + op); + break; + } +} + +char ib_qp_state_to_string[IB_QPS_ERR+1][sizeof "RESET"] = { + [IB_QPS_RESET] = "RESET", + [IB_QPS_INIT] = "INIT", + [IB_QPS_RTR] = "RTR", + [IB_QPS_RTS] = "RTS", + [IB_QPS_SQD] = "SQD", + [IB_QPS_SQE] = "SQE", + [IB_QPS_ERR] = "ERR" +}; diff --git a/drivers/infiniband/sw/siw/siw_debug.h b/drivers/infiniband/sw/siw/siw_debug.h new file mode 100644 index 000000000000..b7804e826e67 --- /dev/null +++ b/drivers/infiniband/sw/siw/siw_debug.h @@ -0,0 +1,87 @@ +/* + * Software iWARP device driver + * + * Authors: Fredy Neeser + * Bernard Metzler + * + * Copyright (c) 2008-2017, IBM Corporation + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of IBM nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +#ifndef _SIW_DEBUG_H +#define _SIW_DEBUG_H + +#include +#include /* in_interrupt() */ + +struct siw_device; +struct siw_iwarp_rx; +union iwarp_hdr; + +extern void siw_debug_init(void); +extern void siw_debugfs_add_device(struct siw_device *dev); +extern void siw_debugfs_del_device(struct siw_device *dev); +extern void siw_debugfs_delete(void); + +extern void siw_print_hdr(union iwarp_hdr *hdr, int id, char *msg); +extern void siw_print_qp_attr_mask(enum ib_qp_attr_mask mask, char *msg); +extern char ib_qp_state_to_string[IB_QPS_ERR+1][sizeof "RESET"]; + +#ifndef refcount_read +#define refcount_read(x) atomic_read(x.refcount.refs) +#endif + +#define siw_dbg(ddev, fmt, ...) \ + dev_dbg(&(ddev)->base_dev.dev, "cpu%2d %s: " fmt, smp_processor_id(),\ + __func__, ##__VA_ARGS__) + +#define siw_dbg_qp(qp, fmt, ...) \ + siw_dbg(qp->hdr.sdev, "[QP %d]: " fmt, QP_ID(qp), ##__VA_ARGS__) + +#define siw_dbg_cep(cep, fmt, ...) \ + siw_dbg(cep->sdev, "[CEP 0x%p]: " fmt, cep, ##__VA_ARGS__) + +#define siw_dbg_obj(obj, fmt, ...) \ + siw_dbg(obj->hdr.sdev, "[OBJ ID %d]: " fmt, obj->hdr.id, ##__VA_ARGS__) + +#ifdef DEBUG + +#define siw_dprint_hdr(h, i, m) siw_print_hdr(h, i, m) + +#else + +#define dprint(dbgcat, fmt, args...) do { } while (0) +#define siw_dprint_hdr(h, i, m) do { } while (0) + +#endif + +#endif