^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * CXL Flash Device Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (C) 2015 IBM Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/syscalls.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <scsi/scsi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <scsi/scsi_host.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <scsi/scsi_cmnd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <scsi/scsi_eh.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <uapi/scsi/cxlflash_ioctl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "sislite.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "vlun.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "superpipe.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct cxlflash_global global;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * marshal_rele_to_resize() - translate release to resize structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * @rele: Source structure from which to translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * @resize: Destination structure for the translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static void marshal_rele_to_resize(struct dk_cxlflash_release *release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct dk_cxlflash_resize *resize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) resize->hdr = release->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) resize->context_id = release->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) resize->rsrc_handle = release->rsrc_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * marshal_det_to_rele() - translate detach to release structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * @detach: Destination structure for the translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * @rele: Source structure from which to translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static void marshal_det_to_rele(struct dk_cxlflash_detach *detach,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct dk_cxlflash_release *release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) release->hdr = detach->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) release->context_id = detach->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * marshal_udir_to_rele() - translate udirect to release structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) * @udirect: Source structure from which to translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * @release: Destination structure for the translate/copy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void marshal_udir_to_rele(struct dk_cxlflash_udirect *udirect,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct dk_cxlflash_release *release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) release->hdr = udirect->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) release->context_id = udirect->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) release->rsrc_handle = udirect->rsrc_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) * cxlflash_free_errpage() - frees resources associated with global error page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) void cxlflash_free_errpage(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mutex_lock(&global.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (global.err_page) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) __free_page(global.err_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) global.err_page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) mutex_unlock(&global.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * cxlflash_stop_term_user_contexts() - stops/terminates known user contexts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * When the host needs to go down, all users must be quiesced and their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * memory freed. This is accomplished by putting the contexts in error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * state which will notify the user and let them 'drive' the tear down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * Meanwhile, this routine camps until all user contexts have been removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) * Note that the main loop in this routine will always execute at least once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * to flush the reset_waitq.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int i, found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) cxlflash_mark_contexts_error(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) for (i = 0; i < MAX_CONTEXT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (cfg->ctx_tbl[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) found = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!found && list_empty(&cfg->ctx_err_recovery))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) dev_dbg(dev, "%s: Wait for user contexts to quiesce...\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) wake_up_all(&cfg->reset_waitq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) found = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * find_error_context() - locates a context by cookie on the error recovery list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @rctxid: Desired context by id.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @file: Desired context by file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) * Return: Found context on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) static struct ctx_info *find_error_context(struct cxlflash_cfg *cfg, u64 rctxid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) struct ctx_info *ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) list_for_each_entry(ctxi, &cfg->ctx_err_recovery, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if ((ctxi->ctxid == rctxid) || (ctxi->file == file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) return ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * get_context() - obtains a validated and locked context reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * @rctxid: Desired context (raw, un-decoded format).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @arg: LUN information or file associated with request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @ctx_ctrl: Control information to 'steer' desired lookup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * NOTE: despite the name pid, in linux, current->pid actually refers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * to the lightweight process id (tid) and can change if the process is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * multi threaded. The tgid remains constant for the process and only changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * when the process of fork. For all intents and purposes, think of tgid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * as a pid in the traditional sense.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) * Return: Validated context on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct ctx_info *get_context(struct cxlflash_cfg *cfg, u64 rctxid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) void *arg, enum ctx_ctrl ctx_ctrl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) struct lun_access *lun_access = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct file *file = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct llun_info *lli = arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u64 ctxid = DECODE_CTXID(rctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) pid_t pid = task_tgid_nr(current), ctxpid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) if (ctx_ctrl & CTX_CTRL_FILE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) lli = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) file = (struct file *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (ctx_ctrl & CTX_CTRL_CLONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) pid = task_ppid_nr(current);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (likely(ctxid < MAX_CONTEXT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) while (true) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) mutex_lock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ctxi = cfg->ctx_tbl[ctxid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) if ((file && (ctxi->file != file)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) (!file && (ctxi->ctxid != rctxid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) if ((ctx_ctrl & CTX_CTRL_ERR) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) (!ctxi && (ctx_ctrl & CTX_CTRL_ERR_FALLBACK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) ctxi = find_error_context(cfg, rctxid, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Need to acquire ownership of the context while still
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) * under the table/list lock to serialize with a remove
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) * thread. Use the 'try' to avoid stalling the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * table/list lock for a single context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) * Note that the lock order is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) * cfg->ctx_tbl_list_mutex -> ctxi->mutex
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) * Therefore release ctx_tbl_list_mutex before retrying.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) rc = mutex_trylock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) if (rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) break; /* got the context's lock! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ctxi->unavail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) ctxpid = ctxi->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (likely(!(ctx_ctrl & CTX_CTRL_NOPID)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) if (pid != ctxpid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) if (lli) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) list_for_each_entry(lun_access, &ctxi->luns, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if (lun_access->lli == lli)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) goto denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_dbg(dev, "%s: rctxid=%016llx ctxinfo=%p ctxpid=%u pid=%u "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) "ctx_ctrl=%u\n", __func__, rctxid, ctxi, ctxpid, pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ctx_ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) denied:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * put_context() - release a context that was retrieved from get_context()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * @ctxi: Context to release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * For now, releasing the context equates to unlocking it's mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) void put_context(struct ctx_info *ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * afu_attach() - attach a context to the AFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * @ctxi: Context to attach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * Upon setting the context capabilities, they must be confirmed with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * a read back operation as the context might have been closed since
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * the mailbox was unlocked. When this occurs, registration is failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) static int afu_attach(struct cxlflash_cfg *cfg, struct ctx_info *ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) struct sisl_ctrl_map __iomem *ctrl_map = ctxi->ctrl_map;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) u64 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) /* Unlock cap and restrict user to read/write cmds in translated mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) readq_be(&ctrl_map->mbox_r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) val = (SISL_CTX_CAP_READ_CMD | SISL_CTX_CAP_WRITE_CMD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) writeq_be(val, &ctrl_map->ctx_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) val = readq_be(&ctrl_map->ctx_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) if (val != (SISL_CTX_CAP_READ_CMD | SISL_CTX_CAP_WRITE_CMD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dev_err(dev, "%s: ctx may be closed val=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) __func__, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) rc = -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) if (afu_is_ocxl_lisn(afu)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) /* Set up the LISN effective address for each interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) for (i = 0; i < ctxi->irqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) val = cfg->ops->get_irq_objhndl(ctxi->ctx, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) writeq_be(val, &ctrl_map->lisn_ea[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) /* Use primary HWQ PASID as identifier for all interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) val = hwq->ctx_hndl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) writeq_be(SISL_LISN_PASID(val, val), &ctrl_map->lisn_pasid[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) writeq_be(SISL_LISN_PASID(0UL, val), &ctrl_map->lisn_pasid[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Set up MMIO registers pointing to the RHT */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) writeq_be((u64)ctxi->rht_start, &ctrl_map->rht_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) val = SISL_RHT_CNT_ID((u64)MAX_RHT_PER_CONTEXT, (u64)(hwq->ctx_hndl));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) writeq_be(val, &ctrl_map->rht_cnt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * read_cap16() - issues a SCSI READ_CAP16 command
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * @lli: LUN destined for capacity request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) * The READ_CAP16 can take quite a while to complete. Should an EEH occur while
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * in scsi_execute(), the EEH handler will attempt to recover. As part of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * recovery, the handler drains all currently running ioctls, waiting until they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * have completed before proceeding with a reset. As this routine is used on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * ioctl path, this can create a condition where the EEH handler becomes stuck,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * infinitely waiting for this ioctl thread. To avoid this behavior, temporarily
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * unmark this thread as an ioctl thread by releasing the ioctl read semaphore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * This will allow the EEH handler to proceed with a recovery while this thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * is still running. Once the scsi_execute() returns, reacquire the ioctl read
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) * semaphore and check the adapter state in case it changed while inside of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * scsi_execute(). The state check will wait if the adapter is still being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * recovered or return a failure if the recovery failed. In the event that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * adapter reset failed, simply return the failure as the ioctl would be unable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * to continue.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * Note that the above puts a requirement on this routine to only be called on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) * an ioctl thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) static int read_cap16(struct scsi_device *sdev, struct llun_info *lli)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) struct scsi_sense_hdr sshdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) u8 *cmd_buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) u8 *scsi_cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) int result = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) int retry_cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) u32 to = CMD_TIMEOUT * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) scsi_cmd = kzalloc(MAX_COMMAND_SIZE, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (unlikely(!cmd_buf || !scsi_cmd)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) scsi_cmd[0] = SERVICE_ACTION_IN_16; /* read cap(16) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) scsi_cmd[1] = SAI_READ_CAPACITY_16; /* service action */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) put_unaligned_be32(CMD_BUFSIZE, &scsi_cmd[10]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) dev_dbg(dev, "%s: %ssending cmd(%02x)\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) retry_cnt ? "re" : "", scsi_cmd[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /* Drop the ioctl read semahpore across lengthy call */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) up_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) result = scsi_execute(sdev, scsi_cmd, DMA_FROM_DEVICE, cmd_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) CMD_BUFSIZE, NULL, &sshdr, to, CMD_RETRIES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 0, 0, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) down_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) rc = check_state(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dev_err(dev, "%s: Failed state result=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) if (driver_byte(result) == DRIVER_SENSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) result &= ~(0xFF<<24); /* DRIVER_SENSE is not an error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (result & SAM_STAT_CHECK_CONDITION) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) switch (sshdr.sense_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) case NO_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) case RECOVERED_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) case NOT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) result &= ~SAM_STAT_CHECK_CONDITION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case UNIT_ATTENTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) switch (sshdr.asc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) case 0x29: /* Power on Reset or Device Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) case 0x2A: /* Device capacity changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case 0x3F: /* Report LUNs changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* Retry the command once more */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) if (retry_cnt++ < 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) kfree(cmd_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) kfree(scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) dev_err(dev, "%s: command failed, result=%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) __func__, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * Read cap was successful, grab values from the buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) * note that we don't need to worry about unaligned access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * as the buffer is allocated on an aligned boundary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) mutex_lock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) gli->max_lba = be64_to_cpu(*((__be64 *)&cmd_buf[0]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) gli->blk_len = be32_to_cpu(*((__be32 *)&cmd_buf[8]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) mutex_unlock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) kfree(cmd_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) kfree(scsi_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) dev_dbg(dev, "%s: maxlba=%lld blklen=%d rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) __func__, gli->max_lba, gli->blk_len, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * get_rhte() - obtains validated resource handle table entry reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @ctxi: Context owning the resource handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * @rhndl: Resource handle associated with entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * @lli: LUN associated with request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * Return: Validated RHTE on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct sisl_rht_entry *get_rhte(struct ctx_info *ctxi, res_hndl_t rhndl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) struct llun_info *lli)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct cxlflash_cfg *cfg = ctxi->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) struct sisl_rht_entry *rhte = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) if (unlikely(!ctxi->rht_start)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) dev_dbg(dev, "%s: Context does not have allocated RHT\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (unlikely(rhndl >= MAX_RHT_PER_CONTEXT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) dev_dbg(dev, "%s: Bad resource handle rhndl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) __func__, rhndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (unlikely(ctxi->rht_lun[rhndl] != lli)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) dev_dbg(dev, "%s: Bad resource handle LUN rhndl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) __func__, rhndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) rhte = &ctxi->rht_start[rhndl];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (unlikely(rhte->nmask == 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) dev_dbg(dev, "%s: Unopened resource handle rhndl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) __func__, rhndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) rhte = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) return rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * rhte_checkout() - obtains free/empty resource handle table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) * @ctxi: Context owning the resource handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) * @lli: LUN associated with request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * Return: Free RHTE on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct sisl_rht_entry *rhte_checkout(struct ctx_info *ctxi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct llun_info *lli)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct cxlflash_cfg *cfg = ctxi->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct sisl_rht_entry *rhte = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /* Find a free RHT entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) for (i = 0; i < MAX_RHT_PER_CONTEXT; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) if (ctxi->rht_start[i].nmask == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) rhte = &ctxi->rht_start[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) ctxi->rht_out++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) if (likely(rhte))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ctxi->rht_lun[i] = lli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) dev_dbg(dev, "%s: returning rhte=%p index=%d\n", __func__, rhte, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) return rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) * rhte_checkin() - releases a resource handle table entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) * @ctxi: Context owning the resource handle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) * @rhte: RHTE to release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) void rhte_checkin(struct ctx_info *ctxi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) struct sisl_rht_entry *rhte)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) u32 rsrc_handle = rhte - ctxi->rht_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) rhte->nmask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) rhte->fp = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) ctxi->rht_out--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) ctxi->rht_lun[rsrc_handle] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) ctxi->rht_needs_ws[rsrc_handle] = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * rhte_format1() - populates a RHTE for format 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * @rhte: RHTE to populate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * @lun_id: LUN ID of LUN associated with RHTE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * @perm: Desired permissions for RHTE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) * @port_sel: Port selection mask
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static void rht_format1(struct sisl_rht_entry *rhte, u64 lun_id, u32 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) u32 port_sel)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * Populate the Format 1 RHT entry for direct access (physical
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * LUN) using the synchronization sequence defined in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * SISLite specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct sisl_rht_entry_f1 dummy = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) struct sisl_rht_entry_f1 *rhte_f1 = (struct sisl_rht_entry_f1 *)rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) memset(rhte_f1, 0, sizeof(*rhte_f1));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) rhte_f1->fp = SISL_RHT_FP(1U, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) dma_wmb(); /* Make setting of format bit visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) rhte_f1->lun_id = lun_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dma_wmb(); /* Make setting of LUN id visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) * Use a dummy RHT Format 1 entry to build the second dword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * of the entry that must be populated in a single write when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * enabled (valid bit set to TRUE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) dummy.valid = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) dummy.fp = SISL_RHT_FP(1U, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) dummy.port_sel = port_sel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) rhte_f1->dw = dummy.dw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) dma_wmb(); /* Make remaining RHT entry fields visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * cxlflash_lun_attach() - attaches a user to a LUN and manages the LUN's mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * @gli: LUN to attach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * @mode: Desired mode of the LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * @locked: Mutex status on current thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) int cxlflash_lun_attach(struct glun_info *gli, enum lun_mode mode, bool locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (!locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) mutex_lock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) if (gli->mode == MODE_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) gli->mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) else if (gli->mode != mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) pr_debug("%s: gli_mode=%d requested_mode=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) __func__, gli->mode, mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) gli->users++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) WARN_ON(gli->users <= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) pr_debug("%s: Returning rc=%d gli->mode=%u gli->users=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) __func__, rc, gli->mode, gli->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) mutex_unlock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * cxlflash_lun_detach() - detaches a user from a LUN and resets the LUN's mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * @gli: LUN to detach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * When resetting the mode, terminate block allocation resources as they
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * are no longer required (service is safe to call even when block allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) * resources were not present - such as when transitioning from physical mode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * These resources will be reallocated when needed (subsequent transition to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) * virtual mode).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) void cxlflash_lun_detach(struct glun_info *gli)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) mutex_lock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) WARN_ON(gli->mode == MODE_NONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) if (--gli->users == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) gli->mode = MODE_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) cxlflash_ba_terminate(&gli->blka.ba_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) pr_debug("%s: gli->users=%u\n", __func__, gli->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) WARN_ON(gli->users < 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) mutex_unlock(&gli->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * _cxlflash_disk_release() - releases the specified resource entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * @ctxi: Context owning resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * @release: Release ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) * For LUNs in virtual mode, the virtual LUN associated with the specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) * resource handle is resized to 0 prior to releasing the RHTE. Note that the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) * AFU sync should _not_ be performed when the context is sitting on the error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) * recovery list. A context on the error recovery list is not known to the AFU
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * due to reset. When the context is recovered, it will be reattached and made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) * known again to the AFU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) int _cxlflash_disk_release(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct ctx_info *ctxi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) struct dk_cxlflash_release *release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) bool put_ctx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) struct dk_cxlflash_resize size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) res_hndl_t rhndl = release->rsrc_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int rcr = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) u64 ctxid = DECODE_CTXID(release->context_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) rctxid = release->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) struct sisl_rht_entry *rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) struct sisl_rht_entry_f1 *rhte_f1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) dev_dbg(dev, "%s: ctxid=%llu rhndl=%llu gli->mode=%u gli->users=%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) __func__, ctxid, release->rsrc_handle, gli->mode, gli->users);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (!ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) ctxi = get_context(cfg, rctxid, lli, CTX_CTRL_ERR_FALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) dev_dbg(dev, "%s: Bad context ctxid=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) put_ctx = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) rhte = get_rhte(ctxi, rhndl, lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) if (unlikely(!rhte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) dev_dbg(dev, "%s: Bad resource handle rhndl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) __func__, rhndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) * Resize to 0 for virtual LUNS by setting the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * to 0. This will clear LXT_START and LXT_CNT fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * in the RHT entry and properly sync with the AFU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) * Afterwards we clear the remaining fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) switch (gli->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) case MODE_VIRTUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) marshal_rele_to_resize(release, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) size.req_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) rc = _cxlflash_vlun_resize(sdev, ctxi, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) dev_dbg(dev, "%s: resize failed rc %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) case MODE_PHYSICAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * Clear the Format 1 RHT entry for direct access
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * (physical LUN) using the synchronization sequence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) * defined in the SISLite specification.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) rhte_f1 = (struct sisl_rht_entry_f1 *)rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) rhte_f1->valid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) dma_wmb(); /* Make revocation of RHT entry visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) rhte_f1->lun_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) dma_wmb(); /* Make clearing of LUN id visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) rhte_f1->dw = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) dma_wmb(); /* Make RHT entry bottom-half clearing visible */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) if (!ctxi->err_recovery_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) rcr = cxlflash_afu_sync(afu, ctxid, rhndl, AFU_HW_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) if (unlikely(rcr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) dev_dbg(dev, "%s: AFU sync failed rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) __func__, rcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) WARN(1, "Unsupported LUN mode!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) rhte_checkin(ctxi, rhte);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) cxlflash_lun_detach(gli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) if (put_ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) int cxlflash_disk_release(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) struct dk_cxlflash_release *release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) return _cxlflash_disk_release(sdev, NULL, release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) * destroy_context() - releases a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) * @ctxi: Context to release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) * This routine is safe to be called with a a non-initialized context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) * Also note that the routine conditionally checks for the existence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) * of the context control map before clearing the RHT registers and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * context capabilities because it is possible to destroy a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * while the context is in the error state (previous mapping was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * removed [so there is no need to worry about clearing] and context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * is waiting for a new mapping).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) static void destroy_context(struct cxlflash_cfg *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) struct ctx_info *ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) if (ctxi->initialized) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) WARN_ON(!list_empty(&ctxi->luns));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /* Clear RHT registers and drop all capabilities for context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) if (afu->afu_map && ctxi->ctrl_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) writeq_be(0, &ctxi->ctrl_map->rht_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) writeq_be(0, &ctxi->ctrl_map->rht_cnt_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) writeq_be(0, &ctxi->ctrl_map->ctx_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) /* Free memory associated with context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) free_page((ulong)ctxi->rht_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) kfree(ctxi->rht_needs_ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) kfree(ctxi->rht_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) kfree(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * create_context() - allocates and initializes a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * Return: Allocated context on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static struct ctx_info *create_context(struct cxlflash_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct llun_info **lli = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) u8 *ws = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) struct sisl_rht_entry *rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) ctxi = kzalloc(sizeof(*ctxi), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) lli = kzalloc((MAX_RHT_PER_CONTEXT * sizeof(*lli)), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) ws = kzalloc((MAX_RHT_PER_CONTEXT * sizeof(*ws)), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) if (unlikely(!ctxi || !lli || !ws)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) dev_err(dev, "%s: Unable to allocate context\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) rhte = (struct sisl_rht_entry *)get_zeroed_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) if (unlikely(!rhte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) dev_err(dev, "%s: Unable to allocate RHT\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) ctxi->rht_lun = lli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ctxi->rht_needs_ws = ws;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) ctxi->rht_start = rhte;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) return ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) kfree(ws);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) kfree(lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) kfree(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) * init_context() - initializes a previously allocated context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * @ctxi: Previously allocated context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) * @ctx: Previously obtained context cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) * @ctxid: Previously obtained process element associated with CXL context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) * @file: Previously obtained file associated with CXL context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) * @perms: User-specified permissions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) * @irqs: User-specified number of interrupts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) static void init_context(struct ctx_info *ctxi, struct cxlflash_cfg *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) void *ctx, int ctxid, struct file *file, u32 perms,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) u64 irqs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ctxi->rht_perms = perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ctxi->ctrl_map = &afu->afu_map->ctrls[ctxid].ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) ctxi->ctxid = ENCODE_CTXID(ctxi, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) ctxi->irqs = irqs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) ctxi->pid = task_tgid_nr(current); /* tgid = pid */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ctxi->ctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) ctxi->cfg = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) ctxi->file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) ctxi->initialized = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) mutex_init(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) kref_init(&ctxi->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) INIT_LIST_HEAD(&ctxi->luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) INIT_LIST_HEAD(&ctxi->list); /* initialize for list_empty() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) * remove_context() - context kref release handler
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) * @kref: Kernel reference associated with context to be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * When a context no longer has any references it can safely be removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) * from global access and destroyed. Note that it is assumed the thread
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * relinquishing access to the context holds its mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) static void remove_context(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) struct ctx_info *ctxi = container_of(kref, struct ctx_info, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) struct cxlflash_cfg *cfg = ctxi->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) u64 ctxid = DECODE_CTXID(ctxi->ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) /* Remove context from table/error list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) WARN_ON(!mutex_is_locked(&ctxi->mutex));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) ctxi->unavail = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) mutex_lock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (!list_empty(&ctxi->list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) list_del(&ctxi->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) cfg->ctx_tbl[ctxid] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /* Context now completely uncoupled/unreachable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) destroy_context(cfg, ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * _cxlflash_disk_detach() - detaches a LUN from a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) * @ctxi: Context owning resources.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) * @detach: Detach ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) * As part of the detach, all per-context resources associated with the LUN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) * are cleaned up. When detaching the last LUN for a context, the context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) * itself is cleaned up and released.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) static int _cxlflash_disk_detach(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct ctx_info *ctxi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct dk_cxlflash_detach *detach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) struct lun_access *lun_access, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct dk_cxlflash_release rel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) bool put_ctx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) u64 ctxid = DECODE_CTXID(detach->context_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) rctxid = detach->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) dev_dbg(dev, "%s: ctxid=%llu\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) if (!ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) ctxi = get_context(cfg, rctxid, lli, CTX_CTRL_ERR_FALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) dev_dbg(dev, "%s: Bad context ctxid=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) put_ctx = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) /* Cleanup outstanding resources tied to this LUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (ctxi->rht_out) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) marshal_det_to_rele(detach, &rel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) for (i = 0; i < MAX_RHT_PER_CONTEXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (ctxi->rht_lun[i] == lli) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) rel.rsrc_handle = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) _cxlflash_disk_release(sdev, ctxi, &rel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) /* No need to loop further if we're done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) if (ctxi->rht_out == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) /* Take our LUN out of context, free the node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) list_for_each_entry_safe(lun_access, t, &ctxi->luns, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (lun_access->lli == lli) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) list_del(&lun_access->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) kfree(lun_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) lun_access = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Release the context reference and the sdev reference that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) * bound this LUN to the context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) if (kref_put(&ctxi->kref, remove_context))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) put_ctx = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) if (put_ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) static int cxlflash_disk_detach(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct dk_cxlflash_detach *detach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) return _cxlflash_disk_detach(sdev, NULL, detach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) * cxlflash_cxl_release() - release handler for adapter file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) * @inode: File-system inode associated with fd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) * @file: File installed with adapter file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) * This routine is the release handler for the fops registered with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) * the CXL services on an initial attach for a context. It is called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) * when a close (explicity by the user or as part of a process tear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) * down) is performed on the adapter file descriptor returned to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) * user. The user should be aware that explicitly performing a close
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) * considered catastrophic and subsequent usage of the superpipe API
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) * with previously saved off tokens will fail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) * This routine derives the context reference and calls detach for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * each LUN associated with the context.The final detach operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * causes the context itself to be freed. With exception to when the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * CXL process element (context id) lookup fails (a case that should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * theoretically never occur), every call into this routine results
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * in a complete freeing of a context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * Detaching the LUN is typically an ioctl() operation and the underlying
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * code assumes that ioctl_rwsem has been acquired as a reader. To support
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * that design point, the semaphore is acquired and released around detach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) * Return: 0 on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) static int cxlflash_cxl_release(struct inode *inode, struct file *file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) struct cxlflash_cfg *cfg = container_of(file->f_op, struct cxlflash_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) cxl_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) void *ctx = cfg->ops->fops_get_context(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct dk_cxlflash_detach detach = { { 0 }, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) struct lun_access *lun_access, *t;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) enum ctx_ctrl ctrl = CTX_CTRL_ERR_FALLBACK | CTX_CTRL_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) int ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) ctxid = cfg->ops->process_element(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (unlikely(ctxid < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) dev_err(dev, "%s: Context %p was closed ctxid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) __func__, ctx, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ctxi = get_context(cfg, ctxid, file, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) ctxi = get_context(cfg, ctxid, file, ctrl | CTX_CTRL_CLONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) if (!ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) dev_dbg(dev, "%s: ctxid=%d already free\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) goto out_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) dev_dbg(dev, "%s: Another process owns ctxid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) dev_dbg(dev, "%s: close for ctxid=%d\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) down_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) detach.context_id = ctxi->ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) list_for_each_entry_safe(lun_access, t, &ctxi->luns, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) _cxlflash_disk_detach(lun_access->sdev, ctxi, &detach);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) up_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) out_release:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) cfg->ops->fd_release(inode, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) dev_dbg(dev, "%s: returning\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) * unmap_context() - clears a previously established mapping
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) * @ctxi: Context owning the mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) * This routine is used to switch between the error notification page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) * (dummy page of all 1's) and the real mapping (established by the CXL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) * fault handler).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void unmap_context(struct ctx_info *ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) unmap_mapping_range(ctxi->file->f_mapping, 0, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) * get_err_page() - obtains and allocates the error notification page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) * Return: error notification page on success, NULL on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) static struct page *get_err_page(struct cxlflash_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) struct page *err_page = global.err_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) if (unlikely(!err_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) err_page = alloc_page(GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) if (unlikely(!err_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) dev_err(dev, "%s: Unable to allocate err_page\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) memset(page_address(err_page), -1, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) /* Serialize update w/ other threads to avoid a leak */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) mutex_lock(&global.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) if (likely(!global.err_page))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) global.err_page = err_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) __free_page(err_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) err_page = global.err_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) mutex_unlock(&global.mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dev_dbg(dev, "%s: returning err_page=%p\n", __func__, err_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return err_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) * cxlflash_mmap_fault() - mmap fault handler for adapter file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) * @vmf: VM fault associated with current fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) * To support error notification via MMIO, faults are 'caught' by this routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) * that was inserted before passing back the adapter file descriptor on attach.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) * When a fault occurs, this routine evaluates if error recovery is active and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) * if so, installs the error page to 'notify' the user about the error state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) * During normal operation, the fault is simply handled by the original fault
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) * handler that was installed by CXL services as part of initializing the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) * adapter file descriptor. The VMA's page protection bits are toggled to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) * indicate cached/not-cached depending on the memory backing the fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) * Return: 0 on success, VM_FAULT_SIGBUS on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) static vm_fault_t cxlflash_mmap_fault(struct vm_fault *vmf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) struct vm_area_struct *vma = vmf->vma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) struct file *file = vma->vm_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) struct cxlflash_cfg *cfg = container_of(file->f_op, struct cxlflash_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) cxl_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) void *ctx = cfg->ops->fops_get_context(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) struct page *err_page = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) enum ctx_ctrl ctrl = CTX_CTRL_ERR_FALLBACK | CTX_CTRL_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) vm_fault_t rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) int ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ctxid = cfg->ops->process_element(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (unlikely(ctxid < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) dev_err(dev, "%s: Context %p was closed ctxid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) __func__, ctx, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) ctxi = get_context(cfg, ctxid, file, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) dev_dbg(dev, "%s: Bad context ctxid=%d\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dev_dbg(dev, "%s: fault for context %d\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) if (likely(!ctxi->err_recovery_active)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) rc = ctxi->cxl_mmap_vmops->fault(vmf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) dev_dbg(dev, "%s: err recovery active, use err_page\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) err_page = get_err_page(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (unlikely(!err_page)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev_err(dev, "%s: Could not get err_page\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) rc = VM_FAULT_RETRY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) get_page(err_page);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) vmf->page = err_page;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) vma->vm_page_prot = pgprot_cached(vma->vm_page_prot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) if (likely(ctxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) dev_dbg(dev, "%s: returning rc=%x\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) rc = VM_FAULT_SIGBUS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) * Local MMAP vmops to 'catch' faults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) static const struct vm_operations_struct cxlflash_mmap_vmops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) .fault = cxlflash_mmap_fault,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) * cxlflash_cxl_mmap() - mmap handler for adapter file descriptor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) * @file: File installed with adapter file descriptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * @vma: VM area associated with mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) * Installs local mmap vmops to 'catch' faults for error notification support.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) static int cxlflash_cxl_mmap(struct file *file, struct vm_area_struct *vma)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) struct cxlflash_cfg *cfg = container_of(file->f_op, struct cxlflash_cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) cxl_fops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) void *ctx = cfg->ops->fops_get_context(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) enum ctx_ctrl ctrl = CTX_CTRL_ERR_FALLBACK | CTX_CTRL_FILE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) int ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) ctxid = cfg->ops->process_element(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) if (unlikely(ctxid < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) dev_err(dev, "%s: Context %p was closed ctxid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) __func__, ctx, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) ctxi = get_context(cfg, ctxid, file, ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) dev_dbg(dev, "%s: Bad context ctxid=%d\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) dev_dbg(dev, "%s: mmap for context %d\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) rc = cfg->ops->fd_mmap(file, vma);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) if (likely(!rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) /* Insert ourself in the mmap fault handler path */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ctxi->cxl_mmap_vmops = vma->vm_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) vma->vm_ops = &cxlflash_mmap_vmops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (likely(ctxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) const struct file_operations cxlflash_cxl_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) .mmap = cxlflash_cxl_mmap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) .release = cxlflash_cxl_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) * cxlflash_mark_contexts_error() - move contexts to error state and list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) * A context is only moved over to the error list when there are no outstanding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * references to it. This ensures that a running operation has completed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) int cxlflash_mark_contexts_error(struct cxlflash_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) int i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) mutex_lock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) for (i = 0; i < MAX_CONTEXT; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) ctxi = cfg->ctx_tbl[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) cfg->ctx_tbl[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) list_add(&ctxi->list, &cfg->ctx_err_recovery);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) ctxi->err_recovery_active = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) ctxi->ctrl_map = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) unmap_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * Dummy NULL fops
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static const struct file_operations null_fops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * check_state() - checks and responds to the current adapter state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * This routine can block and should only be used on process context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) * It assumes that the caller is an ioctl thread and holding the ioctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) * read semaphore. This is temporarily let up across the wait to allow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) * for draining actively running ioctls. Also note that when waking up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) * from waiting in reset, the state is unknown and must be checked again
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) * before proceeding.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) int check_state(struct cxlflash_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) switch (cfg->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) case STATE_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) dev_dbg(dev, "%s: Reset state, going to wait...\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) up_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) rc = wait_event_interruptible(cfg->reset_waitq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) cfg->state != STATE_RESET);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) down_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) if (unlikely(rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) case STATE_FAILTERM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) dev_dbg(dev, "%s: Failed/Terminating\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) * cxlflash_disk_attach() - attach a LUN to a context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) * @attach: Attach ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * Creates a context and attaches LUN to it. A LUN can only be attached
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) * one time to a context (subsequent attaches for the same context/LUN pair
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * are not supported). Additional LUNs can be attached to a context by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) * specifying the 'reuse' flag defined in the cxlflash_ioctl.h header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) static int cxlflash_disk_attach(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) struct dk_cxlflash_attach *attach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) struct lun_access *lun_access = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) u32 perms;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) int ctxid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) u64 irqs = attach->num_interrupts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) u64 flags = 0UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) u64 rctxid = 0UL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) struct file *file = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) void *ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) int fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) if (irqs > 4) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) dev_dbg(dev, "%s: Cannot support this many interrupts %llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) __func__, irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) if (gli->max_lba == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) dev_dbg(dev, "%s: No capacity info for LUN=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) __func__, lli->lun_id[sdev->channel]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) rc = read_cap16(sdev, lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) dev_err(dev, "%s: Invalid device rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) dev_dbg(dev, "%s: LBA = %016llx\n", __func__, gli->max_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) dev_dbg(dev, "%s: BLK_LEN = %08x\n", __func__, gli->blk_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (attach->hdr.flags & DK_CXLFLASH_ATTACH_REUSE_CONTEXT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) rctxid = attach->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) ctxi = get_context(cfg, rctxid, NULL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) if (!ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) dev_dbg(dev, "%s: Bad context rctxid=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) __func__, rctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) list_for_each_entry(lun_access, &ctxi->luns, list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) if (lun_access->lli == lli) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) dev_dbg(dev, "%s: Already attached\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) rc = scsi_device_get(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) dev_err(dev, "%s: Unable to get sdev reference\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) lun_access = kzalloc(sizeof(*lun_access), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) if (unlikely(!lun_access)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) dev_err(dev, "%s: Unable to allocate lun_access\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) lun_access->lli = lli;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) lun_access->sdev = sdev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) /* Non-NULL context indicates reuse (another context reference) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) if (ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) dev_dbg(dev, "%s: Reusing context for LUN rctxid=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) __func__, rctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) kref_get(&ctxi->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) list_add(&lun_access->list, &ctxi->luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) goto out_attach;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) ctxi = create_context(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) dev_err(dev, "%s: Failed to create context ctxid=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) rc = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) ctx = cfg->ops->dev_context_init(cfg->dev, cfg->afu_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) if (IS_ERR_OR_NULL(ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) dev_err(dev, "%s: Could not initialize context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) __func__, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) rc = cfg->ops->start_work(ctx, irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) dev_dbg(dev, "%s: Could not start context rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) ctxid = cfg->ops->process_element(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) dev_err(dev, "%s: ctxid=%d invalid\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) file = cfg->ops->get_fd(ctx, &cfg->cxl_fops, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) if (unlikely(fd < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) dev_err(dev, "%s: Could not get file descriptor\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) /* Translate read/write O_* flags from fcntl.h to AFU permission bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) perms = SISL_RHT_PERM(attach->hdr.flags + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /* Context mutex is locked upon return */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) init_context(ctxi, cfg, ctx, ctxid, file, perms, irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) rc = afu_attach(cfg, ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) * No error paths after this point. Once the fd is installed it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) * visible to user space and can't be undone safely on this thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) * There is no need to worry about a deadlock here because no one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) * knows about us yet; we can be the only one holding our mutex.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) list_add(&lun_access->list, &ctxi->luns);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) mutex_lock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) cfg->ctx_tbl[ctxid] = ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) fd_install(fd, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) out_attach:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) if (fd != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) flags |= DK_CXLFLASH_APP_CLOSE_ADAP_FD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) if (afu_is_sq_cmd_mode(afu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) flags |= DK_CXLFLASH_CONTEXT_SQ_CMD_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) attach->hdr.return_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) attach->context_id = ctxi->ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) attach->block_size = gli->blk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) attach->mmio_size = sizeof(afu->afu_map->hosts[0].harea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) attach->last_lba = gli->max_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) attach->max_xfer = sdev->host->max_sectors * MAX_SECTOR_UNIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) attach->max_xfer /= gli->blk_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) attach->adap_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) if (ctxi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) dev_dbg(dev, "%s: returning ctxid=%d fd=%d bs=%lld rc=%d llba=%lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) __func__, ctxid, fd, attach->block_size, rc, attach->last_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) /* Cleanup CXL context; okay to 'stop' even if it was not started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) if (!IS_ERR_OR_NULL(ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) cfg->ops->stop_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) cfg->ops->release_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) ctx = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) * Here, we're overriding the fops with a dummy all-NULL fops because
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) * fput() calls the release fop, which will cause us to mistakenly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) * call into the CXL code. Rather than try to add yet more complexity
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) * to that routine (cxlflash_cxl_release) we should try to fix the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) * issue here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) if (fd > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) file->f_op = &null_fops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) put_unused_fd(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) file = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) /* Cleanup our context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) if (ctxi) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) destroy_context(cfg, ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) kfree(lun_access);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) scsi_device_put(sdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) * recover_context() - recovers a context in error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) * @cfg: Internal structure associated with the host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) * @ctxi: Context to release.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) * @adap_fd: Adapter file descriptor associated with new/recovered context.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) * Restablishes the state for a context-in-error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) static int recover_context(struct cxlflash_cfg *cfg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) struct ctx_info *ctxi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) int *adap_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) int fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) int ctxid = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) struct file *file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) void *ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) ctx = cfg->ops->dev_context_init(cfg->dev, cfg->afu_cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) if (IS_ERR_OR_NULL(ctx)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) dev_err(dev, "%s: Could not initialize context %p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) __func__, ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) rc = cfg->ops->start_work(ctx, ctxi->irqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) dev_dbg(dev, "%s: Could not start context rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) ctxid = cfg->ops->process_element(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) if (unlikely((ctxid >= MAX_CONTEXT) || (ctxid < 0))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) dev_err(dev, "%s: ctxid=%d invalid\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) rc = -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) file = cfg->ops->get_fd(ctx, &cfg->cxl_fops, &fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) if (unlikely(fd < 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) dev_err(dev, "%s: Could not get file descriptor\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /* Update with new MMIO area based on updated context id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) ctxi->ctrl_map = &afu->afu_map->ctrls[ctxid].ctrl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) rc = afu_attach(cfg, ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) dev_err(dev, "%s: Could not attach AFU rc %d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) goto err3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) * No error paths after this point. Once the fd is installed it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) * visible to user space and can't be undone safely on this thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) ctxi->ctxid = ENCODE_CTXID(ctxi, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) ctxi->ctx = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) ctxi->file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) * Put context back in table (note the reinit of the context list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) * we must first drop the context's mutex and then acquire it in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) * order with the table/list mutex to avoid a deadlock - safe to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) * here because no one can find us at this moment in time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) mutex_lock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) list_del_init(&ctxi->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) cfg->ctx_tbl[ctxid] = ctxi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) mutex_unlock(&cfg->ctx_tbl_list_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) fd_install(fd, file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) *adap_fd = fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) dev_dbg(dev, "%s: returning ctxid=%d fd=%d rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) __func__, ctxid, fd, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) err3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) fput(file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) put_unused_fd(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) cfg->ops->stop_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) cfg->ops->release_context(ctx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) * cxlflash_afu_recover() - initiates AFU recovery
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) * @recover: Recover ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) * Only a single recovery is allowed at a time to avoid exhausting CXL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) * resources (leading to recovery failure) in the event that we're up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) * against the maximum number of contexts limit. For similar reasons,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) * a context recovery is retried if there are multiple recoveries taking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) * place at the same time and the failure was due to CXL services being
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) * unable to keep up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) * As this routine is called on ioctl context, it holds the ioctl r/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) * semaphore that is used to drain ioctls in recovery scenarios. The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) * implementation to achieve the pacing described above (a local mutex)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) * requires that the ioctl r/w semaphore be dropped and reacquired to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) * avoid a 3-way deadlock when multiple process recoveries operate in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) * parallel.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) * Because a user can detect an error condition before the kernel, it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) * quite possible for this routine to act as the kernel's EEH detection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) * source (MMIO read of mbox_r). Because of this, there is a window of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) * time where an EEH might have been detected but not yet 'serviced'
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) * (callback invoked, causing the device to enter reset state). To avoid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) * looping in this routine during that window, a 1 second sleep is in place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) * between the time the MMIO failure is detected and the time a wait on the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) * reset wait queue is attempted via check_state().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) static int cxlflash_afu_recover(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) struct dk_cxlflash_recover_afu *recover)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) struct mutex *mutex = &cfg->ctx_recovery_mutex;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) struct hwq *hwq = get_hwq(afu, PRIMARY_HWQ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) u64 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) u64 ctxid = DECODE_CTXID(recover->context_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) rctxid = recover->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) long reg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) bool locked = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) int lretry = 20; /* up to 2 seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) int new_adap_fd = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) atomic_inc(&cfg->recovery_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) up_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) rc = mutex_lock_interruptible(mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) down_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) locked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) rc = check_state(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) dev_err(dev, "%s: Failed state rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) dev_dbg(dev, "%s: reason=%016llx rctxid=%016llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) __func__, recover->reason, rctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) retry:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) /* Ensure that this process is attached to the context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) ctxi = get_context(cfg, rctxid, lli, CTX_CTRL_ERR_FALLBACK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) dev_dbg(dev, "%s: Bad context ctxid=%llu\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) if (ctxi->err_recovery_active) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) retry_recover:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) rc = recover_context(cfg, ctxi, &new_adap_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) dev_err(dev, "%s: Recovery failed ctxid=%llu rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) __func__, ctxid, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) if ((rc == -ENODEV) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) ((atomic_read(&cfg->recovery_threads) > 1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) (lretry--))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) dev_dbg(dev, "%s: Going to try again\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) mutex_unlock(mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) rc = mutex_lock_interruptible(mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) locked = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) goto retry_recover;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) ctxi->err_recovery_active = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) flags = DK_CXLFLASH_APP_CLOSE_ADAP_FD |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) if (afu_is_sq_cmd_mode(afu))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) flags |= DK_CXLFLASH_CONTEXT_SQ_CMD_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) recover->hdr.return_flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) recover->context_id = ctxi->ctxid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) recover->adap_fd = new_adap_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) recover->mmio_size = sizeof(afu->afu_map->hosts[0].harea);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) /* Test if in error state */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) reg = readq_be(&hwq->ctrl_map->mbox_r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) if (reg == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) dev_dbg(dev, "%s: MMIO fail, wait for recovery.\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) * Before checking the state, put back the context obtained with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) * get_context() as it is no longer needed and sleep for a short
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) * period of time (see prolog notes).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) ssleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) rc = check_state(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) if (unlikely(rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) goto retry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) dev_dbg(dev, "%s: MMIO working, no recovery required\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) if (likely(ctxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) if (locked)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) mutex_unlock(mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) atomic_dec_if_positive(&cfg->recovery_threads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) * process_sense() - evaluates and processes sense data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) * @verify: Verify ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) static int process_sense(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) struct dk_cxlflash_verify *verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) u64 prev_lba = gli->max_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) struct scsi_sense_hdr sshdr = { 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) rc = scsi_normalize_sense((const u8 *)&verify->sense_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) DK_CXLFLASH_VERIFY_SENSE_LEN, &sshdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) dev_err(dev, "%s: Failed to normalize sense data\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) switch (sshdr.sense_key) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) case NO_SENSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) case RECOVERED_ERROR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) case NOT_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) case UNIT_ATTENTION:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) switch (sshdr.asc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) case 0x29: /* Power on Reset or Device Reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) case 0x2A: /* Device settings/capacity changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) rc = read_cap16(sdev, lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) if (rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) rc = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) if (prev_lba != gli->max_lba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) dev_dbg(dev, "%s: Capacity changed old=%lld "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) "new=%lld\n", __func__, prev_lba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) gli->max_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) case 0x3F: /* Report LUNs changed, Rescan. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) scsi_scan_host(cfg->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) rc = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) dev_dbg(dev, "%s: sense_key %x asc %x ascq %x rc %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) sshdr.sense_key, sshdr.asc, sshdr.ascq, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) * cxlflash_disk_verify() - verifies a LUN is the same and handle size changes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) * @verify: Verify ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) static int cxlflash_disk_verify(struct scsi_device *sdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) struct dk_cxlflash_verify *verify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) struct sisl_rht_entry *rhte = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) res_hndl_t rhndl = verify->rsrc_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) u64 ctxid = DECODE_CTXID(verify->context_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) rctxid = verify->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) u64 last_lba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) dev_dbg(dev, "%s: ctxid=%llu rhndl=%016llx, hint=%016llx, "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) "flags=%016llx\n", __func__, ctxid, verify->rsrc_handle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) verify->hint, verify->hdr.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) ctxi = get_context(cfg, rctxid, lli, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) dev_dbg(dev, "%s: Bad context ctxid=%llu\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) rhte = get_rhte(ctxi, rhndl, lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) if (unlikely(!rhte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) dev_dbg(dev, "%s: Bad resource handle rhndl=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) __func__, rhndl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) * Look at the hint/sense to see if it requires us to redrive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) * inquiry (i.e. the Unit attention is due to the WWN changing).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) if (verify->hint & DK_CXLFLASH_VERIFY_HINT_SENSE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) /* Can't hold mutex across process_sense/read_cap16,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) * since we could have an intervening EEH event.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) ctxi->unavail = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) mutex_unlock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) rc = process_sense(sdev, verify);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) dev_err(dev, "%s: Failed to validate sense data (%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) ctxi->unavail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) mutex_lock(&ctxi->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) ctxi->unavail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) switch (gli->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) case MODE_PHYSICAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) last_lba = gli->max_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) case MODE_VIRTUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) /* Cast lxt_cnt to u64 for multiply to be treated as 64bit op */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) last_lba = ((u64)rhte->lxt_cnt * MC_CHUNK_SIZE * gli->blk_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) last_lba /= CXLFLASH_BLOCK_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) last_lba--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) WARN(1, "Unsupported LUN mode!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) verify->last_lba = last_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) if (likely(ctxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) dev_dbg(dev, "%s: returning rc=%d llba=%llx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) __func__, rc, verify->last_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) * decode_ioctl() - translates an encoded ioctl to an easily identifiable string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) * @cmd: The ioctl command to decode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) * Return: A string identifying the decoded ioctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) static char *decode_ioctl(unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) case DK_CXLFLASH_ATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) return __stringify_1(DK_CXLFLASH_ATTACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) case DK_CXLFLASH_USER_DIRECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) return __stringify_1(DK_CXLFLASH_USER_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) case DK_CXLFLASH_USER_VIRTUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) return __stringify_1(DK_CXLFLASH_USER_VIRTUAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) case DK_CXLFLASH_VLUN_RESIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) return __stringify_1(DK_CXLFLASH_VLUN_RESIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) case DK_CXLFLASH_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) return __stringify_1(DK_CXLFLASH_RELEASE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) case DK_CXLFLASH_DETACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) return __stringify_1(DK_CXLFLASH_DETACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) case DK_CXLFLASH_VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) return __stringify_1(DK_CXLFLASH_VERIFY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) case DK_CXLFLASH_VLUN_CLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) return __stringify_1(DK_CXLFLASH_VLUN_CLONE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) case DK_CXLFLASH_RECOVER_AFU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) return __stringify_1(DK_CXLFLASH_RECOVER_AFU);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) case DK_CXLFLASH_MANAGE_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) return __stringify_1(DK_CXLFLASH_MANAGE_LUN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) return "UNKNOWN";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) * cxlflash_disk_direct_open() - opens a direct (physical) disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) * @arg: UDirect ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) * On successful return, the user is informed of the resource handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) * to be used to identify the direct lun and the size (in blocks) of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) * the direct lun in last LBA format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) static int cxlflash_disk_direct_open(struct scsi_device *sdev, void *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) struct glun_info *gli = lli->parent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) struct dk_cxlflash_release rel = { { 0 }, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) struct dk_cxlflash_udirect *pphys = (struct dk_cxlflash_udirect *)arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) u64 ctxid = DECODE_CTXID(pphys->context_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) rctxid = pphys->context_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) u64 lun_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) u64 last_lba = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) u64 rsrc_handle = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) u32 port = CHAN2PORTMASK(sdev->channel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) struct ctx_info *ctxi = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) struct sisl_rht_entry *rhte = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) dev_dbg(dev, "%s: ctxid=%llu ls=%llu\n", __func__, ctxid, lun_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) rc = cxlflash_lun_attach(gli, MODE_PHYSICAL, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) dev_dbg(dev, "%s: Failed attach to LUN (PHYSICAL)\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) ctxi = get_context(cfg, rctxid, lli, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) if (unlikely(!ctxi)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) dev_dbg(dev, "%s: Bad context ctxid=%llu\n", __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) rhte = rhte_checkout(ctxi, lli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) if (unlikely(!rhte)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) dev_dbg(dev, "%s: Too many opens ctxid=%lld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) __func__, ctxid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) rc = -EMFILE; /* too many opens */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) goto err1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) rsrc_handle = (rhte - ctxi->rht_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) rht_format1(rhte, lli->lun_id[sdev->channel], ctxi->rht_perms, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) last_lba = gli->max_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) pphys->hdr.return_flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) pphys->last_lba = last_lba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) pphys->rsrc_handle = rsrc_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) rc = cxlflash_afu_sync(afu, ctxid, rsrc_handle, AFU_LW_SYNC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) if (unlikely(rc)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) dev_dbg(dev, "%s: AFU sync failed rc=%d\n", __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) goto err2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) if (likely(ctxi))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) put_context(ctxi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) dev_dbg(dev, "%s: returning handle=%llu rc=%d llba=%llu\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) __func__, rsrc_handle, rc, last_lba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) err2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) marshal_udir_to_rele(pphys, &rel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) _cxlflash_disk_release(sdev, ctxi, &rel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) err1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) cxlflash_lun_detach(gli);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) * ioctl_common() - common IOCTL handler for driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) * @cmd: IOCTL command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) * Handles common fencing operations that are valid for multiple ioctls. Always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) * allow through ioctls that are cleanup oriented in nature, even when operating
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) * in a failed/terminating state.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) static int ioctl_common(struct scsi_device *sdev, unsigned int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) struct llun_info *lli = sdev->hostdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) if (unlikely(!lli)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056) dev_dbg(dev, "%s: Unknown LUN\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061) rc = check_state(cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) if (unlikely(rc) && (cfg->state == STATE_FAILTERM)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) case DK_CXLFLASH_VLUN_RESIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) case DK_CXLFLASH_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) case DK_CXLFLASH_DETACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) dev_dbg(dev, "%s: Command override rc=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) __func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) * cxlflash_ioctl() - IOCTL handler for driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) * @sdev: SCSI device associated with LUN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) * @cmd: IOCTL command.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) * @arg: Userspace ioctl data structure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) * A read/write semaphore is used to implement a 'drain' of currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) * running ioctls. The read semaphore is taken at the beginning of each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) * ioctl thread and released upon concluding execution. Additionally the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) * semaphore should be released and then reacquired in any ioctl execution
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) * path which will wait for an event to occur that is outside the scope of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) * the ioctl (i.e. an adapter reset). To drain the ioctls currently running,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) * a thread simply needs to acquire the write semaphore.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) * Return: 0 on success, -errno on failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) int cxlflash_ioctl(struct scsi_device *sdev, unsigned int cmd, void __user *arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) typedef int (*sioctl) (struct scsi_device *, void *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) struct cxlflash_cfg *cfg = shost_priv(sdev->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) struct device *dev = &cfg->dev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) struct afu *afu = cfg->afu;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) struct dk_cxlflash_hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) char buf[sizeof(union cxlflash_ioctls)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) size_t size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) bool known_ioctl = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) struct Scsi_Host *shost = sdev->host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) sioctl do_ioctl = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) static const struct {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) size_t size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) sioctl ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) } ioctl_tbl[] = { /* NOTE: order matters here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) {sizeof(struct dk_cxlflash_attach), (sioctl)cxlflash_disk_attach},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) {sizeof(struct dk_cxlflash_udirect), cxlflash_disk_direct_open},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) {sizeof(struct dk_cxlflash_release), (sioctl)cxlflash_disk_release},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {sizeof(struct dk_cxlflash_detach), (sioctl)cxlflash_disk_detach},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) {sizeof(struct dk_cxlflash_verify), (sioctl)cxlflash_disk_verify},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) {sizeof(struct dk_cxlflash_recover_afu), (sioctl)cxlflash_afu_recover},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) {sizeof(struct dk_cxlflash_manage_lun), (sioctl)cxlflash_manage_lun},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) {sizeof(struct dk_cxlflash_uvirtual), cxlflash_disk_virtual_open},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) {sizeof(struct dk_cxlflash_resize), (sioctl)cxlflash_vlun_resize},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) {sizeof(struct dk_cxlflash_clone), (sioctl)cxlflash_disk_clone},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) /* Hold read semaphore so we can drain if needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) down_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) /* Restrict command set to physical support only for internal LUN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) if (afu->internal_lun)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) case DK_CXLFLASH_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) case DK_CXLFLASH_USER_VIRTUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) case DK_CXLFLASH_VLUN_RESIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) case DK_CXLFLASH_VLUN_CLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) dev_dbg(dev, "%s: %s not supported for lun_mode=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) __func__, decode_ioctl(cmd), afu->internal_lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) case DK_CXLFLASH_ATTACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) case DK_CXLFLASH_USER_DIRECT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) case DK_CXLFLASH_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) case DK_CXLFLASH_DETACH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) case DK_CXLFLASH_VERIFY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) case DK_CXLFLASH_RECOVER_AFU:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) case DK_CXLFLASH_USER_VIRTUAL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) case DK_CXLFLASH_VLUN_RESIZE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) case DK_CXLFLASH_VLUN_CLONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) dev_dbg(dev, "%s: %s (%08X) on dev(%d/%d/%d/%llu)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) __func__, decode_ioctl(cmd), cmd, shost->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) sdev->channel, sdev->id, sdev->lun);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) rc = ioctl_common(sdev, cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) if (unlikely(rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) case DK_CXLFLASH_MANAGE_LUN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) known_ioctl = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) idx = _IOC_NR(cmd) - _IOC_NR(DK_CXLFLASH_ATTACH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) size = ioctl_tbl[idx].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) do_ioctl = ioctl_tbl[idx].ioctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) if (likely(do_ioctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) if (unlikely(copy_from_user(&buf, arg, size))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) dev_err(dev, "%s: copy_from_user() fail size=%lu cmd=%u (%s) arg=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) __func__, size, cmd, decode_ioctl(cmd), arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) hdr = (struct dk_cxlflash_hdr *)&buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) if (hdr->version != DK_CXLFLASH_VERSION_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) dev_dbg(dev, "%s: Version %u not supported for %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) __func__, hdr->version, decode_ioctl(cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190) if (hdr->rsvd[0] || hdr->rsvd[1] || hdr->rsvd[2] || hdr->return_flags) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191) dev_dbg(dev, "%s: Reserved/rflags populated\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) goto cxlflash_ioctl_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) rc = do_ioctl(sdev, (void *)&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) if (likely(!rc))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) if (unlikely(copy_to_user(arg, &buf, size))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) dev_err(dev, "%s: copy_to_user() fail size=%lu cmd=%u (%s) arg=%p\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) __func__, size, cmd, decode_ioctl(cmd), arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) rc = -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) /* fall through to exit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) cxlflash_ioctl_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) up_read(&cfg->ioctl_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) if (unlikely(rc && known_ioctl))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) dev_err(dev, "%s: ioctl %s (%08X) on dev(%d/%d/%d/%llu) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) "returned rc %d\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) decode_ioctl(cmd), cmd, shost->host_no,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) sdev->channel, sdev->id, sdev->lun, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) dev_dbg(dev, "%s: ioctl %s (%08X) on dev(%d/%d/%d/%llu) "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) "returned rc %d\n", __func__, decode_ioctl(cmd),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) cmd, shost->host_no, sdev->channel, sdev->id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) sdev->lun, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) }