cxlflash: Virtual LUN support
Add support for physical LUN segmentation (virtual LUNs) to device driver supporting the IBM CXL Flash adapter. This patch allows user space applications to virtually segment a physical LUN into N virtual LUNs, taking advantage of the translation features provided by this adapter. Signed-off-by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com> Signed-off-by: Manoj N. Kumar <manoj@linux.vnet.ibm.com> Reviewed-by: Michael Neuling <mikey@neuling.org> Reviewed-by: Wen Xiong <wenxiong@linux.vnet.ibm.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
This commit is contained in:

committed by
James Bottomley

parent
65be2c79ac
commit
2cb79266d6
@@ -1,2 +1,2 @@
|
||||
obj-$(CONFIG_CXLFLASH) += cxlflash.o
|
||||
cxlflash-y += main.o superpipe.o lunmgt.o
|
||||
cxlflash-y += main.o superpipe.o lunmgt.o vlun.o
|
||||
|
@@ -116,6 +116,9 @@ struct cxlflash_cfg {
|
||||
|
||||
atomic_t num_user_contexts;
|
||||
|
||||
/* Parameters that are LUN table related */
|
||||
int last_lun_index[CXLFLASH_NUM_FC_PORTS];
|
||||
int promote_lun_index;
|
||||
struct list_head lluns; /* list of llun_info structs */
|
||||
|
||||
wait_queue_head_t tmf_waitq;
|
||||
@@ -200,5 +203,6 @@ int cxlflash_ioctl(struct scsi_device *, int, void __user *);
|
||||
void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *);
|
||||
int cxlflash_mark_contexts_error(struct cxlflash_cfg *);
|
||||
void cxlflash_term_local_luns(struct cxlflash_cfg *);
|
||||
void cxlflash_restore_luntable(struct cxlflash_cfg *);
|
||||
|
||||
#endif /* ifndef _CXLFLASH_COMMON_H */
|
||||
|
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "sislite.h"
|
||||
#include "common.h"
|
||||
#include "vlun.h"
|
||||
#include "superpipe.h"
|
||||
|
||||
/**
|
||||
@@ -42,6 +43,7 @@ static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
|
||||
lli->sdev = sdev;
|
||||
lli->newly_created = true;
|
||||
lli->host_no = sdev->host->host_no;
|
||||
lli->in_table = false;
|
||||
|
||||
memcpy(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
|
||||
out:
|
||||
@@ -208,6 +210,7 @@ void cxlflash_term_global_luns(void)
|
||||
mutex_lock(&global.mutex);
|
||||
list_for_each_entry_safe(gli, temp, &global.gluns, list) {
|
||||
list_del(&gli->list);
|
||||
cxlflash_ba_terminate(&gli->blka.ba_lun);
|
||||
kfree(gli);
|
||||
}
|
||||
mutex_unlock(&global.mutex);
|
||||
|
@@ -1989,6 +1989,8 @@ static int init_afu(struct cxlflash_cfg *cfg)
|
||||
afu_err_intr_init(cfg->afu);
|
||||
atomic64_set(&afu->room, readq_be(&afu->host_map->cmd_room));
|
||||
|
||||
/* Restore the LUN mappings */
|
||||
cxlflash_restore_luntable(cfg);
|
||||
err1:
|
||||
pr_debug("%s: returning rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
@@ -2286,6 +2288,17 @@ static int cxlflash_probe(struct pci_dev *pdev,
|
||||
|
||||
cfg->init_state = INIT_STATE_NONE;
|
||||
cfg->dev = pdev;
|
||||
|
||||
/*
|
||||
* The promoted LUNs move to the top of the LUN table. The rest stay
|
||||
* on the bottom half. The bottom half grows from the end
|
||||
* (index = 255), whereas the top half grows from the beginning
|
||||
* (index = 0).
|
||||
*/
|
||||
cfg->promote_lun_index = 0;
|
||||
cfg->last_lun_index[0] = CXLFLASH_NUM_VLUNS/2 - 1;
|
||||
cfg->last_lun_index[1] = CXLFLASH_NUM_VLUNS/2 - 1;
|
||||
|
||||
cfg->dev_id = (struct pci_device_id *)dev_id;
|
||||
cfg->mcctx = NULL;
|
||||
|
||||
|
@@ -397,16 +397,17 @@ struct cxlflash_afu_map {
|
||||
};
|
||||
};
|
||||
|
||||
/* LBA translation control blocks */
|
||||
|
||||
/*
|
||||
* LXT - LBA Translation Table
|
||||
* LXT control blocks
|
||||
*/
|
||||
struct sisl_lxt_entry {
|
||||
u64 rlba_base; /* bits 0:47 is base
|
||||
* b48:55 is lun index
|
||||
* b58:59 is write & read perms
|
||||
* (if no perm, afu_rc=0x15)
|
||||
* b60:63 is port_sel mask
|
||||
*/
|
||||
|
||||
* b48:55 is lun index
|
||||
* b58:59 is write & read perms
|
||||
* (if no perm, afu_rc=0x15)
|
||||
* b60:63 is port_sel mask
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -465,4 +466,7 @@ struct sisl_rht_entry_f1 {
|
||||
#define TMF_LUN_RESET 0x1U
|
||||
#define TMF_CLEAR_ACA 0x2U
|
||||
|
||||
|
||||
#define SISLITE_MAX_WS_BLOCKS 512
|
||||
|
||||
#endif /* _SISLITE_H */
|
||||
|
@@ -26,10 +26,24 @@
|
||||
|
||||
#include "sislite.h"
|
||||
#include "common.h"
|
||||
#include "vlun.h"
|
||||
#include "superpipe.h"
|
||||
|
||||
struct cxlflash_global global;
|
||||
|
||||
/**
|
||||
* marshal_rele_to_resize() - translate release to resize structure
|
||||
* @rele: Source structure from which to translate/copy.
|
||||
* @resize: Destination structure for the translate/copy.
|
||||
*/
|
||||
static void marshal_rele_to_resize(struct dk_cxlflash_release *release,
|
||||
struct dk_cxlflash_resize *resize)
|
||||
{
|
||||
resize->hdr = release->hdr;
|
||||
resize->context_id = release->context_id;
|
||||
resize->rsrc_handle = release->rsrc_handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* marshal_det_to_rele() - translate detach to release structure
|
||||
* @detach: Destination structure for the translate/copy.
|
||||
@@ -449,6 +463,7 @@ void rhte_checkin(struct ctx_info *ctxi,
|
||||
rhte->fp = 0;
|
||||
ctxi->rht_out--;
|
||||
ctxi->rht_lun[rsrc_handle] = NULL;
|
||||
ctxi->rht_needs_ws[rsrc_handle] = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,13 +541,21 @@ out:
|
||||
/**
|
||||
* cxlflash_lun_detach() - detaches a user from a LUN and resets the LUN's mode
|
||||
* @gli: LUN to detach.
|
||||
*
|
||||
* When resetting the mode, terminate block allocation resources as they
|
||||
* are no longer required (service is safe to call even when block allocation
|
||||
* resources were not present - such as when transitioning from physical mode).
|
||||
* These resources will be reallocated when needed (subsequent transition to
|
||||
* virtual mode).
|
||||
*/
|
||||
void cxlflash_lun_detach(struct glun_info *gli)
|
||||
{
|
||||
mutex_lock(&gli->mutex);
|
||||
WARN_ON(gli->mode == MODE_NONE);
|
||||
if (--gli->users == 0)
|
||||
if (--gli->users == 0) {
|
||||
gli->mode = MODE_NONE;
|
||||
cxlflash_ba_terminate(&gli->blka.ba_lun);
|
||||
}
|
||||
pr_debug("%s: gli->users=%u\n", __func__, gli->users);
|
||||
WARN_ON(gli->users < 0);
|
||||
mutex_unlock(&gli->mutex);
|
||||
@@ -544,10 +567,12 @@ void cxlflash_lun_detach(struct glun_info *gli)
|
||||
* @ctxi: Context owning resources.
|
||||
* @release: Release ioctl data structure.
|
||||
*
|
||||
* Note that the AFU sync should _not_ be performed when the context is sitting
|
||||
* on the error recovery list. A context on the error recovery list is not known
|
||||
* to the AFU due to reset. When the context is recovered, it will be reattached
|
||||
* and made known again to the AFU.
|
||||
* For LUNs in virtual mode, the virtual LUN associated with the specified
|
||||
* resource handle is resized to 0 prior to releasing the RHTE. Note that the
|
||||
* AFU sync should _not_ be performed when the context is sitting on the error
|
||||
* recovery list. A context on the error recovery list is not known to the AFU
|
||||
* due to reset. When the context is recovered, it will be reattached and made
|
||||
* known again to the AFU.
|
||||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
@@ -562,6 +587,7 @@ int _cxlflash_disk_release(struct scsi_device *sdev,
|
||||
struct afu *afu = cfg->afu;
|
||||
bool put_ctx = false;
|
||||
|
||||
struct dk_cxlflash_resize size;
|
||||
res_hndl_t rhndl = release->rsrc_handle;
|
||||
|
||||
int rc = 0;
|
||||
@@ -594,7 +620,24 @@ int _cxlflash_disk_release(struct scsi_device *sdev,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* Resize to 0 for virtual LUNS by setting the size
|
||||
* to 0. This will clear LXT_START and LXT_CNT fields
|
||||
* in the RHT entry and properly sync with the AFU.
|
||||
*
|
||||
* Afterwards we clear the remaining fields.
|
||||
*/
|
||||
switch (gli->mode) {
|
||||
case MODE_VIRTUAL:
|
||||
marshal_rele_to_resize(release, &size);
|
||||
size.req_size = 0;
|
||||
rc = _cxlflash_vlun_resize(sdev, ctxi, &size);
|
||||
if (rc) {
|
||||
dev_dbg(dev, "%s: resize failed rc %d\n", __func__, rc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
break;
|
||||
case MODE_PHYSICAL:
|
||||
/*
|
||||
* Clear the Format 1 RHT entry for direct access
|
||||
@@ -666,6 +709,7 @@ static void destroy_context(struct cxlflash_cfg *cfg,
|
||||
|
||||
/* Free memory associated with context */
|
||||
free_page((ulong)ctxi->rht_start);
|
||||
kfree(ctxi->rht_needs_ws);
|
||||
kfree(ctxi->rht_lun);
|
||||
kfree(ctxi);
|
||||
atomic_dec_if_positive(&cfg->num_user_contexts);
|
||||
@@ -693,11 +737,13 @@ static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
|
||||
struct afu *afu = cfg->afu;
|
||||
struct ctx_info *ctxi = NULL;
|
||||
struct llun_info **lli = NULL;
|
||||
bool *ws = NULL;
|
||||
struct sisl_rht_entry *rhte;
|
||||
|
||||
ctxi = kzalloc(sizeof(*ctxi), GFP_KERNEL);
|
||||
lli = kzalloc((MAX_RHT_PER_CONTEXT * sizeof(*lli)), GFP_KERNEL);
|
||||
if (unlikely(!ctxi || !lli)) {
|
||||
ws = kzalloc((MAX_RHT_PER_CONTEXT * sizeof(*ws)), GFP_KERNEL);
|
||||
if (unlikely(!ctxi || !lli || !ws)) {
|
||||
dev_err(dev, "%s: Unable to allocate context!\n", __func__);
|
||||
goto err;
|
||||
}
|
||||
@@ -709,6 +755,7 @@ static struct ctx_info *create_context(struct cxlflash_cfg *cfg,
|
||||
}
|
||||
|
||||
ctxi->rht_lun = lli;
|
||||
ctxi->rht_needs_ws = ws;
|
||||
ctxi->rht_start = rhte;
|
||||
ctxi->rht_perms = perms;
|
||||
|
||||
@@ -728,6 +775,7 @@ out:
|
||||
return ctxi;
|
||||
|
||||
err:
|
||||
kfree(ws);
|
||||
kfree(lli);
|
||||
kfree(ctxi);
|
||||
ctxi = NULL;
|
||||
@@ -1729,6 +1777,12 @@ static int cxlflash_disk_verify(struct scsi_device *sdev,
|
||||
case MODE_PHYSICAL:
|
||||
last_lba = gli->max_lba;
|
||||
break;
|
||||
case MODE_VIRTUAL:
|
||||
/* Cast lxt_cnt to u64 for multiply to be treated as 64bit op */
|
||||
last_lba = ((u64)rhte->lxt_cnt * MC_CHUNK_SIZE * gli->blk_len);
|
||||
last_lba /= CXLFLASH_BLOCK_SIZE;
|
||||
last_lba--;
|
||||
break;
|
||||
default:
|
||||
WARN(1, "Unsupported LUN mode!");
|
||||
}
|
||||
@@ -1756,12 +1810,18 @@ static char *decode_ioctl(int cmd)
|
||||
return __stringify_1(DK_CXLFLASH_ATTACH);
|
||||
case DK_CXLFLASH_USER_DIRECT:
|
||||
return __stringify_1(DK_CXLFLASH_USER_DIRECT);
|
||||
case DK_CXLFLASH_USER_VIRTUAL:
|
||||
return __stringify_1(DK_CXLFLASH_USER_VIRTUAL);
|
||||
case DK_CXLFLASH_VLUN_RESIZE:
|
||||
return __stringify_1(DK_CXLFLASH_VLUN_RESIZE);
|
||||
case DK_CXLFLASH_RELEASE:
|
||||
return __stringify_1(DK_CXLFLASH_RELEASE);
|
||||
case DK_CXLFLASH_DETACH:
|
||||
return __stringify_1(DK_CXLFLASH_DETACH);
|
||||
case DK_CXLFLASH_VERIFY:
|
||||
return __stringify_1(DK_CXLFLASH_VERIFY);
|
||||
case DK_CXLFLASH_VLUN_CLONE:
|
||||
return __stringify_1(DK_CXLFLASH_VLUN_CLONE);
|
||||
case DK_CXLFLASH_RECOVER_AFU:
|
||||
return __stringify_1(DK_CXLFLASH_RECOVER_AFU);
|
||||
case DK_CXLFLASH_MANAGE_LUN:
|
||||
@@ -1876,6 +1936,7 @@ static int ioctl_common(struct scsi_device *sdev, int cmd)
|
||||
rc = check_state(cfg);
|
||||
if (unlikely(rc) && (cfg->state == STATE_FAILTERM)) {
|
||||
switch (cmd) {
|
||||
case DK_CXLFLASH_VLUN_RESIZE:
|
||||
case DK_CXLFLASH_RELEASE:
|
||||
case DK_CXLFLASH_DETACH:
|
||||
dev_dbg(dev, "%s: Command override! (%d)\n",
|
||||
@@ -1923,12 +1984,18 @@ int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
||||
{sizeof(struct dk_cxlflash_verify), (sioctl)cxlflash_disk_verify},
|
||||
{sizeof(struct dk_cxlflash_recover_afu), (sioctl)cxlflash_afu_recover},
|
||||
{sizeof(struct dk_cxlflash_manage_lun), (sioctl)cxlflash_manage_lun},
|
||||
{sizeof(struct dk_cxlflash_uvirtual), cxlflash_disk_virtual_open},
|
||||
{sizeof(struct dk_cxlflash_resize), (sioctl)cxlflash_vlun_resize},
|
||||
{sizeof(struct dk_cxlflash_clone), (sioctl)cxlflash_disk_clone},
|
||||
};
|
||||
|
||||
/* Restrict command set to physical support only for internal LUN */
|
||||
if (afu->internal_lun)
|
||||
switch (cmd) {
|
||||
case DK_CXLFLASH_RELEASE:
|
||||
case DK_CXLFLASH_USER_VIRTUAL:
|
||||
case DK_CXLFLASH_VLUN_RESIZE:
|
||||
case DK_CXLFLASH_VLUN_CLONE:
|
||||
dev_dbg(dev, "%s: %s not supported for lun_mode=%d\n",
|
||||
__func__, decode_ioctl(cmd), afu->internal_lun);
|
||||
rc = -EINVAL;
|
||||
@@ -1942,6 +2009,9 @@ int cxlflash_ioctl(struct scsi_device *sdev, int cmd, void __user *arg)
|
||||
case DK_CXLFLASH_DETACH:
|
||||
case DK_CXLFLASH_VERIFY:
|
||||
case DK_CXLFLASH_RECOVER_AFU:
|
||||
case DK_CXLFLASH_USER_VIRTUAL:
|
||||
case DK_CXLFLASH_VLUN_RESIZE:
|
||||
case DK_CXLFLASH_VLUN_CLONE:
|
||||
dev_dbg(dev, "%s: %s (%08X) on dev(%d/%d/%d/%llu)\n",
|
||||
__func__, decode_ioctl(cmd), cmd, shost->host_no,
|
||||
sdev->channel, sdev->id, sdev->lun);
|
||||
|
@@ -31,9 +31,11 @@ extern struct cxlflash_global global;
|
||||
#define MC_DISCOVERY_TIMEOUT 5 /* 5 secs */
|
||||
|
||||
#define CHAN2PORT(_x) ((_x) + 1)
|
||||
#define PORT2CHAN(_x) ((_x) - 1)
|
||||
|
||||
enum lun_mode {
|
||||
MODE_NONE = 0,
|
||||
MODE_VIRTUAL,
|
||||
MODE_PHYSICAL
|
||||
};
|
||||
|
||||
@@ -41,13 +43,14 @@ enum lun_mode {
|
||||
struct glun_info {
|
||||
u64 max_lba; /* from read cap(16) */
|
||||
u32 blk_len; /* from read cap(16) */
|
||||
enum lun_mode mode; /* NONE, PHYSICAL */
|
||||
enum lun_mode mode; /* NONE, VIRTUAL, PHYSICAL */
|
||||
int users; /* Number of users w/ references to LUN */
|
||||
|
||||
u8 wwid[16];
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
struct blka blka;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@@ -58,6 +61,7 @@ struct llun_info {
|
||||
u32 host_no; /* host_no from Scsi_host */
|
||||
u32 port_sel; /* What port to use for this LUN */
|
||||
bool newly_created; /* Whether the LUN was just discovered */
|
||||
bool in_table; /* Whether a LUN table entry was created */
|
||||
|
||||
u8 wwid[16]; /* Keep a duplicate copy here? */
|
||||
|
||||
@@ -90,6 +94,7 @@ struct ctx_info {
|
||||
u32 rht_out; /* Number of checked out RHT entries */
|
||||
u32 rht_perms; /* User-defined permissions for RHT entries */
|
||||
struct llun_info **rht_lun; /* Mapping of RHT entries to LUNs */
|
||||
bool *rht_needs_ws; /* User-desired write-same function per RHTE */
|
||||
|
||||
struct cxl_ioctl_start_work work;
|
||||
u64 ctxid;
|
||||
@@ -111,10 +116,18 @@ struct cxlflash_global {
|
||||
struct page *err_page; /* One page of all 0xF for error notification */
|
||||
};
|
||||
|
||||
int cxlflash_vlun_resize(struct scsi_device *, struct dk_cxlflash_resize *);
|
||||
int _cxlflash_vlun_resize(struct scsi_device *, struct ctx_info *,
|
||||
struct dk_cxlflash_resize *);
|
||||
|
||||
int cxlflash_disk_release(struct scsi_device *, struct dk_cxlflash_release *);
|
||||
int _cxlflash_disk_release(struct scsi_device *, struct ctx_info *,
|
||||
struct dk_cxlflash_release *);
|
||||
|
||||
int cxlflash_disk_clone(struct scsi_device *, struct dk_cxlflash_clone *);
|
||||
|
||||
int cxlflash_disk_virtual_open(struct scsi_device *, void *);
|
||||
|
||||
int cxlflash_lun_attach(struct glun_info *, enum lun_mode, bool);
|
||||
void cxlflash_lun_detach(struct glun_info *);
|
||||
|
||||
@@ -127,6 +140,8 @@ struct sisl_rht_entry *get_rhte(struct ctx_info *, res_hndl_t,
|
||||
struct sisl_rht_entry *rhte_checkout(struct ctx_info *, struct llun_info *);
|
||||
void rhte_checkin(struct ctx_info *, struct sisl_rht_entry *);
|
||||
|
||||
void cxlflash_ba_terminate(struct ba_lun *);
|
||||
|
||||
int cxlflash_manage_lun(struct scsi_device *, struct dk_cxlflash_manage_lun *);
|
||||
|
||||
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */
|
||||
|
1243
drivers/scsi/cxlflash/vlun.c
Normal file
1243
drivers/scsi/cxlflash/vlun.c
Normal file
File diff suppressed because it is too large
Load Diff
86
drivers/scsi/cxlflash/vlun.h
Normal file
86
drivers/scsi/cxlflash/vlun.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_VLUN_H
|
||||
#define _CXLFLASH_VLUN_H
|
||||
|
||||
/* RHT - Resource Handle Table */
|
||||
#define MC_RHT_NMASK 16 /* in bits */
|
||||
#define MC_CHUNK_SHIFT MC_RHT_NMASK /* shift to go from LBA to chunk# */
|
||||
|
||||
#define HIBIT (BITS_PER_LONG - 1)
|
||||
|
||||
#define MAX_AUN_CLONE_CNT 0xFF
|
||||
|
||||
/*
|
||||
* LXT - LBA Translation Table
|
||||
*
|
||||
* +-------+-------+-------+-------+-------+-------+-------+---+---+
|
||||
* | RLBA_BASE |LUN_IDX| P |SEL|
|
||||
* +-------+-------+-------+-------+-------+-------+-------+---+---+
|
||||
*
|
||||
* The LXT Entry contains the physical LBA where the chunk starts (RLBA_BASE).
|
||||
* AFU ORes the low order bits from the virtual LBA (offset into the chunk)
|
||||
* with RLBA_BASE. The result is the physical LBA to be sent to storage.
|
||||
* The LXT Entry also contains an index to a LUN TBL and a bitmask of which
|
||||
* outgoing (FC) * ports can be selected. The port select bit-mask is ANDed
|
||||
* with a global port select bit-mask maintained by the driver.
|
||||
* In addition, it has permission bits that are ANDed with the
|
||||
* RHT permissions to arrive at the final permissions for the chunk.
|
||||
*
|
||||
* LXT tables are allocated dynamically in groups. This is done to avoid
|
||||
* a malloc/free overhead each time the LXT has to grow or shrink.
|
||||
*
|
||||
* Based on the current lxt_cnt (used), it is always possible to know
|
||||
* how many are allocated (used+free). The number of allocated entries is
|
||||
* not stored anywhere.
|
||||
*
|
||||
* The LXT table is re-allocated whenever it needs to cross into another group.
|
||||
*/
|
||||
#define LXT_GROUP_SIZE 8
|
||||
#define LXT_NUM_GROUPS(lxt_cnt) (((lxt_cnt) + 7)/8) /* alloc'ed groups */
|
||||
#define LXT_LUNIDX_SHIFT 8 /* LXT entry, shift for LUN index */
|
||||
#define LXT_PERM_SHIFT 4 /* LXT entry, shift for permission bits */
|
||||
|
||||
struct ba_lun_info {
|
||||
u64 *lun_alloc_map;
|
||||
u32 lun_bmap_size;
|
||||
u32 total_aus;
|
||||
u64 free_aun_cnt;
|
||||
|
||||
/* indices to be used for elevator lookup of free map */
|
||||
u32 free_low_idx;
|
||||
u32 free_curr_idx;
|
||||
u32 free_high_idx;
|
||||
|
||||
u8 *aun_clone_map;
|
||||
};
|
||||
|
||||
struct ba_lun {
|
||||
u64 lun_id;
|
||||
u64 wwpn;
|
||||
size_t lsize; /* LUN size in number of LBAs */
|
||||
size_t lba_size; /* LBA size in number of bytes */
|
||||
size_t au_size; /* Allocation Unit size in number of LBAs */
|
||||
struct ba_lun_info *ba_lun_handle;
|
||||
};
|
||||
|
||||
/* Block Allocator */
|
||||
struct blka {
|
||||
struct ba_lun ba_lun;
|
||||
u64 nchunk; /* number of chunks */
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */
|
Reference in New Issue
Block a user