1/* 2 * Copyright (c) 2005 Topspin Communications. All rights reserved. 3 * Copyright (c) 2005 Intel Corporation. All rights reserved. 4 * 5 * This software is available to you under a choice of one of two 6 * licenses. You may choose to be licensed under the terms of the GNU 7 * General Public License (GPL) Version 2, available from the file 8 * COPYING in the main directory of this source tree, or the 9 * OpenIB.org BSD license below: 10 * 11 * Redistribution and use in source and binary forms, with or 12 * without modification, are permitted provided that the following 13 * conditions are met: 14 * 15 * - Redistributions of source code must retain the above 16 * copyright notice, this list of conditions and the following 17 * disclaimer. 18 * 19 * - Redistributions in binary form must reproduce the above 20 * copyright notice, this list of conditions and the following 21 * disclaimer in the documentation and/or other materials 22 * provided with the distribution. 23 * 24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 25 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 26 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 27 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 28 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 29 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 30 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 * SOFTWARE. 32 */ 33 34#include <linux/completion.h> 35#include <linux/init.h> 36#include <linux/fs.h> 37#include <linux/module.h> 38#include <linux/device.h> 39#include <linux/err.h> 40#include <linux/poll.h> 41#include <linux/sched.h> 42#include <linux/file.h> 43#include <linux/mount.h> 44#include <linux/cdev.h> 45#include <linux/idr.h> 46#include <linux/mutex.h> 47#include <linux/slab.h> 48 49#include <asm/uaccess.h> 50 51#include <rdma/ib_cm.h> 52#include <rdma/ib_user_cm.h> 53#include <rdma/ib_marshall.h> 54 55MODULE_AUTHOR("Libor Michalek"); 56MODULE_DESCRIPTION("InfiniBand userspace Connection Manager access"); 57MODULE_LICENSE("Dual BSD/GPL"); 58 59struct ib_ucm_device { 60 int devnum; 61 struct cdev cdev; 62 struct device dev; 63 struct ib_device *ib_dev; 64}; 65 66struct ib_ucm_file { 67 struct mutex file_mutex; 68 struct file *filp; 69 struct ib_ucm_device *device; 70 71 struct list_head ctxs; 72 struct list_head events; 73 wait_queue_head_t poll_wait; 74}; 75 76struct ib_ucm_context { 77 int id; 78 struct completion comp; 79 atomic_t ref; 80 int events_reported; 81 82 struct ib_ucm_file *file; 83 struct ib_cm_id *cm_id; 84 __u64 uid; 85 86 struct list_head events; /* list of pending events. */ 87 struct list_head file_list; /* member in file ctx list */ 88}; 89 90struct ib_ucm_event { 91 struct ib_ucm_context *ctx; 92 struct list_head file_list; /* member in file event list */ 93 struct list_head ctx_list; /* member in ctx event list */ 94 95 struct ib_cm_id *cm_id; 96 struct ib_ucm_event_resp resp; 97 void *data; 98 void *info; 99 int data_len; 100 int info_len; 101}; 102 103enum { 104 IB_UCM_MAJOR = 231, 105 IB_UCM_BASE_MINOR = 224, 106 IB_UCM_MAX_DEVICES = 32 107}; 108 109/* ib_cm and ib_user_cm modules share /sys/class/infiniband_cm */ 110extern struct class cm_class; 111 112#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR) 113 114static void ib_ucm_add_one(struct ib_device *device); 115static void ib_ucm_remove_one(struct ib_device *device); 116 117static struct ib_client ucm_client = { 118 .name = "ucm", 119 .add = ib_ucm_add_one, 120 .remove = ib_ucm_remove_one 121}; 122 123static DEFINE_MUTEX(ctx_id_mutex); 124static DEFINE_IDR(ctx_id_table); 125static DECLARE_BITMAP(dev_map, IB_UCM_MAX_DEVICES); 126 127static struct ib_ucm_context *ib_ucm_ctx_get(struct ib_ucm_file *file, int id) 128{ 129 struct ib_ucm_context *ctx; 130 131 mutex_lock(&ctx_id_mutex); 132 ctx = idr_find(&ctx_id_table, id); 133 if (!ctx) 134 ctx = ERR_PTR(-ENOENT); 135 else if (ctx->file != file) 136 ctx = ERR_PTR(-EINVAL); 137 else 138 atomic_inc(&ctx->ref); 139 mutex_unlock(&ctx_id_mutex); 140 141 return ctx; 142} 143 144static void ib_ucm_ctx_put(struct ib_ucm_context *ctx) 145{ 146 if (atomic_dec_and_test(&ctx->ref)) 147 complete(&ctx->comp); 148} 149 150static inline int ib_ucm_new_cm_id(int event) 151{ 152 return event == IB_CM_REQ_RECEIVED || event == IB_CM_SIDR_REQ_RECEIVED; 153} 154 155static void ib_ucm_cleanup_events(struct ib_ucm_context *ctx) 156{ 157 struct ib_ucm_event *uevent; 158 159 mutex_lock(&ctx->file->file_mutex); 160 list_del(&ctx->file_list); 161 while (!list_empty(&ctx->events)) { 162 163 uevent = list_entry(ctx->events.next, 164 struct ib_ucm_event, ctx_list); 165 list_del(&uevent->file_list); 166 list_del(&uevent->ctx_list); 167 mutex_unlock(&ctx->file->file_mutex); 168 169 /* clear incoming connections. */ 170 if (ib_ucm_new_cm_id(uevent->resp.event)) 171 ib_destroy_cm_id(uevent->cm_id); 172 173 kfree(uevent); 174 mutex_lock(&ctx->file->file_mutex); 175 } 176 mutex_unlock(&ctx->file->file_mutex); 177} 178 179static struct ib_ucm_context *ib_ucm_ctx_alloc(struct ib_ucm_file *file) 180{ 181 struct ib_ucm_context *ctx; 182 int result; 183 184 ctx = kzalloc(sizeof *ctx, GFP_KERNEL); 185 if (!ctx) 186 return NULL; 187 188 atomic_set(&ctx->ref, 1); 189 init_completion(&ctx->comp); 190 ctx->file = file; 191 INIT_LIST_HEAD(&ctx->events); 192 193 do { 194 result = idr_pre_get(&ctx_id_table, GFP_KERNEL); 195 if (!result) 196 goto error; 197 198 mutex_lock(&ctx_id_mutex); 199 result = idr_get_new(&ctx_id_table, ctx, &ctx->id); 200 mutex_unlock(&ctx_id_mutex); 201 } while (result == -EAGAIN); 202 203 if (result) 204 goto error; 205 206 list_add_tail(&ctx->file_list, &file->ctxs); 207 return ctx; 208 209error: 210 kfree(ctx); 211 return NULL; 212} 213 214static void ib_ucm_event_req_get(struct ib_ucm_req_event_resp *ureq, 215 struct ib_cm_req_event_param *kreq) 216{ 217 ureq->remote_ca_guid = kreq->remote_ca_guid; 218 ureq->remote_qkey = kreq->remote_qkey; 219 ureq->remote_qpn = kreq->remote_qpn; 220 ureq->qp_type = kreq->qp_type; 221 ureq->starting_psn = kreq->starting_psn; 222 ureq->responder_resources = kreq->responder_resources; 223 ureq->initiator_depth = kreq->initiator_depth; 224 ureq->local_cm_response_timeout = kreq->local_cm_response_timeout; 225 ureq->flow_control = kreq->flow_control; 226 ureq->remote_cm_response_timeout = kreq->remote_cm_response_timeout; 227 ureq->retry_count = kreq->retry_count; 228 ureq->rnr_retry_count = kreq->rnr_retry_count; 229 ureq->srq = kreq->srq; 230 ureq->port = kreq->port; 231 232 ib_copy_path_rec_to_user(&ureq->primary_path, kreq->primary_path); 233 if (kreq->alternate_path) 234 ib_copy_path_rec_to_user(&ureq->alternate_path, 235 kreq->alternate_path); 236} 237 238static void ib_ucm_event_rep_get(struct ib_ucm_rep_event_resp *urep, 239 struct ib_cm_rep_event_param *krep) 240{ 241 urep->remote_ca_guid = krep->remote_ca_guid; 242 urep->remote_qkey = krep->remote_qkey; 243 urep->remote_qpn = krep->remote_qpn; 244 urep->starting_psn = krep->starting_psn; 245 urep->responder_resources = krep->responder_resources; 246 urep->initiator_depth = krep->initiator_depth; 247 urep->target_ack_delay = krep->target_ack_delay; 248 urep->failover_accepted = krep->failover_accepted; 249 urep->flow_control = krep->flow_control; 250 urep->rnr_retry_count = krep->rnr_retry_count; 251 urep->srq = krep->srq; 252} 253 254static void ib_ucm_event_sidr_rep_get(struct ib_ucm_sidr_rep_event_resp *urep, 255 struct ib_cm_sidr_rep_event_param *krep) 256{ 257 urep->status = krep->status; 258 urep->qkey = krep->qkey; 259 urep->qpn = krep->qpn; 260}; 261 262static int ib_ucm_event_process(struct ib_cm_event *evt, 263 struct ib_ucm_event *uvt) 264{ 265 void *info = NULL; 266 267 switch (evt->event) { 268 case IB_CM_REQ_RECEIVED: 269 ib_ucm_event_req_get(&uvt->resp.u.req_resp, 270 &evt->param.req_rcvd); 271 uvt->data_len = IB_CM_REQ_PRIVATE_DATA_SIZE; 272 uvt->resp.present = IB_UCM_PRES_PRIMARY; 273 uvt->resp.present |= (evt->param.req_rcvd.alternate_path ? 274 IB_UCM_PRES_ALTERNATE : 0); 275 break; 276 case IB_CM_REP_RECEIVED: 277 ib_ucm_event_rep_get(&uvt->resp.u.rep_resp, 278 &evt->param.rep_rcvd); 279 uvt->data_len = IB_CM_REP_PRIVATE_DATA_SIZE; 280 break; 281 case IB_CM_RTU_RECEIVED: 282 uvt->data_len = IB_CM_RTU_PRIVATE_DATA_SIZE; 283 uvt->resp.u.send_status = evt->param.send_status; 284 break; 285 case IB_CM_DREQ_RECEIVED: 286 uvt->data_len = IB_CM_DREQ_PRIVATE_DATA_SIZE; 287 uvt->resp.u.send_status = evt->param.send_status; 288 break; 289 case IB_CM_DREP_RECEIVED: 290 uvt->data_len = IB_CM_DREP_PRIVATE_DATA_SIZE; 291 uvt->resp.u.send_status = evt->param.send_status; 292 break; 293 case IB_CM_MRA_RECEIVED: 294 uvt->resp.u.mra_resp.timeout = 295 evt->param.mra_rcvd.service_timeout; 296 uvt->data_len = IB_CM_MRA_PRIVATE_DATA_SIZE; 297 break; 298 case IB_CM_REJ_RECEIVED: 299 uvt->resp.u.rej_resp.reason = evt->param.rej_rcvd.reason; 300 uvt->data_len = IB_CM_REJ_PRIVATE_DATA_SIZE; 301 uvt->info_len = evt->param.rej_rcvd.ari_length; 302 info = evt->param.rej_rcvd.ari; 303 break; 304 case IB_CM_LAP_RECEIVED: 305 ib_copy_path_rec_to_user(&uvt->resp.u.lap_resp.path, 306 evt->param.lap_rcvd.alternate_path); 307 uvt->data_len = IB_CM_LAP_PRIVATE_DATA_SIZE; 308 uvt->resp.present = IB_UCM_PRES_ALTERNATE; 309 break; 310 case IB_CM_APR_RECEIVED: 311 uvt->resp.u.apr_resp.status = evt->param.apr_rcvd.ap_status; 312 uvt->data_len = IB_CM_APR_PRIVATE_DATA_SIZE; 313 uvt->info_len = evt->param.apr_rcvd.info_len; 314 info = evt->param.apr_rcvd.apr_info; 315 break; 316 case IB_CM_SIDR_REQ_RECEIVED: 317 uvt->resp.u.sidr_req_resp.pkey = 318 evt->param.sidr_req_rcvd.pkey; 319 uvt->resp.u.sidr_req_resp.port = 320 evt->param.sidr_req_rcvd.port; 321 uvt->data_len = IB_CM_SIDR_REQ_PRIVATE_DATA_SIZE; 322 break; 323 case IB_CM_SIDR_REP_RECEIVED: 324 ib_ucm_event_sidr_rep_get(&uvt->resp.u.sidr_rep_resp, 325 &evt->param.sidr_rep_rcvd); 326 uvt->data_len = IB_CM_SIDR_REP_PRIVATE_DATA_SIZE; 327 uvt->info_len = evt->param.sidr_rep_rcvd.info_len; 328 info = evt->param.sidr_rep_rcvd.info; 329 break; 330 default: 331 uvt->resp.u.send_status = evt->param.send_status; 332 break; 333 } 334 335 if (uvt->data_len) { 336 uvt->data = kmemdup(evt->private_data, uvt->data_len, GFP_KERNEL); 337 if (!uvt->data) 338 goto err1; 339 340 uvt->resp.present |= IB_UCM_PRES_DATA; 341 } 342 343 if (uvt->info_len) { 344 uvt->info = kmemdup(info, uvt->info_len, GFP_KERNEL); 345 if (!uvt->info) 346 goto err2; 347 348 uvt->resp.present |= IB_UCM_PRES_INFO; 349 } 350 return 0; 351 352err2: 353 kfree(uvt->data); 354err1: 355 return -ENOMEM; 356} 357 358static int ib_ucm_event_handler(struct ib_cm_id *cm_id, 359 struct ib_cm_event *event) 360{ 361 struct ib_ucm_event *uevent; 362 struct ib_ucm_context *ctx; 363 int result = 0; 364 365 ctx = cm_id->context; 366 367 uevent = kzalloc(sizeof *uevent, GFP_KERNEL); 368 if (!uevent) 369 goto err1; 370 371 uevent->ctx = ctx; 372 uevent->cm_id = cm_id; 373 uevent->resp.uid = ctx->uid; 374 uevent->resp.id = ctx->id; 375 uevent->resp.event = event->event; 376 377 result = ib_ucm_event_process(event, uevent); 378 if (result) 379 goto err2; 380 381 mutex_lock(&ctx->file->file_mutex); 382 list_add_tail(&uevent->file_list, &ctx->file->events); 383 list_add_tail(&uevent->ctx_list, &ctx->events); 384 wake_up_interruptible(&ctx->file->poll_wait); 385 mutex_unlock(&ctx->file->file_mutex); 386 return 0; 387 388err2: 389 kfree(uevent); 390err1: 391 /* Destroy new cm_id's */ 392 return ib_ucm_new_cm_id(event->event); 393} 394 395static ssize_t ib_ucm_event(struct ib_ucm_file *file, 396 const char __user *inbuf, 397 int in_len, int out_len) 398{ 399 struct ib_ucm_context *ctx; 400 struct ib_ucm_event_get cmd; 401 struct ib_ucm_event *uevent; 402 int result = 0; 403 DEFINE_WAIT(wait); 404 405 if (out_len < sizeof(struct ib_ucm_event_resp)) 406 return -ENOSPC; 407 408 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 409 return -EFAULT; 410 411 mutex_lock(&file->file_mutex); 412 while (list_empty(&file->events)) { 413 mutex_unlock(&file->file_mutex); 414 415 if (file->filp->f_flags & O_NONBLOCK) 416 return -EAGAIN; 417 418 if (wait_event_interruptible(file->poll_wait, 419 !list_empty(&file->events))) 420 return -ERESTARTSYS; 421 422 mutex_lock(&file->file_mutex); 423 } 424 425 uevent = list_entry(file->events.next, struct ib_ucm_event, file_list); 426 427 if (ib_ucm_new_cm_id(uevent->resp.event)) { 428 ctx = ib_ucm_ctx_alloc(file); 429 if (!ctx) { 430 result = -ENOMEM; 431 goto done; 432 } 433 434 ctx->cm_id = uevent->cm_id; 435 ctx->cm_id->context = ctx; 436 uevent->resp.id = ctx->id; 437 } 438 439 if (copy_to_user((void __user *)(unsigned long)cmd.response, 440 &uevent->resp, sizeof(uevent->resp))) { 441 result = -EFAULT; 442 goto done; 443 } 444 445 if (uevent->data) { 446 if (cmd.data_len < uevent->data_len) { 447 result = -ENOMEM; 448 goto done; 449 } 450 if (copy_to_user((void __user *)(unsigned long)cmd.data, 451 uevent->data, uevent->data_len)) { 452 result = -EFAULT; 453 goto done; 454 } 455 } 456 457 if (uevent->info) { 458 if (cmd.info_len < uevent->info_len) { 459 result = -ENOMEM; 460 goto done; 461 } 462 if (copy_to_user((void __user *)(unsigned long)cmd.info, 463 uevent->info, uevent->info_len)) { 464 result = -EFAULT; 465 goto done; 466 } 467 } 468 469 list_del(&uevent->file_list); 470 list_del(&uevent->ctx_list); 471 uevent->ctx->events_reported++; 472 473 kfree(uevent->data); 474 kfree(uevent->info); 475 kfree(uevent); 476done: 477 mutex_unlock(&file->file_mutex); 478 return result; 479} 480 481static ssize_t ib_ucm_create_id(struct ib_ucm_file *file, 482 const char __user *inbuf, 483 int in_len, int out_len) 484{ 485 struct ib_ucm_create_id cmd; 486 struct ib_ucm_create_id_resp resp; 487 struct ib_ucm_context *ctx; 488 int result; 489 490 if (out_len < sizeof(resp)) 491 return -ENOSPC; 492 493 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 494 return -EFAULT; 495 496 mutex_lock(&file->file_mutex); 497 ctx = ib_ucm_ctx_alloc(file); 498 mutex_unlock(&file->file_mutex); 499 if (!ctx) 500 return -ENOMEM; 501 502 ctx->uid = cmd.uid; 503 ctx->cm_id = ib_create_cm_id(file->device->ib_dev, 504 ib_ucm_event_handler, ctx); 505 if (IS_ERR(ctx->cm_id)) { 506 result = PTR_ERR(ctx->cm_id); 507 goto err1; 508 } 509 510 resp.id = ctx->id; 511 if (copy_to_user((void __user *)(unsigned long)cmd.response, 512 &resp, sizeof(resp))) { 513 result = -EFAULT; 514 goto err2; 515 } 516 return 0; 517 518err2: 519 ib_destroy_cm_id(ctx->cm_id); 520err1: 521 mutex_lock(&ctx_id_mutex); 522 idr_remove(&ctx_id_table, ctx->id); 523 mutex_unlock(&ctx_id_mutex); 524 kfree(ctx); 525 return result; 526} 527 528static ssize_t ib_ucm_destroy_id(struct ib_ucm_file *file, 529 const char __user *inbuf, 530 int in_len, int out_len) 531{ 532 struct ib_ucm_destroy_id cmd; 533 struct ib_ucm_destroy_id_resp resp; 534 struct ib_ucm_context *ctx; 535 int result = 0; 536 537 if (out_len < sizeof(resp)) 538 return -ENOSPC; 539 540 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 541 return -EFAULT; 542 543 mutex_lock(&ctx_id_mutex); 544 ctx = idr_find(&ctx_id_table, cmd.id); 545 if (!ctx) 546 ctx = ERR_PTR(-ENOENT); 547 else if (ctx->file != file) 548 ctx = ERR_PTR(-EINVAL); 549 else 550 idr_remove(&ctx_id_table, ctx->id); 551 mutex_unlock(&ctx_id_mutex); 552 553 if (IS_ERR(ctx)) 554 return PTR_ERR(ctx); 555 556 ib_ucm_ctx_put(ctx); 557 wait_for_completion(&ctx->comp); 558 559 /* No new events will be generated after destroying the cm_id. */ 560 ib_destroy_cm_id(ctx->cm_id); 561 /* Cleanup events not yet reported to the user. */ 562 ib_ucm_cleanup_events(ctx); 563 564 resp.events_reported = ctx->events_reported; 565 if (copy_to_user((void __user *)(unsigned long)cmd.response, 566 &resp, sizeof(resp))) 567 result = -EFAULT; 568 569 kfree(ctx); 570 return result; 571} 572 573static ssize_t ib_ucm_attr_id(struct ib_ucm_file *file, 574 const char __user *inbuf, 575 int in_len, int out_len) 576{ 577 struct ib_ucm_attr_id_resp resp; 578 struct ib_ucm_attr_id cmd; 579 struct ib_ucm_context *ctx; 580 int result = 0; 581 582 if (out_len < sizeof(resp)) 583 return -ENOSPC; 584 585 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 586 return -EFAULT; 587 588 ctx = ib_ucm_ctx_get(file, cmd.id); 589 if (IS_ERR(ctx)) 590 return PTR_ERR(ctx); 591 592 resp.service_id = ctx->cm_id->service_id; 593 resp.service_mask = ctx->cm_id->service_mask; 594 resp.local_id = ctx->cm_id->local_id; 595 resp.remote_id = ctx->cm_id->remote_id; 596 597 if (copy_to_user((void __user *)(unsigned long)cmd.response, 598 &resp, sizeof(resp))) 599 result = -EFAULT; 600 601 ib_ucm_ctx_put(ctx); 602 return result; 603} 604 605static ssize_t ib_ucm_init_qp_attr(struct ib_ucm_file *file, 606 const char __user *inbuf, 607 int in_len, int out_len) 608{ 609 struct ib_uverbs_qp_attr resp; 610 struct ib_ucm_init_qp_attr cmd; 611 struct ib_ucm_context *ctx; 612 struct ib_qp_attr qp_attr; 613 int result = 0; 614 615 if (out_len < sizeof(resp)) 616 return -ENOSPC; 617 618 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 619 return -EFAULT; 620 621 ctx = ib_ucm_ctx_get(file, cmd.id); 622 if (IS_ERR(ctx)) 623 return PTR_ERR(ctx); 624 625 resp.qp_attr_mask = 0; 626 memset(&qp_attr, 0, sizeof qp_attr); 627 qp_attr.qp_state = cmd.qp_state; 628 result = ib_cm_init_qp_attr(ctx->cm_id, &qp_attr, &resp.qp_attr_mask); 629 if (result) 630 goto out; 631 632 ib_copy_qp_attr_to_user(&resp, &qp_attr); 633 634 if (copy_to_user((void __user *)(unsigned long)cmd.response, 635 &resp, sizeof(resp))) 636 result = -EFAULT; 637 638out: 639 ib_ucm_ctx_put(ctx); 640 return result; 641} 642 643static int ucm_validate_listen(__be64 service_id, __be64 service_mask) 644{ 645 service_id &= service_mask; 646 647 if (((service_id & IB_CMA_SERVICE_ID_MASK) == IB_CMA_SERVICE_ID) || 648 ((service_id & IB_SDP_SERVICE_ID_MASK) == IB_SDP_SERVICE_ID)) 649 return -EINVAL; 650 651 return 0; 652} 653 654static ssize_t ib_ucm_listen(struct ib_ucm_file *file, 655 const char __user *inbuf, 656 int in_len, int out_len) 657{ 658 struct ib_ucm_listen cmd; 659 struct ib_ucm_context *ctx; 660 int result; 661 662 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 663 return -EFAULT; 664 665 ctx = ib_ucm_ctx_get(file, cmd.id); 666 if (IS_ERR(ctx)) 667 return PTR_ERR(ctx); 668 669 result = ucm_validate_listen(cmd.service_id, cmd.service_mask); 670 if (result) 671 goto out; 672 673 result = ib_cm_listen(ctx->cm_id, cmd.service_id, cmd.service_mask, 674 NULL); 675out: 676 ib_ucm_ctx_put(ctx); 677 return result; 678} 679 680static ssize_t ib_ucm_notify(struct ib_ucm_file *file, 681 const char __user *inbuf, 682 int in_len, int out_len) 683{ 684 struct ib_ucm_notify cmd; 685 struct ib_ucm_context *ctx; 686 int result; 687 688 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 689 return -EFAULT; 690 691 ctx = ib_ucm_ctx_get(file, cmd.id); 692 if (IS_ERR(ctx)) 693 return PTR_ERR(ctx); 694 695 result = ib_cm_notify(ctx->cm_id, (enum ib_event_type) cmd.event); 696 ib_ucm_ctx_put(ctx); 697 return result; 698} 699 700static int ib_ucm_alloc_data(const void **dest, u64 src, u32 len) 701{ 702 void *data; 703 704 *dest = NULL; 705 706 if (!len) 707 return 0; 708 709 data = memdup_user((void __user *)(unsigned long)src, len); 710 if (IS_ERR(data)) 711 return PTR_ERR(data); 712 713 *dest = data; 714 return 0; 715} 716 717static int ib_ucm_path_get(struct ib_sa_path_rec **path, u64 src) 718{ 719 struct ib_user_path_rec upath; 720 struct ib_sa_path_rec *sa_path; 721 722 *path = NULL; 723 724 if (!src) 725 return 0; 726 727 sa_path = kmalloc(sizeof(*sa_path), GFP_KERNEL); 728 if (!sa_path) 729 return -ENOMEM; 730 731 if (copy_from_user(&upath, (void __user *)(unsigned long)src, 732 sizeof(upath))) { 733 734 kfree(sa_path); 735 return -EFAULT; 736 } 737 738 ib_copy_path_rec_from_user(sa_path, &upath); 739 *path = sa_path; 740 return 0; 741} 742 743static ssize_t ib_ucm_send_req(struct ib_ucm_file *file, 744 const char __user *inbuf, 745 int in_len, int out_len) 746{ 747 struct ib_cm_req_param param; 748 struct ib_ucm_context *ctx; 749 struct ib_ucm_req cmd; 750 int result; 751 752 param.private_data = NULL; 753 param.primary_path = NULL; 754 param.alternate_path = NULL; 755 756 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 757 return -EFAULT; 758 759 result = ib_ucm_alloc_data(¶m.private_data, cmd.data, cmd.len); 760 if (result) 761 goto done; 762 763 result = ib_ucm_path_get(¶m.primary_path, cmd.primary_path); 764 if (result) 765 goto done; 766 767 result = ib_ucm_path_get(¶m.alternate_path, cmd.alternate_path); 768 if (result) 769 goto done; 770 771 param.private_data_len = cmd.len; 772 param.service_id = cmd.sid; 773 param.qp_num = cmd.qpn; 774 param.qp_type = cmd.qp_type; 775 param.starting_psn = cmd.psn; 776 param.peer_to_peer = cmd.peer_to_peer; 777 param.responder_resources = cmd.responder_resources; 778 param.initiator_depth = cmd.initiator_depth; 779 param.remote_cm_response_timeout = cmd.remote_cm_response_timeout; 780 param.flow_control = cmd.flow_control; 781 param.local_cm_response_timeout = cmd.local_cm_response_timeout; 782 param.retry_count = cmd.retry_count; 783 param.rnr_retry_count = cmd.rnr_retry_count; 784 param.max_cm_retries = cmd.max_cm_retries; 785 param.srq = cmd.srq; 786 787 ctx = ib_ucm_ctx_get(file, cmd.id); 788 if (!IS_ERR(ctx)) { 789 result = ib_send_cm_req(ctx->cm_id, ¶m); 790 ib_ucm_ctx_put(ctx); 791 } else 792 result = PTR_ERR(ctx); 793 794done: 795 kfree(param.private_data); 796 kfree(param.primary_path); 797 kfree(param.alternate_path); 798 return result; 799} 800 801static ssize_t ib_ucm_send_rep(struct ib_ucm_file *file, 802 const char __user *inbuf, 803 int in_len, int out_len) 804{ 805 struct ib_cm_rep_param param; 806 struct ib_ucm_context *ctx; 807 struct ib_ucm_rep cmd; 808 int result; 809 810 param.private_data = NULL; 811 812 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 813 return -EFAULT; 814 815 result = ib_ucm_alloc_data(¶m.private_data, cmd.data, cmd.len); 816 if (result) 817 return result; 818 819 param.qp_num = cmd.qpn; 820 param.starting_psn = cmd.psn; 821 param.private_data_len = cmd.len; 822 param.responder_resources = cmd.responder_resources; 823 param.initiator_depth = cmd.initiator_depth; 824 param.failover_accepted = cmd.failover_accepted; 825 param.flow_control = cmd.flow_control; 826 param.rnr_retry_count = cmd.rnr_retry_count; 827 param.srq = cmd.srq; 828 829 ctx = ib_ucm_ctx_get(file, cmd.id); 830 if (!IS_ERR(ctx)) { 831 ctx->uid = cmd.uid; 832 result = ib_send_cm_rep(ctx->cm_id, ¶m); 833 ib_ucm_ctx_put(ctx); 834 } else 835 result = PTR_ERR(ctx); 836 837 kfree(param.private_data); 838 return result; 839} 840 841static ssize_t ib_ucm_send_private_data(struct ib_ucm_file *file, 842 const char __user *inbuf, int in_len, 843 int (*func)(struct ib_cm_id *cm_id, 844 const void *private_data, 845 u8 private_data_len)) 846{ 847 struct ib_ucm_private_data cmd; 848 struct ib_ucm_context *ctx; 849 const void *private_data = NULL; 850 int result; 851 852 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 853 return -EFAULT; 854 855 result = ib_ucm_alloc_data(&private_data, cmd.data, cmd.len); 856 if (result) 857 return result; 858 859 ctx = ib_ucm_ctx_get(file, cmd.id); 860 if (!IS_ERR(ctx)) { 861 result = func(ctx->cm_id, private_data, cmd.len); 862 ib_ucm_ctx_put(ctx); 863 } else 864 result = PTR_ERR(ctx); 865 866 kfree(private_data); 867 return result; 868} 869 870static ssize_t ib_ucm_send_rtu(struct ib_ucm_file *file, 871 const char __user *inbuf, 872 int in_len, int out_len) 873{ 874 return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_rtu); 875} 876 877static ssize_t ib_ucm_send_dreq(struct ib_ucm_file *file, 878 const char __user *inbuf, 879 int in_len, int out_len) 880{ 881 return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_dreq); 882} 883 884static ssize_t ib_ucm_send_drep(struct ib_ucm_file *file, 885 const char __user *inbuf, 886 int in_len, int out_len) 887{ 888 return ib_ucm_send_private_data(file, inbuf, in_len, ib_send_cm_drep); 889} 890 891static ssize_t ib_ucm_send_info(struct ib_ucm_file *file, 892 const char __user *inbuf, int in_len, 893 int (*func)(struct ib_cm_id *cm_id, 894 int status, 895 const void *info, 896 u8 info_len, 897 const void *data, 898 u8 data_len)) 899{ 900 struct ib_ucm_context *ctx; 901 struct ib_ucm_info cmd; 902 const void *data = NULL; 903 const void *info = NULL; 904 int result; 905 906 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 907 return -EFAULT; 908 909 result = ib_ucm_alloc_data(&data, cmd.data, cmd.data_len); 910 if (result) 911 goto done; 912 913 result = ib_ucm_alloc_data(&info, cmd.info, cmd.info_len); 914 if (result) 915 goto done; 916 917 ctx = ib_ucm_ctx_get(file, cmd.id); 918 if (!IS_ERR(ctx)) { 919 result = func(ctx->cm_id, cmd.status, info, cmd.info_len, 920 data, cmd.data_len); 921 ib_ucm_ctx_put(ctx); 922 } else 923 result = PTR_ERR(ctx); 924 925done: 926 kfree(data); 927 kfree(info); 928 return result; 929} 930 931static ssize_t ib_ucm_send_rej(struct ib_ucm_file *file, 932 const char __user *inbuf, 933 int in_len, int out_len) 934{ 935 return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_rej); 936} 937 938static ssize_t ib_ucm_send_apr(struct ib_ucm_file *file, 939 const char __user *inbuf, 940 int in_len, int out_len) 941{ 942 return ib_ucm_send_info(file, inbuf, in_len, (void *)ib_send_cm_apr); 943} 944 945static ssize_t ib_ucm_send_mra(struct ib_ucm_file *file, 946 const char __user *inbuf, 947 int in_len, int out_len) 948{ 949 struct ib_ucm_context *ctx; 950 struct ib_ucm_mra cmd; 951 const void *data = NULL; 952 int result; 953 954 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 955 return -EFAULT; 956 957 result = ib_ucm_alloc_data(&data, cmd.data, cmd.len); 958 if (result) 959 return result; 960 961 ctx = ib_ucm_ctx_get(file, cmd.id); 962 if (!IS_ERR(ctx)) { 963 result = ib_send_cm_mra(ctx->cm_id, cmd.timeout, data, cmd.len); 964 ib_ucm_ctx_put(ctx); 965 } else 966 result = PTR_ERR(ctx); 967 968 kfree(data); 969 return result; 970} 971 972static ssize_t ib_ucm_send_lap(struct ib_ucm_file *file, 973 const char __user *inbuf, 974 int in_len, int out_len) 975{ 976 struct ib_ucm_context *ctx; 977 struct ib_sa_path_rec *path = NULL; 978 struct ib_ucm_lap cmd; 979 const void *data = NULL; 980 int result; 981 982 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 983 return -EFAULT; 984 985 result = ib_ucm_alloc_data(&data, cmd.data, cmd.len); 986 if (result) 987 goto done; 988 989 result = ib_ucm_path_get(&path, cmd.path); 990 if (result) 991 goto done; 992 993 ctx = ib_ucm_ctx_get(file, cmd.id); 994 if (!IS_ERR(ctx)) { 995 result = ib_send_cm_lap(ctx->cm_id, path, data, cmd.len); 996 ib_ucm_ctx_put(ctx); 997 } else 998 result = PTR_ERR(ctx); 999 1000done: 1001 kfree(data); 1002 kfree(path); 1003 return result; 1004} 1005 1006static ssize_t ib_ucm_send_sidr_req(struct ib_ucm_file *file, 1007 const char __user *inbuf, 1008 int in_len, int out_len) 1009{ 1010 struct ib_cm_sidr_req_param param; 1011 struct ib_ucm_context *ctx; 1012 struct ib_ucm_sidr_req cmd; 1013 int result; 1014 1015 param.private_data = NULL; 1016 param.path = NULL; 1017 1018 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1019 return -EFAULT; 1020 1021 result = ib_ucm_alloc_data(¶m.private_data, cmd.data, cmd.len); 1022 if (result) 1023 goto done; 1024 1025 result = ib_ucm_path_get(¶m.path, cmd.path); 1026 if (result) 1027 goto done; 1028 1029 param.private_data_len = cmd.len; 1030 param.service_id = cmd.sid; 1031 param.timeout_ms = cmd.timeout; 1032 param.max_cm_retries = cmd.max_cm_retries; 1033 1034 ctx = ib_ucm_ctx_get(file, cmd.id); 1035 if (!IS_ERR(ctx)) { 1036 result = ib_send_cm_sidr_req(ctx->cm_id, ¶m); 1037 ib_ucm_ctx_put(ctx); 1038 } else 1039 result = PTR_ERR(ctx); 1040 1041done: 1042 kfree(param.private_data); 1043 kfree(param.path); 1044 return result; 1045} 1046 1047static ssize_t ib_ucm_send_sidr_rep(struct ib_ucm_file *file, 1048 const char __user *inbuf, 1049 int in_len, int out_len) 1050{ 1051 struct ib_cm_sidr_rep_param param; 1052 struct ib_ucm_sidr_rep cmd; 1053 struct ib_ucm_context *ctx; 1054 int result; 1055 1056 param.info = NULL; 1057 1058 if (copy_from_user(&cmd, inbuf, sizeof(cmd))) 1059 return -EFAULT; 1060 1061 result = ib_ucm_alloc_data(¶m.private_data, 1062 cmd.data, cmd.data_len); 1063 if (result) 1064 goto done; 1065 1066 result = ib_ucm_alloc_data(¶m.info, cmd.info, cmd.info_len); 1067 if (result) 1068 goto done; 1069 1070 param.qp_num = cmd.qpn; 1071 param.qkey = cmd.qkey; 1072 param.status = cmd.status; 1073 param.info_length = cmd.info_len; 1074 param.private_data_len = cmd.data_len; 1075 1076 ctx = ib_ucm_ctx_get(file, cmd.id); 1077 if (!IS_ERR(ctx)) { 1078 result = ib_send_cm_sidr_rep(ctx->cm_id, ¶m); 1079 ib_ucm_ctx_put(ctx); 1080 } else 1081 result = PTR_ERR(ctx); 1082 1083done: 1084 kfree(param.private_data); 1085 kfree(param.info); 1086 return result; 1087} 1088 1089static ssize_t (*ucm_cmd_table[])(struct ib_ucm_file *file, 1090 const char __user *inbuf, 1091 int in_len, int out_len) = { 1092 [IB_USER_CM_CMD_CREATE_ID] = ib_ucm_create_id, 1093 [IB_USER_CM_CMD_DESTROY_ID] = ib_ucm_destroy_id, 1094 [IB_USER_CM_CMD_ATTR_ID] = ib_ucm_attr_id, 1095 [IB_USER_CM_CMD_LISTEN] = ib_ucm_listen, 1096 [IB_USER_CM_CMD_NOTIFY] = ib_ucm_notify, 1097 [IB_USER_CM_CMD_SEND_REQ] = ib_ucm_send_req, 1098 [IB_USER_CM_CMD_SEND_REP] = ib_ucm_send_rep, 1099 [IB_USER_CM_CMD_SEND_RTU] = ib_ucm_send_rtu, 1100 [IB_USER_CM_CMD_SEND_DREQ] = ib_ucm_send_dreq, 1101 [IB_USER_CM_CMD_SEND_DREP] = ib_ucm_send_drep, 1102 [IB_USER_CM_CMD_SEND_REJ] = ib_ucm_send_rej, 1103 [IB_USER_CM_CMD_SEND_MRA] = ib_ucm_send_mra, 1104 [IB_USER_CM_CMD_SEND_LAP] = ib_ucm_send_lap, 1105 [IB_USER_CM_CMD_SEND_APR] = ib_ucm_send_apr, 1106 [IB_USER_CM_CMD_SEND_SIDR_REQ] = ib_ucm_send_sidr_req, 1107 [IB_USER_CM_CMD_SEND_SIDR_REP] = ib_ucm_send_sidr_rep, 1108 [IB_USER_CM_CMD_EVENT] = ib_ucm_event, 1109 [IB_USER_CM_CMD_INIT_QP_ATTR] = ib_ucm_init_qp_attr, 1110}; 1111 1112static ssize_t ib_ucm_write(struct file *filp, const char __user *buf, 1113 size_t len, loff_t *pos) 1114{ 1115 struct ib_ucm_file *file = filp->private_data; 1116 struct ib_ucm_cmd_hdr hdr; 1117 ssize_t result; 1118 1119 if (len < sizeof(hdr)) 1120 return -EINVAL; 1121 1122 if (copy_from_user(&hdr, buf, sizeof(hdr))) 1123 return -EFAULT; 1124 1125 if (hdr.cmd < 0 || hdr.cmd >= ARRAY_SIZE(ucm_cmd_table)) 1126 return -EINVAL; 1127 1128 if (hdr.in + sizeof(hdr) > len) 1129 return -EINVAL; 1130 1131 result = ucm_cmd_table[hdr.cmd](file, buf + sizeof(hdr), 1132 hdr.in, hdr.out); 1133 if (!result) 1134 result = len; 1135 1136 return result; 1137} 1138 1139static unsigned int ib_ucm_poll(struct file *filp, 1140 struct poll_table_struct *wait) 1141{ 1142 struct ib_ucm_file *file = filp->private_data; 1143 unsigned int mask = 0; 1144 1145 poll_wait(filp, &file->poll_wait, wait); 1146 1147 if (!list_empty(&file->events)) 1148 mask = POLLIN | POLLRDNORM; 1149 1150 return mask; 1151} 1152 1153/* 1154 * ib_ucm_open() does not need the BKL: 1155 * 1156 * - no global state is referred to; 1157 * - there is no ioctl method to race against; 1158 * - no further module initialization is required for open to work 1159 * after the device is registered. 1160 */ 1161static int ib_ucm_open(struct inode *inode, struct file *filp) 1162{ 1163 struct ib_ucm_file *file; 1164 1165 file = kmalloc(sizeof(*file), GFP_KERNEL); 1166 if (!file) 1167 return -ENOMEM; 1168 1169 INIT_LIST_HEAD(&file->events); 1170 INIT_LIST_HEAD(&file->ctxs); 1171 init_waitqueue_head(&file->poll_wait); 1172 1173 mutex_init(&file->file_mutex); 1174 1175 filp->private_data = file; 1176 file->filp = filp; 1177 file->device = container_of(inode->i_cdev, struct ib_ucm_device, cdev); 1178 1179 return nonseekable_open(inode, filp); 1180} 1181 1182static int ib_ucm_close(struct inode *inode, struct file *filp) 1183{ 1184 struct ib_ucm_file *file = filp->private_data; 1185 struct ib_ucm_context *ctx; 1186 1187 mutex_lock(&file->file_mutex); 1188 while (!list_empty(&file->ctxs)) { 1189 ctx = list_entry(file->ctxs.next, 1190 struct ib_ucm_context, file_list); 1191 mutex_unlock(&file->file_mutex); 1192 1193 mutex_lock(&ctx_id_mutex); 1194 idr_remove(&ctx_id_table, ctx->id); 1195 mutex_unlock(&ctx_id_mutex); 1196 1197 ib_destroy_cm_id(ctx->cm_id); 1198 ib_ucm_cleanup_events(ctx); 1199 kfree(ctx); 1200 1201 mutex_lock(&file->file_mutex); 1202 } 1203 mutex_unlock(&file->file_mutex); 1204 kfree(file); 1205 return 0; 1206} 1207 1208static void ib_ucm_release_dev(struct device *dev) 1209{ 1210 struct ib_ucm_device *ucm_dev; 1211 1212 ucm_dev = container_of(dev, struct ib_ucm_device, dev); 1213 cdev_del(&ucm_dev->cdev); 1214 if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) 1215 clear_bit(ucm_dev->devnum, dev_map); 1216 else 1217 clear_bit(ucm_dev->devnum - IB_UCM_MAX_DEVICES, dev_map); 1218 kfree(ucm_dev); 1219} 1220 1221static const struct file_operations ucm_fops = { 1222 .owner = THIS_MODULE, 1223 .open = ib_ucm_open, 1224 .release = ib_ucm_close, 1225 .write = ib_ucm_write, 1226 .poll = ib_ucm_poll, 1227 .llseek = no_llseek, 1228}; 1229 1230static ssize_t show_ibdev(struct device *dev, struct device_attribute *attr, 1231 char *buf) 1232{ 1233 struct ib_ucm_device *ucm_dev; 1234 1235 ucm_dev = container_of(dev, struct ib_ucm_device, dev); 1236 return sprintf(buf, "%s\n", ucm_dev->ib_dev->name); 1237} 1238static DEVICE_ATTR(ibdev, S_IRUGO, show_ibdev, NULL); 1239 1240static dev_t overflow_maj; 1241static DECLARE_BITMAP(overflow_map, IB_UCM_MAX_DEVICES); 1242static int find_overflow_devnum(void) 1243{ 1244 int ret; 1245 1246 if (!overflow_maj) { 1247 ret = alloc_chrdev_region(&overflow_maj, 0, IB_UCM_MAX_DEVICES, 1248 "infiniband_cm"); 1249 if (ret) { 1250 printk(KERN_ERR "ucm: couldn't register dynamic device number\n"); 1251 return ret; 1252 } 1253 } 1254 1255 ret = find_first_zero_bit(overflow_map, IB_UCM_MAX_DEVICES); 1256 if (ret >= IB_UCM_MAX_DEVICES) 1257 return -1; 1258 1259 return ret; 1260} 1261 1262static void ib_ucm_add_one(struct ib_device *device) 1263{ 1264 int devnum; 1265 dev_t base; 1266 struct ib_ucm_device *ucm_dev; 1267 1268 if (!device->alloc_ucontext || 1269 rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB) 1270 return; 1271 1272 ucm_dev = kzalloc(sizeof *ucm_dev, GFP_KERNEL); 1273 if (!ucm_dev) 1274 return; 1275 1276 ucm_dev->ib_dev = device; 1277 1278 devnum = find_first_zero_bit(dev_map, IB_UCM_MAX_DEVICES); 1279 if (devnum >= IB_UCM_MAX_DEVICES) { 1280 devnum = find_overflow_devnum(); 1281 if (devnum < 0) 1282 goto err; 1283 1284 ucm_dev->devnum = devnum + IB_UCM_MAX_DEVICES; 1285 base = devnum + overflow_maj; 1286 set_bit(devnum, overflow_map); 1287 } else { 1288 ucm_dev->devnum = devnum; 1289 base = devnum + IB_UCM_BASE_DEV; 1290 set_bit(devnum, dev_map); 1291 } 1292 1293 cdev_init(&ucm_dev->cdev, &ucm_fops); 1294 ucm_dev->cdev.owner = THIS_MODULE; 1295 kobject_set_name(&ucm_dev->cdev.kobj, "ucm%d", ucm_dev->devnum); 1296 if (cdev_add(&ucm_dev->cdev, base, 1)) 1297 goto err; 1298 1299 ucm_dev->dev.class = &cm_class; 1300 ucm_dev->dev.parent = device->dma_device; 1301 ucm_dev->dev.devt = ucm_dev->cdev.dev; 1302 ucm_dev->dev.release = ib_ucm_release_dev; 1303 dev_set_name(&ucm_dev->dev, "ucm%d", ucm_dev->devnum); 1304 if (device_register(&ucm_dev->dev)) 1305 goto err_cdev; 1306 1307 if (device_create_file(&ucm_dev->dev, &dev_attr_ibdev)) 1308 goto err_dev; 1309 1310 ib_set_client_data(device, &ucm_client, ucm_dev); 1311 return; 1312 1313err_dev: 1314 device_unregister(&ucm_dev->dev); 1315err_cdev: 1316 cdev_del(&ucm_dev->cdev); 1317 if (ucm_dev->devnum < IB_UCM_MAX_DEVICES) 1318 clear_bit(devnum, dev_map); 1319 else 1320 clear_bit(devnum, overflow_map); 1321err: 1322 kfree(ucm_dev); 1323 return; 1324} 1325 1326static void ib_ucm_remove_one(struct ib_device *device) 1327{ 1328 struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client); 1329 1330 if (!ucm_dev) 1331 return; 1332 1333 device_unregister(&ucm_dev->dev); 1334} 1335 1336static CLASS_ATTR_STRING(abi_version, S_IRUGO, 1337 __stringify(IB_USER_CM_ABI_VERSION)); 1338 1339static int __init ib_ucm_init(void) 1340{ 1341 int ret; 1342 1343 ret = register_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES, 1344 "infiniband_cm"); 1345 if (ret) { 1346 printk(KERN_ERR "ucm: couldn't register device number\n"); 1347 goto error1; 1348 } 1349 1350 ret = class_create_file(&cm_class, &class_attr_abi_version.attr); 1351 if (ret) { 1352 printk(KERN_ERR "ucm: couldn't create abi_version attribute\n"); 1353 goto error2; 1354 } 1355 1356 ret = ib_register_client(&ucm_client); 1357 if (ret) { 1358 printk(KERN_ERR "ucm: couldn't register client\n"); 1359 goto error3; 1360 } 1361 return 0; 1362 1363error3: 1364 class_remove_file(&cm_class, &class_attr_abi_version.attr); 1365error2: 1366 unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); 1367error1: 1368 return ret; 1369} 1370 1371static void __exit ib_ucm_cleanup(void) 1372{ 1373 ib_unregister_client(&ucm_client); 1374 class_remove_file(&cm_class, &class_attr_abi_version.attr); 1375 unregister_chrdev_region(IB_UCM_BASE_DEV, IB_UCM_MAX_DEVICES); 1376 if (overflow_maj) 1377 unregister_chrdev_region(overflow_maj, IB_UCM_MAX_DEVICES); 1378 idr_destroy(&ctx_id_table); 1379} 1380 1381module_init(ib_ucm_init); 1382module_exit(ib_ucm_cleanup); 1383