This is a specific case for NVMe where given data buffer pointers must
be dword (4 bytes) aligned.
There is no virtual memory management between the user thread and NVMe
driver (which one could detect such wrong alignement on physical memory
and thus reallocate the memory properly, so it would be fully
transparent for the user thread), thus the need to push that check to
the user.
This has been going under the radar so far as Qemu does not seem to
follow NVMe specifications where PRP1 (in DPTR) must always be
dword-aligned. It really does not follow the rule: specifications
details that if bits 1:0 of PRP1 are set, the controller may generate
an error or treat the address as if these bits were unset. Seems like
a bug in Qemu, I did not check the code there however.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Former way was difficult to read, so let's have a better way which
easily follows the specifications.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
This will provide a detailed error status report.
As for most of the original code of the driver, this is a backport of
the work done by Jim Harris in FreeBSD.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Fix few mismatched CONTAINER_OF, one missing k_work_delayable_from_work
conversion and few cases where the target should be pointing at the
first element explicitly.
Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
This is currently the only end-point where multiple threads can access
the NVMe device (all calls are synchronous).
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Pre-allocating PRP list for such purpose. Which PRP list is relevantly
filled in depending on the data size and data pointer page alignment.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Based on FreeBSD's implementation made by James Harris, Intel Copyright
2012-2016.
Namespace in this context, will be a disk. It's not exposed from DTS, as
an actualy NVMe hardware controller card can bring more than one
namespace (disk).
Thus namespace are not instanciated through the device driver model, but
statically allocated and runtime configured, depending on what the
controller exposes.
By default the amount of namespace supported is one as it is the most
common setup.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Based on FreeBSD's implementation made by James Harris, Intel Copyright
2012-2016.
This is the corner stone of the whole NVMe logic: sending commands and
getting replies, all through memory shared from the host to the
controller.
Then using it to inialize admit/IO queues and identifying the
controller.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
Based on FreeBSD's implementation made by James Harris, Intel Copyright
2012-2016.
Since Zephyr does not propose any advanced interfaces as FreeBSD (bus
abstractions, memory and DMA abstraction and many more), this comes with
a much simplified and Zephyr-ish way to instanciate, initialize and use
NVMe controller.
ToDo: IO Queues cannot be more than 1. Macros will need to be improved to
manage the case of 2+ IO queues.
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>