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