1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 24 */ 25 26 /* 27 * Solaris SCSI RDMA Protocol Target (SRP) transport port provider 28 * module for the COMSTAR framework. 29 */ 30 31 #include <sys/cpuvar.h> 32 #include <sys/types.h> 33 #include <sys/conf.h> 34 #include <sys/stat.h> 35 #include <sys/file.h> 36 #include <sys/ddi.h> 37 #include <sys/sunddi.h> 38 #include <sys/modctl.h> 39 #include <sys/sysmacros.h> 40 #include <sys/sdt.h> 41 #include <sys/taskq.h> 42 43 #include <sys/stmf.h> 44 #include <sys/stmf_ioctl.h> 45 #include <sys/portif.h> 46 47 #include "srp.h" 48 #include "srpt_impl.h" 49 #include "srpt_ioc.h" 50 #include "srpt_stp.h" 51 #include "srpt_cm.h" 52 #include "srpt_ioctl.h" 53 #include "srpt_common.h" 54 55 #define SRPT_NAME_VERSION "COMSTAR SRP Target" 56 57 /* 58 * srpt_enable_by_default - configurable parameter that 59 * determines whether targets are created automatically for 60 * all HCAs when the service is enabled. 61 * 62 * B_TRUE is the legacy default as srpt originally shipped 63 * this way. Changing it to false is highly desirable. 64 */ 65 boolean_t srpt_enable_by_default = B_TRUE; 66 67 /* 68 * srpt_send_msg_depth - Tunable parameter that specifies the 69 * maximum messages that could be in flight for a channel. 70 */ 71 uint16_t srpt_send_msg_depth = SRPT_DEFAULT_SEND_MSG_DEPTH; 72 73 /* 74 * srpt_errlevel -- determine which error conditions are logged 75 */ 76 uint_t srpt_errlevel = SRPT_LOG_DEFAULT_LEVEL; 77 78 /* 79 * srpt_iu_size -- must be a multiple of 64 as it is registered 80 * as memory regions with IB. To support a scatter/gather table 81 * size of 32, the size must be at not less than 960. To support 82 * the maximum scatter/gather table size of 255, the IU must 83 * be at least 4160 bytes. 84 */ 85 uint32_t srpt_iu_size = SRPT_DEFAULT_SEND_MSG_SIZE; 86 87 srpt_ctxt_t *srpt_ctxt; 88 89 /* 90 * DDI entry points. 91 */ 92 static int srpt_drv_attach(dev_info_t *, ddi_attach_cmd_t); 93 static int srpt_drv_detach(dev_info_t *, ddi_detach_cmd_t); 94 static int srpt_drv_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 95 static int srpt_drv_open(dev_t *, int, int, cred_t *); 96 static int srpt_drv_close(dev_t, int, int, cred_t *); 97 static int srpt_drv_ioctl(dev_t, int, intptr_t, int, cred_t *, int *); 98 99 /* helper functions */ 100 static int srpt_disable_srp_services(void); 101 static int srpt_enable_srp_services(void); 102 static int srpt_ibdma_ops_load(srpt_ibdma_ops_t *); 103 static void srpt_ibdma_ops_unload(srpt_ibdma_ops_t *); 104 105 extern struct mod_ops mod_miscops; 106 107 static struct cb_ops srpt_cb_ops = { 108 srpt_drv_open, /* cb_open */ 109 srpt_drv_close, /* cb_close */ 110 nodev, /* cb_strategy */ 111 nodev, /* cb_print */ 112 nodev, /* cb_dump */ 113 nodev, /* cb_read */ 114 nodev, /* cb_write */ 115 srpt_drv_ioctl, /* cb_ioctl */ 116 nodev, /* cb_devmap */ 117 nodev, /* cb_mmap */ 118 nodev, /* cb_segmap */ 119 nochpoll, /* cb_chpoll */ 120 ddi_prop_op, /* cb_prop_op */ 121 NULL, /* cb_streamtab */ 122 D_MP, /* cb_flag */ 123 CB_REV, /* cb_rev */ 124 nodev, /* cb_aread */ 125 nodev, /* cb_awrite */ 126 }; 127 128 static struct dev_ops srpt_dev_ops = { 129 DEVO_REV, /* devo_rev */ 130 0, /* devo_refcnt */ 131 srpt_drv_getinfo, /* devo_getinfo */ 132 nulldev, /* devo_identify */ 133 nulldev, /* devo_probe */ 134 srpt_drv_attach, /* devo_attach */ 135 srpt_drv_detach, /* devo_detach */ 136 nodev, /* devo_reset */ 137 &srpt_cb_ops, /* devo_cb_ops */ 138 NULL, /* devo_bus_ops */ 139 NULL, /* devo_power */ 140 ddi_quiesce_not_needed, /* quiesce */ 141 }; 142 143 static struct modldrv modldrv = { 144 &mod_driverops, 145 SRPT_NAME_VERSION, 146 &srpt_dev_ops, 147 }; 148 149 static struct modlinkage srpt_modlinkage = { 150 MODREV_1, 151 { &modldrv, NULL } 152 }; 153 154 static char srpt_pp_name[] = "srpt"; 155 156 /* 157 * Prototypes 158 */ 159 static void srpt_pp_cb(stmf_port_provider_t *, int, void *, uint32_t); 160 161 /* 162 * _init() 163 */ 164 int 165 _init(void) 166 { 167 int status; 168 169 /* 170 * Global one time initialization. 171 */ 172 srpt_ctxt = kmem_zalloc(sizeof (srpt_ctxt_t), KM_SLEEP); 173 ASSERT(srpt_ctxt != NULL); 174 rw_init(&srpt_ctxt->sc_rwlock, NULL, RW_DRIVER, NULL); 175 176 /* Start-up state is DISABLED. SMF will tell us if we should enable. */ 177 srpt_ctxt->sc_svc_state = SRPT_SVC_DISABLED; 178 list_create(&srpt_ctxt->sc_ioc_list, sizeof (srpt_ioc_t), 179 offsetof(srpt_ioc_t, ioc_node)); 180 181 list_create(&srpt_ctxt->sc_ioc_list, sizeof (srpt_ioc_t), 182 offsetof(srpt_ioc_t, ioc_node)); 183 184 status = mod_install(&srpt_modlinkage); 185 if (status != DDI_SUCCESS) { 186 cmn_err(CE_CONT, "_init, failed mod_install %d", status); 187 rw_destroy(&srpt_ctxt->sc_rwlock); 188 kmem_free(srpt_ctxt, sizeof (srpt_ctxt_t)); 189 srpt_ctxt = NULL; 190 } 191 192 return (status); 193 } 194 195 /* 196 * _info() 197 */ 198 int 199 _info(struct modinfo *modinfop) 200 { 201 return (mod_info(&srpt_modlinkage, modinfop)); 202 } 203 204 /* 205 * _fini() 206 */ 207 int 208 _fini(void) 209 { 210 int status; 211 212 status = mod_remove(&srpt_modlinkage); 213 if (status != DDI_SUCCESS) { 214 return (status); 215 } 216 217 list_destroy(&srpt_ctxt->sc_ioc_list); 218 219 rw_destroy(&srpt_ctxt->sc_rwlock); 220 kmem_free(srpt_ctxt, sizeof (srpt_ctxt_t)); 221 srpt_ctxt = NULL; 222 223 return (status); 224 } 225 226 /* 227 * DDI entry points. 228 */ 229 230 /* 231 * srpt_getinfo() 232 */ 233 /* ARGSUSED */ 234 static int 235 srpt_drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 236 { 237 238 switch (cmd) { 239 case DDI_INFO_DEVT2DEVINFO: 240 *result = srpt_ctxt->sc_dip; 241 return (DDI_SUCCESS); 242 243 case DDI_INFO_DEVT2INSTANCE: 244 *result = NULL; 245 return (DDI_SUCCESS); 246 247 default: 248 break; 249 } 250 return (DDI_FAILURE); 251 } 252 253 /* 254 * srpt_drv_attach() 255 */ 256 static int 257 srpt_drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 258 { 259 int status; 260 261 switch (cmd) { 262 case DDI_ATTACH: 263 break; 264 265 case DDI_RESUME: 266 return (DDI_SUCCESS); 267 268 default: 269 return (DDI_FAILURE); 270 } 271 272 /* 273 * We only allow a single instance. 274 */ 275 if (ddi_get_instance(dip) != 0) { 276 SRPT_DPRINTF_L1("drv_attach, error non-zero instance"); 277 return (DDI_FAILURE); 278 } 279 280 /* 281 * Create minor node that might ultimately be used to create 282 * targets outside of srpt. 283 */ 284 status = ddi_create_minor_node(dip, ddi_get_name(dip), 285 S_IFCHR, 0, DDI_PSEUDO, 0); 286 if (status != DDI_SUCCESS) { 287 SRPT_DPRINTF_L1("drv_attach, minor node creation error (%d)", 288 status); 289 return (DDI_FAILURE); 290 } 291 292 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 293 srpt_ctxt->sc_dip = dip; 294 rw_exit(&srpt_ctxt->sc_rwlock); 295 296 return (DDI_SUCCESS); 297 } 298 299 /* 300 * srpt_enable_srp_services() 301 * 302 * Caller must be holding the sc_rwlock as RW_WRITER. 303 */ 304 static int 305 srpt_enable_srp_services(void) 306 { 307 int status; 308 309 ASSERT((rw_read_locked(&srpt_ctxt->sc_rwlock)) == 0); 310 311 SRPT_DPRINTF_L3("srpt_enable_srp_services"); 312 313 /* Register the port provider */ 314 srpt_ctxt->sc_pp = (stmf_port_provider_t *) 315 stmf_alloc(STMF_STRUCT_PORT_PROVIDER, 0, 0); 316 srpt_ctxt->sc_pp->pp_portif_rev = PORTIF_REV_1; 317 srpt_ctxt->sc_pp->pp_name = srpt_pp_name; 318 srpt_ctxt->sc_pp->pp_cb = srpt_pp_cb; 319 status = stmf_register_port_provider(srpt_ctxt->sc_pp); 320 if (status != STMF_SUCCESS) { 321 SRPT_DPRINTF_L1("enable_srp: SRP port_provider registration" 322 " failed(%d)", status); 323 goto err_exit_1; 324 } 325 326 /* 327 * Initialize IB resources, creating a list of SRP I/O Controllers 328 * and for each controller, register the SCSI Target Port with STMF 329 * and prepare profile and services. 330 */ 331 status = srpt_ioc_attach(); 332 if (status != DDI_SUCCESS) { 333 SRPT_DPRINTF_L1("enable_srp: error attach I/O" 334 " Controllers (%d)", status); 335 goto err_exit_2; 336 } 337 338 /* 339 * No configured controllers is not a fatal error. This can happen 340 * if all HCAs are currently disabled for use by SRP. The service 341 * should remain running in case the user changes their mind and 342 * enables an HCA for SRP services. 343 */ 344 if (srpt_ctxt->sc_num_iocs == 0) { 345 SRPT_DPRINTF_L2("enable_srp: no IB I/O Controllers found"); 346 return (DDI_SUCCESS); 347 } 348 349 return (DDI_SUCCESS); 350 351 err_exit_2: 352 (void) stmf_deregister_port_provider(srpt_ctxt->sc_pp); 353 354 err_exit_1: 355 stmf_free(srpt_ctxt->sc_pp); 356 srpt_ctxt->sc_pp = NULL; 357 358 return (status); 359 } 360 361 /* 362 * srpt_drv_detach() 363 * 364 * Refuse the detach request if we have channels open on 365 * any IOC. Users should use 'svcadm disable' to shutdown 366 * active targets. 367 */ 368 /*ARGSUSED*/ 369 static int 370 srpt_drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 371 { 372 switch (cmd) { 373 case DDI_DETACH: 374 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 375 if (srpt_ctxt->sc_svc_state != SRPT_SVC_DISABLED) { 376 rw_exit(&srpt_ctxt->sc_rwlock); 377 return (DDI_FAILURE); 378 } 379 380 ddi_remove_minor_node(dip, NULL); 381 srpt_ctxt->sc_dip = NULL; 382 383 if (srpt_ctxt->sc_cfg_hca_nv != NULL) { 384 nvlist_free(srpt_ctxt->sc_cfg_hca_nv); 385 srpt_ctxt->sc_cfg_hca_nv = NULL; 386 } 387 388 rw_exit(&srpt_ctxt->sc_rwlock); 389 390 break; 391 392 case DDI_SUSPEND: 393 return (DDI_FAILURE); 394 395 default: 396 return (DDI_FAILURE); 397 } 398 399 return (DDI_SUCCESS); 400 } 401 402 /* 403 * srpt_disable_srp_services() 404 * 405 * Offlines all targets, deregisters all IOCs. Caller must hold 406 * the srpt_ctxt->sc_rwlock as RW_WRITER. 407 */ 408 static int 409 srpt_disable_srp_services(void) 410 { 411 stmf_status_t stmf_status; 412 srpt_ioc_t *ioc; 413 srpt_target_port_t *tgt; 414 int ret_status = 0; 415 416 ASSERT((rw_read_locked(&srpt_ctxt->sc_rwlock)) == 0); 417 418 /* 419 * For each I/O Controller remove all SRP services and de-register 420 * with the associated I/O Unit's IB Device Management Agent. 421 */ 422 ioc = list_head(&srpt_ctxt->sc_ioc_list); 423 424 while (ioc != NULL) { 425 rw_enter(&ioc->ioc_rwlock, RW_WRITER); 426 427 tgt = ioc->ioc_tgt_port; 428 if (tgt != NULL) { 429 stmf_status = srpt_stp_destroy_port(tgt); 430 if (stmf_status == STMF_SUCCESS) { 431 ioc->ioc_tgt_port = NULL; 432 (void) srpt_stp_free_port(tgt); 433 } else { 434 ret_status = DDI_FAILURE; 435 break; 436 } 437 } 438 439 rw_exit(&ioc->ioc_rwlock); 440 ioc = list_next(&srpt_ctxt->sc_ioc_list, ioc); 441 } 442 443 /* don't release IOCs until all ports are deregistered */ 444 if (ret_status != 0) { 445 return (ret_status); 446 } 447 448 /* 449 * Release I/O Controller(s) resources and detach. 450 */ 451 srpt_ioc_detach(); 452 453 /* De-register ourselves as an STMF port provider */ 454 (void) stmf_deregister_port_provider(srpt_ctxt->sc_pp); 455 stmf_free(srpt_ctxt->sc_pp); 456 srpt_ctxt->sc_pp = NULL; 457 458 return (0); 459 } 460 461 /* 462 * srpt_drv_open() 463 */ 464 /* ARGSUSED */ 465 static int 466 srpt_drv_open(dev_t *devp, int flag, int otyp, cred_t *credp) 467 { 468 SRPT_DPRINTF_L3("drv_open, invoked"); 469 return (0); 470 } 471 472 /* 473 * srpt_drv_close() 474 */ 475 /* ARGSUSED */ 476 static int 477 srpt_drv_close(dev_t dev, int flag, int otyp, cred_t *credp) 478 { 479 SRPT_DPRINTF_L3("drv_close, invoked"); 480 return (0); 481 } 482 483 /* 484 * srpt_drv_ioctl() 485 */ 486 /* ARGSUSED */ 487 static int 488 srpt_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred, 489 int *retval) 490 { 491 int ret = 0; 492 493 SRPT_DPRINTF_L3("drv_ioctl, invoked, cmd = %d", cmd); 494 495 if (drv_priv(cred) != 0) { 496 return (EPERM); 497 } 498 499 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 500 501 switch (cmd) { 502 case SRPT_IOC_ENABLE_SVC: 503 if (srpt_ctxt->sc_svc_state != SRPT_SVC_DISABLED) { 504 break; 505 } 506 507 ret = srpt_ibdma_ops_load(&srpt_ctxt->sc_ibdma_ops); 508 if (ret != 0) { 509 break; 510 } 511 512 ret = srpt_enable_srp_services(); 513 if (ret == 0) { 514 srpt_ctxt->sc_svc_state = SRPT_SVC_ENABLED; 515 } 516 517 break; 518 519 case SRPT_IOC_DISABLE_SVC: 520 if (srpt_ctxt->sc_svc_state != SRPT_SVC_ENABLED) { 521 break; 522 } 523 524 ret = srpt_disable_srp_services(); 525 if (ret == 0) { 526 srpt_ctxt->sc_svc_state = SRPT_SVC_DISABLED; 527 } 528 529 srpt_ibdma_ops_unload(&srpt_ctxt->sc_ibdma_ops); 530 531 break; 532 533 default: 534 ret = EFAULT; 535 break; 536 } 537 538 rw_exit(&srpt_ctxt->sc_rwlock); 539 540 return (ret); 541 } 542 543 /* 544 * srpt_pp_cb() 545 */ 546 /* ARGSUSED */ 547 static void 548 srpt_pp_cb(stmf_port_provider_t *pp, int cmd, void *arg, uint32_t flags) 549 { 550 int ret; 551 nvlist_t *in_nvl = (nvlist_t *)arg; 552 nvlist_t *nvl = NULL; 553 nvlist_t *hcalist; 554 nvlist_t *ctxt_nvl; 555 boolean_t defaultEnabled = B_TRUE; 556 boolean_t called_by_reg = B_TRUE; 557 558 SRPT_DPRINTF_L2("srpt_pp_cb, invoked (%d)", cmd); 559 560 if (cmd != STMF_PROVIDER_DATA_UPDATED) { 561 return; 562 } 563 564 /* 565 * If STMF_PCB_PREG_COMPLETE is set in the flags, we're being 566 * called back during provider registration with STMF. 567 * (while we're calling stmf_register_port_provider()). 568 * srpt_enable_service() already holds the sc_wrlock, and will 569 * make sure the configuration is activated, so we just need to 570 * set the config and get out. If this function is called at any 571 * time other than SRPT service start, need to grab the sc_wrlock 572 * as WRITER. 573 */ 574 if (!(flags & STMF_PCB_PREG_COMPLETE)) { 575 SRPT_DPRINTF_L2( 576 "srpt_pp_cb: called after registration"); 577 called_by_reg = B_FALSE; 578 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 579 } else { 580 called_by_reg = B_TRUE; 581 SRPT_DPRINTF_L2( 582 "srpt_pp_cb: called as part of registration"); 583 } 584 585 if (in_nvl != NULL) { 586 /* copy nvlist */ 587 ret = nvlist_lookup_nvlist(in_nvl, SRPT_PROP_HCALIST, &hcalist); 588 if (ret != 0) { 589 SRPT_DPRINTF_L1( 590 "srpt_pp_cb: Could not read hca config, err=%d", 591 ret); 592 return; 593 } 594 595 ret = nvlist_dup(hcalist, &nvl, 0); 596 if (ret != 0) { 597 SRPT_DPRINTF_L1( 598 "srpt_pp_cb: Could not copy hca config, err=%d", 599 ret); 600 return; 601 } 602 if (nvlist_lookup_boolean_value(in_nvl, 603 SRPT_PROP_DEFAULT_ENABLED, &defaultEnabled) == 0) { 604 /* set whether targets are created by default */ 605 SRPT_DPRINTF_L2( 606 "srpt_pp_cb: setting default enabled = %d\n", 607 (int)defaultEnabled); 608 srpt_enable_by_default = defaultEnabled; 609 } 610 } else { 611 SRPT_DPRINTF_L2( 612 "srpt_pp_cb: null config received"); 613 } 614 615 /* put list in ctxt and set default state */ 616 ctxt_nvl = srpt_ctxt->sc_cfg_hca_nv; 617 618 /* set new config, NULL is valid */ 619 srpt_ctxt->sc_cfg_hca_nv = nvl; 620 621 /* free the old nvlist */ 622 if (ctxt_nvl != NULL) { 623 nvlist_free(ctxt_nvl); 624 } 625 626 if (called_by_reg) { 627 return; 628 } 629 630 /* Update the HCA based on the new config */ 631 srpt_ioc_update(); 632 633 rw_exit(&srpt_ctxt->sc_rwlock); 634 } 635 636 static int 637 srpt_ibdma_ops_load(srpt_ibdma_ops_t *ops) 638 { 639 int ibdma_err = 0; 640 641 ASSERT(ops != NULL); 642 643 ops->ibdmah = ddi_modopen("ibdma", KRTLD_MODE_FIRST, &ibdma_err); 644 if (ops->ibdmah == NULL) { 645 SRPT_DPRINTF_L0("failed to open ibdma driver, error = %d", 646 ibdma_err); 647 return (ibdma_err); 648 } 649 650 ops->ibdma_register = (ibdma_hdl_t (*)())ddi_modsym(ops->ibdmah, 651 "ibdma_ioc_register", &ibdma_err); 652 if (ops->ibdma_register == NULL) { 653 SRPT_DPRINTF_L0( 654 "failed to modsym ibdma_ioc_register, error = %d", 655 ibdma_err); 656 goto done; 657 } 658 659 ops->ibdma_unregister = (ibdma_status_t (*)())ddi_modsym(ops->ibdmah, 660 "ibdma_ioc_unregister", &ibdma_err); 661 if (ops->ibdma_unregister == NULL) { 662 SRPT_DPRINTF_L0( 663 "failed to modsym ibdma_ioc_unregister, error = %d", 664 ibdma_err); 665 goto done; 666 } 667 668 ops->ibdma_update = (ibdma_status_t (*)())ddi_modsym(ops->ibdmah, 669 "ibdma_ioc_update", &ibdma_err); 670 if (ops->ibdma_update == NULL) { 671 SRPT_DPRINTF_L0( 672 "failed to modsym ibdma_ioc_update, error = %d", 673 ibdma_err); 674 } 675 676 done: 677 if (ibdma_err != 0) { 678 srpt_ibdma_ops_unload(ops); 679 } 680 681 return (ibdma_err); 682 } 683 684 static void 685 srpt_ibdma_ops_unload(srpt_ibdma_ops_t *ops) 686 { 687 if (ops != NULL) { 688 if (ops->ibdmah != NULL) { 689 (void) ddi_modclose(ops->ibdmah); 690 } 691 bzero(ops, sizeof (srpt_ibdma_ops_t)); 692 } 693 }