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