mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
scsi: cxlflash: Remove driver
Remove the cxlflash driver for IBM CAPI Flash devices. The cxlflash driver has received minimal maintenance for some time, and the CAPI Flash hardware that uses it is no longer commercially available. Thanks to Uma Krishnan, Matthew Ochs and Manoj Kumar for their work on this driver over the years. Signed-off-by: Andrew Donnellan <ajd@linux.ibm.com> Link: https://lore.kernel.org/r/20250203072801.365551-2-ajd@linux.ibm.com Reviewed-by: Frederic Barrat <fbarrat@linux.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
08795f4c09
commit
772ba9b5bd
@ -1,433 +0,0 @@
|
||||
================================
|
||||
Coherent Accelerator (CXL) Flash
|
||||
================================
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
The IBM Power architecture provides support for CAPI (Coherent
|
||||
Accelerator Power Interface), which is available to certain PCIe slots
|
||||
on Power 8 systems. CAPI can be thought of as a special tunneling
|
||||
protocol through PCIe that allow PCIe adapters to look like special
|
||||
purpose co-processors which can read or write an application's
|
||||
memory and generate page faults. As a result, the host interface to
|
||||
an adapter running in CAPI mode does not require the data buffers to
|
||||
be mapped to the device's memory (IOMMU bypass) nor does it require
|
||||
memory to be pinned.
|
||||
|
||||
On Linux, Coherent Accelerator (CXL) kernel services present CAPI
|
||||
devices as a PCI device by implementing a virtual PCI host bridge.
|
||||
This abstraction simplifies the infrastructure and programming
|
||||
model, allowing for drivers to look similar to other native PCI
|
||||
device drivers.
|
||||
|
||||
CXL provides a mechanism by which user space applications can
|
||||
directly talk to a device (network or storage) bypassing the typical
|
||||
kernel/device driver stack. The CXL Flash Adapter Driver enables a
|
||||
user space application direct access to Flash storage.
|
||||
|
||||
The CXL Flash Adapter Driver is a kernel module that sits in the
|
||||
SCSI stack as a low level device driver (below the SCSI disk and
|
||||
protocol drivers) for the IBM CXL Flash Adapter. This driver is
|
||||
responsible for the initialization of the adapter, setting up the
|
||||
special path for user space access, and performing error recovery. It
|
||||
communicates directly the Flash Accelerator Functional Unit (AFU)
|
||||
as described in Documentation/arch/powerpc/cxl.rst.
|
||||
|
||||
The cxlflash driver supports two, mutually exclusive, modes of
|
||||
operation at the device (LUN) level:
|
||||
|
||||
- Any flash device (LUN) can be configured to be accessed as a
|
||||
regular disk device (i.e.: /dev/sdc). This is the default mode.
|
||||
|
||||
- Any flash device (LUN) can be configured to be accessed from
|
||||
user space with a special block library. This mode further
|
||||
specifies the means of accessing the device and provides for
|
||||
either raw access to the entire LUN (referred to as direct
|
||||
or physical LUN access) or access to a kernel/AFU-mediated
|
||||
partition of the LUN (referred to as virtual LUN access). The
|
||||
segmentation of a disk device into virtual LUNs is assisted
|
||||
by special translation services provided by the Flash AFU.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The Coherent Accelerator Interface Architecture (CAIA) introduces a
|
||||
concept of a master context. A master typically has special privileges
|
||||
granted to it by the kernel or hypervisor allowing it to perform AFU
|
||||
wide management and control. The master may or may not be involved
|
||||
directly in each user I/O, but at the minimum is involved in the
|
||||
initial setup before the user application is allowed to send requests
|
||||
directly to the AFU.
|
||||
|
||||
The CXL Flash Adapter Driver establishes a master context with the
|
||||
AFU. It uses memory mapped I/O (MMIO) for this control and setup. The
|
||||
Adapter Problem Space Memory Map looks like this::
|
||||
|
||||
+-------------------------------+
|
||||
| 512 * 64 KB User MMIO |
|
||||
| (per context) |
|
||||
| User Accessible |
|
||||
+-------------------------------+
|
||||
| 512 * 128 B per context |
|
||||
| Provisioning and Control |
|
||||
| Trusted Process accessible |
|
||||
+-------------------------------+
|
||||
| 64 KB Global |
|
||||
| Trusted Process accessible |
|
||||
+-------------------------------+
|
||||
|
||||
This driver configures itself into the SCSI software stack as an
|
||||
adapter driver. The driver is the only entity that is considered a
|
||||
Trusted Process to program the Provisioning and Control and Global
|
||||
areas in the MMIO Space shown above. The master context driver
|
||||
discovers all LUNs attached to the CXL Flash adapter and instantiates
|
||||
scsi block devices (/dev/sdb, /dev/sdc etc.) for each unique LUN
|
||||
seen from each path.
|
||||
|
||||
Once these scsi block devices are instantiated, an application
|
||||
written to a specification provided by the block library may get
|
||||
access to the Flash from user space (without requiring a system call).
|
||||
|
||||
This master context driver also provides a series of ioctls for this
|
||||
block library to enable this user space access. The driver supports
|
||||
two modes for accessing the block device.
|
||||
|
||||
The first mode is called a virtual mode. In this mode a single scsi
|
||||
block device (/dev/sdb) may be carved up into any number of distinct
|
||||
virtual LUNs. The virtual LUNs may be resized as long as the sum of
|
||||
the sizes of all the virtual LUNs, along with the meta-data associated
|
||||
with it does not exceed the physical capacity.
|
||||
|
||||
The second mode is called the physical mode. In this mode a single
|
||||
block device (/dev/sdb) may be opened directly by the block library
|
||||
and the entire space for the LUN is available to the application.
|
||||
|
||||
Only the physical mode provides persistence of the data. i.e. The
|
||||
data written to the block device will survive application exit and
|
||||
restart and also reboot. The virtual LUNs do not persist (i.e. do
|
||||
not survive after the application terminates or the system reboots).
|
||||
|
||||
|
||||
Block library API
|
||||
=================
|
||||
|
||||
Applications intending to get access to the CXL Flash from user
|
||||
space should use the block library, as it abstracts the details of
|
||||
interfacing directly with the cxlflash driver that are necessary for
|
||||
performing administrative actions (i.e.: setup, tear down, resize).
|
||||
The block library can be thought of as a 'user' of services,
|
||||
implemented as IOCTLs, that are provided by the cxlflash driver
|
||||
specifically for devices (LUNs) operating in user space access
|
||||
mode. While it is not a requirement that applications understand
|
||||
the interface between the block library and the cxlflash driver,
|
||||
a high-level overview of each supported service (IOCTL) is provided
|
||||
below.
|
||||
|
||||
The block library can be found on GitHub:
|
||||
http://github.com/open-power/capiflash
|
||||
|
||||
|
||||
CXL Flash Driver LUN IOCTLs
|
||||
===========================
|
||||
|
||||
Users, such as the block library, that wish to interface with a flash
|
||||
device (LUN) via user space access need to use the services provided
|
||||
by the cxlflash driver. As these services are implemented as ioctls,
|
||||
a file descriptor handle must first be obtained in order to establish
|
||||
the communication channel between a user and the kernel. This file
|
||||
descriptor is obtained by opening the device special file associated
|
||||
with the scsi disk device (/dev/sdb) that was created during LUN
|
||||
discovery. As per the location of the cxlflash driver within the
|
||||
SCSI protocol stack, this open is actually not seen by the cxlflash
|
||||
driver. Upon successful open, the user receives a file descriptor
|
||||
(herein referred to as fd1) that should be used for issuing the
|
||||
subsequent ioctls listed below.
|
||||
|
||||
The structure definitions for these IOCTLs are available in:
|
||||
uapi/scsi/cxlflash_ioctl.h
|
||||
|
||||
DK_CXLFLASH_ATTACH
|
||||
------------------
|
||||
|
||||
This ioctl obtains, initializes, and starts a context using the CXL
|
||||
kernel services. These services specify a context id (u16) by which
|
||||
to uniquely identify the context and its allocated resources. The
|
||||
services additionally provide a second file descriptor (herein
|
||||
referred to as fd2) that is used by the block library to initiate
|
||||
memory mapped I/O (via mmap()) to the CXL flash device and poll for
|
||||
completion events. This file descriptor is intentionally installed by
|
||||
this driver and not the CXL kernel services to allow for intermediary
|
||||
notification and access in the event of a non-user-initiated close(),
|
||||
such as a killed process. This design point is described in further
|
||||
detail in the description for the DK_CXLFLASH_DETACH ioctl.
|
||||
|
||||
There are a few important aspects regarding the "tokens" (context id
|
||||
and fd2) that are provided back to the user:
|
||||
|
||||
- These tokens are only valid for the process under which they
|
||||
were created. The child of a forked process cannot continue
|
||||
to use the context id or file descriptor created by its parent
|
||||
(see DK_CXLFLASH_VLUN_CLONE for further details).
|
||||
|
||||
- These tokens are only valid for the lifetime of the context and
|
||||
the process under which they were created. Once either is
|
||||
destroyed, the tokens are to be considered stale and subsequent
|
||||
usage will result in errors.
|
||||
|
||||
- A valid adapter file descriptor (fd2 >= 0) is only returned on
|
||||
the initial attach for a context. Subsequent attaches to an
|
||||
existing context (DK_CXLFLASH_ATTACH_REUSE_CONTEXT flag present)
|
||||
do not provide the adapter file descriptor as it was previously
|
||||
made known to the application.
|
||||
|
||||
- When a context is no longer needed, the user shall detach from
|
||||
the context via the DK_CXLFLASH_DETACH ioctl. When this ioctl
|
||||
returns with a valid adapter file descriptor and the return flag
|
||||
DK_CXLFLASH_APP_CLOSE_ADAP_FD is present, the application _must_
|
||||
close the adapter file descriptor following a successful detach.
|
||||
|
||||
- When this ioctl returns with a valid fd2 and the return flag
|
||||
DK_CXLFLASH_APP_CLOSE_ADAP_FD is present, the application _must_
|
||||
close fd2 in the following circumstances:
|
||||
|
||||
+ Following a successful detach of the last user of the context
|
||||
+ Following a successful recovery on the context's original fd2
|
||||
+ In the child process of a fork(), following a clone ioctl,
|
||||
on the fd2 associated with the source context
|
||||
|
||||
- At any time, a close on fd2 will invalidate the tokens. Applications
|
||||
should exercise caution to only close fd2 when appropriate (outlined
|
||||
in the previous bullet) to avoid premature loss of I/O.
|
||||
|
||||
DK_CXLFLASH_USER_DIRECT
|
||||
-----------------------
|
||||
This ioctl is responsible for transitioning the LUN to direct
|
||||
(physical) mode access and configuring the AFU for direct access from
|
||||
user space on a per-context basis. Additionally, the block size and
|
||||
last logical block address (LBA) are returned to the user.
|
||||
|
||||
As mentioned previously, when operating in user space access mode,
|
||||
LUNs may be accessed in whole or in part. Only one mode is allowed
|
||||
at a time and if one mode is active (outstanding references exist),
|
||||
requests to use the LUN in a different mode are denied.
|
||||
|
||||
The AFU is configured for direct access from user space by adding an
|
||||
entry to the AFU's resource handle table. The index of the entry is
|
||||
treated as a resource handle that is returned to the user. The user
|
||||
is then able to use the handle to reference the LUN during I/O.
|
||||
|
||||
DK_CXLFLASH_USER_VIRTUAL
|
||||
------------------------
|
||||
This ioctl is responsible for transitioning the LUN to virtual mode
|
||||
of access and configuring the AFU for virtual access from user space
|
||||
on a per-context basis. Additionally, the block size and last logical
|
||||
block address (LBA) are returned to the user.
|
||||
|
||||
As mentioned previously, when operating in user space access mode,
|
||||
LUNs may be accessed in whole or in part. Only one mode is allowed
|
||||
at a time and if one mode is active (outstanding references exist),
|
||||
requests to use the LUN in a different mode are denied.
|
||||
|
||||
The AFU is configured for virtual access from user space by adding
|
||||
an entry to the AFU's resource handle table. The index of the entry
|
||||
is treated as a resource handle that is returned to the user. The
|
||||
user is then able to use the handle to reference the LUN during I/O.
|
||||
|
||||
By default, the virtual LUN is created with a size of 0. The user
|
||||
would need to use the DK_CXLFLASH_VLUN_RESIZE ioctl to adjust the grow
|
||||
the virtual LUN to a desired size. To avoid having to perform this
|
||||
resize for the initial creation of the virtual LUN, the user has the
|
||||
option of specifying a size as part of the DK_CXLFLASH_USER_VIRTUAL
|
||||
ioctl, such that when success is returned to the user, the
|
||||
resource handle that is provided is already referencing provisioned
|
||||
storage. This is reflected by the last LBA being a non-zero value.
|
||||
|
||||
When a LUN is accessible from more than one port, this ioctl will
|
||||
return with the DK_CXLFLASH_ALL_PORTS_ACTIVE return flag set. This
|
||||
provides the user with a hint that I/O can be retried in the event
|
||||
of an I/O error as the LUN can be reached over multiple paths.
|
||||
|
||||
DK_CXLFLASH_VLUN_RESIZE
|
||||
-----------------------
|
||||
This ioctl is responsible for resizing a previously created virtual
|
||||
LUN and will fail if invoked upon a LUN that is not in virtual
|
||||
mode. Upon success, an updated last LBA is returned to the user
|
||||
indicating the new size of the virtual LUN associated with the
|
||||
resource handle.
|
||||
|
||||
The partitioning of virtual LUNs is jointly mediated by the cxlflash
|
||||
driver and the AFU. An allocation table is kept for each LUN that is
|
||||
operating in the virtual mode and used to program a LUN translation
|
||||
table that the AFU references when provided with a resource handle.
|
||||
|
||||
This ioctl can return -EAGAIN if an AFU sync operation takes too long.
|
||||
In addition to returning a failure to user, cxlflash will also schedule
|
||||
an asynchronous AFU reset. Should the user choose to retry the operation,
|
||||
it is expected to succeed. If this ioctl fails with -EAGAIN, the user
|
||||
can either retry the operation or treat it as a failure.
|
||||
|
||||
DK_CXLFLASH_RELEASE
|
||||
-------------------
|
||||
This ioctl is responsible for releasing a previously obtained
|
||||
reference to either a physical or virtual LUN. This can be
|
||||
thought of as the inverse of the DK_CXLFLASH_USER_DIRECT or
|
||||
DK_CXLFLASH_USER_VIRTUAL ioctls. Upon success, the resource handle
|
||||
is no longer valid and the entry in the resource handle table is
|
||||
made available to be used again.
|
||||
|
||||
As part of the release process for virtual LUNs, the virtual LUN
|
||||
is first resized to 0 to clear out and free the translation tables
|
||||
associated with the virtual LUN reference.
|
||||
|
||||
DK_CXLFLASH_DETACH
|
||||
------------------
|
||||
This ioctl is responsible for unregistering a context with the
|
||||
cxlflash driver and release outstanding resources that were
|
||||
not explicitly released via the DK_CXLFLASH_RELEASE ioctl. Upon
|
||||
success, all "tokens" which had been provided to the user from the
|
||||
DK_CXLFLASH_ATTACH onward are no longer valid.
|
||||
|
||||
When the DK_CXLFLASH_APP_CLOSE_ADAP_FD flag was returned on a successful
|
||||
attach, the application _must_ close the fd2 associated with the context
|
||||
following the detach of the final user of the context.
|
||||
|
||||
DK_CXLFLASH_VLUN_CLONE
|
||||
----------------------
|
||||
This ioctl is responsible for cloning a previously created
|
||||
context to a more recently created context. It exists solely to
|
||||
support maintaining user space access to storage after a process
|
||||
forks. Upon success, the child process (which invoked the ioctl)
|
||||
will have access to the same LUNs via the same resource handle(s)
|
||||
as the parent, but under a different context.
|
||||
|
||||
Context sharing across processes is not supported with CXL and
|
||||
therefore each fork must be met with establishing a new context
|
||||
for the child process. This ioctl simplifies the state management
|
||||
and playback required by a user in such a scenario. When a process
|
||||
forks, child process can clone the parents context by first creating
|
||||
a context (via DK_CXLFLASH_ATTACH) and then using this ioctl to
|
||||
perform the clone from the parent to the child.
|
||||
|
||||
The clone itself is fairly simple. The resource handle and lun
|
||||
translation tables are copied from the parent context to the child's
|
||||
and then synced with the AFU.
|
||||
|
||||
When the DK_CXLFLASH_APP_CLOSE_ADAP_FD flag was returned on a successful
|
||||
attach, the application _must_ close the fd2 associated with the source
|
||||
context (still resident/accessible in the parent process) following the
|
||||
clone. This is to avoid a stale entry in the file descriptor table of the
|
||||
child process.
|
||||
|
||||
This ioctl can return -EAGAIN if an AFU sync operation takes too long.
|
||||
In addition to returning a failure to user, cxlflash will also schedule
|
||||
an asynchronous AFU reset. Should the user choose to retry the operation,
|
||||
it is expected to succeed. If this ioctl fails with -EAGAIN, the user
|
||||
can either retry the operation or treat it as a failure.
|
||||
|
||||
DK_CXLFLASH_VERIFY
|
||||
------------------
|
||||
This ioctl is used to detect various changes such as the capacity of
|
||||
the disk changing, the number of LUNs visible changing, etc. In cases
|
||||
where the changes affect the application (such as a LUN resize), the
|
||||
cxlflash driver will report the changed state to the application.
|
||||
|
||||
The user calls in when they want to validate that a LUN hasn't been
|
||||
changed in response to a check condition. As the user is operating out
|
||||
of band from the kernel, they will see these types of events without
|
||||
the kernel's knowledge. When encountered, the user's architected
|
||||
behavior is to call in to this ioctl, indicating what they want to
|
||||
verify and passing along any appropriate information. For now, only
|
||||
verifying a LUN change (ie: size different) with sense data is
|
||||
supported.
|
||||
|
||||
DK_CXLFLASH_RECOVER_AFU
|
||||
-----------------------
|
||||
This ioctl is used to drive recovery (if such an action is warranted)
|
||||
of a specified user context. Any state associated with the user context
|
||||
is re-established upon successful recovery.
|
||||
|
||||
User contexts are put into an error condition when the device needs to
|
||||
be reset or is terminating. Users are notified of this error condition
|
||||
by seeing all 0xF's on an MMIO read. Upon encountering this, the
|
||||
architected behavior for a user is to call into this ioctl to recover
|
||||
their context. A user may also call into this ioctl at any time to
|
||||
check if the device is operating normally. If a failure is returned
|
||||
from this ioctl, the user is expected to gracefully clean up their
|
||||
context via release/detach ioctls. Until they do, the context they
|
||||
hold is not relinquished. The user may also optionally exit the process
|
||||
at which time the context/resources they held will be freed as part of
|
||||
the release fop.
|
||||
|
||||
When the DK_CXLFLASH_APP_CLOSE_ADAP_FD flag was returned on a successful
|
||||
attach, the application _must_ unmap and close the fd2 associated with the
|
||||
original context following this ioctl returning success and indicating that
|
||||
the context was recovered (DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET).
|
||||
|
||||
DK_CXLFLASH_MANAGE_LUN
|
||||
----------------------
|
||||
This ioctl is used to switch a LUN from a mode where it is available
|
||||
for file-system access (legacy), to a mode where it is set aside for
|
||||
exclusive user space access (superpipe). In case a LUN is visible
|
||||
across multiple ports and adapters, this ioctl is used to uniquely
|
||||
identify each LUN by its World Wide Node Name (WWNN).
|
||||
|
||||
|
||||
CXL Flash Driver Host IOCTLs
|
||||
============================
|
||||
|
||||
Each host adapter instance that is supported by the cxlflash driver
|
||||
has a special character device associated with it to enable a set of
|
||||
host management function. These character devices are hosted in a
|
||||
class dedicated for cxlflash and can be accessed via `/dev/cxlflash/*`.
|
||||
|
||||
Applications can be written to perform various functions using the
|
||||
host ioctl APIs below.
|
||||
|
||||
The structure definitions for these IOCTLs are available in:
|
||||
uapi/scsi/cxlflash_ioctl.h
|
||||
|
||||
HT_CXLFLASH_LUN_PROVISION
|
||||
-------------------------
|
||||
This ioctl is used to create and delete persistent LUNs on cxlflash
|
||||
devices that lack an external LUN management interface. It is only
|
||||
valid when used with AFUs that support the LUN provision capability.
|
||||
|
||||
When sufficient space is available, LUNs can be created by specifying
|
||||
the target port to host the LUN and a desired size in 4K blocks. Upon
|
||||
success, the LUN ID and WWID of the created LUN will be returned and
|
||||
the SCSI bus can be scanned to detect the change in LUN topology. Note
|
||||
that partial allocations are not supported. Should a creation fail due
|
||||
to a space issue, the target port can be queried for its current LUN
|
||||
geometry.
|
||||
|
||||
To remove a LUN, the device must first be disassociated from the Linux
|
||||
SCSI subsystem. The LUN deletion can then be initiated by specifying a
|
||||
target port and LUN ID. Upon success, the LUN geometry associated with
|
||||
the port will be updated to reflect new number of provisioned LUNs and
|
||||
available capacity.
|
||||
|
||||
To query the LUN geometry of a port, the target port is specified and
|
||||
upon success, the following information is presented:
|
||||
|
||||
- Maximum number of provisioned LUNs allowed for the port
|
||||
- Current number of provisioned LUNs for the port
|
||||
- Maximum total capacity of provisioned LUNs for the port (4K blocks)
|
||||
- Current total capacity of provisioned LUNs for the port (4K blocks)
|
||||
|
||||
With this information, the number of available LUNs and capacity can be
|
||||
can be calculated.
|
||||
|
||||
HT_CXLFLASH_AFU_DEBUG
|
||||
---------------------
|
||||
This ioctl is used to debug AFUs by supporting a command pass-through
|
||||
interface. It is only valid when used with AFUs that support the AFU
|
||||
debug capability.
|
||||
|
||||
With exception of buffer management, AFU debug commands are opaque to
|
||||
cxlflash and treated as pass-through. For debug commands that do require
|
||||
data transfer, the user supplies an adequately sized data buffer and must
|
||||
specify the data transfer direction with respect to the host. There is a
|
||||
maximum transfer size of 256K imposed. Note that partial read completions
|
||||
are not supported - when errors are experienced with a host read data
|
||||
transfer, the data buffer is not copied back to the user.
|
@ -13,7 +13,6 @@ powerpc
|
||||
cpu_families
|
||||
cpu_features
|
||||
cxl
|
||||
cxlflash
|
||||
dawr-power9
|
||||
dexcr
|
||||
dscr
|
||||
|
@ -373,7 +373,7 @@ Code Seq# Include File Comments
|
||||
0xC0 00-0F linux/usb/iowarrior.h
|
||||
0xCA 00-0F uapi/misc/cxl.h
|
||||
0xCA 10-2F uapi/misc/ocxl.h
|
||||
0xCA 80-BF uapi/scsi/cxlflash_ioctl.h
|
||||
0xCA 80-BF uapi/scsi/cxlflash_ioctl.h Dead since 6.14
|
||||
0xCB 00-1F CBM serial IEC bus in development:
|
||||
<mailto:michael.klein@puffin.lb.shuttle.de>
|
||||
0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver
|
||||
|
@ -6318,15 +6318,6 @@ F: drivers/misc/cxl/
|
||||
F: include/misc/cxl*
|
||||
F: include/uapi/misc/cxl.h
|
||||
|
||||
CXLFLASH (IBM Coherent Accelerator Processor Interface CAPI Flash) SCSI DRIVER
|
||||
M: Manoj N. Kumar <manoj@linux.ibm.com>
|
||||
M: Uma Krishnan <ukrishn@linux.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
S: Obsolete
|
||||
F: Documentation/arch/powerpc/cxlflash.rst
|
||||
F: drivers/scsi/cxlflash/
|
||||
F: include/uapi/scsi/cxlflash_ioctl.h
|
||||
|
||||
CYBERPRO FB DRIVER
|
||||
M: Russell King <linux@armlinux.org.uk>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
|
@ -336,7 +336,6 @@ source "drivers/scsi/cxgbi/Kconfig"
|
||||
source "drivers/scsi/bnx2i/Kconfig"
|
||||
source "drivers/scsi/bnx2fc/Kconfig"
|
||||
source "drivers/scsi/be2iscsi/Kconfig"
|
||||
source "drivers/scsi/cxlflash/Kconfig"
|
||||
|
||||
config SGIWD93_SCSI
|
||||
tristate "SGI WD93C93 SCSI Driver"
|
||||
|
@ -96,7 +96,6 @@ obj-$(CONFIG_SCSI_SYM53C8XX_2) += sym53c8xx_2/
|
||||
obj-$(CONFIG_SCSI_ZALON) += zalon7xx.o
|
||||
obj-$(CONFIG_SCSI_DC395x) += dc395x.o
|
||||
obj-$(CONFIG_SCSI_AM53C974) += esp_scsi.o am53c974.o
|
||||
obj-$(CONFIG_CXLFLASH) += cxlflash/
|
||||
obj-$(CONFIG_MEGARAID_LEGACY) += megaraid.o
|
||||
obj-$(CONFIG_MEGARAID_NEWGEN) += megaraid/
|
||||
obj-$(CONFIG_MEGARAID_SAS) += megaraid/
|
||||
|
@ -1,15 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# IBM CXL-attached Flash Accelerator SCSI Driver
|
||||
#
|
||||
|
||||
config CXLFLASH
|
||||
tristate "Support for IBM CAPI Flash (DEPRECATED)"
|
||||
depends on PCI && SCSI && (CXL || OCXL) && EEH
|
||||
select IRQ_POLL
|
||||
help
|
||||
The cxlflash driver is deprecated and will be removed in a future
|
||||
kernel release.
|
||||
|
||||
Allows CAPI Accelerated IO to Flash
|
||||
If unsure, say N.
|
@ -1,5 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
obj-$(CONFIG_CXLFLASH) += cxlflash.o
|
||||
cxlflash-y += main.o superpipe.o lunmgt.o vlun.o
|
||||
cxlflash-$(CONFIG_CXL) += cxl_hw.o
|
||||
cxlflash-$(CONFIG_OCXL) += ocxl_hw.o
|
@ -1,48 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2018 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_BACKEND_H
|
||||
#define _CXLFLASH_BACKEND_H
|
||||
|
||||
extern const struct cxlflash_backend_ops cxlflash_cxl_ops;
|
||||
extern const struct cxlflash_backend_ops cxlflash_ocxl_ops;
|
||||
|
||||
struct cxlflash_backend_ops {
|
||||
struct module *module;
|
||||
void __iomem * (*psa_map)(void *ctx_cookie);
|
||||
void (*psa_unmap)(void __iomem *addr);
|
||||
int (*process_element)(void *ctx_cookie);
|
||||
int (*map_afu_irq)(void *ctx_cookie, int num, irq_handler_t handler,
|
||||
void *cookie, char *name);
|
||||
void (*unmap_afu_irq)(void *ctx_cookie, int num, void *cookie);
|
||||
u64 (*get_irq_objhndl)(void *ctx_cookie, int irq);
|
||||
int (*start_context)(void *ctx_cookie);
|
||||
int (*stop_context)(void *ctx_cookie);
|
||||
int (*afu_reset)(void *ctx_cookie);
|
||||
void (*set_master)(void *ctx_cookie);
|
||||
void * (*get_context)(struct pci_dev *dev, void *afu_cookie);
|
||||
void * (*dev_context_init)(struct pci_dev *dev, void *afu_cookie);
|
||||
int (*release_context)(void *ctx_cookie);
|
||||
void (*perst_reloads_same_image)(void *afu_cookie, bool image);
|
||||
ssize_t (*read_adapter_vpd)(struct pci_dev *dev, void *buf,
|
||||
size_t count);
|
||||
int (*allocate_afu_irqs)(void *ctx_cookie, int num);
|
||||
void (*free_afu_irqs)(void *ctx_cookie);
|
||||
void * (*create_afu)(struct pci_dev *dev);
|
||||
void (*destroy_afu)(void *afu_cookie);
|
||||
struct file * (*get_fd)(void *ctx_cookie, struct file_operations *fops,
|
||||
int *fd);
|
||||
void * (*fops_get_context)(struct file *file);
|
||||
int (*start_work)(void *ctx_cookie, u64 irqs);
|
||||
int (*fd_mmap)(struct file *file, struct vm_area_struct *vm);
|
||||
int (*fd_release)(struct inode *inode, struct file *file);
|
||||
};
|
||||
|
||||
#endif /* _CXLFLASH_BACKEND_H */
|
@ -1,340 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_COMMON_H
|
||||
#define _CXLFLASH_COMMON_H
|
||||
|
||||
#include <linux/async.h>
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/irq_poll.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/rwsem.h>
|
||||
#include <linux/types.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_cmnd.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
#include "backend.h"
|
||||
|
||||
extern const struct file_operations cxlflash_cxl_fops;
|
||||
|
||||
#define MAX_CONTEXT CXLFLASH_MAX_CONTEXT /* num contexts per afu */
|
||||
#define MAX_FC_PORTS CXLFLASH_MAX_FC_PORTS /* max ports per AFU */
|
||||
#define LEGACY_FC_PORTS 2 /* legacy ports per AFU */
|
||||
|
||||
#define CHAN2PORTBANK(_x) ((_x) >> ilog2(CXLFLASH_NUM_FC_PORTS_PER_BANK))
|
||||
#define CHAN2BANKPORT(_x) ((_x) & (CXLFLASH_NUM_FC_PORTS_PER_BANK - 1))
|
||||
|
||||
#define CHAN2PORTMASK(_x) (1 << (_x)) /* channel to port mask */
|
||||
#define PORTMASK2CHAN(_x) (ilog2((_x))) /* port mask to channel */
|
||||
#define PORTNUM2CHAN(_x) ((_x) - 1) /* port number to channel */
|
||||
|
||||
#define CXLFLASH_BLOCK_SIZE 4096 /* 4K blocks */
|
||||
#define CXLFLASH_MAX_XFER_SIZE 16777216 /* 16MB transfer */
|
||||
#define CXLFLASH_MAX_SECTORS (CXLFLASH_MAX_XFER_SIZE/512) /* SCSI wants
|
||||
* max_sectors
|
||||
* in units of
|
||||
* 512 byte
|
||||
* sectors
|
||||
*/
|
||||
|
||||
#define MAX_RHT_PER_CONTEXT (PAGE_SIZE / sizeof(struct sisl_rht_entry))
|
||||
|
||||
/* AFU command retry limit */
|
||||
#define MC_RETRY_CNT 5 /* Sufficient for SCSI and certain AFU errors */
|
||||
|
||||
/* Command management definitions */
|
||||
#define CXLFLASH_MAX_CMDS 256
|
||||
#define CXLFLASH_MAX_CMDS_PER_LUN CXLFLASH_MAX_CMDS
|
||||
|
||||
/* RRQ for master issued cmds */
|
||||
#define NUM_RRQ_ENTRY CXLFLASH_MAX_CMDS
|
||||
|
||||
/* SQ for master issued cmds */
|
||||
#define NUM_SQ_ENTRY CXLFLASH_MAX_CMDS
|
||||
|
||||
/* Hardware queue definitions */
|
||||
#define CXLFLASH_DEF_HWQS 1
|
||||
#define CXLFLASH_MAX_HWQS 8
|
||||
#define PRIMARY_HWQ 0
|
||||
|
||||
|
||||
static inline void check_sizes(void)
|
||||
{
|
||||
BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_NUM_FC_PORTS_PER_BANK);
|
||||
BUILD_BUG_ON_NOT_POWER_OF_2(CXLFLASH_MAX_CMDS);
|
||||
}
|
||||
|
||||
/* AFU defines a fixed size of 4K for command buffers (borrow 4K page define) */
|
||||
#define CMD_BUFSIZE SIZE_4K
|
||||
|
||||
enum cxlflash_lr_state {
|
||||
LINK_RESET_INVALID,
|
||||
LINK_RESET_REQUIRED,
|
||||
LINK_RESET_COMPLETE
|
||||
};
|
||||
|
||||
enum cxlflash_init_state {
|
||||
INIT_STATE_NONE,
|
||||
INIT_STATE_PCI,
|
||||
INIT_STATE_AFU,
|
||||
INIT_STATE_SCSI,
|
||||
INIT_STATE_CDEV
|
||||
};
|
||||
|
||||
enum cxlflash_state {
|
||||
STATE_PROBING, /* Initial state during probe */
|
||||
STATE_PROBED, /* Temporary state, probe completed but EEH occurred */
|
||||
STATE_NORMAL, /* Normal running state, everything good */
|
||||
STATE_RESET, /* Reset state, trying to reset/recover */
|
||||
STATE_FAILTERM /* Failed/terminating state, error out users/threads */
|
||||
};
|
||||
|
||||
enum cxlflash_hwq_mode {
|
||||
HWQ_MODE_RR, /* Roundrobin (default) */
|
||||
HWQ_MODE_TAG, /* Distribute based on block MQ tag */
|
||||
HWQ_MODE_CPU, /* CPU affinity */
|
||||
MAX_HWQ_MODE
|
||||
};
|
||||
|
||||
/*
|
||||
* Each context has its own set of resource handles that is visible
|
||||
* only from that context.
|
||||
*/
|
||||
|
||||
struct cxlflash_cfg {
|
||||
struct afu *afu;
|
||||
|
||||
const struct cxlflash_backend_ops *ops;
|
||||
struct pci_dev *dev;
|
||||
struct pci_device_id *dev_id;
|
||||
struct Scsi_Host *host;
|
||||
int num_fc_ports;
|
||||
struct cdev cdev;
|
||||
struct device *chardev;
|
||||
|
||||
ulong cxlflash_regs_pci;
|
||||
|
||||
struct work_struct work_q;
|
||||
enum cxlflash_init_state init_state;
|
||||
enum cxlflash_lr_state lr_state;
|
||||
int lr_port;
|
||||
atomic_t scan_host_needed;
|
||||
|
||||
void *afu_cookie;
|
||||
|
||||
atomic_t recovery_threads;
|
||||
struct mutex ctx_recovery_mutex;
|
||||
struct mutex ctx_tbl_list_mutex;
|
||||
struct rw_semaphore ioctl_rwsem;
|
||||
struct ctx_info *ctx_tbl[MAX_CONTEXT];
|
||||
struct list_head ctx_err_recovery; /* contexts w/ recovery pending */
|
||||
struct file_operations cxl_fops;
|
||||
|
||||
/* Parameters that are LUN table related */
|
||||
int last_lun_index[MAX_FC_PORTS];
|
||||
int promote_lun_index;
|
||||
struct list_head lluns; /* list of llun_info structs */
|
||||
|
||||
wait_queue_head_t tmf_waitq;
|
||||
spinlock_t tmf_slock;
|
||||
bool tmf_active;
|
||||
bool ws_unmap; /* Write-same unmap supported */
|
||||
wait_queue_head_t reset_waitq;
|
||||
enum cxlflash_state state;
|
||||
async_cookie_t async_reset_cookie;
|
||||
};
|
||||
|
||||
struct afu_cmd {
|
||||
struct sisl_ioarcb rcb; /* IOARCB (cache line aligned) */
|
||||
struct sisl_ioasa sa; /* IOASA must follow IOARCB */
|
||||
struct afu *parent;
|
||||
struct scsi_cmnd *scp;
|
||||
struct completion cevent;
|
||||
struct list_head queue;
|
||||
u32 hwq_index;
|
||||
|
||||
u8 cmd_tmf:1,
|
||||
cmd_aborted:1;
|
||||
|
||||
struct list_head list; /* Pending commands link */
|
||||
|
||||
/* As per the SISLITE spec the IOARCB EA has to be 16-byte aligned.
|
||||
* However for performance reasons the IOARCB/IOASA should be
|
||||
* cache line aligned.
|
||||
*/
|
||||
} __aligned(cache_line_size());
|
||||
|
||||
static inline struct afu_cmd *sc_to_afuc(struct scsi_cmnd *sc)
|
||||
{
|
||||
return PTR_ALIGN(scsi_cmd_priv(sc), __alignof__(struct afu_cmd));
|
||||
}
|
||||
|
||||
static inline struct afu_cmd *sc_to_afuci(struct scsi_cmnd *sc)
|
||||
{
|
||||
struct afu_cmd *afuc = sc_to_afuc(sc);
|
||||
|
||||
INIT_LIST_HEAD(&afuc->queue);
|
||||
return afuc;
|
||||
}
|
||||
|
||||
static inline struct afu_cmd *sc_to_afucz(struct scsi_cmnd *sc)
|
||||
{
|
||||
struct afu_cmd *afuc = sc_to_afuc(sc);
|
||||
|
||||
memset(afuc, 0, sizeof(*afuc));
|
||||
return sc_to_afuci(sc);
|
||||
}
|
||||
|
||||
struct hwq {
|
||||
/* Stuff requiring alignment go first. */
|
||||
struct sisl_ioarcb sq[NUM_SQ_ENTRY]; /* 16K SQ */
|
||||
u64 rrq_entry[NUM_RRQ_ENTRY]; /* 2K RRQ */
|
||||
|
||||
/* Beware of alignment till here. Preferably introduce new
|
||||
* fields after this point
|
||||
*/
|
||||
struct afu *afu;
|
||||
void *ctx_cookie;
|
||||
struct sisl_host_map __iomem *host_map; /* MC host map */
|
||||
struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */
|
||||
ctx_hndl_t ctx_hndl; /* master's context handle */
|
||||
u32 index; /* Index of this hwq */
|
||||
int num_irqs; /* Number of interrupts requested for context */
|
||||
struct list_head pending_cmds; /* Commands pending completion */
|
||||
|
||||
atomic_t hsq_credits;
|
||||
spinlock_t hsq_slock; /* Hardware send queue lock */
|
||||
struct sisl_ioarcb *hsq_start;
|
||||
struct sisl_ioarcb *hsq_end;
|
||||
struct sisl_ioarcb *hsq_curr;
|
||||
spinlock_t hrrq_slock;
|
||||
u64 *hrrq_start;
|
||||
u64 *hrrq_end;
|
||||
u64 *hrrq_curr;
|
||||
bool toggle;
|
||||
bool hrrq_online;
|
||||
|
||||
s64 room;
|
||||
|
||||
struct irq_poll irqpoll;
|
||||
} __aligned(cache_line_size());
|
||||
|
||||
struct afu {
|
||||
struct hwq hwqs[CXLFLASH_MAX_HWQS];
|
||||
int (*send_cmd)(struct afu *afu, struct afu_cmd *cmd);
|
||||
int (*context_reset)(struct hwq *hwq);
|
||||
|
||||
/* AFU HW */
|
||||
struct cxlflash_afu_map __iomem *afu_map; /* entire MMIO map */
|
||||
|
||||
atomic_t cmds_active; /* Number of currently active AFU commands */
|
||||
struct mutex sync_active; /* Mutex to serialize AFU commands */
|
||||
u64 hb;
|
||||
u32 internal_lun; /* User-desired LUN mode for this AFU */
|
||||
|
||||
u32 num_hwqs; /* Number of hardware queues */
|
||||
u32 desired_hwqs; /* Desired h/w queues, effective on AFU reset */
|
||||
enum cxlflash_hwq_mode hwq_mode; /* Steering mode for h/w queues */
|
||||
u32 hwq_rr_count; /* Count to distribute traffic for roundrobin */
|
||||
|
||||
char version[16];
|
||||
u64 interface_version;
|
||||
|
||||
u32 irqpoll_weight;
|
||||
struct cxlflash_cfg *parent; /* Pointer back to parent cxlflash_cfg */
|
||||
};
|
||||
|
||||
static inline struct hwq *get_hwq(struct afu *afu, u32 index)
|
||||
{
|
||||
WARN_ON(index >= CXLFLASH_MAX_HWQS);
|
||||
|
||||
return &afu->hwqs[index];
|
||||
}
|
||||
|
||||
static inline bool afu_is_irqpoll_enabled(struct afu *afu)
|
||||
{
|
||||
return !!afu->irqpoll_weight;
|
||||
}
|
||||
|
||||
static inline bool afu_has_cap(struct afu *afu, u64 cap)
|
||||
{
|
||||
u64 afu_cap = afu->interface_version >> SISL_INTVER_CAP_SHIFT;
|
||||
|
||||
return afu_cap & cap;
|
||||
}
|
||||
|
||||
static inline bool afu_is_ocxl_lisn(struct afu *afu)
|
||||
{
|
||||
return afu_has_cap(afu, SISL_INTVER_CAP_OCXL_LISN);
|
||||
}
|
||||
|
||||
static inline bool afu_is_afu_debug(struct afu *afu)
|
||||
{
|
||||
return afu_has_cap(afu, SISL_INTVER_CAP_AFU_DEBUG);
|
||||
}
|
||||
|
||||
static inline bool afu_is_lun_provision(struct afu *afu)
|
||||
{
|
||||
return afu_has_cap(afu, SISL_INTVER_CAP_LUN_PROVISION);
|
||||
}
|
||||
|
||||
static inline bool afu_is_sq_cmd_mode(struct afu *afu)
|
||||
{
|
||||
return afu_has_cap(afu, SISL_INTVER_CAP_SQ_CMD_MODE);
|
||||
}
|
||||
|
||||
static inline bool afu_is_ioarrin_cmd_mode(struct afu *afu)
|
||||
{
|
||||
return afu_has_cap(afu, SISL_INTVER_CAP_IOARRIN_CMD_MODE);
|
||||
}
|
||||
|
||||
static inline u64 lun_to_lunid(u64 lun)
|
||||
{
|
||||
__be64 lun_id;
|
||||
|
||||
int_to_scsilun(lun, (struct scsi_lun *)&lun_id);
|
||||
return be64_to_cpu(lun_id);
|
||||
}
|
||||
|
||||
static inline struct fc_port_bank __iomem *get_fc_port_bank(
|
||||
struct cxlflash_cfg *cfg, int i)
|
||||
{
|
||||
struct afu *afu = cfg->afu;
|
||||
|
||||
return &afu->afu_map->global.bank[CHAN2PORTBANK(i)];
|
||||
}
|
||||
|
||||
static inline __be64 __iomem *get_fc_port_regs(struct cxlflash_cfg *cfg, int i)
|
||||
{
|
||||
struct fc_port_bank __iomem *fcpb = get_fc_port_bank(cfg, i);
|
||||
|
||||
return &fcpb->fc_port_regs[CHAN2BANKPORT(i)][0];
|
||||
}
|
||||
|
||||
static inline __be64 __iomem *get_fc_port_luns(struct cxlflash_cfg *cfg, int i)
|
||||
{
|
||||
struct fc_port_bank __iomem *fcpb = get_fc_port_bank(cfg, i);
|
||||
|
||||
return &fcpb->fc_port_luns[CHAN2BANKPORT(i)][0];
|
||||
}
|
||||
|
||||
int cxlflash_afu_sync(struct afu *afu, ctx_hndl_t c, res_hndl_t r, u8 mode);
|
||||
void cxlflash_list_init(void);
|
||||
void cxlflash_term_global_luns(void);
|
||||
void cxlflash_free_errpage(void);
|
||||
int cxlflash_ioctl(struct scsi_device *sdev, unsigned int cmd,
|
||||
void __user *arg);
|
||||
void cxlflash_stop_term_user_contexts(struct cxlflash_cfg *cfg);
|
||||
int cxlflash_mark_contexts_error(struct cxlflash_cfg *cfg);
|
||||
void cxlflash_term_local_luns(struct cxlflash_cfg *cfg);
|
||||
void cxlflash_restore_luntable(struct cxlflash_cfg *cfg);
|
||||
|
||||
#endif /* ifndef _CXLFLASH_COMMON_H */
|
@ -1,177 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2018 IBM Corporation
|
||||
*/
|
||||
|
||||
#include <misc/cxl.h>
|
||||
|
||||
#include "backend.h"
|
||||
|
||||
/*
|
||||
* The following routines map the cxlflash backend operations to existing CXL
|
||||
* kernel API function and are largely simple shims that provide an abstraction
|
||||
* for converting generic context and AFU cookies into cxl_context or cxl_afu
|
||||
* pointers.
|
||||
*/
|
||||
|
||||
static void __iomem *cxlflash_psa_map(void *ctx_cookie)
|
||||
{
|
||||
return cxl_psa_map(ctx_cookie);
|
||||
}
|
||||
|
||||
static void cxlflash_psa_unmap(void __iomem *addr)
|
||||
{
|
||||
cxl_psa_unmap(addr);
|
||||
}
|
||||
|
||||
static int cxlflash_process_element(void *ctx_cookie)
|
||||
{
|
||||
return cxl_process_element(ctx_cookie);
|
||||
}
|
||||
|
||||
static int cxlflash_map_afu_irq(void *ctx_cookie, int num,
|
||||
irq_handler_t handler, void *cookie, char *name)
|
||||
{
|
||||
return cxl_map_afu_irq(ctx_cookie, num, handler, cookie, name);
|
||||
}
|
||||
|
||||
static void cxlflash_unmap_afu_irq(void *ctx_cookie, int num, void *cookie)
|
||||
{
|
||||
cxl_unmap_afu_irq(ctx_cookie, num, cookie);
|
||||
}
|
||||
|
||||
static u64 cxlflash_get_irq_objhndl(void *ctx_cookie, int irq)
|
||||
{
|
||||
/* Dummy fop for cxl */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cxlflash_start_context(void *ctx_cookie)
|
||||
{
|
||||
return cxl_start_context(ctx_cookie, 0, NULL);
|
||||
}
|
||||
|
||||
static int cxlflash_stop_context(void *ctx_cookie)
|
||||
{
|
||||
return cxl_stop_context(ctx_cookie);
|
||||
}
|
||||
|
||||
static int cxlflash_afu_reset(void *ctx_cookie)
|
||||
{
|
||||
return cxl_afu_reset(ctx_cookie);
|
||||
}
|
||||
|
||||
static void cxlflash_set_master(void *ctx_cookie)
|
||||
{
|
||||
cxl_set_master(ctx_cookie);
|
||||
}
|
||||
|
||||
static void *cxlflash_get_context(struct pci_dev *dev, void *afu_cookie)
|
||||
{
|
||||
return cxl_get_context(dev);
|
||||
}
|
||||
|
||||
static void *cxlflash_dev_context_init(struct pci_dev *dev, void *afu_cookie)
|
||||
{
|
||||
return cxl_dev_context_init(dev);
|
||||
}
|
||||
|
||||
static int cxlflash_release_context(void *ctx_cookie)
|
||||
{
|
||||
return cxl_release_context(ctx_cookie);
|
||||
}
|
||||
|
||||
static void cxlflash_perst_reloads_same_image(void *afu_cookie, bool image)
|
||||
{
|
||||
cxl_perst_reloads_same_image(afu_cookie, image);
|
||||
}
|
||||
|
||||
static ssize_t cxlflash_read_adapter_vpd(struct pci_dev *dev,
|
||||
void *buf, size_t count)
|
||||
{
|
||||
return cxl_read_adapter_vpd(dev, buf, count);
|
||||
}
|
||||
|
||||
static int cxlflash_allocate_afu_irqs(void *ctx_cookie, int num)
|
||||
{
|
||||
return cxl_allocate_afu_irqs(ctx_cookie, num);
|
||||
}
|
||||
|
||||
static void cxlflash_free_afu_irqs(void *ctx_cookie)
|
||||
{
|
||||
cxl_free_afu_irqs(ctx_cookie);
|
||||
}
|
||||
|
||||
static void *cxlflash_create_afu(struct pci_dev *dev)
|
||||
{
|
||||
return cxl_pci_to_afu(dev);
|
||||
}
|
||||
|
||||
static void cxlflash_destroy_afu(void *afu)
|
||||
{
|
||||
/* Dummy fop for cxl */
|
||||
}
|
||||
|
||||
static struct file *cxlflash_get_fd(void *ctx_cookie,
|
||||
struct file_operations *fops, int *fd)
|
||||
{
|
||||
return cxl_get_fd(ctx_cookie, fops, fd);
|
||||
}
|
||||
|
||||
static void *cxlflash_fops_get_context(struct file *file)
|
||||
{
|
||||
return cxl_fops_get_context(file);
|
||||
}
|
||||
|
||||
static int cxlflash_start_work(void *ctx_cookie, u64 irqs)
|
||||
{
|
||||
struct cxl_ioctl_start_work work = { 0 };
|
||||
|
||||
work.num_interrupts = irqs;
|
||||
work.flags = CXL_START_WORK_NUM_IRQS;
|
||||
|
||||
return cxl_start_work(ctx_cookie, &work);
|
||||
}
|
||||
|
||||
static int cxlflash_fd_mmap(struct file *file, struct vm_area_struct *vm)
|
||||
{
|
||||
return cxl_fd_mmap(file, vm);
|
||||
}
|
||||
|
||||
static int cxlflash_fd_release(struct inode *inode, struct file *file)
|
||||
{
|
||||
return cxl_fd_release(inode, file);
|
||||
}
|
||||
|
||||
const struct cxlflash_backend_ops cxlflash_cxl_ops = {
|
||||
.module = THIS_MODULE,
|
||||
.psa_map = cxlflash_psa_map,
|
||||
.psa_unmap = cxlflash_psa_unmap,
|
||||
.process_element = cxlflash_process_element,
|
||||
.map_afu_irq = cxlflash_map_afu_irq,
|
||||
.unmap_afu_irq = cxlflash_unmap_afu_irq,
|
||||
.get_irq_objhndl = cxlflash_get_irq_objhndl,
|
||||
.start_context = cxlflash_start_context,
|
||||
.stop_context = cxlflash_stop_context,
|
||||
.afu_reset = cxlflash_afu_reset,
|
||||
.set_master = cxlflash_set_master,
|
||||
.get_context = cxlflash_get_context,
|
||||
.dev_context_init = cxlflash_dev_context_init,
|
||||
.release_context = cxlflash_release_context,
|
||||
.perst_reloads_same_image = cxlflash_perst_reloads_same_image,
|
||||
.read_adapter_vpd = cxlflash_read_adapter_vpd,
|
||||
.allocate_afu_irqs = cxlflash_allocate_afu_irqs,
|
||||
.free_afu_irqs = cxlflash_free_afu_irqs,
|
||||
.create_afu = cxlflash_create_afu,
|
||||
.destroy_afu = cxlflash_destroy_afu,
|
||||
.get_fd = cxlflash_get_fd,
|
||||
.fops_get_context = cxlflash_fops_get_context,
|
||||
.start_work = cxlflash_start_work,
|
||||
.fd_mmap = cxlflash_fd_mmap,
|
||||
.fd_release = cxlflash_fd_release,
|
||||
};
|
@ -1,278 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#include <linux/unaligned.h>
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/pci.h>
|
||||
|
||||
#include <scsi/scsi_host.h>
|
||||
#include <uapi/scsi/cxlflash_ioctl.h>
|
||||
|
||||
#include "sislite.h"
|
||||
#include "common.h"
|
||||
#include "vlun.h"
|
||||
#include "superpipe.h"
|
||||
|
||||
/**
|
||||
* create_local() - allocate and initialize a local LUN information structure
|
||||
* @sdev: SCSI device associated with LUN.
|
||||
* @wwid: World Wide Node Name for LUN.
|
||||
*
|
||||
* Return: Allocated local llun_info structure on success, NULL on failure
|
||||
*/
|
||||
static struct llun_info *create_local(struct scsi_device *sdev, u8 *wwid)
|
||||
{
|
||||
struct cxlflash_cfg *cfg = shost_priv(sdev->host);
|
||||
struct device *dev = &cfg->dev->dev;
|
||||
struct llun_info *lli = NULL;
|
||||
|
||||
lli = kzalloc(sizeof(*lli), GFP_KERNEL);
|
||||
if (unlikely(!lli)) {
|
||||
dev_err(dev, "%s: could not allocate lli\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
lli->sdev = sdev;
|
||||
lli->host_no = sdev->host->host_no;
|
||||
lli->in_table = false;
|
||||
|
||||
memcpy(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
|
||||
out:
|
||||
return lli;
|
||||
}
|
||||
|
||||
/**
|
||||
* create_global() - allocate and initialize a global LUN information structure
|
||||
* @sdev: SCSI device associated with LUN.
|
||||
* @wwid: World Wide Node Name for LUN.
|
||||
*
|
||||
* Return: Allocated global glun_info structure on success, NULL on failure
|
||||
*/
|
||||
static struct glun_info *create_global(struct scsi_device *sdev, u8 *wwid)
|
||||
{
|
||||
struct cxlflash_cfg *cfg = shost_priv(sdev->host);
|
||||
struct device *dev = &cfg->dev->dev;
|
||||
struct glun_info *gli = NULL;
|
||||
|
||||
gli = kzalloc(sizeof(*gli), GFP_KERNEL);
|
||||
if (unlikely(!gli)) {
|
||||
dev_err(dev, "%s: could not allocate gli\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
mutex_init(&gli->mutex);
|
||||
memcpy(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN);
|
||||
out:
|
||||
return gli;
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup_local() - find a local LUN information structure by WWID
|
||||
* @cfg: Internal structure associated with the host.
|
||||
* @wwid: WWID associated with LUN.
|
||||
*
|
||||
* Return: Found local lun_info structure on success, NULL on failure
|
||||
*/
|
||||
static struct llun_info *lookup_local(struct cxlflash_cfg *cfg, u8 *wwid)
|
||||
{
|
||||
struct llun_info *lli, *temp;
|
||||
|
||||
list_for_each_entry_safe(lli, temp, &cfg->lluns, list)
|
||||
if (!memcmp(lli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
|
||||
return lli;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* lookup_global() - find a global LUN information structure by WWID
|
||||
* @wwid: WWID associated with LUN.
|
||||
*
|
||||
* Return: Found global lun_info structure on success, NULL on failure
|
||||
*/
|
||||
static struct glun_info *lookup_global(u8 *wwid)
|
||||
{
|
||||
struct glun_info *gli, *temp;
|
||||
|
||||
list_for_each_entry_safe(gli, temp, &global.gluns, list)
|
||||
if (!memcmp(gli->wwid, wwid, DK_CXLFLASH_MANAGE_LUN_WWID_LEN))
|
||||
return gli;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* find_and_create_lun() - find or create a local LUN information structure
|
||||
* @sdev: SCSI device associated with LUN.
|
||||
* @wwid: WWID associated with LUN.
|
||||
*
|
||||
* The LUN is kept both in a local list (per adapter) and in a global list
|
||||
* (across all adapters). Certain attributes of the LUN are local to the
|
||||
* adapter (such as index, port selection mask, etc.).
|
||||
*
|
||||
* The block allocation map is shared across all adapters (i.e. associated
|
||||
* wih the global list). Since different attributes are associated with
|
||||
* the per adapter and global entries, allocate two separate structures for each
|
||||
* LUN (one local, one global).
|
||||
*
|
||||
* Keep a pointer back from the local to the global entry.
|
||||
*
|
||||
* This routine assumes the caller holds the global mutex.
|
||||
*
|
||||
* Return: Found/Allocated local lun_info structure on success, NULL on failure
|
||||
*/
|
||||
static struct llun_info *find_and_create_lun(struct scsi_device *sdev, u8 *wwid)
|
||||
{
|
||||
struct cxlflash_cfg *cfg = shost_priv(sdev->host);
|
||||
struct device *dev = &cfg->dev->dev;
|
||||
struct llun_info *lli = NULL;
|
||||
struct glun_info *gli = NULL;
|
||||
|
||||
if (unlikely(!wwid))
|
||||
goto out;
|
||||
|
||||
lli = lookup_local(cfg, wwid);
|
||||
if (lli)
|
||||
goto out;
|
||||
|
||||
lli = create_local(sdev, wwid);
|
||||
if (unlikely(!lli))
|
||||
goto out;
|
||||
|
||||
gli = lookup_global(wwid);
|
||||
if (gli) {
|
||||
lli->parent = gli;
|
||||
list_add(&lli->list, &cfg->lluns);
|
||||
goto out;
|
||||
}
|
||||
|
||||
gli = create_global(sdev, wwid);
|
||||
if (unlikely(!gli)) {
|
||||
kfree(lli);
|
||||
lli = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
lli->parent = gli;
|
||||
list_add(&lli->list, &cfg->lluns);
|
||||
|
||||
list_add(&gli->list, &global.gluns);
|
||||
|
||||
out:
|
||||
dev_dbg(dev, "%s: returning lli=%p, gli=%p\n", __func__, lli, gli);
|
||||
return lli;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_term_local_luns() - Delete all entries from local LUN list, free.
|
||||
* @cfg: Internal structure associated with the host.
|
||||
*/
|
||||
void cxlflash_term_local_luns(struct cxlflash_cfg *cfg)
|
||||
{
|
||||
struct llun_info *lli, *temp;
|
||||
|
||||
mutex_lock(&global.mutex);
|
||||
list_for_each_entry_safe(lli, temp, &cfg->lluns, list) {
|
||||
list_del(&lli->list);
|
||||
kfree(lli);
|
||||
}
|
||||
mutex_unlock(&global.mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_list_init() - initializes the global LUN list
|
||||
*/
|
||||
void cxlflash_list_init(void)
|
||||
{
|
||||
INIT_LIST_HEAD(&global.gluns);
|
||||
mutex_init(&global.mutex);
|
||||
global.err_page = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_term_global_luns() - frees resources associated with global LUN list
|
||||
*/
|
||||
void cxlflash_term_global_luns(void)
|
||||
{
|
||||
struct glun_info *gli, *temp;
|
||||
|
||||
mutex_lock(&global.mutex);
|
||||
list_for_each_entry_safe(gli, temp, &global.gluns, list) {
|
||||
list_del(&gli->list);
|
||||
cxlflash_ba_terminate(&gli->blka.ba_lun);
|
||||
kfree(gli);
|
||||
}
|
||||
mutex_unlock(&global.mutex);
|
||||
}
|
||||
|
||||
/**
|
||||
* cxlflash_manage_lun() - handles LUN management activities
|
||||
* @sdev: SCSI device associated with LUN.
|
||||
* @arg: Manage ioctl data structure.
|
||||
*
|
||||
* This routine is used to notify the driver about a LUN's WWID and associate
|
||||
* SCSI devices (sdev) with a global LUN instance. Additionally it serves to
|
||||
* change a LUN's operating mode: legacy or superpipe.
|
||||
*
|
||||
* Return: 0 on success, -errno on failure
|
||||
*/
|
||||
int cxlflash_manage_lun(struct scsi_device *sdev, void *arg)
|
||||
{
|
||||
struct dk_cxlflash_manage_lun *manage = arg;
|
||||
struct cxlflash_cfg *cfg = shost_priv(sdev->host);
|
||||
struct device *dev = &cfg->dev->dev;
|
||||
struct llun_info *lli = NULL;
|
||||
int rc = 0;
|
||||
u64 flags = manage->hdr.flags;
|
||||
u32 chan = sdev->channel;
|
||||
|
||||
mutex_lock(&global.mutex);
|
||||
lli = find_and_create_lun(sdev, manage->wwid);
|
||||
dev_dbg(dev, "%s: WWID=%016llx%016llx, flags=%016llx lli=%p\n",
|
||||
__func__, get_unaligned_be64(&manage->wwid[0]),
|
||||
get_unaligned_be64(&manage->wwid[8]), manage->hdr.flags, lli);
|
||||
if (unlikely(!lli)) {
|
||||
rc = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (flags & DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE) {
|
||||
/*
|
||||
* Update port selection mask based upon channel, store off LUN
|
||||
* in unpacked, AFU-friendly format, and hang LUN reference in
|
||||
* the sdev.
|
||||
*/
|
||||
lli->port_sel |= CHAN2PORTMASK(chan);
|
||||
lli->lun_id[chan] = lun_to_lunid(sdev->lun);
|
||||
sdev->hostdata = lli;
|
||||
} else if (flags & DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE) {
|
||||
if (lli->parent->mode != MODE_NONE)
|
||||
rc = -EBUSY;
|
||||
else {
|
||||
/*
|
||||
* Clean up local LUN for this port and reset table
|
||||
* tracking when no more references exist.
|
||||
*/
|
||||
sdev->hostdata = NULL;
|
||||
lli->port_sel &= ~CHAN2PORTMASK(chan);
|
||||
if (lli->port_sel == 0U)
|
||||
lli->in_table = false;
|
||||
}
|
||||
}
|
||||
|
||||
dev_dbg(dev, "%s: port_sel=%08x chan=%u lun_id=%016llx\n",
|
||||
__func__, lli->port_sel, chan, lli->lun_id[chan]);
|
||||
|
||||
out:
|
||||
mutex_unlock(&global.mutex);
|
||||
dev_dbg(dev, "%s: returning rc=%d\n", __func__, rc);
|
||||
return rc;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1,129 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_MAIN_H
|
||||
#define _CXLFLASH_MAIN_H
|
||||
|
||||
#include <linux/list.h>
|
||||
#include <linux/types.h>
|
||||
#include <scsi/scsi.h>
|
||||
#include <scsi/scsi_device.h>
|
||||
|
||||
#include "backend.h"
|
||||
|
||||
#define CXLFLASH_NAME "cxlflash"
|
||||
#define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter"
|
||||
#define CXLFLASH_MAX_ADAPTERS 32
|
||||
|
||||
#define PCI_DEVICE_ID_IBM_CORSA 0x04F0
|
||||
#define PCI_DEVICE_ID_IBM_FLASH_GT 0x0600
|
||||
#define PCI_DEVICE_ID_IBM_BRIARD 0x0624
|
||||
|
||||
/* Since there is only one target, make it 0 */
|
||||
#define CXLFLASH_TARGET 0
|
||||
#define CXLFLASH_MAX_CDB_LEN 16
|
||||
|
||||
/* Really only one target per bus since the Texan is directly attached */
|
||||
#define CXLFLASH_MAX_NUM_TARGETS_PER_BUS 1
|
||||
#define CXLFLASH_MAX_NUM_LUNS_PER_TARGET 65536
|
||||
|
||||
#define CXLFLASH_PCI_ERROR_RECOVERY_TIMEOUT (120 * HZ)
|
||||
|
||||
/* FC defines */
|
||||
#define FC_MTIP_CMDCONFIG 0x010
|
||||
#define FC_MTIP_STATUS 0x018
|
||||
#define FC_MAX_NUM_LUNS 0x080 /* Max LUNs host can provision for port */
|
||||
#define FC_CUR_NUM_LUNS 0x088 /* Cur number LUNs provisioned for port */
|
||||
#define FC_MAX_CAP_PORT 0x090 /* Max capacity all LUNs for port (4K blocks) */
|
||||
#define FC_CUR_CAP_PORT 0x098 /* Cur capacity all LUNs for port (4K blocks) */
|
||||
|
||||
#define FC_PNAME 0x300
|
||||
#define FC_CONFIG 0x320
|
||||
#define FC_CONFIG2 0x328
|
||||
#define FC_STATUS 0x330
|
||||
#define FC_ERROR 0x380
|
||||
#define FC_ERRCAP 0x388
|
||||
#define FC_ERRMSK 0x390
|
||||
#define FC_CNT_CRCERR 0x538
|
||||
#define FC_CRC_THRESH 0x580
|
||||
|
||||
#define FC_MTIP_CMDCONFIG_ONLINE 0x20ULL
|
||||
#define FC_MTIP_CMDCONFIG_OFFLINE 0x40ULL
|
||||
|
||||
#define FC_MTIP_STATUS_MASK 0x30ULL
|
||||
#define FC_MTIP_STATUS_ONLINE 0x20ULL
|
||||
#define FC_MTIP_STATUS_OFFLINE 0x10ULL
|
||||
|
||||
/* TIMEOUT and RETRY definitions */
|
||||
|
||||
/* AFU command timeout values */
|
||||
#define MC_AFU_SYNC_TIMEOUT 5 /* 5 secs */
|
||||
#define MC_LUN_PROV_TIMEOUT 5 /* 5 secs */
|
||||
#define MC_AFU_DEBUG_TIMEOUT 5 /* 5 secs */
|
||||
|
||||
/* AFU command room retry limit */
|
||||
#define MC_ROOM_RETRY_CNT 10
|
||||
|
||||
/* FC CRC clear periodic timer */
|
||||
#define MC_CRC_THRESH 100 /* threshold in 5 mins */
|
||||
|
||||
#define FC_PORT_STATUS_RETRY_CNT 100 /* 100 100ms retries = 10 seconds */
|
||||
#define FC_PORT_STATUS_RETRY_INTERVAL_US 100000 /* microseconds */
|
||||
|
||||
/* VPD defines */
|
||||
#define CXLFLASH_VPD_LEN 256
|
||||
#define WWPN_LEN 16
|
||||
#define WWPN_BUF_LEN (WWPN_LEN + 1)
|
||||
|
||||
enum undo_level {
|
||||
UNDO_NOOP = 0,
|
||||
FREE_IRQ,
|
||||
UNMAP_ONE,
|
||||
UNMAP_TWO,
|
||||
UNMAP_THREE
|
||||
};
|
||||
|
||||
struct dev_dependent_vals {
|
||||
u64 max_sectors;
|
||||
u64 flags;
|
||||
#define CXLFLASH_NOTIFY_SHUTDOWN 0x0000000000000001ULL
|
||||
#define CXLFLASH_WWPN_VPD_REQUIRED 0x0000000000000002ULL
|
||||
#define CXLFLASH_OCXL_DEV 0x0000000000000004ULL
|
||||
};
|
||||
|
||||
static inline const struct cxlflash_backend_ops *
|
||||
cxlflash_assign_ops(struct dev_dependent_vals *ddv)
|
||||
{
|
||||
const struct cxlflash_backend_ops *ops = NULL;
|
||||
|
||||
#ifdef CONFIG_OCXL_BASE
|
||||
if (ddv->flags & CXLFLASH_OCXL_DEV)
|
||||
ops = &cxlflash_ocxl_ops;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CXL_BASE
|
||||
if (!(ddv->flags & CXLFLASH_OCXL_DEV))
|
||||
ops = &cxlflash_cxl_ops;
|
||||
#endif
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
struct asyc_intr_info {
|
||||
u64 status;
|
||||
char *desc;
|
||||
u8 port;
|
||||
u8 action;
|
||||
#define CLR_FC_ERROR 0x01
|
||||
#define LINK_RESET 0x02
|
||||
#define SCAN_HOST 0x04
|
||||
};
|
||||
|
||||
#endif /* _CXLFLASH_MAIN_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,72 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Uma Krishnan <ukrishn@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2018 IBM Corporation
|
||||
*/
|
||||
|
||||
#define OCXL_MAX_IRQS 4 /* Max interrupts per process */
|
||||
|
||||
struct ocxlflash_irqs {
|
||||
int hwirq;
|
||||
u32 virq;
|
||||
void __iomem *vtrig;
|
||||
};
|
||||
|
||||
/* OCXL hardware AFU associated with the host */
|
||||
struct ocxl_hw_afu {
|
||||
struct ocxlflash_context *ocxl_ctx; /* Host context */
|
||||
struct pci_dev *pdev; /* PCI device */
|
||||
struct device *dev; /* Generic device */
|
||||
bool perst_same_image; /* Same image loaded on perst */
|
||||
|
||||
struct ocxl_fn_config fcfg; /* DVSEC config of the function */
|
||||
struct ocxl_afu_config acfg; /* AFU configuration data */
|
||||
|
||||
int fn_actag_base; /* Function acTag base */
|
||||
int fn_actag_enabled; /* Function acTag number enabled */
|
||||
int afu_actag_base; /* AFU acTag base */
|
||||
int afu_actag_enabled; /* AFU acTag number enabled */
|
||||
|
||||
phys_addr_t ppmmio_phys; /* Per process MMIO space */
|
||||
phys_addr_t gmmio_phys; /* Global AFU MMIO space */
|
||||
void __iomem *gmmio_virt; /* Global MMIO map */
|
||||
|
||||
void *link_token; /* Link token for the SPA */
|
||||
struct idr idr; /* IDR to manage contexts */
|
||||
int max_pasid; /* Maximum number of contexts */
|
||||
bool is_present; /* Function has AFUs defined */
|
||||
};
|
||||
|
||||
enum ocxlflash_ctx_state {
|
||||
CLOSED,
|
||||
OPENED,
|
||||
STARTED
|
||||
};
|
||||
|
||||
struct ocxlflash_context {
|
||||
struct ocxl_hw_afu *hw_afu; /* HW AFU back pointer */
|
||||
struct address_space *mapping; /* Mapping for pseudo filesystem */
|
||||
bool master; /* Whether this is a master context */
|
||||
int pe; /* Process element */
|
||||
|
||||
phys_addr_t psn_phys; /* Process mapping */
|
||||
u64 psn_size; /* Process mapping size */
|
||||
|
||||
spinlock_t slock; /* Protects irq/fault/event updates */
|
||||
wait_queue_head_t wq; /* Wait queue for poll and interrupts */
|
||||
struct mutex state_mutex; /* Mutex to update context state */
|
||||
enum ocxlflash_ctx_state state; /* Context state */
|
||||
|
||||
struct ocxlflash_irqs *irqs; /* Pointer to array of structures */
|
||||
int num_irqs; /* Number of interrupts */
|
||||
bool pending_irq; /* Pending interrupt on the context */
|
||||
ulong irq_bitmap; /* Bits indicating pending irq num */
|
||||
|
||||
u64 fault_addr; /* Address that triggered the fault */
|
||||
u64 fault_dsisr; /* Value of dsisr register at fault */
|
||||
bool pending_fault; /* Pending translation fault */
|
||||
};
|
@ -1,560 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _SISLITE_H
|
||||
#define _SISLITE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
typedef u16 ctx_hndl_t;
|
||||
typedef u32 res_hndl_t;
|
||||
|
||||
#define SIZE_4K 4096
|
||||
#define SIZE_64K 65536
|
||||
|
||||
/*
|
||||
* IOARCB: 64 bytes, min 16 byte alignment required, host native endianness
|
||||
* except for SCSI CDB which remains big endian per SCSI standards.
|
||||
*/
|
||||
struct sisl_ioarcb {
|
||||
u16 ctx_id; /* ctx_hndl_t */
|
||||
u16 req_flags;
|
||||
#define SISL_REQ_FLAGS_RES_HNDL 0x8000U /* bit 0 (MSB) */
|
||||
#define SISL_REQ_FLAGS_PORT_LUN_ID 0x0000U
|
||||
|
||||
#define SISL_REQ_FLAGS_SUP_UNDERRUN 0x4000U /* bit 1 */
|
||||
|
||||
#define SISL_REQ_FLAGS_TIMEOUT_SECS 0x0000U /* bits 8,9 */
|
||||
#define SISL_REQ_FLAGS_TIMEOUT_MSECS 0x0040U
|
||||
#define SISL_REQ_FLAGS_TIMEOUT_USECS 0x0080U
|
||||
#define SISL_REQ_FLAGS_TIMEOUT_CYCLES 0x00C0U
|
||||
|
||||
#define SISL_REQ_FLAGS_TMF_CMD 0x0004u /* bit 13 */
|
||||
|
||||
#define SISL_REQ_FLAGS_AFU_CMD 0x0002U /* bit 14 */
|
||||
|
||||
#define SISL_REQ_FLAGS_HOST_WRITE 0x0001U /* bit 15 (LSB) */
|
||||
#define SISL_REQ_FLAGS_HOST_READ 0x0000U
|
||||
|
||||
union {
|
||||
u32 res_hndl; /* res_hndl_t */
|
||||
u32 port_sel; /* this is a selection mask:
|
||||
* 0x1 -> port#0 can be selected,
|
||||
* 0x2 -> port#1 can be selected.
|
||||
* Can be bitwise ORed.
|
||||
*/
|
||||
};
|
||||
u64 lun_id;
|
||||
u32 data_len; /* 4K for read/write */
|
||||
u32 ioadl_len;
|
||||
union {
|
||||
u64 data_ea; /* min 16 byte aligned */
|
||||
u64 ioadl_ea;
|
||||
};
|
||||
u8 msi; /* LISN to send on RRQ write */
|
||||
#define SISL_MSI_CXL_PFAULT 0 /* reserved for CXL page faults */
|
||||
#define SISL_MSI_SYNC_ERROR 1 /* recommended for AFU sync error */
|
||||
#define SISL_MSI_RRQ_UPDATED 2 /* recommended for IO completion */
|
||||
#define SISL_MSI_ASYNC_ERROR 3 /* master only - for AFU async error */
|
||||
|
||||
u8 rrq; /* 0 for a single RRQ */
|
||||
u16 timeout; /* in units specified by req_flags */
|
||||
u32 rsvd1;
|
||||
u8 cdb[16]; /* must be in big endian */
|
||||
#define SISL_AFU_CMD_SYNC 0xC0 /* AFU sync command */
|
||||
#define SISL_AFU_CMD_LUN_PROVISION 0xD0 /* AFU LUN provision command */
|
||||
#define SISL_AFU_CMD_DEBUG 0xE0 /* AFU debug command */
|
||||
|
||||
#define SISL_AFU_LUN_PROVISION_CREATE 0x00 /* LUN provision create type */
|
||||
#define SISL_AFU_LUN_PROVISION_DELETE 0x01 /* LUN provision delete type */
|
||||
|
||||
union {
|
||||
u64 reserved; /* Reserved for IOARRIN mode */
|
||||
struct sisl_ioasa *ioasa; /* IOASA EA for SQ Mode */
|
||||
};
|
||||
} __packed;
|
||||
|
||||
struct sisl_rc {
|
||||
u8 flags;
|
||||
#define SISL_RC_FLAGS_SENSE_VALID 0x80U
|
||||
#define SISL_RC_FLAGS_FCP_RSP_CODE_VALID 0x40U
|
||||
#define SISL_RC_FLAGS_OVERRUN 0x20U
|
||||
#define SISL_RC_FLAGS_UNDERRUN 0x10U
|
||||
|
||||
u8 afu_rc;
|
||||
#define SISL_AFU_RC_RHT_INVALID 0x01U /* user error */
|
||||
#define SISL_AFU_RC_RHT_UNALIGNED 0x02U /* should never happen */
|
||||
#define SISL_AFU_RC_RHT_OUT_OF_BOUNDS 0x03u /* user error */
|
||||
#define SISL_AFU_RC_RHT_DMA_ERR 0x04u /* see afu_extra
|
||||
* may retry if afu_retry is off
|
||||
* possible on master exit
|
||||
*/
|
||||
#define SISL_AFU_RC_RHT_RW_PERM 0x05u /* no RW perms, user error */
|
||||
#define SISL_AFU_RC_LXT_UNALIGNED 0x12U /* should never happen */
|
||||
#define SISL_AFU_RC_LXT_OUT_OF_BOUNDS 0x13u /* user error */
|
||||
#define SISL_AFU_RC_LXT_DMA_ERR 0x14u /* see afu_extra
|
||||
* may retry if afu_retry is off
|
||||
* possible on master exit
|
||||
*/
|
||||
#define SISL_AFU_RC_LXT_RW_PERM 0x15u /* no RW perms, user error */
|
||||
|
||||
#define SISL_AFU_RC_NOT_XLATE_HOST 0x1au /* possible if master exited */
|
||||
|
||||
/* NO_CHANNELS means the FC ports selected by dest_port in
|
||||
* IOARCB or in the LXT entry are down when the AFU tried to select
|
||||
* a FC port. If the port went down on an active IO, it will set
|
||||
* fc_rc to =0x54(NOLOGI) or 0x57(LINKDOWN) instead.
|
||||
*/
|
||||
#define SISL_AFU_RC_NO_CHANNELS 0x20U /* see afu_extra, may retry */
|
||||
#define SISL_AFU_RC_CAP_VIOLATION 0x21U /* either user error or
|
||||
* afu reset/master restart
|
||||
*/
|
||||
#define SISL_AFU_RC_OUT_OF_DATA_BUFS 0x30U /* always retry */
|
||||
#define SISL_AFU_RC_DATA_DMA_ERR 0x31U /* see afu_extra
|
||||
* may retry if afu_retry is off
|
||||
*/
|
||||
|
||||
u8 scsi_rc; /* SCSI status byte, retry as appropriate */
|
||||
#define SISL_SCSI_RC_CHECK 0x02U
|
||||
#define SISL_SCSI_RC_BUSY 0x08u
|
||||
|
||||
u8 fc_rc; /* retry */
|
||||
/*
|
||||
* We should only see fc_rc=0x57 (LINKDOWN) or 0x54(NOLOGI) for
|
||||
* commands that are in flight when a link goes down or is logged out.
|
||||
* If the link is down or logged out before AFU selects the port, either
|
||||
* it will choose the other port or we will get afu_rc=0x20 (no_channel)
|
||||
* if there is no valid port to use.
|
||||
*
|
||||
* ABORTPEND/ABORTOK/ABORTFAIL/TGTABORT can be retried, typically these
|
||||
* would happen if a frame is dropped and something times out.
|
||||
* NOLOGI or LINKDOWN can be retried if the other port is up.
|
||||
* RESIDERR can be retried as well.
|
||||
*
|
||||
* ABORTFAIL might indicate that lots of frames are getting CRC errors.
|
||||
* So it maybe retried once and reset the link if it happens again.
|
||||
* The link can also be reset on the CRC error threshold interrupt.
|
||||
*/
|
||||
#define SISL_FC_RC_ABORTPEND 0x52 /* exchange timeout or abort request */
|
||||
#define SISL_FC_RC_WRABORTPEND 0x53 /* due to write XFER_RDY invalid */
|
||||
#define SISL_FC_RC_NOLOGI 0x54 /* port not logged in, in-flight cmds */
|
||||
#define SISL_FC_RC_NOEXP 0x55 /* FC protocol error or HW bug */
|
||||
#define SISL_FC_RC_INUSE 0x56 /* tag already in use, HW bug */
|
||||
#define SISL_FC_RC_LINKDOWN 0x57 /* link down, in-flight cmds */
|
||||
#define SISL_FC_RC_ABORTOK 0x58 /* pending abort completed w/success */
|
||||
#define SISL_FC_RC_ABORTFAIL 0x59 /* pending abort completed w/fail */
|
||||
#define SISL_FC_RC_RESID 0x5A /* ioasa underrun/overrun flags set */
|
||||
#define SISL_FC_RC_RESIDERR 0x5B /* actual data len does not match SCSI
|
||||
* reported len, possibly due to dropped
|
||||
* frames
|
||||
*/
|
||||
#define SISL_FC_RC_TGTABORT 0x5C /* command aborted by target */
|
||||
};
|
||||
|
||||
#define SISL_SENSE_DATA_LEN 20 /* Sense data length */
|
||||
#define SISL_WWID_DATA_LEN 16 /* WWID data length */
|
||||
|
||||
/*
|
||||
* IOASA: 64 bytes & must follow IOARCB, min 16 byte alignment required,
|
||||
* host native endianness
|
||||
*/
|
||||
struct sisl_ioasa {
|
||||
union {
|
||||
struct sisl_rc rc;
|
||||
u32 ioasc;
|
||||
#define SISL_IOASC_GOOD_COMPLETION 0x00000000U
|
||||
};
|
||||
|
||||
union {
|
||||
u32 resid;
|
||||
u32 lunid_hi;
|
||||
};
|
||||
|
||||
u8 port;
|
||||
u8 afu_extra;
|
||||
/* when afu_rc=0x04, 0x14, 0x31 (_xxx_DMA_ERR):
|
||||
* afu_exta contains PSL response code. Useful codes are:
|
||||
*/
|
||||
#define SISL_AFU_DMA_ERR_PAGE_IN 0x0A /* AFU_retry_on_pagein Action
|
||||
* Enabled N/A
|
||||
* Disabled retry
|
||||
*/
|
||||
#define SISL_AFU_DMA_ERR_INVALID_EA 0x0B /* this is a hard error
|
||||
* afu_rc Implies
|
||||
* 0x04, 0x14 master exit.
|
||||
* 0x31 user error.
|
||||
*/
|
||||
/* when afu rc=0x20 (no channels):
|
||||
* afu_extra bits [4:5]: available portmask, [6:7]: requested portmask.
|
||||
*/
|
||||
#define SISL_AFU_NO_CLANNELS_AMASK(afu_extra) (((afu_extra) & 0x0C) >> 2)
|
||||
#define SISL_AFU_NO_CLANNELS_RMASK(afu_extra) ((afu_extra) & 0x03)
|
||||
|
||||
u8 scsi_extra;
|
||||
u8 fc_extra;
|
||||
|
||||
union {
|
||||
u8 sense_data[SISL_SENSE_DATA_LEN];
|
||||
struct {
|
||||
u32 lunid_lo;
|
||||
u8 wwid[SISL_WWID_DATA_LEN];
|
||||
};
|
||||
};
|
||||
|
||||
/* These fields are defined by the SISlite architecture for the
|
||||
* host to use as they see fit for their implementation.
|
||||
*/
|
||||
union {
|
||||
u64 host_use[4];
|
||||
u8 host_use_b[32];
|
||||
};
|
||||
} __packed;
|
||||
|
||||
#define SISL_RESP_HANDLE_T_BIT 0x1ULL /* Toggle bit */
|
||||
|
||||
/* MMIO space is required to support only 64-bit access */
|
||||
|
||||
/*
|
||||
* This AFU has two mechanisms to deal with endian-ness.
|
||||
* One is a global configuration (in the afu_config) register
|
||||
* below that specifies the endian-ness of the host.
|
||||
* The other is a per context (i.e. application) specification
|
||||
* controlled by the endian_ctrl field here. Since the master
|
||||
* context is one such application the master context's
|
||||
* endian-ness is set to be the same as the host.
|
||||
*
|
||||
* As per the SISlite spec, the MMIO registers are always
|
||||
* big endian.
|
||||
*/
|
||||
#define SISL_ENDIAN_CTRL_BE 0x8000000000000080ULL
|
||||
#define SISL_ENDIAN_CTRL_LE 0x0000000000000000ULL
|
||||
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define SISL_ENDIAN_CTRL SISL_ENDIAN_CTRL_BE
|
||||
#else
|
||||
#define SISL_ENDIAN_CTRL SISL_ENDIAN_CTRL_LE
|
||||
#endif
|
||||
|
||||
/* per context host transport MMIO */
|
||||
struct sisl_host_map {
|
||||
__be64 endian_ctrl; /* Per context Endian Control. The AFU will
|
||||
* operate on whatever the context is of the
|
||||
* host application.
|
||||
*/
|
||||
|
||||
__be64 intr_status; /* this sends LISN# programmed in ctx_ctrl.
|
||||
* Only recovery in a PERM_ERR is a context
|
||||
* exit since there is no way to tell which
|
||||
* command caused the error.
|
||||
*/
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_3_EA 0x0400ULL /* b53, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_2_EA 0x0200ULL /* b54, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_1_EA 0x0100ULL /* b55, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_3_PASID 0x0080ULL /* b56, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_2_PASID 0x0040ULL /* b57, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_LISN_1_PASID 0x0020ULL /* b58, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_CMDROOM 0x0010ULL /* b59, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_RCB_READ 0x0008ULL /* b60, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_SA_WRITE 0x0004ULL /* b61, user error */
|
||||
#define SISL_ISTATUS_PERM_ERR_RRQ_WRITE 0x0002ULL /* b62, user error */
|
||||
/* Page in wait accessing RCB/IOASA/RRQ is reported in b63.
|
||||
* Same error in data/LXT/RHT access is reported via IOASA.
|
||||
*/
|
||||
#define SISL_ISTATUS_TEMP_ERR_PAGEIN 0x0001ULL /* b63, can only be
|
||||
* generated when AFU
|
||||
* auto retry is
|
||||
* disabled. If user
|
||||
* can determine the
|
||||
* command that caused
|
||||
* the error, it can
|
||||
* be retried.
|
||||
*/
|
||||
#define SISL_ISTATUS_UNMASK (0x07FFULL) /* 1 means unmasked */
|
||||
#define SISL_ISTATUS_MASK ~(SISL_ISTATUS_UNMASK) /* 1 means masked */
|
||||
|
||||
__be64 intr_clear;
|
||||
__be64 intr_mask;
|
||||
__be64 ioarrin; /* only write what cmd_room permits */
|
||||
__be64 rrq_start; /* start & end are both inclusive */
|
||||
__be64 rrq_end; /* write sequence: start followed by end */
|
||||
__be64 cmd_room;
|
||||
__be64 ctx_ctrl; /* least significant byte or b56:63 is LISN# */
|
||||
#define SISL_CTX_CTRL_UNMAP_SECTOR 0x8000000000000000ULL /* b0 */
|
||||
#define SISL_CTX_CTRL_LISN_MASK (0xFFULL)
|
||||
__be64 mbox_w; /* restricted use */
|
||||
__be64 sq_start; /* Submission Queue (R/W): write sequence and */
|
||||
__be64 sq_end; /* inclusion semantics are the same as RRQ */
|
||||
__be64 sq_head; /* Submission Queue Head (R): for debugging */
|
||||
__be64 sq_tail; /* Submission Queue TAIL (R/W): next IOARCB */
|
||||
__be64 sq_ctx_reset; /* Submission Queue Context Reset (R/W) */
|
||||
};
|
||||
|
||||
/* per context provisioning & control MMIO */
|
||||
struct sisl_ctrl_map {
|
||||
__be64 rht_start;
|
||||
__be64 rht_cnt_id;
|
||||
/* both cnt & ctx_id args must be ULL */
|
||||
#define SISL_RHT_CNT_ID(cnt, ctx_id) (((cnt) << 48) | ((ctx_id) << 32))
|
||||
|
||||
__be64 ctx_cap; /* afu_rc below is when the capability is violated */
|
||||
#define SISL_CTX_CAP_PROXY_ISSUE 0x8000000000000000ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_REAL_MODE 0x4000000000000000ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_HOST_XLATE 0x2000000000000000ULL /* afu_rc 0x1a */
|
||||
#define SISL_CTX_CAP_PROXY_TARGET 0x1000000000000000ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_AFU_CMD 0x0000000000000008ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_GSCSI_CMD 0x0000000000000004ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_WRITE_CMD 0x0000000000000002ULL /* afu_rc 0x21 */
|
||||
#define SISL_CTX_CAP_READ_CMD 0x0000000000000001ULL /* afu_rc 0x21 */
|
||||
__be64 mbox_r;
|
||||
__be64 lisn_pasid[2];
|
||||
/* pasid _a arg must be ULL */
|
||||
#define SISL_LISN_PASID(_a, _b) (((_a) << 32) | (_b))
|
||||
__be64 lisn_ea[3];
|
||||
};
|
||||
|
||||
/* single copy global regs */
|
||||
struct sisl_global_regs {
|
||||
__be64 aintr_status;
|
||||
/*
|
||||
* In cxlflash, FC port/link are arranged in port pairs, each
|
||||
* gets a byte of status:
|
||||
*
|
||||
* *_OTHER: other err, FC_ERRCAP[31:20]
|
||||
* *_LOGO: target sent FLOGI/PLOGI/LOGO while logged in
|
||||
* *_CRC_T: CRC threshold exceeded
|
||||
* *_LOGI_R: login state machine timed out and retrying
|
||||
* *_LOGI_F: login failed, FC_ERROR[19:0]
|
||||
* *_LOGI_S: login succeeded
|
||||
* *_LINK_DN: link online to offline
|
||||
* *_LINK_UP: link offline to online
|
||||
*/
|
||||
#define SISL_ASTATUS_FC2_OTHER 0x80000000ULL /* b32 */
|
||||
#define SISL_ASTATUS_FC2_LOGO 0x40000000ULL /* b33 */
|
||||
#define SISL_ASTATUS_FC2_CRC_T 0x20000000ULL /* b34 */
|
||||
#define SISL_ASTATUS_FC2_LOGI_R 0x10000000ULL /* b35 */
|
||||
#define SISL_ASTATUS_FC2_LOGI_F 0x08000000ULL /* b36 */
|
||||
#define SISL_ASTATUS_FC2_LOGI_S 0x04000000ULL /* b37 */
|
||||
#define SISL_ASTATUS_FC2_LINK_DN 0x02000000ULL /* b38 */
|
||||
#define SISL_ASTATUS_FC2_LINK_UP 0x01000000ULL /* b39 */
|
||||
|
||||
#define SISL_ASTATUS_FC3_OTHER 0x00800000ULL /* b40 */
|
||||
#define SISL_ASTATUS_FC3_LOGO 0x00400000ULL /* b41 */
|
||||
#define SISL_ASTATUS_FC3_CRC_T 0x00200000ULL /* b42 */
|
||||
#define SISL_ASTATUS_FC3_LOGI_R 0x00100000ULL /* b43 */
|
||||
#define SISL_ASTATUS_FC3_LOGI_F 0x00080000ULL /* b44 */
|
||||
#define SISL_ASTATUS_FC3_LOGI_S 0x00040000ULL /* b45 */
|
||||
#define SISL_ASTATUS_FC3_LINK_DN 0x00020000ULL /* b46 */
|
||||
#define SISL_ASTATUS_FC3_LINK_UP 0x00010000ULL /* b47 */
|
||||
|
||||
#define SISL_ASTATUS_FC0_OTHER 0x00008000ULL /* b48 */
|
||||
#define SISL_ASTATUS_FC0_LOGO 0x00004000ULL /* b49 */
|
||||
#define SISL_ASTATUS_FC0_CRC_T 0x00002000ULL /* b50 */
|
||||
#define SISL_ASTATUS_FC0_LOGI_R 0x00001000ULL /* b51 */
|
||||
#define SISL_ASTATUS_FC0_LOGI_F 0x00000800ULL /* b52 */
|
||||
#define SISL_ASTATUS_FC0_LOGI_S 0x00000400ULL /* b53 */
|
||||
#define SISL_ASTATUS_FC0_LINK_DN 0x00000200ULL /* b54 */
|
||||
#define SISL_ASTATUS_FC0_LINK_UP 0x00000100ULL /* b55 */
|
||||
|
||||
#define SISL_ASTATUS_FC1_OTHER 0x00000080ULL /* b56 */
|
||||
#define SISL_ASTATUS_FC1_LOGO 0x00000040ULL /* b57 */
|
||||
#define SISL_ASTATUS_FC1_CRC_T 0x00000020ULL /* b58 */
|
||||
#define SISL_ASTATUS_FC1_LOGI_R 0x00000010ULL /* b59 */
|
||||
#define SISL_ASTATUS_FC1_LOGI_F 0x00000008ULL /* b60 */
|
||||
#define SISL_ASTATUS_FC1_LOGI_S 0x00000004ULL /* b61 */
|
||||
#define SISL_ASTATUS_FC1_LINK_DN 0x00000002ULL /* b62 */
|
||||
#define SISL_ASTATUS_FC1_LINK_UP 0x00000001ULL /* b63 */
|
||||
|
||||
#define SISL_FC_INTERNAL_UNMASK 0x0000000300000000ULL /* 1 means unmasked */
|
||||
#define SISL_FC_INTERNAL_MASK ~(SISL_FC_INTERNAL_UNMASK)
|
||||
#define SISL_FC_INTERNAL_SHIFT 32
|
||||
|
||||
#define SISL_FC_SHUTDOWN_NORMAL 0x0000000000000010ULL
|
||||
#define SISL_FC_SHUTDOWN_ABRUPT 0x0000000000000020ULL
|
||||
|
||||
#define SISL_STATUS_SHUTDOWN_ACTIVE 0x0000000000000010ULL
|
||||
#define SISL_STATUS_SHUTDOWN_COMPLETE 0x0000000000000020ULL
|
||||
|
||||
#define SISL_ASTATUS_UNMASK 0xFFFFFFFFULL /* 1 means unmasked */
|
||||
#define SISL_ASTATUS_MASK ~(SISL_ASTATUS_UNMASK) /* 1 means masked */
|
||||
|
||||
__be64 aintr_clear;
|
||||
__be64 aintr_mask;
|
||||
__be64 afu_ctrl;
|
||||
__be64 afu_hb;
|
||||
__be64 afu_scratch_pad;
|
||||
__be64 afu_port_sel;
|
||||
#define SISL_AFUCONF_AR_IOARCB 0x4000ULL
|
||||
#define SISL_AFUCONF_AR_LXT 0x2000ULL
|
||||
#define SISL_AFUCONF_AR_RHT 0x1000ULL
|
||||
#define SISL_AFUCONF_AR_DATA 0x0800ULL
|
||||
#define SISL_AFUCONF_AR_RSRC 0x0400ULL
|
||||
#define SISL_AFUCONF_AR_IOASA 0x0200ULL
|
||||
#define SISL_AFUCONF_AR_RRQ 0x0100ULL
|
||||
/* Aggregate all Auto Retry Bits */
|
||||
#define SISL_AFUCONF_AR_ALL (SISL_AFUCONF_AR_IOARCB|SISL_AFUCONF_AR_LXT| \
|
||||
SISL_AFUCONF_AR_RHT|SISL_AFUCONF_AR_DATA| \
|
||||
SISL_AFUCONF_AR_RSRC|SISL_AFUCONF_AR_IOASA| \
|
||||
SISL_AFUCONF_AR_RRQ)
|
||||
#ifdef __BIG_ENDIAN
|
||||
#define SISL_AFUCONF_ENDIAN 0x0000ULL
|
||||
#else
|
||||
#define SISL_AFUCONF_ENDIAN 0x0020ULL
|
||||
#endif
|
||||
#define SISL_AFUCONF_MBOX_CLR_READ 0x0010ULL
|
||||
__be64 afu_config;
|
||||
__be64 rsvd[0xf8];
|
||||
__le64 afu_version;
|
||||
__be64 interface_version;
|
||||
#define SISL_INTVER_CAP_SHIFT 16
|
||||
#define SISL_INTVER_MAJ_SHIFT 8
|
||||
#define SISL_INTVER_CAP_MASK 0xFFFFFFFF00000000ULL
|
||||
#define SISL_INTVER_MAJ_MASK 0x00000000FFFF0000ULL
|
||||
#define SISL_INTVER_MIN_MASK 0x000000000000FFFFULL
|
||||
#define SISL_INTVER_CAP_IOARRIN_CMD_MODE 0x800000000000ULL
|
||||
#define SISL_INTVER_CAP_SQ_CMD_MODE 0x400000000000ULL
|
||||
#define SISL_INTVER_CAP_RESERVED_CMD_MODE_A 0x200000000000ULL
|
||||
#define SISL_INTVER_CAP_RESERVED_CMD_MODE_B 0x100000000000ULL
|
||||
#define SISL_INTVER_CAP_LUN_PROVISION 0x080000000000ULL
|
||||
#define SISL_INTVER_CAP_AFU_DEBUG 0x040000000000ULL
|
||||
#define SISL_INTVER_CAP_OCXL_LISN 0x020000000000ULL
|
||||
};
|
||||
|
||||
#define CXLFLASH_NUM_FC_PORTS_PER_BANK 2 /* fixed # of ports per bank */
|
||||
#define CXLFLASH_MAX_FC_BANKS 2 /* max # of banks supported */
|
||||
#define CXLFLASH_MAX_FC_PORTS (CXLFLASH_NUM_FC_PORTS_PER_BANK * \
|
||||
CXLFLASH_MAX_FC_BANKS)
|
||||
#define CXLFLASH_MAX_CONTEXT 512 /* number of contexts per AFU */
|
||||
#define CXLFLASH_NUM_VLUNS 512 /* number of vluns per AFU/port */
|
||||
#define CXLFLASH_NUM_REGS 512 /* number of registers per port */
|
||||
|
||||
struct fc_port_bank {
|
||||
__be64 fc_port_regs[CXLFLASH_NUM_FC_PORTS_PER_BANK][CXLFLASH_NUM_REGS];
|
||||
__be64 fc_port_luns[CXLFLASH_NUM_FC_PORTS_PER_BANK][CXLFLASH_NUM_VLUNS];
|
||||
};
|
||||
|
||||
struct sisl_global_map {
|
||||
union {
|
||||
struct sisl_global_regs regs;
|
||||
char page0[SIZE_4K]; /* page 0 */
|
||||
};
|
||||
|
||||
char page1[SIZE_4K]; /* page 1 */
|
||||
|
||||
struct fc_port_bank bank[CXLFLASH_MAX_FC_BANKS]; /* pages 2 - 9 */
|
||||
|
||||
/* pages 10 - 15 are reserved */
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* CXL Flash Memory Map
|
||||
*
|
||||
* +-------------------------------+
|
||||
* | 512 * 64 KB User MMIO |
|
||||
* | (per context) |
|
||||
* | User Accessible |
|
||||
* +-------------------------------+
|
||||
* | 512 * 128 B per context |
|
||||
* | Provisioning and Control |
|
||||
* | Trusted Process accessible |
|
||||
* +-------------------------------+
|
||||
* | 64 KB Global |
|
||||
* | Trusted Process accessible |
|
||||
* +-------------------------------+
|
||||
*/
|
||||
struct cxlflash_afu_map {
|
||||
union {
|
||||
struct sisl_host_map host;
|
||||
char harea[SIZE_64K]; /* 64KB each */
|
||||
} hosts[CXLFLASH_MAX_CONTEXT];
|
||||
|
||||
union {
|
||||
struct sisl_ctrl_map ctrl;
|
||||
char carea[cache_line_size()]; /* 128B each */
|
||||
} ctrls[CXLFLASH_MAX_CONTEXT];
|
||||
|
||||
union {
|
||||
struct sisl_global_map global;
|
||||
char garea[SIZE_64K]; /* 64KB single block */
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
* LXT - LBA Translation Table
|
||||
* LXT control blocks
|
||||
*/
|
||||
struct sisl_lxt_entry {
|
||||
u64 rlba_base; /* bits 0:47 is base
|
||||
* b48:55 is lun index
|
||||
* b58:59 is write & read perms
|
||||
* (if no perm, afu_rc=0x15)
|
||||
* b60:63 is port_sel mask
|
||||
*/
|
||||
};
|
||||
|
||||
/*
|
||||
* RHT - Resource Handle Table
|
||||
* Per the SISlite spec, RHT entries are to be 16-byte aligned
|
||||
*/
|
||||
struct sisl_rht_entry {
|
||||
struct sisl_lxt_entry *lxt_start;
|
||||
u32 lxt_cnt;
|
||||
u16 rsvd;
|
||||
u8 fp; /* format & perm nibbles.
|
||||
* (if no perm, afu_rc=0x05)
|
||||
*/
|
||||
u8 nmask;
|
||||
} __packed __aligned(16);
|
||||
|
||||
struct sisl_rht_entry_f1 {
|
||||
u64 lun_id;
|
||||
union {
|
||||
struct {
|
||||
u8 valid;
|
||||
u8 rsvd[5];
|
||||
u8 fp;
|
||||
u8 port_sel;
|
||||
};
|
||||
|
||||
u64 dw;
|
||||
};
|
||||
} __packed __aligned(16);
|
||||
|
||||
/* make the fp byte */
|
||||
#define SISL_RHT_FP(fmt, perm) (((fmt) << 4) | (perm))
|
||||
|
||||
/* make the fp byte for a clone from a source fp and clone flags
|
||||
* flags must be only 2 LSB bits.
|
||||
*/
|
||||
#define SISL_RHT_FP_CLONE(src_fp, cln_flags) ((src_fp) & (0xFC | (cln_flags)))
|
||||
|
||||
#define RHT_PERM_READ 0x01U
|
||||
#define RHT_PERM_WRITE 0x02U
|
||||
#define RHT_PERM_RW (RHT_PERM_READ | RHT_PERM_WRITE)
|
||||
|
||||
/* extract the perm bits from a fp */
|
||||
#define SISL_RHT_PERM(fp) ((fp) & RHT_PERM_RW)
|
||||
|
||||
#define PORT0 0x01U
|
||||
#define PORT1 0x02U
|
||||
#define PORT2 0x04U
|
||||
#define PORT3 0x08U
|
||||
#define PORT_MASK(_n) ((1 << (_n)) - 1)
|
||||
|
||||
/* AFU Sync Mode byte */
|
||||
#define AFU_LW_SYNC 0x0U
|
||||
#define AFU_HW_SYNC 0x1U
|
||||
#define AFU_GSYNC 0x2U
|
||||
|
||||
/* Special Task Management Function CDB */
|
||||
#define TMF_LUN_RESET 0x1U
|
||||
#define TMF_CLEAR_ACA 0x2U
|
||||
|
||||
#endif /* _SISLITE_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_SUPERPIPE_H
|
||||
#define _CXLFLASH_SUPERPIPE_H
|
||||
|
||||
extern struct cxlflash_global global;
|
||||
|
||||
/*
|
||||
* Terminology: use afu (and not adapter) to refer to the HW.
|
||||
* Adapter is the entire slot and includes PSL out of which
|
||||
* only the AFU is visible to user space.
|
||||
*/
|
||||
|
||||
/* Chunk size parms: note sislite minimum chunk size is
|
||||
* 0x10000 LBAs corresponding to a NMASK or 16.
|
||||
*/
|
||||
#define MC_CHUNK_SIZE (1 << MC_RHT_NMASK) /* in LBAs */
|
||||
|
||||
#define CMD_TIMEOUT 30 /* 30 secs */
|
||||
#define CMD_RETRIES 5 /* 5 retries for scsi_execute */
|
||||
|
||||
#define MAX_SECTOR_UNIT 512 /* max_sector is in 512 byte multiples */
|
||||
|
||||
enum lun_mode {
|
||||
MODE_NONE = 0,
|
||||
MODE_VIRTUAL,
|
||||
MODE_PHYSICAL
|
||||
};
|
||||
|
||||
/* Global (entire driver, spans adapters) lun_info structure */
|
||||
struct glun_info {
|
||||
u64 max_lba; /* from read cap(16) */
|
||||
u32 blk_len; /* from read cap(16) */
|
||||
enum lun_mode mode; /* NONE, VIRTUAL, PHYSICAL */
|
||||
int users; /* Number of users w/ references to LUN */
|
||||
|
||||
u8 wwid[16];
|
||||
|
||||
struct mutex mutex;
|
||||
|
||||
struct blka blka;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
/* Local (per-adapter) lun_info structure */
|
||||
struct llun_info {
|
||||
u64 lun_id[MAX_FC_PORTS]; /* from REPORT_LUNS */
|
||||
u32 lun_index; /* Index in the LUN table */
|
||||
u32 host_no; /* host_no from Scsi_host */
|
||||
u32 port_sel; /* What port to use for this LUN */
|
||||
bool in_table; /* Whether a LUN table entry was created */
|
||||
|
||||
u8 wwid[16]; /* Keep a duplicate copy here? */
|
||||
|
||||
struct glun_info *parent; /* Pointer to entry in global LUN structure */
|
||||
struct scsi_device *sdev;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct lun_access {
|
||||
struct llun_info *lli;
|
||||
struct scsi_device *sdev;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
enum ctx_ctrl {
|
||||
CTX_CTRL_CLONE = (1 << 1),
|
||||
CTX_CTRL_ERR = (1 << 2),
|
||||
CTX_CTRL_ERR_FALLBACK = (1 << 3),
|
||||
CTX_CTRL_NOPID = (1 << 4),
|
||||
CTX_CTRL_FILE = (1 << 5)
|
||||
};
|
||||
|
||||
#define ENCODE_CTXID(_ctx, _id) (((((u64)_ctx) & 0xFFFFFFFF0ULL) << 28) | _id)
|
||||
#define DECODE_CTXID(_val) (_val & 0xFFFFFFFF)
|
||||
|
||||
struct ctx_info {
|
||||
struct sisl_ctrl_map __iomem *ctrl_map; /* initialized at startup */
|
||||
struct sisl_rht_entry *rht_start; /* 1 page (req'd for alignment),
|
||||
* alloc/free on attach/detach
|
||||
*/
|
||||
u32 rht_out; /* Number of checked out RHT entries */
|
||||
u32 rht_perms; /* User-defined permissions for RHT entries */
|
||||
struct llun_info **rht_lun; /* Mapping of RHT entries to LUNs */
|
||||
u8 *rht_needs_ws; /* User-desired write-same function per RHTE */
|
||||
|
||||
u64 ctxid;
|
||||
u64 irqs; /* Number of interrupts requested for context */
|
||||
pid_t pid;
|
||||
bool initialized;
|
||||
bool unavail;
|
||||
bool err_recovery_active;
|
||||
struct mutex mutex; /* Context protection */
|
||||
struct kref kref;
|
||||
void *ctx;
|
||||
struct cxlflash_cfg *cfg;
|
||||
struct list_head luns; /* LUNs attached to this context */
|
||||
const struct vm_operations_struct *cxl_mmap_vmops;
|
||||
struct file *file;
|
||||
struct list_head list; /* Link contexts in error recovery */
|
||||
};
|
||||
|
||||
struct cxlflash_global {
|
||||
struct mutex mutex;
|
||||
struct list_head gluns;/* list of glun_info structs */
|
||||
struct page *err_page; /* One page of all 0xF for error notification */
|
||||
};
|
||||
|
||||
int cxlflash_vlun_resize(struct scsi_device *sdev, void *resize);
|
||||
int _cxlflash_vlun_resize(struct scsi_device *sdev, struct ctx_info *ctxi,
|
||||
struct dk_cxlflash_resize *resize);
|
||||
|
||||
int cxlflash_disk_release(struct scsi_device *sdev,
|
||||
void *release);
|
||||
int _cxlflash_disk_release(struct scsi_device *sdev, struct ctx_info *ctxi,
|
||||
struct dk_cxlflash_release *release);
|
||||
|
||||
int cxlflash_disk_clone(struct scsi_device *sdev, void *arg);
|
||||
|
||||
int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg);
|
||||
|
||||
int cxlflash_lun_attach(struct glun_info *gli, enum lun_mode mode, bool locked);
|
||||
void cxlflash_lun_detach(struct glun_info *gli);
|
||||
|
||||
struct ctx_info *get_context(struct cxlflash_cfg *cfg, u64 rctxit, void *arg,
|
||||
enum ctx_ctrl ctrl);
|
||||
void put_context(struct ctx_info *ctxi);
|
||||
|
||||
struct sisl_rht_entry *get_rhte(struct ctx_info *ctxi, res_hndl_t rhndl,
|
||||
struct llun_info *lli);
|
||||
|
||||
struct sisl_rht_entry *rhte_checkout(struct ctx_info *ctxi,
|
||||
struct llun_info *lli);
|
||||
void rhte_checkin(struct ctx_info *ctxi, struct sisl_rht_entry *rhte);
|
||||
|
||||
void cxlflash_ba_terminate(struct ba_lun *ba_lun);
|
||||
|
||||
int cxlflash_manage_lun(struct scsi_device *sdev, void *manage);
|
||||
|
||||
int check_state(struct cxlflash_cfg *cfg);
|
||||
|
||||
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,82 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_VLUN_H
|
||||
#define _CXLFLASH_VLUN_H
|
||||
|
||||
/* RHT - Resource Handle Table */
|
||||
#define MC_RHT_NMASK 16 /* in bits */
|
||||
#define MC_CHUNK_SHIFT MC_RHT_NMASK /* shift to go from LBA to chunk# */
|
||||
|
||||
#define HIBIT (BITS_PER_LONG - 1)
|
||||
|
||||
#define MAX_AUN_CLONE_CNT 0xFF
|
||||
|
||||
/*
|
||||
* LXT - LBA Translation Table
|
||||
*
|
||||
* +-------+-------+-------+-------+-------+-------+-------+---+---+
|
||||
* | RLBA_BASE |LUN_IDX| P |SEL|
|
||||
* +-------+-------+-------+-------+-------+-------+-------+---+---+
|
||||
*
|
||||
* The LXT Entry contains the physical LBA where the chunk starts (RLBA_BASE).
|
||||
* AFU ORes the low order bits from the virtual LBA (offset into the chunk)
|
||||
* with RLBA_BASE. The result is the physical LBA to be sent to storage.
|
||||
* The LXT Entry also contains an index to a LUN TBL and a bitmask of which
|
||||
* outgoing (FC) * ports can be selected. The port select bit-mask is ANDed
|
||||
* with a global port select bit-mask maintained by the driver.
|
||||
* In addition, it has permission bits that are ANDed with the
|
||||
* RHT permissions to arrive at the final permissions for the chunk.
|
||||
*
|
||||
* LXT tables are allocated dynamically in groups. This is done to avoid
|
||||
* a malloc/free overhead each time the LXT has to grow or shrink.
|
||||
*
|
||||
* Based on the current lxt_cnt (used), it is always possible to know
|
||||
* how many are allocated (used+free). The number of allocated entries is
|
||||
* not stored anywhere.
|
||||
*
|
||||
* The LXT table is re-allocated whenever it needs to cross into another group.
|
||||
*/
|
||||
#define LXT_GROUP_SIZE 8
|
||||
#define LXT_NUM_GROUPS(lxt_cnt) (((lxt_cnt) + 7)/8) /* alloc'ed groups */
|
||||
#define LXT_LUNIDX_SHIFT 8 /* LXT entry, shift for LUN index */
|
||||
#define LXT_PERM_SHIFT 4 /* LXT entry, shift for permission bits */
|
||||
|
||||
struct ba_lun_info {
|
||||
u64 *lun_alloc_map;
|
||||
u32 lun_bmap_size;
|
||||
u32 total_aus;
|
||||
u64 free_aun_cnt;
|
||||
|
||||
/* indices to be used for elevator lookup of free map */
|
||||
u32 free_low_idx;
|
||||
u32 free_curr_idx;
|
||||
u32 free_high_idx;
|
||||
|
||||
u8 *aun_clone_map;
|
||||
};
|
||||
|
||||
struct ba_lun {
|
||||
u64 lun_id;
|
||||
u64 wwpn;
|
||||
size_t lsize; /* LUN size in number of LBAs */
|
||||
size_t lba_size; /* LBA size in number of bytes */
|
||||
size_t au_size; /* Allocation Unit size in number of LBAs */
|
||||
struct ba_lun_info *ba_lun_handle;
|
||||
};
|
||||
|
||||
/* Block Allocator */
|
||||
struct blka {
|
||||
struct ba_lun ba_lun;
|
||||
u64 nchunk; /* number of chunks */
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#endif /* ifndef _CXLFLASH_SUPERPIPE_H */
|
@ -1,276 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */
|
||||
/*
|
||||
* CXL Flash Device Driver
|
||||
*
|
||||
* Written by: Manoj N. Kumar <manoj@linux.vnet.ibm.com>, IBM Corporation
|
||||
* Matthew R. Ochs <mrochs@linux.vnet.ibm.com>, IBM Corporation
|
||||
*
|
||||
* Copyright (C) 2015 IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version
|
||||
* 2 of the License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef _CXLFLASH_IOCTL_H
|
||||
#define _CXLFLASH_IOCTL_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
/*
|
||||
* Structure and definitions for all CXL Flash ioctls
|
||||
*/
|
||||
#define CXLFLASH_WWID_LEN 16
|
||||
|
||||
/*
|
||||
* Structure and flag definitions CXL Flash superpipe ioctls
|
||||
*/
|
||||
|
||||
#define DK_CXLFLASH_VERSION_0 0
|
||||
|
||||
struct dk_cxlflash_hdr {
|
||||
__u16 version; /* Version data */
|
||||
__u16 rsvd[3]; /* Reserved for future use */
|
||||
__u64 flags; /* Input flags */
|
||||
__u64 return_flags; /* Returned flags */
|
||||
};
|
||||
|
||||
/*
|
||||
* Return flag definitions available to all superpipe ioctls
|
||||
*
|
||||
* Similar to the input flags, these are grown from the bottom-up with the
|
||||
* intention that ioctl-specific return flag definitions would grow from the
|
||||
* top-down, allowing the two sets to co-exist. While not required/enforced
|
||||
* at this time, this provides future flexibility.
|
||||
*/
|
||||
#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0000000000000001ULL
|
||||
#define DK_CXLFLASH_APP_CLOSE_ADAP_FD 0x0000000000000002ULL
|
||||
#define DK_CXLFLASH_CONTEXT_SQ_CMD_MODE 0x0000000000000004ULL
|
||||
|
||||
/*
|
||||
* General Notes:
|
||||
* -------------
|
||||
* The 'context_id' field of all ioctl structures contains the context
|
||||
* identifier for a context in the lower 32-bits (upper 32-bits are not
|
||||
* to be used when identifying a context to the AFU). That said, the value
|
||||
* in its entirety (all 64-bits) is to be treated as an opaque cookie and
|
||||
* should be presented as such when issuing ioctls.
|
||||
*/
|
||||
|
||||
/*
|
||||
* DK_CXLFLASH_ATTACH Notes:
|
||||
* ------------------------
|
||||
* Read/write access permissions are specified via the O_RDONLY, O_WRONLY,
|
||||
* and O_RDWR flags defined in the fcntl.h header file.
|
||||
*
|
||||
* A valid adapter file descriptor (fd >= 0) is only returned on the initial
|
||||
* attach (successful) of a context. When a context is shared(reused), the user
|
||||
* is expected to already 'know' the adapter file descriptor associated with the
|
||||
* context.
|
||||
*/
|
||||
#define DK_CXLFLASH_ATTACH_REUSE_CONTEXT 0x8000000000000000ULL
|
||||
|
||||
struct dk_cxlflash_attach {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 num_interrupts; /* Requested number of interrupts */
|
||||
__u64 context_id; /* Returned context */
|
||||
__u64 mmio_size; /* Returned size of MMIO area */
|
||||
__u64 block_size; /* Returned block size, in bytes */
|
||||
__u64 adap_fd; /* Returned adapter file descriptor */
|
||||
__u64 last_lba; /* Returned last LBA on the device */
|
||||
__u64 max_xfer; /* Returned max transfer size, blocks */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
struct dk_cxlflash_detach {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context to detach */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
struct dk_cxlflash_udirect {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context to own physical resources */
|
||||
__u64 rsrc_handle; /* Returned resource handle */
|
||||
__u64 last_lba; /* Returned last LBA on the device */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
#define DK_CXLFLASH_UVIRTUAL_NEED_WRITE_SAME 0x8000000000000000ULL
|
||||
|
||||
struct dk_cxlflash_uvirtual {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context to own virtual resources */
|
||||
__u64 lun_size; /* Requested size, in 4K blocks */
|
||||
__u64 rsrc_handle; /* Returned resource handle */
|
||||
__u64 last_lba; /* Returned last LBA of LUN */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
struct dk_cxlflash_release {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context owning resources */
|
||||
__u64 rsrc_handle; /* Resource handle to release */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
struct dk_cxlflash_resize {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context owning resources */
|
||||
__u64 rsrc_handle; /* Resource handle of LUN to resize */
|
||||
__u64 req_size; /* New requested size, in 4K blocks */
|
||||
__u64 last_lba; /* Returned last LBA of LUN */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
struct dk_cxlflash_clone {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id_src; /* Context to clone from */
|
||||
__u64 context_id_dst; /* Context to clone to */
|
||||
__u64 adap_fd_src; /* Source context adapter fd */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
#define DK_CXLFLASH_VERIFY_SENSE_LEN 18
|
||||
#define DK_CXLFLASH_VERIFY_HINT_SENSE 0x8000000000000000ULL
|
||||
|
||||
struct dk_cxlflash_verify {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 context_id; /* Context owning resources to verify */
|
||||
__u64 rsrc_handle; /* Resource handle of LUN */
|
||||
__u64 hint; /* Reasons for verify */
|
||||
__u64 last_lba; /* Returned last LBA of device */
|
||||
__u8 sense_data[DK_CXLFLASH_VERIFY_SENSE_LEN]; /* SCSI sense data */
|
||||
__u8 pad[6]; /* Pad to next 8-byte boundary */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
#define DK_CXLFLASH_RECOVER_AFU_CONTEXT_RESET 0x8000000000000000ULL
|
||||
|
||||
struct dk_cxlflash_recover_afu {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u64 reason; /* Reason for recovery request */
|
||||
__u64 context_id; /* Context to recover / updated ID */
|
||||
__u64 mmio_size; /* Returned size of MMIO area */
|
||||
__u64 adap_fd; /* Returned adapter file descriptor */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
#define DK_CXLFLASH_MANAGE_LUN_WWID_LEN CXLFLASH_WWID_LEN
|
||||
#define DK_CXLFLASH_MANAGE_LUN_ENABLE_SUPERPIPE 0x8000000000000000ULL
|
||||
#define DK_CXLFLASH_MANAGE_LUN_DISABLE_SUPERPIPE 0x4000000000000000ULL
|
||||
#define DK_CXLFLASH_MANAGE_LUN_ALL_PORTS_ACCESSIBLE 0x2000000000000000ULL
|
||||
|
||||
struct dk_cxlflash_manage_lun {
|
||||
struct dk_cxlflash_hdr hdr; /* Common fields */
|
||||
__u8 wwid[DK_CXLFLASH_MANAGE_LUN_WWID_LEN]; /* Page83 WWID, NAA-6 */
|
||||
__u64 reserved[8]; /* Rsvd, future use */
|
||||
};
|
||||
|
||||
union cxlflash_ioctls {
|
||||
struct dk_cxlflash_attach attach;
|
||||
struct dk_cxlflash_detach detach;
|
||||
struct dk_cxlflash_udirect udirect;
|
||||
struct dk_cxlflash_uvirtual uvirtual;
|
||||
struct dk_cxlflash_release release;
|
||||
struct dk_cxlflash_resize resize;
|
||||
struct dk_cxlflash_clone clone;
|
||||
struct dk_cxlflash_verify verify;
|
||||
struct dk_cxlflash_recover_afu recover_afu;
|
||||
struct dk_cxlflash_manage_lun manage_lun;
|
||||
};
|
||||
|
||||
#define MAX_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ioctls))
|
||||
|
||||
#define CXL_MAGIC 0xCA
|
||||
#define CXL_IOWR(_n, _s) _IOWR(CXL_MAGIC, _n, struct _s)
|
||||
|
||||
/*
|
||||
* CXL Flash superpipe ioctls start at base of the reserved CXL_MAGIC
|
||||
* region (0x80) and grow upwards.
|
||||
*/
|
||||
#define DK_CXLFLASH_ATTACH CXL_IOWR(0x80, dk_cxlflash_attach)
|
||||
#define DK_CXLFLASH_USER_DIRECT CXL_IOWR(0x81, dk_cxlflash_udirect)
|
||||
#define DK_CXLFLASH_RELEASE CXL_IOWR(0x82, dk_cxlflash_release)
|
||||
#define DK_CXLFLASH_DETACH CXL_IOWR(0x83, dk_cxlflash_detach)
|
||||
#define DK_CXLFLASH_VERIFY CXL_IOWR(0x84, dk_cxlflash_verify)
|
||||
#define DK_CXLFLASH_RECOVER_AFU CXL_IOWR(0x85, dk_cxlflash_recover_afu)
|
||||
#define DK_CXLFLASH_MANAGE_LUN CXL_IOWR(0x86, dk_cxlflash_manage_lun)
|
||||
#define DK_CXLFLASH_USER_VIRTUAL CXL_IOWR(0x87, dk_cxlflash_uvirtual)
|
||||
#define DK_CXLFLASH_VLUN_RESIZE CXL_IOWR(0x88, dk_cxlflash_resize)
|
||||
#define DK_CXLFLASH_VLUN_CLONE CXL_IOWR(0x89, dk_cxlflash_clone)
|
||||
|
||||
/*
|
||||
* Structure and flag definitions CXL Flash host ioctls
|
||||
*/
|
||||
|
||||
#define HT_CXLFLASH_VERSION_0 0
|
||||
|
||||
struct ht_cxlflash_hdr {
|
||||
__u16 version; /* Version data */
|
||||
__u16 subcmd; /* Sub-command */
|
||||
__u16 rsvd[2]; /* Reserved for future use */
|
||||
__u64 flags; /* Input flags */
|
||||
__u64 return_flags; /* Returned flags */
|
||||
};
|
||||
|
||||
/*
|
||||
* Input flag definitions available to all host ioctls
|
||||
*
|
||||
* These are grown from the bottom-up with the intention that ioctl-specific
|
||||
* input flag definitions would grow from the top-down, allowing the two sets
|
||||
* to co-exist. While not required/enforced at this time, this provides future
|
||||
* flexibility.
|
||||
*/
|
||||
#define HT_CXLFLASH_HOST_READ 0x0000000000000000ULL
|
||||
#define HT_CXLFLASH_HOST_WRITE 0x0000000000000001ULL
|
||||
|
||||
#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_CREATE_LUN 0x0001
|
||||
#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_DELETE_LUN 0x0002
|
||||
#define HT_CXLFLASH_LUN_PROVISION_SUBCMD_QUERY_PORT 0x0003
|
||||
|
||||
struct ht_cxlflash_lun_provision {
|
||||
struct ht_cxlflash_hdr hdr; /* Common fields */
|
||||
__u16 port; /* Target port for provision request */
|
||||
__u16 reserved16[3]; /* Reserved for future use */
|
||||
__u64 size; /* Size of LUN (4K blocks) */
|
||||
__u64 lun_id; /* SCSI LUN ID */
|
||||
__u8 wwid[CXLFLASH_WWID_LEN];/* Page83 WWID, NAA-6 */
|
||||
__u64 max_num_luns; /* Maximum number of LUNs provisioned */
|
||||
__u64 cur_num_luns; /* Current number of LUNs provisioned */
|
||||
__u64 max_cap_port; /* Total capacity for port (4K blocks) */
|
||||
__u64 cur_cap_port; /* Current capacity for port (4K blocks) */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
#define HT_CXLFLASH_AFU_DEBUG_MAX_DATA_LEN 262144 /* 256K */
|
||||
#define HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN 12
|
||||
struct ht_cxlflash_afu_debug {
|
||||
struct ht_cxlflash_hdr hdr; /* Common fields */
|
||||
__u8 reserved8[4]; /* Reserved for future use */
|
||||
__u8 afu_subcmd[HT_CXLFLASH_AFU_DEBUG_SUBCMD_LEN]; /* AFU subcommand,
|
||||
* (pass through)
|
||||
*/
|
||||
__u64 data_ea; /* Data buffer effective address */
|
||||
__u32 data_len; /* Data buffer length */
|
||||
__u32 reserved32; /* Reserved for future use */
|
||||
__u64 reserved[8]; /* Reserved for future use */
|
||||
};
|
||||
|
||||
union cxlflash_ht_ioctls {
|
||||
struct ht_cxlflash_lun_provision lun_provision;
|
||||
struct ht_cxlflash_afu_debug afu_debug;
|
||||
};
|
||||
|
||||
#define MAX_HT_CXLFLASH_IOCTL_SZ (sizeof(union cxlflash_ht_ioctls))
|
||||
|
||||
/*
|
||||
* CXL Flash host ioctls start at the top of the reserved CXL_MAGIC
|
||||
* region (0xBF) and grow downwards.
|
||||
*/
|
||||
#define HT_CXLFLASH_LUN_PROVISION CXL_IOWR(0xBF, ht_cxlflash_lun_provision)
|
||||
#define HT_CXLFLASH_AFU_DEBUG CXL_IOWR(0xBE, ht_cxlflash_afu_debug)
|
||||
|
||||
|
||||
#endif /* ifndef _CXLFLASH_IOCTL_H */
|
@ -26,13 +26,12 @@ static const char *const known_fs[] = {
|
||||
"hfsplus", "hostfs", "hpfs", "hugetlbfs", "ibmasmfs", "iomem",
|
||||
"ipathfs", "iso9660", "jffs2", "jfs", "minix", "mqueue", "msdos",
|
||||
"nfs", "nfs4", "nfsd", "nilfs2", "nsfs", "ntfs", "ntfs3", "ocfs2",
|
||||
"ocfs2_dlmfs", "ocxlflash", "omfs", "openpromfs", "overlay", "pipefs",
|
||||
"proc", "pstore", "pvfs2", "qnx4", "qnx6", "ramfs",
|
||||
"resctrl", "romfs", "rootfs", "rpc_pipefs", "s390_hypfs", "secretmem",
|
||||
"securityfs", "selinuxfs", "smackfs", "smb3", "sockfs", "spufs",
|
||||
"squashfs", "sysfs", "sysv", "tmpfs", "tracefs", "ubifs", "udf",
|
||||
"ufs", "v7", "vboxsf", "vfat", "virtiofs", "vxfs", "xenfs", "xfs",
|
||||
"zonefs", NULL };
|
||||
"ocfs2_dlmfs", "omfs", "openpromfs", "overlay", "pipefs", "proc",
|
||||
"pstore", "pvfs2", "qnx4", "qnx6", "ramfs", "resctrl", "romfs",
|
||||
"rootfs", "rpc_pipefs", "s390_hypfs", "secretmem", "securityfs",
|
||||
"selinuxfs", "smackfs", "smb3", "sockfs", "spufs", "squashfs", "sysfs",
|
||||
"sysv", "tmpfs", "tracefs", "ubifs", "udf", "ufs", "v7", "vboxsf",
|
||||
"vfat", "virtiofs", "vxfs", "xenfs", "xfs", "zonefs", NULL };
|
||||
|
||||
static struct statmount *statmount_alloc(uint64_t mnt_id, uint64_t mask, unsigned int flags)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user