Emulex Logo
OneCoreā„¢ Storage SDK Release 11.2
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
ocs_ramdisc.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2011-2015, Emulex
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software
17  * without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  *
31  */
32 
33 /**
34  * @file
35  * OCS ramdisc declarations and exported API
36  */
37 
38 #if !defined(__OCS_RAMDISC_H__)
39 #define __OCS_RAMDISC_H__
40 
41 #define DIF_POOL_SIZE OCS_MAX_DMA_ALLOC
42 #define RAMDISC_MIN_BLOCK_SIZE 512
43 
44 /* Flag to enable DIF verification after write operations and before reads. */
45 #define ENABLE_DIF_VERIFICATION 0
46 
47 /**
48  * @ brief DIF block structure
49  */
50 
51 typedef struct {
52  uint16_t crc;
53  uint16_t app_tag;
54  uint32_t ref_tag;
55 } dif_t;
56 
57 /**
58  * @brief DIF separates allocation pool
59  *
60  */
61 
62 typedef struct dif_pool_s dif_pool_t;
63 
64 struct dif_pool_s {
65  ocs_dma_t dmabuf; /*<< DIF memory pool allocator */
66  uint32_t inuse_count; /*<< bytes in use */
67  ocs_list_link_t link; /*<< link for list of dif_pool_t objects */
68 };
69 
70 typedef struct {
71  void *virt;
72  uintptr_t phys;
73  size_t size;
74 } ocs_difdma_t;
75 
76 /**
77  * @brief ramdisc segment structure
78  */
79 typedef struct {
80  ocs_dma_t data_segment;
83 
84 /**
85  * @brief ramdisc instance structure
86  */
87 
88 typedef struct {
89  uint32_t lun; /**< LUN number for this ramdisc */
90  uint32_t data_block_size; /**< data (logical) block size in bytes */
91  uint32_t phys_block_size; /**< actual formatted block size in bytes including DIF */
92  uint32_t segment_block_size; /**< block size within segment */
93  uint8_t dif_separate; /**< TRUE if separate DIF */
94  uint32_t blocks_per_segment; /**< blocks per segment */
95  uint64_t block_count; /**< block count */
96  uint32_t pending_block_size; /**< last block size sent in a mode select (user data only, no DIF) */
97  uint8_t prot_capable; /**< interface is capable of doing T10 PI */
98  uint8_t p_type; /**< protection type for T10 PI */
99  uint8_t prot_en; /**< protection enabled flag for T10 PI */
100  uint8_t external_dif; /**< proprietary end-to-end protection enabled */
101  char t10_vendor_id[8]; /**< T10 Vendor ID to use with external_dif */
102 
103  uint8_t force_dif_separate; /*<< If TRUE, then always format with DIF separate */
104 
105  ocs_pool_t *segment_pool;
106  ramdisc_segment_t **segments; /**< pointer to allocated segment pointers */
107  uint32_t segment_count; /**< segment count */
108  uint32_t segment_size; /**< segment size in bytes */
109 
110  /* DIF separates allocation pool */
111  ocs_list_t dif_pool_list; /**< linked list of memory segments for DIF separates */
112 
113 } ocs_ramdisc_t;
114 
115 /**
116  * @brief generic ramdisc scatter-gather list
117  */
118 
119 typedef struct ocs_ramdisc_sgl_s {
120  uintptr_t addr; /**< physical address */
121  uintptr_t dif_addr; /**< address of DIF segment, zero if DIF is interleaved */
122  size_t len; /**< length in bytes */
124 
125 
126 extern int32_t ocs_new_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size, uint32_t blocks_per_segment,
127  uint64_t block_count);
128 extern int32_t ocs_del_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc);
129 #define SGL_REQ_FLAGS_PHYS (1U << 0)
130 extern int32_t ocs_ramdisc_sgl(ocs_t *ocs, ocs_ramdisc_t *ramdisc, ocs_ramdisc_sgl_t *sgl,
131  uint32_t max_sgl, uint32_t max_sge_size,
132  uint32_t lba, uint32_t *block_count, uint32_t req_flags,
133  uint8_t dump_buffer);
134 extern int32_t ocs_ramdisc_first_burst(ocs_t *ocs, ocs_ramdisc_t *ramdisc,
135  uint32_t lba, uint32_t lba_offset,
136  uint8_t *buffer, uint32_t buffer_size);
137 extern int32_t ocs_format_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size,
138  uint8_t p_type, uint8_t prot_en, uint8_t separate);
139 extern void ocs_set_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size);
140 extern uint32_t ocs_get_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc);
141 extern uint8_t* ocs_ramdisc_lba_address(ocs_ramdisc_t *ramdisc, uint64_t lba);
142 extern dif_t* ocs_ramdisc_dif_address(ocs_ramdisc_t *ramdisc, uint64_t lba);
143 extern void ocs_ddump_ramdisc(ocs_textbuf_t *textbuf, ocs_ramdisc_t *ramdisc);
144 
145 /* DIF separates allocation */
146 extern void dif_pool_init(ocs_t *ocs, ocs_list_t *head);
147 extern void dif_pool_free(ocs_t *ocs, ocs_list_t *head);
148 extern int32_t dif_pool_alloc(ocs_t *ocs, ocs_list_t *head, uint32_t size, ocs_difdma_t *difdma);
149 
150 /* DIF verification - debugging only */
151 #if ENABLE_DIF_VERIFICATION == 1
152 extern int32_t ocs_ramdisc_dif_verify(ocs_t *ocs, ocs_ramdisc_t *ramdisc,
153  uint64_t lba, uint32_t block_count);
154 #endif
155 
156 #endif // __OCS_RAMDISC_H__
void dif_pool_init(ocs_t *ocs, ocs_list_t *head)
initialize the DIF memory pool
Definition: ocs_ramdisc.c:636
uint32_t data_block_size
Definition: ocs_ramdisc.h:90
int32_t ocs_new_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size, uint32_t blocks_per_segment, uint64_t block_count)
Create a new ramdisc instance (LUN).
Definition: ocs_ramdisc.c:72
ocs_list_t ocs_list_link_t
Definition: ocs_list.h:84
uint8_t * ocs_ramdisc_lba_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of a ramdisc logical block.
Definition: ocs_ramdisc.c:577
uint8_t prot_capable
Definition: ocs_ramdisc.h:97
int32_t dif_pool_alloc(ocs_t *ocs, ocs_list_t *head, uint32_t size, ocs_difdma_t *difdma)
Allocate memory for the DIF memory pool.
Definition: ocs_ramdisc.c:724
uint32_t segment_size
Definition: ocs_ramdisc.h:108
uint32_t phys_block_size
Definition: ocs_ramdisc.h:91
int32_t ocs_ramdisc_sgl(ocs_t *ocs, ocs_ramdisc_t *ramdisc, ocs_ramdisc_sgl_t *sgl, uint32_t max_sgl, uint32_t max_sge_size, uint32_t lba, uint32_t *block_count, uint32_t req_flags, uint8_t dump_buffer)
Build an SGL list for blocks in a ramdisc.
Definition: ocs_ramdisc.c:218
uint64_t block_count
Definition: ocs_ramdisc.h:95
uint32_t segment_count
Definition: ocs_ramdisc.h:107
uint32_t ref_tag
Definition: ocs_ramdisc.h:54
uint32_t blocks_per_segment
Definition: ocs_ramdisc.h:94
void ocs_set_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size)
Set the ramdisc block size.
Definition: ocs_ramdisc.c:537
uint8_t force_dif_separate
Definition: ocs_ramdisc.h:103
ramdisc instance structure
Definition: ocs_ramdisc.h:88
ramdisc segment structure
Definition: ocs_ramdisc.h:79
int32_t ocs_del_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc)
Delete a ramdisc instance.
Definition: ocs_ramdisc.c:151
size_t size
Definition: ocs_ramdisc.h:73
int32_t ocs_ramdisc_first_burst(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t lba, uint32_t lba_offset, uint8_t *buffer, uint32_t buffer_size)
uint8_t external_dif
Definition: ocs_ramdisc.h:100
uint16_t crc
Definition: ocs_ramdisc.h:52
uint8_t prot_en
Definition: ocs_ramdisc.h:99
ramdisc_segment_t ** segments
Definition: ocs_ramdisc.h:106
generic ramdisc scatter-gather list
Definition: ocs_ramdisc.h:119
uintptr_t dif_addr
Definition: ocs_ramdisc.h:121
dif_t * ocs_ramdisc_dif_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of the DIF block if protection is enabled.
Definition: ocs_ramdisc.c:605
uint32_t lun
Definition: ocs_ramdisc.h:89
void * virt
Definition: ocs_ramdisc.h:71
ocs_list_t dif_pool_list
Definition: ocs_ramdisc.h:111
ocs_list_link_t link
Definition: ocs_ramdisc.h:67
uint32_t pending_block_size
Definition: ocs_ramdisc.h:96
DIF separates allocation pool.
Definition: ocs_ramdisc.h:64
uint32_t segment_block_size
Definition: ocs_ramdisc.h:92
uint8_t dif_separate
Definition: ocs_ramdisc.h:93
uintptr_t phys
Definition: ocs_ramdisc.h:72
int32_t ocs_format_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size, uint8_t p_type, uint8_t prot_en, uint8_t dif_separate)
Reformat an existing ramdisc, possibly the changing block size and/or protection. ...
Definition: ocs_ramdisc.c:359
uint16_t app_tag
Definition: ocs_ramdisc.h:53
uint32_t ocs_get_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc)
Get the ramdisc block size.
Definition: ocs_ramdisc.c:555
ocs_pool_t * segment_pool
Definition: ocs_ramdisc.h:105
uint32_t inuse_count
Definition: ocs_ramdisc.h:66
uint8_t p_type
Definition: ocs_ramdisc.h:98
ocs_dma_t data_segment
Definition: ocs_ramdisc.h:80
ocs_dma_t dmabuf
Definition: ocs_ramdisc.h:65
void ocs_ddump_ramdisc(ocs_textbuf_t *textbuf, ocs_ramdisc_t *ramdisc)
Definition: ocs_ramdisc.c:759
ocs_difdma_t dif_segment
Definition: ocs_ramdisc.h:81
void dif_pool_free(ocs_t *ocs, ocs_list_t *head)
Free the DIF memory pool.
Definition: ocs_ramdisc.c:660