1*e73bd0a1SAndrew Jeffery #pragma once 2*e73bd0a1SAndrew Jeffery 3*e73bd0a1SAndrew Jeffery #include "NVMeContext.hpp" 4*e73bd0a1SAndrew Jeffery 5*e73bd0a1SAndrew Jeffery #include <boost/asio/io_service.hpp> 6*e73bd0a1SAndrew Jeffery #include <boost/asio/posix/stream_descriptor.hpp> 7*e73bd0a1SAndrew Jeffery 8*e73bd0a1SAndrew Jeffery #include <thread> 9*e73bd0a1SAndrew Jeffery 10*e73bd0a1SAndrew Jeffery class NVMeBasicContext : public NVMeContext 11*e73bd0a1SAndrew Jeffery { 12*e73bd0a1SAndrew Jeffery public: 13*e73bd0a1SAndrew Jeffery NVMeBasicContext(boost::asio::io_service& io, int rootBus); 14*e73bd0a1SAndrew Jeffery ~NVMeBasicContext() override = default; 15*e73bd0a1SAndrew Jeffery void pollNVMeDevices() override; 16*e73bd0a1SAndrew Jeffery void readAndProcessNVMeSensor() override; 17*e73bd0a1SAndrew Jeffery void processResponse(std::shared_ptr<NVMeSensor>& sensor, void* msg, 18*e73bd0a1SAndrew Jeffery size_t len) override; 19*e73bd0a1SAndrew Jeffery 20*e73bd0a1SAndrew Jeffery private: 21*e73bd0a1SAndrew Jeffery NVMeBasicContext(boost::asio::io_service& io, int rootBus, int cmdOut, 22*e73bd0a1SAndrew Jeffery int streamIn, int streamOut, int cmdIn); 23*e73bd0a1SAndrew Jeffery boost::asio::io_service& io; 24*e73bd0a1SAndrew Jeffery 25*e73bd0a1SAndrew Jeffery // The IO thread must be destructed after the stream descriptors, so 26*e73bd0a1SAndrew Jeffery // initialise it first. http://eel.is/c++draft/class.base.init#note-6 27*e73bd0a1SAndrew Jeffery // 28*e73bd0a1SAndrew Jeffery // Providing a stop-source to the thread execution function isn't 29*e73bd0a1SAndrew Jeffery // particularly useful as it will spend most of its time blocked in a system 30*e73bd0a1SAndrew Jeffery // call - ioctl() for the actual device communication, or read() and write() 31*e73bd0a1SAndrew Jeffery // on the pipes associated with reqStream and respStream. Rather than trying 32*e73bd0a1SAndrew Jeffery // to force a stop, rely on read()/write() failures from closed pipes to 33*e73bd0a1SAndrew Jeffery // coerce it to exit and thus allow completion of the join(). 34*e73bd0a1SAndrew Jeffery std::jthread thread; 35*e73bd0a1SAndrew Jeffery 36*e73bd0a1SAndrew Jeffery // Destruction of the stream descriptors has the effect of issuing cancel(), 37*e73bd0a1SAndrew Jeffery // destroying the closure of the callback where we might be carrying 38*e73bd0a1SAndrew Jeffery // weak_ptrs to `this`. 39*e73bd0a1SAndrew Jeffery // https://www.boost.org/doc/libs/1_79_0/doc/html/boost_asio/reference/posix__basic_descriptor/_basic_descriptor.html 40*e73bd0a1SAndrew Jeffery boost::asio::posix::stream_descriptor reqStream; 41*e73bd0a1SAndrew Jeffery boost::asio::posix::stream_descriptor respStream; 42*e73bd0a1SAndrew Jeffery 43*e73bd0a1SAndrew Jeffery enum 44*e73bd0a1SAndrew Jeffery { 45*e73bd0a1SAndrew Jeffery NVME_MI_BASIC_SFLGS_DRIVE_NOT_READY = 0x40, 46*e73bd0a1SAndrew Jeffery NVME_MI_BASIC_SFLGS_DRIVE_FUNCTIONAL = 0x20, 47*e73bd0a1SAndrew Jeffery }; 48*e73bd0a1SAndrew Jeffery }; 49