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, 152 NULL, 153 }; 154 155 static char srpt_pp_name[] = "srpt"; 156 157 /* 158 * Prototypes 159 */ 160 static void srpt_pp_cb(stmf_port_provider_t *, int, void *, uint32_t); 161 162 /* 163 * _init() 164 */ 165 int 166 _init(void) 167 { 168 int status; 169 170 /* 171 * Global one time initialization. 172 */ 173 srpt_ctxt = kmem_zalloc(sizeof (srpt_ctxt_t), KM_SLEEP); 174 ASSERT(srpt_ctxt != NULL); 175 rw_init(&srpt_ctxt->sc_rwlock, NULL, RW_DRIVER, NULL); 176 177 /* Start-up state is DISABLED. SMF will tell us if we should enable. */ 178 srpt_ctxt->sc_svc_state = SRPT_SVC_DISABLED; 179 list_create(&srpt_ctxt->sc_ioc_list, sizeof (srpt_ioc_t), 180 offsetof(srpt_ioc_t, ioc_node)); 181 182 list_create(&srpt_ctxt->sc_ioc_list, sizeof (srpt_ioc_t), 183 offsetof(srpt_ioc_t, ioc_node)); 184 185 status = mod_install(&srpt_modlinkage); 186 if (status != DDI_SUCCESS) { 187 cmn_err(CE_CONT, "_init, failed mod_install %d", status); 188 rw_destroy(&srpt_ctxt->sc_rwlock); 189 kmem_free(srpt_ctxt, sizeof (srpt_ctxt_t)); 190 srpt_ctxt = NULL; 191 } 192 193 return (status); 194 } 195 196 /* 197 * _info() 198 */ 199 int 200 _info(struct modinfo *modinfop) 201 { 202 return (mod_info(&srpt_modlinkage, modinfop)); 203 } 204 205 /* 206 * _fini() 207 */ 208 int 209 _fini(void) 210 { 211 int status; 212 213 status = mod_remove(&srpt_modlinkage); 214 if (status != DDI_SUCCESS) { 215 return (status); 216 } 217 218 list_destroy(&srpt_ctxt->sc_ioc_list); 219 220 rw_destroy(&srpt_ctxt->sc_rwlock); 221 kmem_free(srpt_ctxt, sizeof (srpt_ctxt_t)); 222 srpt_ctxt = NULL; 223 224 return (status); 225 } 226 227 /* 228 * DDI entry points. 229 */ 230 231 /* 232 * srpt_getinfo() 233 */ 234 /* ARGSUSED */ 235 static int 236 srpt_drv_getinfo(dev_info_t *dip, ddi_info_cmd_t cmd, void *arg, void **result) 237 { 238 239 switch (cmd) { 240 case DDI_INFO_DEVT2DEVINFO: 241 *result = srpt_ctxt->sc_dip; 242 return (DDI_SUCCESS); 243 244 case DDI_INFO_DEVT2INSTANCE: 245 *result = NULL; 246 return (DDI_SUCCESS); 247 248 default: 249 break; 250 } 251 return (DDI_FAILURE); 252 } 253 254 /* 255 * srpt_drv_attach() 256 */ 257 static int 258 srpt_drv_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 259 { 260 int status; 261 262 switch (cmd) { 263 case DDI_ATTACH: 264 break; 265 266 case DDI_RESUME: 267 return (DDI_SUCCESS); 268 269 default: 270 return (DDI_FAILURE); 271 } 272 273 /* 274 * We only allow a single instance. 275 */ 276 if (ddi_get_instance(dip) != 0) { 277 SRPT_DPRINTF_L1("drv_attach, error non-zero instance"); 278 return (DDI_FAILURE); 279 } 280 281 /* 282 * Create minor node that might ultimately be used to create 283 * targets outside of srpt. 284 */ 285 status = ddi_create_minor_node(dip, ddi_get_name(dip), 286 S_IFCHR, 0, DDI_PSEUDO, 0); 287 if (status != DDI_SUCCESS) { 288 SRPT_DPRINTF_L1("drv_attach, minor node creation error (%d)", 289 status); 290 return (DDI_FAILURE); 291 } 292 293 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 294 srpt_ctxt->sc_dip = dip; 295 rw_exit(&srpt_ctxt->sc_rwlock); 296 297 return (DDI_SUCCESS); 298 } 299 300 /* 301 * srpt_enable_srp_services() 302 * 303 * Caller must be holding the sc_rwlock as RW_WRITER. 304 */ 305 static int 306 srpt_enable_srp_services(void) 307 { 308 int status; 309 310 ASSERT((rw_read_locked(&srpt_ctxt->sc_rwlock)) == 0); 311 312 SRPT_DPRINTF_L3("srpt_enable_srp_services"); 313 314 /* Register the port provider */ 315 srpt_ctxt->sc_pp = (stmf_port_provider_t *) 316 stmf_alloc(STMF_STRUCT_PORT_PROVIDER, 0, 0); 317 srpt_ctxt->sc_pp->pp_portif_rev = PORTIF_REV_1; 318 srpt_ctxt->sc_pp->pp_name = srpt_pp_name; 319 srpt_ctxt->sc_pp->pp_cb = srpt_pp_cb; 320 status = stmf_register_port_provider(srpt_ctxt->sc_pp); 321 if (status != STMF_SUCCESS) { 322 SRPT_DPRINTF_L1("enable_srp: SRP port_provider registration" 323 " failed(%d)", status); 324 goto err_exit_1; 325 } 326 327 /* 328 * Initialize IB resources, creating a list of SRP I/O Controllers 329 * and for each controller, register the SCSI Target Port with STMF 330 * and prepare profile and services. 331 */ 332 status = srpt_ioc_attach(); 333 if (status != DDI_SUCCESS) { 334 SRPT_DPRINTF_L1("enable_srp: error attach I/O" 335 " Controllers (%d)", status); 336 goto err_exit_2; 337 } 338 339 /* 340 * No configured controllers is not a fatal error. This can happen 341 * if all HCAs are currently disabled for use by SRP. The service 342 * should remain running in case the user changes their mind and 343 * enables an HCA for SRP services. 344 */ 345 if (srpt_ctxt->sc_num_iocs == 0) { 346 SRPT_DPRINTF_L2("enable_srp: no IB I/O Controllers found"); 347 return (DDI_SUCCESS); 348 } 349 350 return (DDI_SUCCESS); 351 352 err_exit_2: 353 (void) stmf_deregister_port_provider(srpt_ctxt->sc_pp); 354 355 err_exit_1: 356 stmf_free(srpt_ctxt->sc_pp); 357 srpt_ctxt->sc_pp = NULL; 358 359 return (status); 360 } 361 362 /* 363 * srpt_drv_detach() 364 * 365 * Refuse the detach request if we have channels open on 366 * any IOC. Users should use 'svcadm disable' to shutdown 367 * active targets. 368 */ 369 /*ARGSUSED*/ 370 static int 371 srpt_drv_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 372 { 373 switch (cmd) { 374 case DDI_DETACH: 375 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 376 if (srpt_ctxt->sc_svc_state != SRPT_SVC_DISABLED) { 377 rw_exit(&srpt_ctxt->sc_rwlock); 378 return (DDI_FAILURE); 379 } 380 381 ddi_remove_minor_node(dip, NULL); 382 srpt_ctxt->sc_dip = NULL; 383 384 if (srpt_ctxt->sc_cfg_hca_nv != NULL) { 385 nvlist_free(srpt_ctxt->sc_cfg_hca_nv); 386 srpt_ctxt->sc_cfg_hca_nv = NULL; 387 } 388 389 rw_exit(&srpt_ctxt->sc_rwlock); 390 391 break; 392 393 case DDI_SUSPEND: 394 return (DDI_FAILURE); 395 396 default: 397 return (DDI_FAILURE); 398 } 399 400 return (DDI_SUCCESS); 401 } 402 403 /* 404 * srpt_disable_srp_services() 405 * 406 * Offlines all targets, deregisters all IOCs. Caller must hold 407 * the srpt_ctxt->sc_rwlock as RW_WRITER. 408 */ 409 static int 410 srpt_disable_srp_services(void) 411 { 412 stmf_status_t stmf_status; 413 srpt_ioc_t *ioc; 414 srpt_target_port_t *tgt; 415 int ret_status = 0; 416 417 ASSERT((rw_read_locked(&srpt_ctxt->sc_rwlock)) == 0); 418 419 /* 420 * For each I/O Controller remove all SRP services and de-register 421 * with the associated I/O Unit's IB Device Management Agent. 422 */ 423 ioc = list_head(&srpt_ctxt->sc_ioc_list); 424 425 while (ioc != NULL) { 426 rw_enter(&ioc->ioc_rwlock, RW_WRITER); 427 428 tgt = ioc->ioc_tgt_port; 429 if (tgt != NULL) { 430 stmf_status = srpt_stp_destroy_port(tgt); 431 if (stmf_status == STMF_SUCCESS) { 432 ioc->ioc_tgt_port = NULL; 433 (void) srpt_stp_free_port(tgt); 434 } else { 435 ret_status = DDI_FAILURE; 436 break; 437 } 438 } 439 440 rw_exit(&ioc->ioc_rwlock); 441 ioc = list_next(&srpt_ctxt->sc_ioc_list, ioc); 442 } 443 444 /* don't release IOCs until all ports are deregistered */ 445 if (ret_status != 0) { 446 return (ret_status); 447 } 448 449 /* 450 * Release I/O Controller(s) resources and detach. 451 */ 452 srpt_ioc_detach(); 453 454 /* De-register ourselves as an STMF port provider */ 455 (void) stmf_deregister_port_provider(srpt_ctxt->sc_pp); 456 stmf_free(srpt_ctxt->sc_pp); 457 srpt_ctxt->sc_pp = NULL; 458 459 return (0); 460 } 461 462 /* 463 * srpt_drv_open() 464 */ 465 /* ARGSUSED */ 466 static int 467 srpt_drv_open(dev_t *devp, int flag, int otyp, cred_t *credp) 468 { 469 SRPT_DPRINTF_L3("drv_open, invoked"); 470 return (0); 471 } 472 473 /* 474 * srpt_drv_close() 475 */ 476 /* ARGSUSED */ 477 static int 478 srpt_drv_close(dev_t dev, int flag, int otyp, cred_t *credp) 479 { 480 SRPT_DPRINTF_L3("drv_close, invoked"); 481 return (0); 482 } 483 484 /* 485 * srpt_drv_ioctl() 486 */ 487 /* ARGSUSED */ 488 static int 489 srpt_drv_ioctl(dev_t drv, int cmd, intptr_t argp, int flag, cred_t *cred, 490 int *retval) 491 { 492 int ret = 0; 493 494 SRPT_DPRINTF_L3("drv_ioctl, invoked, cmd = %d", cmd); 495 496 if (drv_priv(cred) != 0) { 497 return (EPERM); 498 } 499 500 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 501 502 switch (cmd) { 503 case SRPT_IOC_ENABLE_SVC: 504 if (srpt_ctxt->sc_svc_state != SRPT_SVC_DISABLED) { 505 break; 506 } 507 508 ret = srpt_ibdma_ops_load(&srpt_ctxt->sc_ibdma_ops); 509 if (ret != 0) { 510 break; 511 } 512 513 ret = srpt_enable_srp_services(); 514 if (ret == 0) { 515 srpt_ctxt->sc_svc_state = SRPT_SVC_ENABLED; 516 } 517 518 break; 519 520 case SRPT_IOC_DISABLE_SVC: 521 if (srpt_ctxt->sc_svc_state != SRPT_SVC_ENABLED) { 522 break; 523 } 524 525 ret = srpt_disable_srp_services(); 526 if (ret == 0) { 527 srpt_ctxt->sc_svc_state = SRPT_SVC_DISABLED; 528 } 529 530 srpt_ibdma_ops_unload(&srpt_ctxt->sc_ibdma_ops); 531 532 break; 533 534 default: 535 ret = EFAULT; 536 break; 537 } 538 539 rw_exit(&srpt_ctxt->sc_rwlock); 540 541 return (ret); 542 } 543 544 /* 545 * srpt_pp_cb() 546 */ 547 /* ARGSUSED */ 548 static void 549 srpt_pp_cb(stmf_port_provider_t *pp, int cmd, void *arg, uint32_t flags) 550 { 551 int ret; 552 nvlist_t *in_nvl = (nvlist_t *)arg; 553 nvlist_t *nvl = NULL; 554 nvlist_t *hcalist; 555 nvlist_t *ctxt_nvl; 556 boolean_t defaultEnabled = B_TRUE; 557 boolean_t called_by_reg = B_TRUE; 558 559 SRPT_DPRINTF_L2("srpt_pp_cb, invoked (%d)", cmd); 560 561 if (cmd != STMF_PROVIDER_DATA_UPDATED) { 562 return; 563 } 564 565 /* 566 * If STMF_PCB_PREG_COMPLETE is set in the flags, we're being 567 * called back during provider registration with STMF. 568 * (while we're calling stmf_register_port_provider()). 569 * srpt_enable_service() already holds the sc_wrlock, and will 570 * make sure the configuration is activated, so we just need to 571 * set the config and get out. If this function is called at any 572 * time other than SRPT service start, need to grab the sc_wrlock 573 * as WRITER. 574 */ 575 if (!(flags & STMF_PCB_PREG_COMPLETE)) { 576 SRPT_DPRINTF_L2( 577 "srpt_pp_cb: called after registration"); 578 called_by_reg = B_FALSE; 579 rw_enter(&srpt_ctxt->sc_rwlock, RW_WRITER); 580 } else { 581 called_by_reg = B_TRUE; 582 SRPT_DPRINTF_L2( 583 "srpt_pp_cb: called as part of registration"); 584 } 585 586 if (in_nvl != NULL) { 587 /* copy nvlist */ 588 ret = nvlist_lookup_nvlist(in_nvl, SRPT_PROP_HCALIST, &hcalist); 589 if (ret != 0) { 590 SRPT_DPRINTF_L1( 591 "srpt_pp_cb: Could not read hca config, err=%d", 592 ret); 593 return; 594 } 595 596 ret = nvlist_dup(hcalist, &nvl, 0); 597 if (ret != 0) { 598 SRPT_DPRINTF_L1( 599 "srpt_pp_cb: Could not copy hca config, err=%d", 600 ret); 601 return; 602 } 603 if (nvlist_lookup_boolean_value(in_nvl, 604 SRPT_PROP_DEFAULT_ENABLED, &defaultEnabled) == 0) { 605 /* set whether targets are created by default */ 606 SRPT_DPRINTF_L2( 607 "srpt_pp_cb: setting default enabled = %d\n", 608 (int)defaultEnabled); 609 srpt_enable_by_default = defaultEnabled; 610 } 611 } else { 612 SRPT_DPRINTF_L2( 613 "srpt_pp_cb: null config received"); 614 } 615 616 /* put list in ctxt and set default state */ 617 ctxt_nvl = srpt_ctxt->sc_cfg_hca_nv; 618 619 /* set new config, NULL is valid */ 620 srpt_ctxt->sc_cfg_hca_nv = nvl; 621 622 /* free the old nvlist */ 623 if (ctxt_nvl != NULL) { 624 nvlist_free(ctxt_nvl); 625 } 626 627 if (called_by_reg) { 628 return; 629 } 630 631 /* Update the HCA based on the new config */ 632 srpt_ioc_update(); 633 634 rw_exit(&srpt_ctxt->sc_rwlock); 635 } 636 637 static int 638 srpt_ibdma_ops_load(srpt_ibdma_ops_t *ops) 639 { 640 int ibdma_err = 0; 641 642 ASSERT(ops != NULL); 643 644 ops->ibdmah = ddi_modopen("ibdma", KRTLD_MODE_FIRST, &ibdma_err); 645 if (ops->ibdmah == NULL) { 646 SRPT_DPRINTF_L0("failed to open ibdma driver, error = %d", 647 ibdma_err); 648 return (ibdma_err); 649 } 650 651 ops->ibdma_register = (ibdma_hdl_t (*)())ddi_modsym(ops->ibdmah, 652 "ibdma_ioc_register", &ibdma_err); 653 if (ops->ibdma_register == NULL) { 654 SRPT_DPRINTF_L0( 655 "failed to modsym ibdma_ioc_register, error = %d", 656 ibdma_err); 657 goto done; 658 } 659 660 ops->ibdma_unregister = (ibdma_status_t (*)())ddi_modsym(ops->ibdmah, 661 "ibdma_ioc_unregister", &ibdma_err); 662 if (ops->ibdma_unregister == NULL) { 663 SRPT_DPRINTF_L0( 664 "failed to modsym ibdma_ioc_unregister, error = %d", 665 ibdma_err); 666 goto done; 667 } 668 669 ops->ibdma_update = (ibdma_status_t (*)())ddi_modsym(ops->ibdmah, 670 "ibdma_ioc_update", &ibdma_err); 671 if (ops->ibdma_update == NULL) { 672 SRPT_DPRINTF_L0( 673 "failed to modsym ibdma_ioc_update, error = %d", 674 ibdma_err); 675 } 676 677 done: 678 if (ibdma_err != 0) { 679 srpt_ibdma_ops_unload(ops); 680 } 681 682 return (ibdma_err); 683 } 684 685 static void 686 srpt_ibdma_ops_unload(srpt_ibdma_ops_t *ops) 687 { 688 if (ops != NULL) { 689 if (ops->ibdmah != NULL) { 690 (void) ddi_modclose(ops->ibdmah); 691 } 692 bzero(ops, sizeof (srpt_ibdma_ops_t)); 693 } 694 } 695