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 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24#ifndef _SYS_PPPT_IC_IF_H
25#define	_SYS_PPPT_IC_IF_H
26
27#include <sys/stmf_defines.h>
28
29#ifdef	__cplusplus
30extern "C" {
31#endif
32
33/*
34 * ALUA messaging and interconnect API.
35 */
36
37/*
38 * Message type.
39 */
40typedef enum {
41	STMF_ICM_REGISTER_PROXY_PORT = 0,
42	STMF_ICM_DEREGISTER_PROXY_PORT,
43	STMF_ICM_REGISTER_LUN,
44	STMF_ICM_DEREGISTER_LUN,
45	STMF_ICM_SCSI_CMD,
46	STMF_ICM_SCSI_DATA,
47	STMF_ICM_SCSI_DATA_XFER_DONE,
48	STMF_ICM_SCSI_STATUS,
49	STMF_ICM_R2T,
50	STMF_ICM_STATUS,
51	STMF_ICM_SESSION_CREATE,
52	STMF_ICM_SESSION_DESTROY,
53	STMF_ICM_ECHO_REQUEST,
54	STMF_ICM_ECHO_REPLY,
55	STMF_ICM_LUN_ACTIVE,
56	STMF_ICM_MAX_MSG_TYPE
57} stmf_ic_msg_type_t;
58
59/*
60 * Message id: uniquely identifies a message.
61 * This need not be a sequence number since we don't depend on
62 * messages being delivered in sequence.
63 */
64typedef uint64_t stmf_ic_msgid_t;
65
66/*
67 * IC message.  This is a container for the various specific message types.
68 *
69 * Note that the message contains a pointer to an nvlist.  This pointer
70 * is valid only in the case of messages which are unmarshaled from
71 * nvlists.  In that case, it's important to retain a pointer to the nvlist,
72 * since the message and the nvlist share data in the case of strings
73 * and array elements, and data in the message may be invalid if used
74 * after the nvlist is freed.
75 */
76typedef struct stmf_ic_msg {
77	stmf_ic_msg_type_t icm_msg_type;
78	stmf_ic_msgid_t icm_msgid;
79	nvlist_t *icm_nvlist;		/* nvlist associated with the msg */
80	void *icm_msg;			/* ptr to the specific msg */
81} stmf_ic_msg_t;
82
83/*
84 * Register port message.
85 */
86typedef struct {
87	scsi_devid_desc_t 	*icrp_port_id;
88	uint16_t 		icrp_relative_port_id;
89	/* opaque callback data */
90	uint16_t		icrp_cb_arg_len;
91	uint8_t			*icrp_cb_arg;
92} stmf_ic_reg_port_msg_t;
93
94/*
95 * Deregister port message.
96 */
97typedef struct {
98	scsi_devid_desc_t 	*icdp_port_id;
99	/* opaque callback data */
100	uint16_t		icdp_cb_arg_len;
101	uint8_t			*icdp_cb_arg;
102} stmf_ic_dereg_port_msg_t;
103
104/*
105 * Register/deregister lun message.
106 */
107typedef struct {
108	uint8_t 		icrl_lun_id[16];
109	char			*icrl_lu_provider_name;
110	/* opaque callback data */
111	uint16_t		icrl_cb_arg_len;
112	uint8_t			*icrl_cb_arg;
113} stmf_ic_reg_dereg_lun_msg_t;
114
115/*
116 * SCSI cmd msg.
117 */
118typedef struct {
119	stmf_ic_msgid_t		icsc_task_msgid;
120	scsi_devid_desc_t	*icsc_ini_devid;
121	scsi_devid_desc_t	*icsc_tgt_devid;
122	stmf_remote_port_t	*icsc_rport;
123	uint8_t 		icsc_lun_id[16];
124	/*
125	 * fields from scsi_task_t
126	 */
127	uint64_t	icsc_session_id;
128	uint8_t		icsc_task_lun_no[8];
129	uint32_t	icsc_task_expected_xfer_length;
130	uint16_t	icsc_task_cdb_length;
131	uint8_t 	*icsc_task_cdb;
132	uint8_t		icsc_task_flags;	/* See def. for task flags */
133	uint8_t		icsc_task_priority;	/* As per SAM-3 */
134	uint8_t		icsc_task_mgmt_function;	/* if is a TM req */
135	uint32_t	icsc_immed_data_len;
136	uint8_t		*icsc_immed_data;
137} stmf_ic_scsi_cmd_msg_t;
138
139/*
140 * SCSI data message.
141 */
142typedef struct {
143	stmf_ic_msgid_t icsd_task_msgid;	/* matches msgid of cmd */
144	uint64_t icsd_session_id;
145	uint8_t icsd_lun_id[16];
146	uint64_t icsd_data_len;
147	uint8_t *icsd_data;
148} stmf_ic_scsi_data_msg_t;
149
150/*
151 * SCSI data xfer done msg
152 */
153typedef struct {
154	stmf_ic_msgid_t icsx_task_msgid;	/* matches msgid of cmd */
155	uint64_t icsx_session_id;
156	stmf_status_t	icsx_status;
157} stmf_ic_scsi_data_xfer_done_msg_t;
158
159/*
160 * SCSI status msg.
161 */
162typedef struct {
163	stmf_ic_msgid_t icss_task_msgid;	/* matches msgid of cmd */
164	uint64_t icss_session_id;
165	uint8_t icss_lun_id[16];
166	uint8_t icss_response;		/* was command processed? */
167	uint8_t icss_status;
168	uint8_t	icss_flags;		/* TASK_SCTRL_OVER, TASK_SCTRL_UNDER */
169	uint32_t icss_resid;
170	uint8_t	icss_sense_len;
171	uint8_t	*icss_sense;
172} stmf_ic_scsi_status_msg_t;
173
174/*
175 * Ready to transfer (r2t) msg.
176 */
177typedef struct {
178	stmf_ic_msgid_t icrt_task_msgid;	/* matches msgid of cmd */
179	uint64_t icrt_session_id;
180	uint32_t icrt_offset;
181	uint32_t icrt_length;
182} stmf_ic_r2t_msg_t;
183
184/*
185 * Status message: sent in response to messages other than SCSI messages.
186 */
187typedef struct {
188	stmf_ic_msg_type_t ics_msg_type;	/* msg type rpting status on */
189	stmf_ic_msgid_t ics_msgid;		/* msgid reporting status on */
190	stmf_status_t ics_status;
191} stmf_ic_status_msg_t;
192
193/*
194 * Session create/destroy message.
195 */
196typedef struct {
197	uint64_t		icscd_session_id;
198	scsi_devid_desc_t	*icscd_ini_devid;
199	scsi_devid_desc_t	*icscd_tgt_devid;
200	stmf_remote_port_t	*icscd_rport;
201} stmf_ic_session_create_destroy_msg_t;
202
203/*
204 * Echo request/reply message
205 */
206typedef struct {
207	uint8_t			*icerr_data;
208	uint32_t		icerr_datalen;
209} stmf_ic_echo_request_reply_msg_t;
210
211typedef enum {
212	STMF_IC_MSG_SUCCESS = 0,
213	STMF_IC_MSG_IC_DOWN,
214	STMF_IC_MSG_TIMED_OUT,
215	STMF_IC_MSG_INTERNAL_ERROR
216} stmf_ic_msg_status_t;
217
218/*
219 * Function prototypes.
220 *
221 * Note: Functions which are exported to other modules must have a function
222 * typedef and a prototype; the function type definition is used by
223 * the other module to import the symbol using ddi_modsym().
224 */
225
226void stmf_ic_ioctl_cmd(void *ibuf, uint32_t ibuf_size);
227
228/* Allocate a register port message */
229typedef
230stmf_ic_msg_t *(*stmf_ic_reg_port_msg_alloc_func_t)(
231    scsi_devid_desc_t *port_id,
232    uint16_t relative_port_id,
233    uint16_t cb_arg_len,
234    uint8_t *cb_arg,
235    stmf_ic_msgid_t msgid);
236
237stmf_ic_msg_t *stmf_ic_reg_port_msg_alloc(
238    scsi_devid_desc_t *port_id,
239    uint16_t relative_port_id,
240    uint16_t cb_arg_len,
241    uint8_t *cb_arg,
242    stmf_ic_msgid_t msgid);
243
244/* Allocate a deregister port message */
245typedef
246stmf_ic_msg_t *(*stmf_ic_dereg_port_msg_alloc_func_t)(
247    scsi_devid_desc_t *port_id,
248    uint16_t cb_arg_len,
249    uint8_t *cb_arg,
250    stmf_ic_msgid_t msgid);
251
252stmf_ic_msg_t *stmf_ic_dereg_port_msg_alloc(
253    scsi_devid_desc_t *port_id,
254    uint16_t cb_arg_len,
255    uint8_t *cb_arg,
256    stmf_ic_msgid_t msgid);
257
258
259/* Allocate a register lun message */
260typedef
261stmf_ic_msg_t *(*stmf_ic_reg_lun_msg_alloc_func_t)(
262    uint8_t *icrl_lun_id,	/* should be 16 bytes */
263    char *lu_provider_name,
264    uint16_t cb_arg_len,
265    uint8_t *cb_arg,
266    stmf_ic_msgid_t msgid);
267
268stmf_ic_msg_t *stmf_ic_reg_lun_msg_alloc(
269    uint8_t *icrl_lun_id,	/* should be 16 bytes */
270    char *lu_provider_name,
271    uint16_t cb_arg_len,
272    uint8_t *cb_arg,
273    stmf_ic_msgid_t msgid);
274
275/* Allocate a lun active message */
276typedef
277stmf_ic_msg_t *(*stmf_ic_lun_active_msg_alloc_func_t)(
278    uint8_t *icrl_lun_id,	/* should be 16 bytes */
279    char *lu_provider_name,
280    uint16_t cb_arg_len,
281    uint8_t *cb_arg,
282    stmf_ic_msgid_t msgid);
283
284stmf_ic_msg_t *stmf_ic_lun_active_msg_alloc(
285    uint8_t *icrl_lun_id,	/* should be 16 bytes */
286    char *lu_provider_name,
287    uint16_t cb_arg_len,
288    uint8_t *cb_arg,
289    stmf_ic_msgid_t msgid);
290
291/* Allocate a deregister lun message */
292typedef
293stmf_ic_msg_t *(*stmf_ic_dereg_lun_msg_alloc_func_t)(
294    uint8_t *icrl_lun_id,	/* should be 16 bytes */
295    char *lu_provider_name,
296    uint16_t cb_arg_len,
297    uint8_t *cb_arg,
298    stmf_ic_msgid_t msgid);
299
300stmf_ic_msg_t *stmf_ic_dereg_lun_msg_alloc(
301    uint8_t *icrl_lun_id,	/* should be 16 bytes */
302    char *lu_provider_name,
303    uint16_t cb_arg_len,
304    uint8_t *cb_arg,
305    stmf_ic_msgid_t msgid);
306
307/* Allocate a scsi cmd message */
308typedef
309stmf_ic_msg_t *(*stmf_ic_scsi_cmd_msg_alloc_func_t)(
310    stmf_ic_msgid_t 	task_msgid,
311    scsi_task_t 	*scsi_task,
312    uint32_t		immed_data_len,
313    uint8_t		*immed_data,
314    stmf_ic_msgid_t msgid);
315
316stmf_ic_msg_t *stmf_ic_scsi_cmd_msg_alloc(
317    stmf_ic_msgid_t 	task_msgid,
318    scsi_task_t 	*scsi_task,
319    uint32_t		immed_data_len,
320    uint8_t		*immed_data,
321    stmf_ic_msgid_t msgid);
322
323/* Allocate a scsi data message */
324typedef
325stmf_ic_msg_t *(*stmf_ic_scsi_data_msg_alloc_func_t)(
326    stmf_ic_msgid_t 	task_msgid,
327    uint64_t		session_id,
328    uint8_t		*lun_id,
329    uint64_t		data_len,
330    uint8_t		*data,
331    stmf_ic_msgid_t msgid);
332
333stmf_ic_msg_t *stmf_ic_scsi_data_msg_alloc(
334    stmf_ic_msgid_t 	task_msgid,
335    uint64_t		session_id,
336    uint8_t		*lun_id,
337    uint64_t		data_len,
338    uint8_t		*data,
339    stmf_ic_msgid_t msgid);
340
341/* Allocate a scsi transfer done message */
342typedef
343stmf_ic_msg_t *(*stmf_ic_scsi_data_xfer_done_msg_alloc_func_t)(
344    stmf_ic_msgid_t 	task_msgid,
345    uint64_t		session_id,
346    stmf_status_t	status,
347    stmf_ic_msgid_t	msgid);
348
349stmf_ic_msg_t *stmf_ic_scsi_data_xfer_done_msg_alloc(
350    stmf_ic_msgid_t 	task_msgid,
351    uint64_t		session_id,
352    stmf_status_t	status,
353    stmf_ic_msgid_t	msgid);
354
355
356/* Allocate a scsi status message */
357stmf_ic_msg_t *stmf_ic_scsi_status_msg_alloc(
358    stmf_ic_msgid_t 	task_msgid,
359    uint64_t		session_id,
360    uint8_t		*lun_id,
361    uint8_t		response,		/* was command processed? */
362    uint8_t		status,
363    uint8_t		flags,
364    uint32_t 		resid,
365    uint8_t		sense_len,
366    uint8_t		*sense,
367    stmf_ic_msgid_t msgid);	/* must match corresponding scsi cmd msgid */
368
369
370/* Allocate a scsi ready to transfer (r2t) message */
371stmf_ic_msg_t *stmf_ic_r2t_msg_alloc(
372    stmf_ic_msgid_t 	task_msgid,
373    uint64_t		session_id,
374    uint32_t		offset,
375    uint32_t		length,
376    stmf_ic_msgid_t msgid);	/* must match corresponding scsi cmd msgid */
377
378/* Allocate a status message */
379stmf_ic_msg_t *stmf_ic_status_msg_alloc(
380    stmf_status_t	status,
381    stmf_ic_msg_type_t	msg_type,	/* msg type reporting status on */
382    stmf_ic_msgid_t 	msgid);		/* id of msg reporting status on */
383
384/* Allocate a session create message */
385typedef
386stmf_ic_msg_t *(*stmf_ic_session_create_msg_alloc_func_t)(
387    stmf_scsi_session_t *session,
388    stmf_ic_msgid_t msgid);
389
390stmf_ic_msg_t *stmf_ic_session_create_msg_alloc(
391    stmf_scsi_session_t *session,
392    stmf_ic_msgid_t msgid);
393
394/* Allocate a session destroy message */
395typedef
396stmf_ic_msg_t *(*stmf_ic_session_destroy_msg_alloc_func_t)(
397    stmf_scsi_session_t *session,
398    stmf_ic_msgid_t msgid);
399
400stmf_ic_msg_t *stmf_ic_session_destroy_msg_alloc(
401    stmf_scsi_session_t *session,
402    stmf_ic_msgid_t msgid);
403
404/* Allocate an echo request message */
405stmf_ic_msg_t *stmf_ic_echo_request_msg_alloc(
406    uint32_t data_len,
407    uint8_t *data,
408    stmf_ic_msgid_t msgid);
409
410/* Allocate an echo reply message */
411stmf_ic_msg_t *stmf_ic_echo_reply_msg_alloc(
412    uint32_t data_len,
413    uint8_t *data,
414    stmf_ic_msgid_t msgid);
415
416/*
417 * Free a msg.
418 */
419typedef void (*stmf_ic_msg_free_func_t)(stmf_ic_msg_t *msg);
420void stmf_ic_msg_free(stmf_ic_msg_t *msg);
421
422/*
423 * Send a message out over the interconnect, in the process marshalling
424 * the arguments.
425 *
426 * After being sent, the message is freed by tx_msg().
427 */
428typedef stmf_ic_msg_status_t (*stmf_ic_tx_msg_func_t)(stmf_ic_msg_t *msg);
429stmf_ic_msg_status_t stmf_ic_tx_msg(stmf_ic_msg_t *msg);
430
431/*
432 * This is a low-level upcall which is called when a message has
433 * been received on the interconnect.
434 */
435void stmf_ic_rx_msg(char *buf, size_t len);
436
437stmf_status_t stmf_msg_rx(stmf_ic_msg_t *msg);
438
439#ifdef	__cplusplus
440}
441#endif
442
443#endif	/* _SYS_PPPT_IC_IF_H */
444