Commit 65be2c79 authored by Matthew R. Ochs's avatar Matthew R. Ochs Committed by James Bottomley

cxlflash: Superpipe support

Add superpipe supporting infrastructure to device driver for the IBM CXL
Flash adapter. This patch allows userspace applications to take advantage
of the accelerated I/O features that this adapter provides and bypass the
traditional filesystem stack.
Signed-off-by: default avatarMatthew R. Ochs <mrochs@linux.vnet.ibm.com>
Signed-off-by: default avatarManoj N. Kumar <manoj@linux.vnet.ibm.com>
Reviewed-by: default avatarMichael Neuling <mikey@neuling.org>
Reviewed-by: default avatarWen Xiong <wenxiong@linux.vnet.ibm.com>
Reviewed-by: default avatarBrian King <brking@linux.vnet.ibm.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Odin.com>
parent 5cdac81a
...@@ -314,6 +314,7 @@ Code Seq#(hex) Include File Comments ...@@ -314,6 +314,7 @@ Code Seq#(hex) Include File Comments
0xB3 00 linux/mmc/ioctl.h 0xB3 00 linux/mmc/ioctl.h
0xC0 00-0F linux/usb/iowarrior.h 0xC0 00-0F linux/usb/iowarrior.h
0xCA 00-0F uapi/misc/cxl.h 0xCA 00-0F uapi/misc/cxl.h
0xCA 80-8F uapi/scsi/cxlflash_ioctl.h
0xCB 00-1F CBM serial IEC bus in development: 0xCB 00-1F CBM serial IEC bus in development:
<mailto:michael.klein@puffin.lb.shuttle.de> <mailto:michael.klein@puffin.lb.shuttle.de>
0xCD 01 linux/reiserfs_fs.h 0xCD 01 linux/reiserfs_fs.h
......
This diff is collapsed.
obj-$(CONFIG_CXLFLASH) += cxlflash.o obj-$(CONFIG_CXLFLASH) += cxlflash.o
cxlflash-y += main.o cxlflash-y += main.o superpipe.o lunmgt.o
...@@ -107,6 +107,17 @@ struct cxlflash_cfg { ...@@ -107,6 +107,17 @@ struct cxlflash_cfg {
struct pci_pool *cxlflash_cmd_pool; struct pci_pool *cxlflash_cmd_pool;
struct pci_dev *parent_dev; struct pci_dev *parent_dev;
atomic_t recovery_threads;
struct mutex ctx_recovery_mutex;
struct mutex ctx_tbl_list_mutex;
struct ctx_info *ctx_tbl[MAX_CONTEXT];
struct list_head ctx_err_recovery; /* contexts w/ recovery pending */
struct file_operations cxl_fops;
atomic_t num_user_contexts;
struct list_head lluns; /* list of llun_info structs */
wait_queue_head_t tmf_waitq; wait_queue_head_t tmf_waitq;
bool tmf_active; bool tmf_active;
wait_queue_head_t limbo_waitq; wait_queue_head_t limbo_waitq;
...@@ -182,4 +193,12 @@ int cxlflash_afu_reset(struct cxlflash_cfg *); ...@@ -182,4 +193,12 @@ int cxlflash_afu_reset(struct cxlflash_cfg *);
struct afu_cmd *cxlflash_cmd_checkout(struct afu *); struct afu_cmd *cxlflash_cmd_checkout(struct afu *);
void cxlflash_cmd_checkin(struct afu_cmd *); void cxlflash_cmd_checkin(struct afu_cmd *);
int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8); int cxlflash_afu_sync(struct afu *, ctx_hndl_t, res_hndl_t, u8);
void cxlflash_list_init(void);
void cxlflash_term_global_luns(void);
void cxlflash_free_errpage(void);
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 *);
#endif /* ifndef _CXLFLASH_COMMON_H */ #endif /* ifndef _CXLFLASH_COMMON_H */
/*
* 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.
*/
#include <misc/cxl.h>
#include <asm/unaligned.h>
#include <scsi/scsi_host.h>
#include <uapi/scsi/cxlflash_ioctl.h>
#include "sislite.h"
#include "common.h"
#include "superpipe.h"
/**
* create_local() - allocate and initialize a local LUN information structure
* @sdev: SCSI device associated with LUN.
* @wwid: World Wide Node Name for LUN.
*
* Return: Allocated local llun_info structure on success, NULL on failure
*/
static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
{
struct llun_info *lli = NULL;
lli = kzalloc(sizeof(*lli), GFP_KERNEL);
if (unlikely(!lli)) {
pr_err("%s: could not allocate lli\n", __func__);
goto out;
}
lli->sdev = sdev;
lli->newly_created = true;
lli->host_no = sdev->host->host_no;
memcpy(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
out:
return lli;
}
/**
* create_global() - allocate and initialize a global LUN information structure
* @sdev: SCSI device associated with LUN.
* @wwid: World Wide Node Name for LUN.
*
* Return: Allocated global glun_info structure on success, NULL on failure
*/
static struct glun_info *create_global(struct scsi_device *sdev, u8 *wwid)
{
struct glun_info *gli = NULL;
gli = kzalloc(sizeof(*gli), GFP_KERNEL);
if (unlikely(!gli)) {
pr_err("%s: could not allocate gli\n", __func__);
goto out;
}
mutex_init(&gli->mutex);
memcpy(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
out:
return gli;
}
/**
* refresh_local() - find and update local LUN information structure by WWID
* @cfg: Internal structure associated with the host.
* @wwid: WWID associated with LUN.
*
* When the LUN is found, mark it by updating it's newly_created field.
*
* Return: Found local lun_info structure on success, NULL on failure
* If a LUN with the WWID is found in the list, refresh it's state.
*/
static struct llun_info *refresh_local(struct cxlflash_cfg *cfg, u8 *wwid)
{
struct llun_info *lli, *temp;
list_for_each_entry_safe(lli, temp, &cfg->lluns, list)
if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN)) {
lli->newly_created = false;
return lli;
}
return NULL;
}
/**
* lookup_global() - find a global LUN information structure by WWID
* @wwid: WWID associated with LUN.
*
* Return: Found global lun_info structure on success, NULL on failure
*/
static struct glun_info *lookup_global(u8 *wwid)
{
struct glun_info *gli, *temp;
list_for_each_entry_safe(gli, temp, &global.gluns, list)
if (!memcmp(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
return gli;
return NULL;
}
/**
* find_and_create_lun() - find or create a local LUN information structure
* @sdev: SCSI device associated with LUN.
* @wwid: WWID associated with LUN.
*
* The LUN is kept both in a local list (per adapter) and in a global list
* (across all adapters). Certain attributes of the LUN are local to the
* adapter (such as index, port selection mask etc.).
* The block allocation map is shared across all adapters (i.e. associated
* wih the global list). Since different attributes are associated with
* the per adapter and global entries, allocate two separate structures for each
* LUN (one local, one global).
*
* Keep a pointer back from the local to the global entry.
*
* Return: Found/Allocated local lun_info structure on success, NULL on failure
*/
static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
{
struct llun_info *lli = NULL;
struct glun_info *gli = NULL;
struct Scsi_Host *shost = sdev->host;
struct cxlflash_cfg *cfg = shost_priv(shost);
mutex_lock(&global.mutex);
if (unlikely(!wwid))
goto out;
lli = refresh_local(cfg, wwid);
if (lli)
goto out;
lli = create_local(sdev, wwid);
if (unlikely(!lli))
goto out;
gli = lookup_global(wwid);
if (gli) {
lli->parent = gli;
list_add(&lli->list, &cfg->lluns);
goto out;
}
gli = create_global(sdev, wwid);
if (unlikely(!gli)) {
kfree(lli);
lli = NULL;
goto out;
}
lli->parent = gli;
list_add(&lli->list, &cfg->lluns);
list_add(&gli->list, &global.gluns);
out:
mutex_unlock(&global.mutex);
pr_debug("%s: returning %p\n", __func__, lli);
return lli;
}
/**
* cxlflash_term_local_luns() - Delete all entries from local LUN list, free.
* @cfg: Internal structure associated with the host.
*/
void cxlflash_term_local_luns(struct cxlflash_cfg *cfg)
{
struct llun_info *lli, *temp;
mutex_lock(&global.mutex);
list_for_each_entry_safe(lli, temp, &cfg->lluns, list) {
list_del(&lli->list);
kfree(lli);
}
mutex_unlock(&global.mutex);
}
/**
* cxlflash_list_init() - initializes the global LUN list
*/
void cxlflash_list_init(void)
{
INIT_LIST_HEAD(&global.gluns);
mutex_init(&global.mutex);
global.err_page = NULL;
}
/**
* cxlflash_term_global_luns() - frees resources associated with global LUN list
*/
void cxlflash_term_global_luns(void)
{
struct glun_info *gli, *temp;
mutex_lock(&global.mutex);
list_for_each_entry_safe(gli, temp, &global.gluns, list) {
list_del(&gli->list);
kfree(gli);
}
mutex_unlock(&global.mutex);
}
/**
* cxlflash_manage_lun() - handles LUN management activities
* @sdev: SCSI device associated with LUN.
* @manage: Manage ioctl data structure.
*
* This routine is used to notify the driver about a LUN's WWID and associate
* SCSI devices (sdev) with a global LUN instance. Additionally it serves to
* change a LUN's operating mode: legacy or superpipe.
*
* Return: 0 on success, -errno on failure
*/
int cxlflash_manage_lun(struct scsi_device *sdev,
struct dk_cxlflash_manage_lun *manage)
{
int rc = 0;
struct llun_info *lli = NULL;
u64 flags = manage->hdr.flags;
u32 chan = sdev->channel;
lli = find_and_create_lun(sdev, manage->wwid);
pr_debug("%s: ENTER: WWID = %016llX%016llX, flags = %016llX li = %p\n",
__func__, get_unaligned_le64(&manage->wwid[0]),
get_unaligned_le64(&manage->wwid[8]),
manage->hdr.flags, lli);
if (unlikely(!lli)) {
rc = -ENOMEM;
goto out;
}
if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) {
if (lli->newly_created)
lli->port_sel = CHAN2PORT(chan);
else
lli->port_sel = BOTH_PORTS;
/* Store off lun in unpacked, AFU-friendly format */
lli->lun_id[chan] = lun_to_lunid(sdev->lun);
sdev->hostdata = lli;
} else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
if (lli->parent->mode != MODE_NONE)
rc = -EBUSY;
else
sdev->hostdata = NULL;
}
out:
pr_debug("%s: returning rc=%d\n", __func__, rc);
return rc;
}
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <scsi/scsi_cmnd.h> #include <scsi/scsi_cmnd.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <uapi/scsi/cxlflash_ioctl.h>
#include "main.h" #include "main.h"
#include "sislite.h" #include "sislite.h"
...@@ -519,7 +520,7 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp) ...@@ -519,7 +520,7 @@ static int cxlflash_eh_host_reset_handler(struct scsi_cmnd *scp)
case STATE_NORMAL: case STATE_NORMAL:
cfg->state = STATE_LIMBO; cfg->state = STATE_LIMBO;
scsi_block_requests(cfg->host); scsi_block_requests(cfg->host);
cxlflash_mark_contexts_error(cfg);
rcr = cxlflash_afu_reset(cfg); rcr = cxlflash_afu_reset(cfg);
if (rcr) { if (rcr) {
rc = FAILED; rc = FAILED;
...@@ -662,6 +663,21 @@ static ssize_t cxlflash_store_lun_mode(struct device *dev, ...@@ -662,6 +663,21 @@ static ssize_t cxlflash_store_lun_mode(struct device *dev,
return count; return count;
} }
/**
* cxlflash_show_ioctl_version() - presents the current ioctl version of the host
* @dev: Generic device associated with the host.
* @attr: Device attribute representing the ioctl version.
* @buf: Buffer of length PAGE_SIZE to report back the ioctl version.
*
* Return: The size of the ASCII string returned in @buf.
*/
static ssize_t cxlflash_show_ioctl_version(struct device *dev,
struct device_attribute *attr,
char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%u\n", DK_CXLFLASH_VERSION_0);
}
/** /**
* cxlflash_show_dev_mode() - presents the current mode of the device * cxlflash_show_dev_mode() - presents the current mode of the device
* @dev: Generic device associated with the device. * @dev: Generic device associated with the device.
...@@ -700,11 +716,13 @@ static DEVICE_ATTR(port0, S_IRUGO, cxlflash_show_port_status, NULL); ...@@ -700,11 +716,13 @@ static DEVICE_ATTR(port0, S_IRUGO, cxlflash_show_port_status, NULL);
static DEVICE_ATTR(port1, S_IRUGO, cxlflash_show_port_status, NULL); static DEVICE_ATTR(port1, S_IRUGO, cxlflash_show_port_status, NULL);
static DEVICE_ATTR(lun_mode, S_IRUGO | S_IWUSR, cxlflash_show_lun_mode, static DEVICE_ATTR(lun_mode, S_IRUGO | S_IWUSR, cxlflash_show_lun_mode,
cxlflash_store_lun_mode); cxlflash_store_lun_mode);
static DEVICE_ATTR(ioctl_version, S_IRUGO, cxlflash_show_ioctl_version, NULL);
static struct device_attribute *cxlflash_host_attrs[] = { static struct device_attribute *cxlflash_host_attrs[] = {
&dev_attr_port0, &dev_attr_port0,
&dev_attr_port1, &dev_attr_port1,
&dev_attr_lun_mode, &dev_attr_lun_mode,
&dev_attr_ioctl_version,
NULL NULL
}; };
...@@ -725,6 +743,7 @@ static struct scsi_host_template driver_template = { ...@@ -725,6 +743,7 @@ static struct scsi_host_template driver_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = CXLFLASH_ADAPTER_NAME, .name = CXLFLASH_ADAPTER_NAME,
.info = cxlflash_driver_info, .info = cxlflash_driver_info,
.ioctl = cxlflash_ioctl,
.proc_name = CXLFLASH_NAME, .proc_name = CXLFLASH_NAME,
.queuecommand = cxlflash_queuecommand, .queuecommand = cxlflash_queuecommand,
.eh_device_reset_handler = cxlflash_eh_device_reset_handler, .eh_device_reset_handler = cxlflash_eh_device_reset_handler,
...@@ -872,9 +891,11 @@ static void cxlflash_remove(struct pci_dev *pdev) ...@@ -872,9 +891,11 @@ static void cxlflash_remove(struct pci_dev *pdev)
spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags); spin_unlock_irqrestore(&cfg->tmf_waitq.lock, lock_flags);
cfg->state = STATE_FAILTERM; cfg->state = STATE_FAILTERM;
cxlflash_stop_term_user_contexts(cfg);
switch (cfg->init_state) { switch (cfg->init_state) {
case INIT_STATE_SCSI: case INIT_STATE_SCSI:
cxlflash_term_local_luns(cfg);
scsi_remove_host(cfg->host); scsi_remove_host(cfg->host);
scsi_host_put(cfg->host); scsi_host_put(cfg->host);
/* Fall through */ /* Fall through */
...@@ -2274,6 +2295,10 @@ static int cxlflash_probe(struct pci_dev *pdev, ...@@ -2274,6 +2295,10 @@ static int cxlflash_probe(struct pci_dev *pdev,
INIT_WORK(&cfg->work_q, cxlflash_worker_thread); INIT_WORK(&cfg->work_q, cxlflash_worker_thread);
cfg->lr_state = LINK_RESET_INVALID; cfg->lr_state = LINK_RESET_INVALID;
cfg->lr_port = -1; cfg->lr_port = -1;
mutex_init(&cfg->ctx_tbl_list_mutex);
mutex_init(&cfg->ctx_recovery_mutex);
INIT_LIST_HEAD(&cfg->ctx_err_recovery);
INIT_LIST_HEAD(&cfg->lluns);
pci_set_drvdata(pdev, cfg); pci_set_drvdata(pdev, cfg);
...@@ -2335,6 +2360,7 @@ static int cxlflash_probe(struct pci_dev *pdev, ...@@ -2335,6 +2360,7 @@ static int cxlflash_probe(struct pci_dev *pdev,
static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
pci_channel_state_t state) pci_channel_state_t state)
{ {
int rc = 0;
struct cxlflash_cfg *cfg = pci_get_drvdata(pdev); struct cxlflash_cfg *cfg = pci_get_drvdata(pdev);
struct device *dev = &cfg->dev->dev; struct device *dev = &cfg->dev->dev;
...@@ -2346,7 +2372,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev, ...@@ -2346,7 +2372,10 @@ static pci_ers_result_t cxlflash_pci_error_detected(struct pci_dev *pdev,
/* Turn off legacy I/O */ /* Turn off legacy I/O */
scsi_block_requests(cfg->host); scsi_block_requests(cfg->host);
rc = cxlflash_mark_contexts_error(cfg);
if (unlikely(rc))
dev_err(dev, "%s: Failed to mark user contexts!(%d)\n",
__func__, rc);
term_mc(cfg, UNDO_START); term_mc(cfg, UNDO_START);
stop_afu(cfg); stop_afu(cfg);
...@@ -2431,6 +2460,8 @@ static int __init init_cxlflash(void) ...@@ -2431,6 +2460,8 @@ static int __init init_cxlflash(void)
pr_info("%s: IBM Power CXL Flash Adapter: %s\n", pr_info("%s: IBM Power CXL Flash Adapter: %s\n",
__func__, CXLFLASH_DRIVER_DATE); __func__, CXLFLASH_DRIVER_DATE);
cxlflash_list_init();
return pci_register_driver(&cxlflash_driver); return pci_register_driver(&cxlflash_driver);
} }
...@@ -2439,6 +2470,9 @@ static int __init init_cxlflash(void) ...@@ -2439,6 +2470,9 @@ static int __init init_cxlflash(void)
*/ */
static void __exit exit_cxlflash(void) static void __exit exit_cxlflash(void)
{ {
cxlflash_term_global_luns();
cxlflash_free_errpage();
pci_unregister_driver(&cxlflash_driver); pci_unregister_driver(&cxlflash_driver);
} }
......
...@@ -409,7 +409,10 @@ struct sisl_lxt_entry { ...@@ -409,7 +409,10 @@ struct sisl_lxt_entry {
}; };
/* Per the SISlite spec, RHT entries are to be 16-byte aligned */ /*
* RHT - Resource Handle Table
* Per the SISlite spec, RHT entries are to be 16-byte aligned
*/
struct sisl_rht_entry { struct sisl_rht_entry {
struct sisl_lxt_entry *lxt_start; struct sisl_lxt_entry *lxt_start;
u32 lxt_cnt; u32 lxt_cnt;
......
This diff is collapsed.
/*
* 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_SUPERPIPE_H
#define _CXLFLASH_SUPERPIPE_H
extern struct cxlflash_global global;
/*
* Terminology: use afu (and not adapter) to refer to the HW.
* Adapter is the entire slot and includes PSL out of which
* only the AFU is visible to user space.
*/
/* Chunk size parms: note sislite minimum chunk size is
0x10000 LBAs corresponding to a NMASK or 16.
*/
#define MC_CHUNK_SIZE (1 << MC_RHT_NMASK) /* in LBAs */
#define MC_DISCOVERY_TIMEOUT 5 /* 5 secs */
#define CHAN2PORT(_x) ((_x) + 1)
enum lun_mode {
MODE_NONE = 0,
MODE_PHYSICAL
};
/* Global (entire driver, spans adapters) lun_info structure */
struct glun_info {
u64 max_lba; /* from read cap(16) */
u32 blk_len; /* from read cap(16) */
enum lun_mode mode; /* NONE, PHYSICAL */
int users; /* Number of users w/ references to LUN */
u8 wwid[16];
struct mutex mutex;
struct list_head list;
};
/* Local (per-adapter) lun_info structure */
struct llun_info {
u64 lun_id[CXLFLASH_NUM_FC_PORTS]; /* from REPORT_LUNS */
u32 lun_index; /* Index in the LUN table */
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 */
u8 wwid[16]; /* Keep a duplicate copy here? */
struct glun_info *parent; /* Pointer to entry in global LUN structure */
struct scsi_device *sdev;
struct list_head list;
};
struct lun_access {
struct llun_info *lli;
struct scsi_device *sdev;
struct list_head list;
};
enum ctx_ctrl {
CTX_CTRL_CLONE = (1 << 1),
CTX_CTRL_ERR = (1 << 2),
CTX_CTRL_ERR_FALLBACK = (1 << 3),
CTX_CTRL_NOPID = (1 << 4),
CTX_CTRL_FILE = (1 << 5)
};
#define ENCODE_CTXID(_ctx, _id) (((((u64)_ctx) & 0xFFFFFFFF0) << 28) | _id)
#define DECODE_CTXID(_val) (_val & 0xFFFFFFFF)
struct ctx_info {
struct sisl_ctrl_map *ctrl_map; /* initialized at startup */
struct sisl_rht_entry *rht_start; /* 1 page (req'd for alignment),
alloc/free on attach/detach */
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 */
struct cxl_ioctl_start_work work;
u64 ctxid;
int lfd;
pid_t pid;
bool unavail;
bool err_recovery_active;
struct mutex mutex; /* Context protection */
struct cxl_context *ctx;
struct list_head luns; /* LUNs attached to this context */
const struct vm_operations_struct *cxl_mmap_vmops;
struct file *file;
struct list_head list; /* Link contexts in error recovery */
};
struct cxlflash_global {
struct mutex mutex;
struct list_head gluns;/* list of glun_info structs */
struct page *err_page; /* One page of all 0xF for error notification */
};
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_lun_attach(struct glun_info *, enum lun_mode, bool);
void cxlflash_lun_detach(struct glun_info *);
struct ctx_info *get_context(struct cxlflash_cfg *, u64, void *, enum ctx_ctrl);
void put_context(struct ctx_info *);
struct sisl_rht_entry *get_rhte(struct ctx_info *, res_hndl_t,
struct llun_info *);
struct sisl_rht_entry *rhte_checkout(struct ctx_info *, struct llun_info *);
void rhte_checkin(struct ctx_info *, struct sisl_rht_entry *);
int cxlflash_manage_lun(struct scsi_device *, struct dk_cxlflash_manage_lun *);
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */
...@@ -3,3 +3,4 @@ header-y += fc/ ...@@ -3,3 +3,4 @@ header-y += fc/
header-y += scsi_bsg_fc.h header-y += scsi_bsg_fc.h
header-y += scsi_netlink.h header-y += scsi_netlink.h
header-y += scsi_netlink_fc.h header-y += scsi_netlink_fc.h
header-y += cxlflash_ioctl.h
/*
* 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_IOCTL_H
#define _CXLFLASH_IOCTL_H
#include <linux/types.h>
/*
* Structure and flag definitions CXL Flash superpipe ioctls
*/
#define DK_CXLFLASH_VERSION_0 0
struct dk_cxlflash_hdr {
__u16 version; /* Version data */
__u16 rsvd[3]; /* Reserved for future use */
__u64 flags; /* Input flags */
__u64 return_flags; /* Returned flags */
};
/*
* Notes:
* -----
* The 'context_id' field of all ioctl structures contains the context
* identifier for a context in the lower 32-bits (upper 32-bits are not
* to be used when identifying a context to the AFU). That said, the value
* in its entirety (all 64-bits) is to be treated as an opaque cookie and
* should be presented as such when issuing ioctls.
*
* For DK_CXLFLASH_ATTACH ioctl, user specifies read/write access
* permissions via the O_RDONLY, O_WRONLY, and O_RDWR flags defined in
* the fcntl.h header file.
*/
#define DK_CXLFLASH_ATTACH_REUSE_CONTEXT 0x8000000000000000ULL
struct dk_cxlflash_attach {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 num_interrupts; /* Requested number of interrupts */
__u64 context_id; /* Returned context */
__u64 mmio_size; /* Returned size of MMIO area */
__u64 block_size; /* Returned block size, in bytes */
__u64 adap_fd; /* Returned adapter file descriptor */
__u64 last_lba; /* Returned last LBA on the device */
__u64 max_xfer; /* Returned max transfer size, blocks */
__u64 reserved[8]; /* Reserved for future use */
};
struct dk_cxlflash_detach {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 context_id; /* Context to detach */
__u64 reserved[8]; /* Reserved for future use */
};
struct dk_cxlflash_udirect {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 context_id; /* Context to own physical resources */
__u64 rsrc_handle; /* Returned resource handle */
__u64 last_lba; /* Returned last LBA on the device */
__u64 reserved[8]; /* Reserved for future use */
};
struct dk_cxlflash_release {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 context_id; /* Context owning resources */
__u64 rsrc_handle; /* Resource handle to release */
__u64 reserved[8]; /* Reserved for future use */
};
#define DK_CXLFLASH_VERIFY_SENSE_LEN 18
#define DK_CXLFLASH_VERIFY_HINT_SENSE 0x8000000000000000ULL
struct dk_cxlflash_verify {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 context_id; /* Context owning resources to verify */
__u64 rsrc_handle; /* Resource handle of LUN */
__u64 hint; /* Reasons for verify */
__u64 last_lba; /* Returned last LBA of device */
__u8 sense_data[DK_CXLFLASH_VERIFY_SENSE_LEN]; /* SCSI sense data */
__u8 pad[6]; /* Pad to next 8-byte boundary */
__u64 reserved[8]; /* Reserved for future use */
};
#define DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET 0x8000000000000000ULL
struct dk_cxlflash_recover_afu {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u64 reason; /* Reason for recovery request */
__u64 context_id; /* Context to recover / updated ID */
__u64 mmio_size; /* Returned size of MMIO area */
__u64 adap_fd; /* Returned adapter file descriptor */
__u64 reserved[8]; /* Reserved for future use */
};
#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN 16
#define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL
#define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL
#define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL
struct dk_cxlflash_manage_lun {
struct dk_cxlflash_hdr hdr; /* Common fields */
__u8 wwid[DK_CXLFLASH_MANAGE_LUN_WWID_LEN]; /* Page83 WWID, NAA-6 */
__u64 reserved[8]; /* Rsvd, future use */
};
union cxlflash_ioctls {
struct dk_cxlflash_attach attach;
struct dk_cxlflash_detach detach;
struct dk_cxlflash_udirect udirect;
struct dk_cxlflash_release release;
struct dk_cxlflash_verify verify;
struct dk_cxlflash_recover_afu recover_afu;
struct dk_cxlflash_manage_lun manage_lun;
};
#define MAX_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ioctls))
#define CXL_MAGIC 0xCA
#define CXL_IOWR(_n, _s) _IOWR(CXL_MAGIC, _n, struct _s)
#define DK_CXLFLASH_ATTACH CXL_IOWR(0x80, dk_cxlflash_attach)
#define DK_CXLFLASH_USER_DIRECT CXL_IOWR(0x81, dk_cxlflash_udirect)
#define DK_CXLFLASH_RELEASE CXL_IOWR(0x82, dk_cxlflash_release)
#define DK_CXLFLASH_DETACH CXL_IOWR(0x83, dk_cxlflash_detach)
#define DK_CXLFLASH_VERIFY CXL_IOWR(0x84, dk_cxlflash_verify)
#define DK_CXLFLASH_RECOVER_AFU CXL_IOWR(0x85, dk_cxlflash_recover_afu)
#define DK_CXLFLASH_MANAGE_LUN CXL_IOWR(0x86, dk_cxlflash_manage_lun)
#endif /* ifndef _CXLFLASH_IOCTL_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment