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