49 #define ENABLE_SEED_WITH_PATTERN 0
51 #if ENABLE_DIF_VERIFICATION == 1 || ENABLE_SEED_WITH_PATTERN == 1
55 #if defined(OCS_INCLUDE_DEBUG)
73 uint32_t blocks_per_segment, uint64_t block_count)
83 ocs_memset(ramdisc, 0,
sizeof(*ramdisc));
95 ramdisc->
segment_count = (block_count + blocks_per_segment - 1) / blocks_per_segment;
99 ocs_log_err(ocs,
"ocs_pool_alloc(%lu, %u) failed\n",
104 #if !defined(OCS_USPACE)
105 if (ocs->ocs_os.hw_cmpl_context != OCS_HW_CMPL_CONTEXT_THREAD)
112 ocs_log_err(ocs,
"ocs_malloc(%u * %lu) segments failed\n",
123 ocs_log_err(ocs,
"unable to get segment %u\n", i);
129 ocs_log_err(ocs,
"ocs_dma_alloc failed creating segment %u\n", i);
172 #if !defined(OCS_USPACE)
173 if (ocs->ocs_os.hw_cmpl_context != OCS_HW_CMPL_CONTEXT_THREAD)
219 uint32_t max_sgl, uint32_t max_sge_size,
220 uint32_t lba, uint32_t *block_count, uint32_t req_flags, uint8_t dump_buffer)
228 uint32_t sgl_count = 0;
229 uint32_t blocks_remaining = *block_count;
232 uint32_t multi_dif_separate = 1;
241 if ((lba + blocks_remaining) > ramdisc->
block_count) {
256 while ((blocks_remaining > 0) &&
257 (sgl_count < max_sgl)) {
263 #if defined(OCS_INCLUDE_DEBUG)
269 sprintf(desc,
"Phy addr: 0x%x 0x%08x size: 0x%x",
281 sprintf(desc,
"Dif Separate Phy addr: 0x%x 0x%08x size: 0x%x",
294 if (!multi_dif_separate) {
301 for (i = 0; i < n; i ++) {
302 if ((sgl_count + 1) < max_sgl) {
332 blocks_remaining -= n;
334 if (dif_separate && !multi_dif_separate) {
339 *block_count -= blocks_remaining;
363 int format_changed = 0;
368 if (block_size == 0) {
411 ocs_log_info(ocs,
"Formating LUN %d with %" PRIu64
" blocks of %d/%d bytes, p_type is %d, prot_en is %d dif_separate %d\n",
419 #if ENABLE_SEED_WITH_PATTERN==1
429 blk_dword[0] = blkCount;
430 for (k = 1; k < dwords_per_blk - 1; k++) {
431 blk_dword[k] = blkCount + k;
434 blk_dword += dwords_per_blk;
454 ocs_log_err(ocs,
"dif_pool_alloc failed: %d\n", rc);
487 #if ENABLE_SEED_WITH_PATTERN==1
502 dif_block[0] = (crc >> 8);
503 dif_block[1] = (crc & 0xff);
506 dif_block[4] = blkCount >> 24;
507 dif_block[5] = (blkCount >> 16) & 0xff;
508 dif_block[6] = (blkCount >> 8) & 0xff;
509 dif_block[7] = blkCount & 0xff;
511 ocs_memset(dif_block, 0xff,
DIF_SIZE);
513 dif_block += dif_incr;
519 return format_changed;
642 difpool->inuse_count = 0;
669 ocs_dma_free(ocs, &difpool->dmabuf);
670 ocs_free(ocs, difpool,
sizeof(*difpool));
693 difpool = ocs_malloc(ocs,
sizeof(*difpool), OCS_M_NOWAIT | OCS_M_ZERO);
694 if (difpool == NULL) {
695 ocs_log_err(ocs,
"ocs_malloc failed\n");
698 rc = ocs_dma_alloc(ocs, &difpool->dmabuf,
DIF_POOL_SIZE, OCS_MIN_DMA_ALIGNMENT);
700 ocs_log_err(ocs,
"ocs_dma_alloc() failed: %d\n", rc);
701 ocs_free(ocs, difpool,
sizeof(*difpool));
730 size = ocs_roundup(size, 16);
742 if ((difpool->dmabuf.size - difpool->inuse_count) < size) {
749 ocs_assert((difpool->dmabuf.size - difpool->inuse_count) >= size, -1);
750 difdma->
phys = difpool->dmabuf.phys + difpool->inuse_count;
751 difdma->
virt = ((uint8_t*)difpool->dmabuf.virt) + difpool->inuse_count;
753 difpool->inuse_count += size;
761 #if defined(ENABLE_DDUMP_RAMDISC_SEGMENTS)
780 #if defined(ENABLE_DDUMP_RAMDISC_SEGMENTS)
800 #if ENABLE_DIF_VERIFICATION == 1
816 uint64_t lba, uint32_t block_count)
823 uint16_t recv_apptag;
824 uint32_t recv_reftag;
831 uint8_t errors_detected;
838 for (i = 0; i < block_count; i++) {
846 lba_off = (lba + i) - l0;
859 errors_detected = FALSE;
861 recv_crc = ((uint16_t)difbytes[0]) << 8 | difbytes[1];
863 if (crc != recv_crc && recv_crc != 0xFFFF) {
864 ocs_log_test(ocs,
"miscompare (CRC) on LBA 0x%" PRIx64
", "
865 "memory contains 0x%x but calculated 0x%x\n",
869 errors_detected = TRUE;
874 recv_apptag = ((uint16_t)difbytes[2]) << 8 | difbytes[3];
875 if (0 != recv_apptag && recv_apptag != 0xFFFF) {
876 ocs_log_test(ocs,
"miscompare (app_tag) on LBA 0x%" PRIx64
", "
877 "memory contains 0x%x but calculated 0x%x\n",
881 errors_detected = TRUE;
886 recv_reftag = (((uint32_t)difbytes[4] << 24) |
887 ((uint32_t)difbytes[5] << 16) |
888 ((uint32_t)difbytes[6] << 8) |
891 if (lba + i != recv_reftag && recv_reftag != 0xFFFFFFFF) {
892 ocs_log_test(ocs,
"miscompare (ref_tag) on LBA 0x%" PRIx64
", "
893 "memory contains 0x%x but calculated 0x%" PRIx64
"\n",
897 errors_detected = TRUE;
902 if (errors_detected) {
905 sprintf(desc,
"Lba 0x%" PRIx64, lba + i);
void dif_pool_init(ocs_t *ocs, ocs_list_t *head)
initialize the DIF memory pool
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).
void * ocs_pool_get(ocs_pool_t *pool)
Allocate a memory pool item.
uint8_t * ocs_ramdisc_lba_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of a ramdisc logical block.
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.
static int32_t ocs_list_empty(ocs_list_t *list)
Test if a list is empty.
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.
uint32_t blocks_per_segment
void ocs_set_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc, uint32_t block_size)
Set the ramdisc block size.
uint8_t force_dif_separate
ramdisc instance structure
void ocs_ddump_section(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section start data.
ramdisc segment structure
ocs_pool_t * ocs_pool_alloc(ocs_os_handle_t os, uint32_t size, uint32_t count, uint32_t use_lock)
Allocate a memory pool.
void ocs_pool_free(ocs_pool_t *pool)
Free a previously allocated memory pool.
int32_t ocs_del_ramdisc(ocs_t *ocs, ocs_ramdisc_t *ramdisc)
Delete a ramdisc instance.
static void * ocs_list_remove(ocs_list_t *list, void *item)
Remove an item from the list.
#define SGL_REQ_FLAGS_PHYS
static void * ocs_list_get_tail(ocs_list_t *list)
Return the first item in the list.
#define ocs_list_init(head, type, link)
void ocs_dump32(uint32_t mask, ocs_os_handle_t os, const char *label, void *buf, uint32_t buf_length)
Dump 32 bit hex/ascii data.
#define RAMDISC_MIN_BLOCK_SIZE
ramdisc_segment_t ** segments
#define ocs_list_foreach_safe(list, item, nxt)
Iterate a linked list safely.
#define OCS_CTRLMASK_TGT_SET_DIF_REF_TAG_CRC
generic ramdisc scatter-gather list
static int32_t dif_pool_new(ocs_t *ocs, ocs_list_t *head)
Allocate a new dif_pool_t entry.
dif_t * ocs_ramdisc_dif_address(ocs_ramdisc_t *ramdisc, uint64_t lba)
Return the address of the DIF block if protection is enabled.
void ocs_ddump_endsection(ocs_textbuf_t *textbuf, const char *name, uint32_t instance)
Generate driver dump section end data.
static void ocs_list_add_tail(ocs_list_t *list, void *item)
Add an item to the tail of the list.
uint32_t pending_block_size
uint32_t segment_block_size
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. ...
#define ocs_assert(cond,...)
uint32_t ocs_get_ramdisc_blocksize(ocs_t *ocs, ocs_ramdisc_t *ramdisc)
Get the ramdisc block size.
ocs_pool_t * segment_pool
uint16_t ocs_scsi_dif_calc_crc(const uint8_t *buffer, uint32_t size, uint16_t crc)
Calculate the T10 PI CRC guard value for a block.
#define ocs_list_foreach(list, item)
Iterate a linked list.
void ocs_ddump_ramdisc(ocs_textbuf_t *textbuf, ocs_ramdisc_t *ramdisc)
void dif_pool_free(ocs_t *ocs, ocs_list_t *head)
Free the DIF memory pool.
uint32_t ocs_scsi_get_property(ocs_t *ocs, ocs_scsi_property_e prop)
Return SCSI API integer valued property.
void ocs_ddump_value(ocs_textbuf_t *textbuf, const char *name, const char *fmt,...)
Generate driver dump data for a given value.