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