xref: /illumos-gate/usr/src/uts/common/io/comstar/lu/stmf_sbd/ats_copy_mgr.h (revision 61dfa5098dc8576d9a5e277deba6df647bb70c06)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2016 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 #ifndef	_ATS_COPY_MGR_H
17 #define	_ATS_COPY_MGR_H
18 
19 #ifdef	__cplusplus
20 extern "C" {
21 #endif
22 
23 /* ATS structures and functions. */
24 
25 typedef struct ats_state_s {
26 	/*
27 	 * We actually dont allow I/O which conflicts with current ats.
28 	 * The conflicting_rw_count is for those I/Os which are currently
29 	 * running and are potentally conflicting.
30 	 */
31 	list_node_t	as_next;
32 	uint8_t		as_cmd;
33 	uint32_t	as_conflicting_rw_count;
34 	uint32_t	as_non_conflicting_rw_count;
35 	uint32_t	as_ats_gen_ndx;
36 	uint32_t	as_cur_ats_handle;
37 	uint64_t	as_cur_ats_lba;
38 	uint64_t	as_cur_ats_lba_end;
39 	uint64_t	as_cur_ats_len;		/* in nblks */
40 	struct scsi_task *as_cur_ats_task;
41 } ats_state_t;
42 
43 /* Since we're technically part of stmf_sbd.h, use some defines here. */
44 #define	sl_conflicting_rw_count	sl_ats_state.as_conflicting_rw_count
45 #define	sl_non_conflicting_rw_count sl_ats_state.as_non_conflicting_rw_count
46 #define	sl_ats_gen_ndx sl_ats_state.as_ats_gen_ndx
47 #define	sl_cur_ats_handle sl_ats_state.as_cur_ats_handle
48 #define	sl_cur_ats_lba sl_ats_state.as_cur_ats_lba
49 #define	sl_cur_ats_len sl_ats_state.as_cur_ats_len
50 #define	sl_cur_ats_task sl_ats_state.as_cur_ats_task
51 
52 struct sbd_cmd;
53 struct sbd_lu;
54 
55 void sbd_handle_ats_xfer_completion(struct scsi_task *, struct sbd_cmd *,
56     struct stmf_data_buf *, uint8_t);
57 void sbd_do_ats_xfer(struct scsi_task *, struct sbd_cmd *,
58     struct stmf_data_buf *, uint8_t);
59 void sbd_handle_ats(scsi_task_t *, struct stmf_data_buf *);
60 void sbd_handle_recv_copy_results(struct scsi_task *, struct stmf_data_buf *);
61 void sbd_free_ats_handle(struct scsi_task *, struct sbd_cmd *);
62 void sbd_handle_ats(scsi_task_t *, struct stmf_data_buf *);
63 uint8_t sbd_ats_max_nblks(void);
64 void sbd_ats_remove_by_task(scsi_task_t *);
65 sbd_status_t sbd_ats_handling_before_io(scsi_task_t *task, struct sbd_lu *sl,
66     uint64_t lba, uint64_t count);
67 
68 /* Block-copy structures and functions. */
69 
70 struct scsi_task;
71 typedef	void *cpmgr_handle_t;
72 
73 #define	CPMGR_INVALID_HANDLE		((cpmgr_handle_t)NULL)
74 
75 #define	CPMGR_DEFAULT_TIMEOUT		30
76 
77 #define	CPMGR_PARAM_HDR_LEN		16
78 #define	CPMGR_IDENT_TARGET_DESCRIPTOR	0xE4
79 #define	CPMGR_MAX_TARGET_DESCRIPTORS	2
80 #define	CPMGR_TARGET_DESCRIPTOR_SIZE	32
81 
82 #define	CPMGR_B2B_SEGMENT_DESCRIPTOR		2
83 #define	CPMGR_MAX_SEGMENT_DESCRIPTORS		1
84 #define	CPMGR_B2B_SEGMENT_DESCRIPTOR_SIZE	28
85 
86 /*
87  * SCSI errors before copy starts.
88  */
89 #define	CPMGR_PARAM_LIST_LEN_ERROR		0x051A00
90 #define	CPMGR_INVALID_FIELD_IN_PARAM_LIST	0x052600
91 #define	CPMGR_TOO_MANY_TARGET_DESCRIPTORS	0x052606
92 #define	CPMGR_UNSUPPORTED_TARGET_DESCRIPTOR	0x052607
93 #define	CPMGR_TOO_MANY_SEGMENT_DESCRIPTORS	0x052608
94 #define	CPMGR_UNSUPPORTED_SEGMENT_DESCRIPTOR	0x052609
95 #define	CPMGR_COPY_TARGET_NOT_REACHABLE		0x050D02
96 #define	CPMGR_INSUFFICIENT_RESOURCES		0x0B5503
97 
98 /*
99  * SCSI errors after copy has started.
100  */
101 #define	CPMGR_LBA_OUT_OF_RANGE			0x0A2100
102 #define	CPMGR_THIRD_PARTY_DEVICE_FAILURE	0x0A0D01
103 
104 /*
105  * SCSI errors which dont result in STATUS_CHECK.
106  * Use and invalid sense key to mark these.
107  */
108 #define	CPMGR_RESERVATION_CONFLICT		0xF00001
109 
110 typedef enum cm_state {
111 	CM_STARTING = 0,
112 	CM_COPYING,
113 	CM_COMPLETE
114 } cm_state_t;
115 
116 #define	CPMGR_XFER_BUF_SIZE		(128 * 1024)
117 
118 typedef struct cm_target_desc {
119 	stmf_lu_t	*td_lu;
120 	uint32_t	td_disk_block_len;
121 	uint8_t		td_lbasize_shift;
122 } cm_target_desc_t;
123 
124 /*
125  * Current implementation supports 2 target descriptors (identification type)
126  * for src and dst and one segment descriptor (block -> block).
127  */
128 typedef struct cpmgr {
129 	cm_target_desc_t	cm_tds[CPMGR_MAX_TARGET_DESCRIPTORS];
130 	uint8_t			cm_td_count;
131 	uint16_t		cm_src_td_ndx;
132 	uint16_t		cm_dst_td_ndx;
133 	cm_state_t		cm_state;
134 	uint32_t		cm_status;
135 	uint64_t		cm_src_offset;
136 	uint64_t		cm_dst_offset;
137 	uint64_t		cm_copy_size;
138 	uint64_t		cm_size_done;
139 	void			*cm_xfer_buf;
140 	scsi_task_t		*cm_task;
141 } cpmgr_t;
142 
143 #define	cpmgr_done(cm)	(((cpmgr_t *)(cm))->cm_state == CM_COMPLETE)
144 #define	cpmgr_status(cm) (((cpmgr_t *)(cm))->cm_status)
145 
146 cpmgr_handle_t cpmgr_create(struct scsi_task *task, uint8_t *params);
147 void cpmgr_destroy(cpmgr_handle_t h);
148 void cpmgr_run(cpmgr_t *cm, clock_t preemption_point);
149 void cpmgr_abort(cpmgr_t *cm, uint32_t s);
150 void sbd_handle_xcopy_xfer(scsi_task_t *, uint8_t *);
151 void sbd_handle_xcopy(scsi_task_t *, stmf_data_buf_t *);
152 
153 #ifdef	__cplusplus
154 }
155 #endif
156 
157 #endif /* _ATS_COPY_MGR_H */
158