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
_init(void)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
_info(struct modinfo * modinfop)200 _info(struct modinfo *modinfop)
201 {
202 return (mod_info(&srpt_modlinkage, modinfop));
203 }
204
205 /*
206 * _fini()
207 */
208 int
_fini(void)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
srpt_drv_getinfo(dev_info_t * dip,ddi_info_cmd_t cmd,void * arg,void ** result)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
srpt_drv_attach(dev_info_t * dip,ddi_attach_cmd_t cmd)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
srpt_enable_srp_services(void)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
srpt_drv_detach(dev_info_t * dip,ddi_detach_cmd_t cmd)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
srpt_disable_srp_services(void)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
srpt_drv_open(dev_t * devp,int flag,int otyp,cred_t * credp)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
srpt_drv_close(dev_t dev,int flag,int otyp,cred_t * credp)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
srpt_drv_ioctl(dev_t drv,int cmd,intptr_t argp,int flag,cred_t * cred,int * retval)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
srpt_pp_cb(stmf_port_provider_t * pp,int cmd,void * arg,uint32_t flags)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
srpt_ibdma_ops_load(srpt_ibdma_ops_t * ops)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
srpt_ibdma_ops_unload(srpt_ibdma_ops_t * ops)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