Print this page
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h
+++ new/usr/src/uts/common/sys/scsi/adapters/scsi_vhci.h
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) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25 /*
26 26 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
27 27 */
28 28
29 29 #ifndef _SYS_SCSI_ADAPTERS_SCSI_VHCI_H
30 30 #define _SYS_SCSI_ADAPTERS_SCSI_VHCI_H
31 31
32 32 /*
33 33 * Multiplexed I/O SCSI vHCI global include
34 34 */
35 35 #include <sys/note.h>
36 36 #include <sys/taskq.h>
37 37 #include <sys/mhd.h>
38 38 #include <sys/sunmdi.h>
39 39 #include <sys/mdi_impldefs.h>
40 40 #include <sys/scsi/adapters/mpapi_impl.h>
41 41 #include <sys/scsi/adapters/mpapi_scsi_vhci.h>
42 42
43 43 #ifdef __cplusplus
44 44 extern "C" {
45 45 #endif
46 46
47 47 #if !defined(_BIT_FIELDS_LTOH) && !defined(_BIT_FIELDS_HTOL)
48 48 #error One of _BIT_FIELDS_LTOH or _BIT_FIELDS_HTOL must be defined
49 49 #endif /* _BIT_FIELDS_LTOH */
50 50
51 51 #ifdef _KERNEL
52 52
53 53 #ifdef UNDEFINED
54 54 #undef UNDEFINED
55 55 #endif
56 56 #define UNDEFINED -1
57 57
58 58 #define VHCI_STATE_OPEN 0x00000001
59 59
60 60
61 61 #define VH_SLEEP 0x0
62 62 #define VH_NOSLEEP 0x1
63 63
64 64 /*
65 65 * HBA interface macros
66 66 */
67 67
68 68 #define TRAN2HBAPRIVATE(tran) ((struct scsi_vhci *)(tran)->tran_hba_private)
69 69 #define VHCI_INIT_WAIT_TIMEOUT 60000000
70 70 #define VHCI_FOWATCH_INTERVAL 1000000 /* in usecs */
71 71 #define VHCI_EXTFO_TIMEOUT (3 * 60 * NANOSEC) /* 3 minutes in nsec */
72 72
73 73 #define SCBP_C(pkt) ((*(pkt)->pkt_scbp) & STATUS_MASK)
74 74
75 75 int vhci_do_scsi_cmd(struct scsi_pkt *);
76 76 /*PRINTFLIKE3*/
77 77 void vhci_log(int, dev_info_t *, const char *, ...);
78 78
79 79 /*
80 80 * debugging stuff
81 81 */
82 82
83 83 #ifdef DEBUG
84 84
85 85 #ifndef VHCI_DEBUG_DEFAULT_VAL
86 86 #define VHCI_DEBUG_DEFAULT_VAL 0
87 87 #endif /* VHCI_DEBUG_DEFAULT_VAL */
88 88
89 89 extern int vhci_debug;
90 90
91 91 #include <sys/debug.h>
92 92
93 93 #define VHCI_DEBUG(level, stmnt) \
94 94 if (vhci_debug >= (level)) vhci_log stmnt
95 95
96 96 #else /* !DEBUG */
97 97
98 98 #define VHCI_DEBUG(level, stmnt)
99 99
100 100 #endif /* !DEBUG */
101 101
102 102
103 103
104 104 #define VHCI_PKT_PRIV_SIZE 2
105 105
106 106 #define ADDR2VHCI(ap) ((struct scsi_vhci *) \
107 107 ((ap)->a_hba_tran->tran_hba_private))
108 108 #define ADDR2VLUN(ap) (scsi_vhci_lun_t *) \
109 109 (scsi_device_hba_private_get(scsi_address_device(ap)))
110 110 #define ADDR2DIP(ap) ((dev_info_t *)(scsi_address_device(ap)->sd_dev))
111 111
112 112 #define HBAPKT2VHCIPKT(pkt) (pkt->pkt_private)
113 113 #define TGTPKT2VHCIPKT(pkt) (pkt->pkt_ha_private)
114 114 #define VHCIPKT2HBAPKT(pkt) (pkt->pkt_hba_pkt)
115 115 #define VHCIPKT2TGTPKT(pkt) (pkt->pkt_tgt_pkt)
116 116
117 117 #define VHCI_DECR_PATH_CMDCOUNT(svp) { \
118 118 mutex_enter(&(svp)->svp_mutex); \
119 119 (svp)->svp_cmds--; \
120 120 if ((svp)->svp_cmds == 0) \
121 121 cv_broadcast(&(svp)->svp_cv); \
122 122 mutex_exit(&(svp)->svp_mutex); \
123 123 }
124 124
125 125 #define VHCI_INCR_PATH_CMDCOUNT(svp) { \
126 126 mutex_enter(&(svp)->svp_mutex); \
127 127 (svp)->svp_cmds++; \
128 128 mutex_exit(&(svp)->svp_mutex); \
129 129 }
130 130
131 131 /*
132 132 * When a LUN is HELD it results in new IOs being returned to the target
133 133 * driver layer with TRAN_BUSY. Should be used while performing
134 134 * operations that require prevention of any new IOs to the LUN and
135 135 * the LUN should be HELD for the duration of such operations.
136 136 * f can be VH_SLEEP or VH_NOSLEEP.
137 137 * h is set to 1 to indicate LUN was successfully HELD.
138 138 * h is set to 0 when f is VH_NOSLEEP and LUN is already HELD.
139 139 *
140 140 * Application examples:
141 141 *
142 142 * 1) SCSI-II RESERVE: HOLD LUN until it is quiesced and the load balancing
143 143 * policy is switched to NONE before proceeding with RESERVE handling.
144 144 *
145 145 * 2) Failover: HOLD LUN before initiating failover.
146 146 *
147 147 * 3) When an externally initiated failover is detected, HOLD LUN until all
148 148 * path states have been refreshed to reflect the new value.
149 149 *
150 150 */
151 151 #define VHCI_HOLD_LUN(vlun, f, h) { \
152 152 int sleep = (f); \
153 153 mutex_enter(&(vlun)->svl_mutex); \
154 154 if ((vlun)->svl_transient == 1) { \
155 155 if (sleep == VH_SLEEP) { \
156 156 while ((vlun)->svl_transient == 1) \
157 157 cv_wait(&(vlun)->svl_cv, &(vlun)->svl_mutex); \
158 158 (vlun)->svl_transient = 1; \
159 159 (h) = 1; \
160 160 } else { \
161 161 (h) = 0; \
162 162 } \
163 163 } else { \
164 164 (vlun)->svl_transient = 1; \
165 165 (h) = 1; \
166 166 } \
167 167 sleep = (h); \
168 168 mutex_exit(&(vlun)->svl_mutex); \
169 169 }
170 170
171 171 #define VHCI_RELEASE_LUN(vlun) { \
172 172 mutex_enter(&(vlun)->svl_mutex); \
173 173 (vlun)->svl_transient = 0; \
174 174 cv_broadcast(&(vlun)->svl_cv); \
175 175 mutex_exit(&(vlun)->svl_mutex); \
176 176 }
177 177
178 178 #define VHCI_LUN_IS_HELD(vlun) ((vlun)->svl_transient == 1)
179 179
180 180 /*
181 181 * vhci_pkt states
182 182 */
183 183 #define VHCI_PKT_IDLE 0x01
184 184 #define VHCI_PKT_ISSUED 0x02
185 185 #define VHCI_PKT_ABORTING 0x04
186 186 #define VHCI_PKT_STALE_BINDING 0x08
187 187 /*
188 188 * Set the first time taskq is dispatched from scsi_start for
189 189 * a packet. To ensure vhci_scsi_start recognizes that the scsi_pkt
190 190 * is being issued from the taskq and not target driver.
191 191 */
192 192 #define VHCI_PKT_THRU_TASKQ 0x20
193 193 /*
194 194 * Set the first time failover is being triggered. To ensure
195 195 * failover won't be triggered again when the packet is being
196 196 * retried by target driver.
197 197 */
198 198 #define VHCI_PKT_IN_FAILOVER 0x40
199 199
200 200 #define VHCI_PKT_TIMEOUT 30 /* seconds */
201 201 #define VHCI_PKT_RETRY_CNT 2
202 202 #define VHCI_POLL_TIMEOUT 60 /* seconds */
203 203
204 204 /*
205 205 * define extended scsi cmd pkt
206 206 */
207 207 #define EXTCMDS_STATUS_SIZE (sizeof (struct scsi_arq_status))
208 208
209 209 #define CFLAG_NOWAIT 0x1000 /* don't sleep */
210 210 #define CFLAG_DMA_PARTIAL 0x2000 /* Support Partial DMA */
211 211
212 212 /*
213 213 * Maximum size of SCSI cdb in SCSI command
214 214 */
215 215 #define VHCI_SCSI_CDB_SIZE 16
216 216 #define VHCI_SCSI_SCB_SIZE (sizeof (struct scsi_arq_status))
217 217
218 218 /*
219 219 * OSD specific definitions
220 220 */
221 221 #define VHCI_SCSI_OSD_CDB_SIZE 224
222 222 #define VHCI_SCSI_OSD_PKT_FLAGS 0x100000
223 223
224 224 /*
225 225 * flag to determine failover support
226 226 */
227 227 #define SCSI_NO_FAILOVER 0x0
228 228 #define SCSI_IMPLICIT_FAILOVER 0x1
229 229 #define SCSI_EXPLICIT_FAILOVER 0x2
230 230 #define SCSI_BOTH_FAILOVER \
231 231 (SCSI_IMPLICIT_FAILOVER | SCSI_EXPLICIT_FAILOVER)
232 232
233 233 struct scsi_vhci_swarg;
234 234
235 235 #define VHCI_NUM_RESV_KEYS 8
236 236
237 237 typedef struct vhci_prin_readkeys {
238 238 uint32_t generation;
239 239 uint32_t length;
240 240 mhioc_resv_key_t keylist[VHCI_NUM_RESV_KEYS];
241 241 } vhci_prin_readkeys_t;
242 242
243 243 #define VHCI_PROUT_SIZE \
244 244 ((sizeof (vhci_prout_t) - 2 * (MHIOC_RESV_KEY_SIZE) * sizeof (char)))
245 245
246 246 typedef struct vhci_prout {
247 247 /* PGR register parameters start */
248 248 uchar_t res_key[MHIOC_RESV_KEY_SIZE];
249 249 uchar_t service_key[MHIOC_RESV_KEY_SIZE];
250 250 uint32_t scope_address;
251 251
252 252 #if defined(_BIT_FIELDS_LTOH)
253 253 uchar_t aptpl:1,
254 254 reserved:7;
255 255 #else
256 256 uchar_t reserved:7,
257 257 aptpl:1;
258 258 #endif /* _BIT_FIELDS_LTOH */
259 259
260 260 uchar_t reserved_1;
261 261 uint16_t ext_len;
262 262 /* PGR register parameters end */
263 263
264 264 /* Update VHCI_PROUT_SIZE if new fields are added here */
265 265
266 266 uchar_t active_res_key[MHIOC_RESV_KEY_SIZE];
267 267 uchar_t active_service_key[MHIOC_RESV_KEY_SIZE];
268 268 } vhci_prout_t;
269 269
270 270 #define VHCI_PROUT_REGISTER 0x0
271 271 #define VHCI_PROUT_RESERVE 0x1
272 272 #define VHCI_PROUT_RELEASE 0x2
273 273 #define VHCI_PROUT_CLEAR 0x3
274 274 #define VHCI_PROUT_PREEMPT 0x4
275 275 #define VHCI_PROUT_P_AND_A 0x5
276 276 #define VHCI_PROUT_R_AND_IGNORE 0x6
277 277
278 278 struct vhci_pkt {
279 279 struct scsi_pkt *vpkt_tgt_pkt;
280 280 mdi_pathinfo_t *vpkt_path; /* path pkt bound to */
281 281
282 282 /*
283 283 * pHCI packet that does the actual work.
284 284 */
285 285 struct scsi_pkt *vpkt_hba_pkt;
286 286
287 287 uint_t vpkt_state;
288 288 uint_t vpkt_flags;
289 289
290 290 /*
291 291 * copy of vhci_scsi_init_pkt args. Used when we invoke
292 292 * scsi_init_pkt() of the pHCI corresponding to the path that we
293 293 * bind to
294 294 */
295 295 int vpkt_tgt_init_cdblen;
296 296 int vpkt_tgt_init_scblen;
297 297 int vpkt_tgt_init_pkt_flags;
298 298 struct buf *vpkt_tgt_init_bp;
299 299
300 300 /*
301 301 * Pointer to original struct vhci_pkt for cmd send by ssd.
302 302 * Saved when the command is being retried internally.
303 303 */
304 304 struct vhci_pkt *vpkt_org_vpkt;
305 305 };
306 306
307 307 typedef struct scsi_vhci_lun {
308 308 kmutex_t svl_mutex;
309 309 kcondvar_t svl_cv;
310 310
311 311 /*
312 312 * following three fields are under svl_mutex protection
313 313 */
314 314 int svl_transient;
315 315
316 316 /*
317 317 * to prevent unnecessary failover when a device is
318 318 * is discovered across a passive path and active path
319 319 * is still comng up
320 320 */
321 321 int svl_waiting_for_activepath;
322 322 hrtime_t svl_wfa_time;
323 323
324 324 /*
325 325 * to keep the failover status in order to return the
326 326 * failure status to target driver when targer driver
327 327 * retries the command which originally triggered the
328 328 * failover.
329 329 */
330 330 int svl_failover_status;
331 331
332 332 /*
333 333 * for RESERVE/RELEASE support
334 334 */
335 335 client_lb_t svl_lb_policy_save;
336 336
337 337 /*
338 338 * Failover ops and ops name selected for the lun.
339 339 */
340 340 struct scsi_failover_ops *svl_fops;
341 341 char *svl_fops_name;
342 342
343 343 void *svl_fops_ctpriv;
344 344
345 345 struct scsi_vhci_lun *svl_hash_next;
346 346 char *svl_lun_wwn;
347 347
348 348 /*
349 349 * currently active pathclass
350 350 */
351 351 char *svl_active_pclass;
352 352
353 353 dev_info_t *svl_dip;
354 354 uint32_t svl_flags; /* protected by svl_mutex */
355 355
356 356 /*
357 357 * When SCSI-II reservations are active we set the following pip
358 358 * to point to the path holding the reservation. As long as
359 359 * the reservation is active this svl_resrv_pip is bound for the
360 360 * transport directly. We bypass calling mdi_select_path to return
361 361 * a pip.
362 362 * The following pip is only valid when VLUN_RESERVE_ACTIVE_FLG
363 363 * is set. This pip should not be accessed if this flag is reset.
364 364 */
365 365 mdi_pathinfo_t *svl_resrv_pip;
366 366
367 367 /*
368 368 * following fields are for PGR support
369 369 */
370 370 taskq_t *svl_taskq;
371 371 ksema_t svl_pgr_sema; /* PGR serialization */
372 372 vhci_prin_readkeys_t svl_prin; /* PGR in data */
373 373 vhci_prout_t svl_prout; /* PGR out data */
374 374 uchar_t svl_cdb[CDB_GROUP4];
375 375 int svl_time; /* pkt_time */
376 376 uint32_t svl_bcount; /* amount of data */
377 377 int svl_pgr_active; /* registrations active */
378 378 mdi_pathinfo_t *svl_first_path;
379 379
380 380 /* external failover */
381 381 int svl_efo_update_path;
382 382 struct scsi_vhci_swarg *svl_swarg;
383 383
384 384 uint32_t svl_support_lun_reset; /* Lun reset support */
385 385 int svl_not_supported;
386 386 int svl_xlf_capable; /* XLF implementation */
387 387 int svl_sector_size;
388 388 int svl_setcap_done;
389 389 uint16_t svl_fo_support; /* failover mode */
390 390 } scsi_vhci_lun_t;
391 391
392 392 #define VLUN_TASK_D_ALIVE_FLG 0x01
393 393
394 394 /*
395 395 * This flag is used to monitor the state of SCSI-II RESERVATION on the
396 396 * lun. A SCSI-II RESERVE cmd may be accepted by the target on the inactive
397 397 * path. This would then cause a subsequent IO to cause the paths to be
398 398 * updated and be returned with a reservation conflict. By monitoring this
399 399 * flag, and sending a reset to the target when needed to clear the reservation,
400 400 * one can avoid this conflict.
401 401 */
402 402 #define VLUN_RESERVE_ACTIVE_FLG 0x04
403 403
404 404 /*
405 405 * This flag is set when a SCSI-II RESERVE cmd is received by scsi_vhci
406 406 * and cleared when the pkt completes in vhci_intr. It ensures that the
407 407 * lun remains quiesced for the duration of this pkt. This is different
408 408 * from VHCI_HOLD_LUN as this pertains to IOs only.
409 409 */
410 410 #define VLUN_QUIESCED_FLG 0x08
411 411
412 412 /*
413 413 * This flag is set to tell vhci_update_pathstates to call back
414 414 * into vhci_mpapi_update_tpg_acc_state.
415 415 */
416 416 #define VLUN_UPDATE_TPG 0x10
417 417
418 418 /*
419 419 * Various reset recovery depth.
420 420 */
421 421
422 422 #define VHCI_DEPTH_ALL 3
423 423 #define VHCI_DEPTH_TARGET 2
424 424 #define VHCI_DEPTH_LUN 1 /* For the sake completeness */
425 425 #define TRUE (1)
426 426 #define FALSE (0)
427 427
428 428 /*
429 429 * this is stashed away in the client private area of
430 430 * pathinfo
431 431 */
432 432 typedef struct scsi_vhci_priv {
433 433 kmutex_t svp_mutex;
434 434 kcondvar_t svp_cv;
435 435 struct scsi_vhci_lun *svp_svl;
436 436
437 437 /*
438 438 * scsi device associated with this
439 439 * pathinfo
440 440 */
441 441 struct scsi_device *svp_psd;
442 442
443 443 /*
444 444 * number of outstanding commands on this
445 445 * path. Protected by svp_mutex
446 446 */
447 447 int svp_cmds;
448 448
449 449 /*
450 450 * following is used to prevent packets completing with the
451 451 * same error reason from flooding the screen
452 452 */
453 453 uchar_t svp_last_pkt_reason;
454 454
455 455 /* external failover scsi_watch token */
456 456 opaque_t svp_sw_token;
457 457
458 458 /* any cleanup operations for a newly found path. */
459 459 int svp_new_path;
460 460 } scsi_vhci_priv_t;
461 461
462 462 /*
463 463 * argument to scsi_watch callback. Used for processing
464 464 * externally initiated failovers
465 465 */
466 466 typedef struct scsi_vhci_swarg {
467 467 scsi_vhci_priv_t *svs_svp;
468 468 hrtime_t svs_tos; /* time of submission */
469 469 mdi_pathinfo_t *svs_pi; /* pathinfo being "watched" */
470 470 int svs_release_lun;
471 471 int svs_done;
472 472 } scsi_vhci_swarg_t;
473 473
474 474 /*
475 475 * scsi_vhci softstate
476 476 *
477 477 * vhci_mutex protects
478 478 * vhci_state
479 479 * and vhci_reset_notify list
480 480 */
481 481 struct scsi_vhci {
482 482 kmutex_t vhci_mutex;
483 483 dev_info_t *vhci_dip;
484 484 struct scsi_hba_tran *vhci_tran;
485 485 uint32_t vhci_state;
486 486 uint32_t vhci_instance;
487 487 kstat_t vhci_kstat;
488 488 /*
489 489 * This taskq is for general vhci operations like reservations,
490 490 * auto-failback, etc.
491 491 */
492 492 taskq_t *vhci_taskq;
493 493 /* Dedicate taskq to handle external failovers */
494 494 taskq_t *vhci_update_pathstates_taskq;
495 495 struct scsi_reset_notify_entry *vhci_reset_notify_listf;
496 496 uint16_t vhci_conf_flags;
497 497 mpapi_priv_t *mp_priv;
498 498 };
499 499
500 500 /*
501 501 * vHCI flags for configuration settings, defined in scsi_vhci.conf
502 502 */
503 503 #define VHCI_CONF_FLAGS_AUTO_FAILBACK 0x0001 /* Enables auto failback */
504 504
505 505 typedef enum {
506 506 SCSI_PATH_INACTIVE,
507 507 SCSI_PATH_ACTIVE,
508 508 SCSI_PATH_ACTIVE_NONOPT
509 509 } scsi_path_state_t;
510 510
511 511 #define SCSI_MAXPCLASSLEN 25
512 512
513 513 #define OPINFO_REV 1
514 514
515 515 /*
516 516 * structure describing operational characteristics of
517 517 * path
518 518 */
519 519 struct scsi_path_opinfo {
520 520 int opinfo_rev;
521 521
522 522 /*
523 523 * name of pathclass. Eg. "primary", "secondary"
524 524 */
525 525 char opinfo_path_attr[SCSI_MAXPCLASSLEN];
526 526
527 527 /*
528 528 * path state: ACTIVE/PASSIVE
529 529 */
530 530 scsi_path_state_t opinfo_path_state;
531 531
532 532 /*
533 533 * the best and worst case time estimates for
534 534 * failover operation to complete
535 535 */
536 536 uint_t opinfo_pswtch_best;
537 537 uint_t opinfo_pswtch_worst;
538 538
539 539 /* XLF implementation */
540 540 int opinfo_xlf_capable;
541 541 uint16_t opinfo_preferred;
542 542 uint16_t opinfo_mode;
543 543
544 544 };
545 545
546 546
547 547 #define SFO_REV 1
548 548
549 549 /*
550 550 * vectors for device specific failover related operations
551 551 */
552 552 struct scsi_failover_ops {
553 553 int sfo_rev;
554 554
555 555 /*
556 556 * failover module name, begins with "f_"
557 557 */
558 558 char *sfo_name;
559 559
560 560 /*
561 561 * devices supported by failover module
562 562 *
563 563 * NOTE: this is an aproximation, sfo_device_probe has the final say.
564 564 */
565 565 char **sfo_devices;
566 566
567 567 /*
568 568 * initialize the failover module
569 569 */
570 570 void (*sfo_init)();
571 571
572 572 /*
573 573 * identify device
574 574 */
575 575 int (*sfo_device_probe)(
576 576 struct scsi_device *sd,
577 577 struct scsi_inquiry *stdinq,
578 578 void **ctpriv);
579 579
580 580 /*
581 581 * housekeeping (free memory etc alloc'ed during probe
582 582 */
583 583 void (*sfo_device_unprobe)(
584 584 struct scsi_device *sd,
585 585 void *ctpriv);
586 586
587 587 /*
588 588 * bring a path ONLINE (ie make it ACTIVE)
589 589 */
590 590 int (*sfo_path_activate)(
591 591 struct scsi_device *sd,
592 592 char *pathclass,
593 593 void *ctpriv);
594 594
595 595 /*
596 596 * inverse of above
597 597 */
598 598 int (*sfo_path_deactivate)(
599 599 struct scsi_device *sd,
600 600 char *pathclass,
601 601 void *ctpriv);
602 602
603 603 /*
604 604 * returns operational characteristics of path
605 605 */
606 606 int (*sfo_path_get_opinfo)(
607 607 struct scsi_device *sd,
608 608 struct scsi_path_opinfo *opinfo,
609 609 void *ctpriv);
610 610
611 611 /*
612 612 * verify path is operational
613 613 */
614 614 int (*sfo_path_ping)(
615 615 struct scsi_device *sd,
616 616 void *ctpriv);
617 617
618 618 /*
619 619 * analyze SENSE data to detect externally initiated
620 620 * failovers
621 621 */
622 622 int (*sfo_analyze_sense)(
623 623 struct scsi_device *sd,
624 624 uint8_t *sense,
625 625 void *ctpriv);
626 626
627 627 /*
628 628 * return the next pathclass in order of preference
629 629 * eg. "secondary" comes after "primary"
630 630 */
631 631 int (*sfo_pathclass_next)(
632 632 char *cur,
633 633 char **nxt,
634 634 void *ctpriv);
635 635 };
636 636
637 637 /*
638 638 * Names of (too) 'well-known' failover ops.
639 639 * NOTE: consumers of these names should look for a better way...
640 640 */
641 641 #define SFO_NAME_SYM "f_sym"
642 642 #define SFO_NAME_TPGS "f_tpgs"
643 643 #define SCSI_FAILOVER_IS_ASYM(svl) \
644 644 ((svl) ? ((svl)->svl_fo_support != SCSI_NO_FAILOVER) : 0)
645 645 #define SCSI_FAILOVER_IS_TPGS(sfo) \
↓ open down ↓ |
645 lines elided |
↑ open up ↑ |
646 646 ((sfo) ? (strcmp((sfo)->sfo_name, SFO_NAME_TPGS) == 0) : 0)
647 647
648 648 /*
649 649 * Macro to provide plumbing for basic failover module
650 650 */
651 651 #define _SCSI_FAILOVER_OP(sfo_name, local_name, ops_name) \
652 652 static struct modlmisc modlmisc = { \
653 653 &mod_miscops, sfo_name \
654 654 }; \
655 655 static struct modlinkage modlinkage = { \
656 - MODREV_1, (void *)&modlmisc, NULL \
656 + MODREV_1, { (void *)&modlmisc, NULL } \
657 657 }; \
658 658 int _init() \
659 659 { \
660 660 return (mod_install(&modlinkage)); \
661 661 } \
662 662 int _fini() \
663 663 { \
664 664 return (mod_remove(&modlinkage)); \
665 665 } \
666 666 int _info(struct modinfo *modinfop) \
667 667 { \
668 668 return (mod_info(&modlinkage, modinfop)); \
669 669 } \
670 670 static int local_name##_device_probe( \
671 671 struct scsi_device *, \
672 672 struct scsi_inquiry *, void **); \
673 673 static void local_name##_device_unprobe( \
674 674 struct scsi_device *, void *); \
675 675 static int local_name##_path_activate( \
676 676 struct scsi_device *, char *, void *); \
677 677 static int local_name##_path_deactivate( \
678 678 struct scsi_device *, char *, void *); \
679 679 static int local_name##_path_get_opinfo( \
680 680 struct scsi_device *, \
681 681 struct scsi_path_opinfo *, void *); \
682 682 static int local_name##_path_ping( \
683 683 struct scsi_device *, void *); \
684 684 static int local_name##_analyze_sense( \
685 685 struct scsi_device *, \
686 686 uint8_t *, void *); \
687 687 static int local_name##_pathclass_next( \
688 688 char *, char **, void *); \
689 689 struct scsi_failover_ops ops_name##_failover_ops = { \
690 690 SFO_REV, \
691 691 sfo_name, \
692 692 local_name##_dev_table, \
693 693 NULL, \
694 694 local_name##_device_probe, \
695 695 local_name##_device_unprobe, \
696 696 local_name##_path_activate, \
697 697 local_name##_path_deactivate, \
698 698 local_name##_path_get_opinfo, \
699 699 local_name##_path_ping, \
700 700 local_name##_analyze_sense, \
701 701 local_name##_pathclass_next \
702 702 }
703 703
704 704 #ifdef lint
705 705 #define SCSI_FAILOVER_OP(sfo_name, local_name) \
706 706 _SCSI_FAILOVER_OP(sfo_name, local_name, local_name)
707 707 #else /* lint */
708 708 #define SCSI_FAILOVER_OP(sfo_name, local_name) \
709 709 _SCSI_FAILOVER_OP(sfo_name, local_name, scsi_vhci)
710 710 #endif /* lint */
711 711
712 712 /*
713 713 * Return values for sfo_device_probe
714 714 */
715 715 #define SFO_DEVICE_PROBE_VHCI 1 /* supported under scsi_vhci */
716 716 #define SFO_DEVICE_PROBE_PHCI 0 /* not supported under scsi_vhci */
717 717
718 718 /* return values for sfo_analyze_sense() */
719 719 #define SCSI_SENSE_NOFAILOVER 0
720 720 #define SCSI_SENSE_FAILOVER_INPROG 1
721 721 #define SCSI_SENSE_ACT2INACT 2
722 722 #define SCSI_SENSE_INACT2ACT 3
723 723 #define SCSI_SENSE_INACTIVE 4
724 724 #define SCSI_SENSE_UNKNOWN 5
725 725 #define SCSI_SENSE_STATE_CHANGED 6
726 726 #define SCSI_SENSE_NOT_READY 7
727 727
728 728 /* vhci_intr action codes */
729 729 #define JUST_RETURN 0
730 730 #define BUSY_RETURN 1
731 731 #define PKT_RETURN 2
732 732
733 733 #if defined(_SYSCALL32)
734 734 /*
735 735 * 32 bit variants of sv_path_info_prop_t and sv_path_info_t;
736 736 * To be used only in the driver and NOT applications
737 737 */
738 738 typedef struct sv_path_info_prop32 {
739 739 uint32_t buf_size; /* user buffer size */
740 740 caddr32_t ret_buf_size; /* actual buffer needed */
741 741 caddr32_t buf; /* user space buffer */
742 742 } sv_path_info_prop32_t;
743 743
744 744 typedef struct sv_path_info32 {
745 745 union {
746 746 char ret_ct[MAXPATHLEN]; /* client device */
747 747 char ret_phci[MAXPATHLEN]; /* pHCI device */
748 748 } device;
749 749
750 750 char ret_addr[MAXNAMELEN]; /* device address */
751 751 mdi_pathinfo_state_t ret_state; /* state information */
752 752 uint32_t ret_ext_state; /* Extended State */
753 753 sv_path_info_prop32_t ret_prop; /* path attributes */
754 754 } sv_path_info32_t;
755 755
756 756 typedef struct sv_iocdata32 {
757 757 caddr32_t client; /* client dev devfs path name */
758 758 caddr32_t phci; /* pHCI dev devfs path name */
759 759 caddr32_t addr; /* device address */
760 760 uint32_t buf_elem; /* number of path_info elems */
761 761 caddr32_t ret_buf; /* addr of array of sv_path_info */
762 762 caddr32_t ret_elem; /* count of above sv_path_info */
763 763 } sv_iocdata32_t;
764 764
765 765 typedef struct sv_switch_to_cntlr_iocdata32 {
766 766 caddr32_t client; /* client device devfs path name */
767 767 caddr32_t class; /* desired path class to be made active */
768 768 } sv_switch_to_cntlr_iocdata32_t;
769 769
770 770 #endif /* _SYSCALL32 */
771 771
772 772 #endif /* _KERNEL */
773 773
774 774 /*
775 775 * Userland (Non Kernel) definitions start here.
776 776 * Multiplexed I/O SCSI vHCI IOCTL Definitions
777 777 */
778 778
779 779 /*
780 780 * IOCTL structure for path properties
781 781 */
782 782 typedef struct sv_path_info_prop {
783 783 uint_t buf_size; /* user buffer size */
784 784 uint_t *ret_buf_size; /* actual buffer needed */
785 785 caddr_t buf; /* user space buffer */
786 786 } sv_path_info_prop_t;
787 787
788 788 /*
789 789 * Max buffer size of getting path properties
790 790 */
791 791 #define SV_PROP_MAX_BUF_SIZE 4096
792 792
793 793 /*
794 794 * String values for "path-class" property
795 795 */
796 796 #define PCLASS_PRIMARY "primary"
797 797 #define PCLASS_SECONDARY "secondary"
798 798
799 799 #define PCLASS_PREFERRED 1
800 800 #define PCLASS_NONPREFERRED 0
801 801
802 802 /*
803 803 * IOCTL structure for path information
804 804 */
805 805 typedef struct sv_path_info {
806 806 union {
807 807 char ret_ct[MAXPATHLEN]; /* client device */
808 808 char ret_phci[MAXPATHLEN]; /* pHCI device */
809 809 } device;
810 810
811 811 char ret_addr[MAXNAMELEN]; /* device address */
812 812 mdi_pathinfo_state_t ret_state; /* state information */
813 813 uint32_t ret_ext_state; /* Extended State */
814 814 sv_path_info_prop_t ret_prop; /* path attributes */
815 815 } sv_path_info_t;
816 816
817 817 /*
818 818 * IOCTL argument structure
819 819 */
820 820 typedef struct sv_iocdata {
821 821 caddr_t client; /* client dev devfs path name */
822 822 caddr_t phci; /* pHCI dev devfs path name */
823 823 caddr_t addr; /* device address */
824 824 uint_t buf_elem; /* number of path_info elems */
825 825 sv_path_info_t *ret_buf; /* array of sv_path_info */
826 826 uint_t *ret_elem; /* count of sv_path_info */
827 827 } sv_iocdata_t;
828 828
829 829 /*
830 830 * IOCTL argument structure for switching controllers
831 831 */
832 832 typedef struct sv_switch_to_cntlr_iocdata {
833 833 caddr_t client; /* client device devfs path name */
834 834 caddr_t class; /* desired path class to be made active */
835 835 } sv_switch_to_cntlr_iocdata_t;
836 836
837 837
838 838 /*
839 839 * IOCTL definitions
840 840 */
841 841 #define SCSI_VHCI_CTL ('X' << 8)
842 842 #define SCSI_VHCI_CTL_CMD (SCSI_VHCI_CTL | ('S' << 8) | 'P')
843 843 #define SCSI_VHCI_CTL_SUB_CMD ('x' << 8)
844 844
845 845 #define SCSI_VHCI_GET_CLIENT_MULTIPATH_INFO (SCSI_VHCI_CTL_SUB_CMD + 0x01)
846 846 #define SCSI_VHCI_GET_PHCI_MULTIPATH_INFO (SCSI_VHCI_CTL_SUB_CMD + 0x02)
847 847 #define SCSI_VHCI_GET_CLIENT_NAME (SCSI_VHCI_CTL_SUB_CMD + 0x03)
848 848 #define SCSI_VHCI_PATH_ONLINE (SCSI_VHCI_CTL_SUB_CMD + 0x04)
849 849 #define SCSI_VHCI_PATH_OFFLINE (SCSI_VHCI_CTL_SUB_CMD + 0x05)
850 850 #define SCSI_VHCI_PATH_STANDBY (SCSI_VHCI_CTL_SUB_CMD + 0x06)
851 851 #define SCSI_VHCI_PATH_TEST (SCSI_VHCI_CTL_SUB_CMD + 0x07)
852 852 #define SCSI_VHCI_SWITCH_TO_CNTLR (SCSI_VHCI_CTL_SUB_CMD + 0x08)
853 853
854 854 #ifdef DEBUG
855 855 #define SCSI_VHCI_GET_PHCI_LIST (SCSI_VHCI_CTL_SUB_CMD + 0x09)
856 856 #define SCSI_VHCI_CONFIGURE_PHCI (SCSI_VHCI_CTL_SUB_CMD + 0x0A)
857 857 #define SCSI_VHCI_UNCONFIGURE_PHCI (SCSI_VHCI_CTL_SUB_CMD + 0x0B)
858 858 #endif
859 859
860 860 #define SCSI_VHCI_PATH_DISABLE (SCSI_VHCI_CTL_SUB_CMD + 0x0C)
861 861 #define SCSI_VHCI_PATH_ENABLE (SCSI_VHCI_CTL_SUB_CMD + 0x0D)
862 862 #define SCSI_VHCI_MPAPI (SCSI_VHCI_CTL_SUB_CMD + 0x0E)
863 863
864 864 #define SCSI_VHCI_GET_TARGET_LONGNAME (SCSI_VHCI_CTL_SUB_CMD + 0x0F)
865 865
866 866 #ifdef __cplusplus
867 867 }
868 868 #endif
869 869
870 870 #endif /* _SYS_SCSI_ADAPTERS_SCSI_VHCI_H */
↓ open down ↓ |
204 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX