1219820Sjeff/* 2219820Sjeff * Copyright (c) 2005 Topspin Communications. All rights reserved. 3219820Sjeff * 4219820Sjeff * This software is available to you under a choice of one of two 5219820Sjeff * licenses. You may choose to be licensed under the terms of the GNU 6219820Sjeff * General Public License (GPL) Version 2, available from the file 7219820Sjeff * COPYING in the main directory of this source tree, or the 8219820Sjeff * OpenIB.org BSD license below: 9219820Sjeff * 10219820Sjeff * Redistribution and use in source and binary forms, with or 11219820Sjeff * without modification, are permitted provided that the following 12219820Sjeff * conditions are met: 13219820Sjeff * 14219820Sjeff * - Redistributions of source code must retain the above 15219820Sjeff * copyright notice, this list of conditions and the following 16219820Sjeff * disclaimer. 17219820Sjeff * 18219820Sjeff * - Redistributions in binary form must reproduce the above 19219820Sjeff * copyright notice, this list of conditions and the following 20219820Sjeff * disclaimer in the documentation and/or other materials 21219820Sjeff * provided with the distribution. 22219820Sjeff * 23219820Sjeff * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24219820Sjeff * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25219820Sjeff * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26219820Sjeff * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27219820Sjeff * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28219820Sjeff * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29219820Sjeff * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30219820Sjeff * SOFTWARE. 31219820Sjeff */ 32331769Shselasky#define _GNU_SOURCE 33331769Shselasky#include <config.h> 34219820Sjeff 35219820Sjeff#include <stdio.h> 36331769Shselasky#include <infiniband/endian.h> 37331769Shselasky#include <getopt.h> 38331769Shselasky#include <string.h> 39219820Sjeff 40219820Sjeff#include <infiniband/verbs.h> 41219820Sjeff 42219820Sjeffstatic const char *event_name_str(enum ibv_event_type event_type) 43219820Sjeff{ 44219820Sjeff switch (event_type) { 45219820Sjeff case IBV_EVENT_DEVICE_FATAL: 46219820Sjeff return "IBV_EVENT_DEVICE_FATAL"; 47219820Sjeff case IBV_EVENT_PORT_ACTIVE: 48219820Sjeff return "IBV_EVENT_PORT_ACTIVE"; 49219820Sjeff case IBV_EVENT_PORT_ERR: 50219820Sjeff return "IBV_EVENT_PORT_ERR"; 51219820Sjeff case IBV_EVENT_LID_CHANGE: 52219820Sjeff return "IBV_EVENT_LID_CHANGE"; 53219820Sjeff case IBV_EVENT_PKEY_CHANGE: 54219820Sjeff return "IBV_EVENT_PKEY_CHANGE"; 55219820Sjeff case IBV_EVENT_SM_CHANGE: 56219820Sjeff return "IBV_EVENT_SM_CHANGE"; 57219820Sjeff case IBV_EVENT_CLIENT_REREGISTER: 58219820Sjeff return "IBV_EVENT_CLIENT_REREGISTER"; 59219820Sjeff case IBV_EVENT_GID_CHANGE: 60219820Sjeff return "IBV_EVENT_GID_CHANGE"; 61219820Sjeff 62219820Sjeff case IBV_EVENT_CQ_ERR: 63219820Sjeff case IBV_EVENT_QP_FATAL: 64219820Sjeff case IBV_EVENT_QP_REQ_ERR: 65219820Sjeff case IBV_EVENT_QP_ACCESS_ERR: 66219820Sjeff case IBV_EVENT_COMM_EST: 67219820Sjeff case IBV_EVENT_SQ_DRAINED: 68219820Sjeff case IBV_EVENT_PATH_MIG: 69219820Sjeff case IBV_EVENT_PATH_MIG_ERR: 70219820Sjeff case IBV_EVENT_SRQ_ERR: 71219820Sjeff case IBV_EVENT_SRQ_LIMIT_REACHED: 72219820Sjeff case IBV_EVENT_QP_LAST_WQE_REACHED: 73219820Sjeff default: 74219820Sjeff return "unexpected"; 75219820Sjeff } 76219820Sjeff} 77219820Sjeff 78331769Shselaskystatic void usage(const char *argv0) 79331769Shselasky{ 80331769Shselasky printf("Usage:\n"); 81331769Shselasky printf(" %s start an asyncwatch process\n", argv0); 82331769Shselasky printf("\n"); 83331769Shselasky printf("Options:\n"); 84331769Shselasky printf(" -d, --ib-dev=<dev> use IB device <dev> (default first device found)\n"); 85331769Shselasky printf(" -h, --help print a help text and exit\n"); 86331769Shselasky} 87331769Shselasky 88219820Sjeffint main(int argc, char *argv[]) 89219820Sjeff{ 90219820Sjeff struct ibv_device **dev_list; 91219820Sjeff struct ibv_context *context; 92219820Sjeff struct ibv_async_event event; 93331769Shselasky char *ib_devname = NULL; 94331769Shselasky int i = 0; 95219820Sjeff 96219820Sjeff /* Force line-buffering in case stdout is redirected */ 97219820Sjeff setvbuf(stdout, NULL, _IOLBF, 0); 98219820Sjeff 99331769Shselasky while (1) { 100331769Shselasky int ret = 1; 101331769Shselasky int c; 102331769Shselasky static struct option long_options[] = { 103331769Shselasky { .name = "ib-dev", .has_arg = 1, .val = 'd' }, 104331769Shselasky { .name = "help", .has_arg = 0, .val = 'h' }, 105331769Shselasky {} 106331769Shselasky }; 107331769Shselasky 108331769Shselasky c = getopt_long(argc, argv, "d:h", long_options, NULL); 109331769Shselasky if (c == -1) 110331769Shselasky break; 111331769Shselasky switch (c) { 112331769Shselasky case 'd': 113331769Shselasky ib_devname = strdupa(optarg); 114331769Shselasky break; 115331769Shselasky case 'h': 116331769Shselasky ret = 0; 117331769Shselasky SWITCH_FALLTHROUGH; 118331769Shselasky default: 119331769Shselasky usage(argv[0]); 120331769Shselasky return ret; 121331769Shselasky } 122331769Shselasky } 123219820Sjeff dev_list = ibv_get_device_list(NULL); 124219820Sjeff if (!dev_list) { 125219820Sjeff perror("Failed to get IB devices list"); 126219820Sjeff return 1; 127219820Sjeff } 128331769Shselasky if (ib_devname) { 129331769Shselasky for (; dev_list[i]; ++i) { 130331769Shselasky if (!strcmp(ibv_get_device_name(dev_list[i]), ib_devname)) 131331769Shselasky break; 132331769Shselasky } 133331769Shselasky } 134219820Sjeff 135331769Shselasky if (!dev_list[i]) { 136331769Shselasky fprintf(stderr, "IB device %s not found\n", 137331769Shselasky ib_devname ? ib_devname : ""); 138219820Sjeff return 1; 139219820Sjeff } 140219820Sjeff 141331769Shselasky context = ibv_open_device(dev_list[i]); 142219820Sjeff if (!context) { 143219820Sjeff fprintf(stderr, "Couldn't get context for %s\n", 144331769Shselasky ibv_get_device_name(dev_list[i])); 145219820Sjeff return 1; 146219820Sjeff } 147219820Sjeff 148219820Sjeff printf("%s: async event FD %d\n", 149331769Shselasky ibv_get_device_name(dev_list[i]), context->async_fd); 150219820Sjeff 151219820Sjeff while (1) { 152219820Sjeff if (ibv_get_async_event(context, &event)) 153219820Sjeff return 1; 154219820Sjeff 155219820Sjeff printf(" event_type %s (%d), port %d\n", 156219820Sjeff event_name_str(event.event_type), 157219820Sjeff event.event_type, event.element.port_num); 158219820Sjeff 159219820Sjeff ibv_ack_async_event(&event); 160219820Sjeff } 161219820Sjeff 162219820Sjeff return 0; 163219820Sjeff} 164