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