10#include <l4/cxx/ref_ptr>
12#include <l4/libblock-device/device.h>
13#include <l4/libblock-device/partition.h>
19namespace Block_device {
27 template <
typename PART_DEV,
typename BASE_DEV,
28 bool = std::is_base_of<Device_discard_feature, BASE_DEV>::value>
37 template <
typename PART_DEV,
typename BASE_DEV>
41 using Base = BASE_DEV;
42 using Part_device = PART_DEV;
45 typename Base::Discard_info discard_info()
const override
47 return dev()->parent()->discard_info();
51 Inout_callback
const &cb,
bool discard)
override
53 auto sz = dev()->partition_size();
61 if (cur->
sector >= sz - offset)
63 if (cur->num_sectors > sz)
65 if (offset + cur->
sector > sz - cur->num_sectors)
68 cur = cur->next.get();
71 auto start = offset + dev()->partition_start();
72 Dbg::trace(
"partition")
73 .printf(
"Starting sector on disk: 0x%llx\n", start);
74 return dev()->parent()->discard(start, blocks, cb, discard);
78 Part_device
const *dev()
const
79 {
return static_cast<Part_device
const *
>(
this); }
91template <
typename BASE_DEV = Device>
96 using Device_type = BASE_DEV;
107 "Last sector of partition before first sector.");
109 if (partition_id > 999)
111 "Partition ID must be smaller than 1000.");
113 snprintf(_partition_id,
sizeof(_partition_id),
"%d", partition_id);
115 static_assert(
sizeof(_guid) ==
sizeof(pi.
guid),
"String size mismatch");
116 memcpy(_guid, pi.
guid,
sizeof(_guid));
120 {
return _parent->notification_domain(); }
122 bool is_read_only()
const override
123 {
return _parent->is_read_only(); }
125 bool match_hid(
cxx::String const &hid)
const override
130 std::u16string whid =
131 std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,
char16_t>{}
132 .from_bytes(std::string(hid.
start(), hid.
len()));
137 char const *delim =
":";
138 char const *pos = hid.
rfind(delim);
147 {
return _size * _parent->sector_size(); }
150 {
return _parent->sector_size(); }
153 {
return _parent->max_size(); }
155 unsigned max_segments()
const override
156 {
return _parent->max_segments(); }
158 void reset()
override
164 {
return _parent->dma_map(region, offset, num_sectors, dir, phys); }
168 {
return _parent->dma_unmap(phys, num_sectors, dir); }
171 Inout_callback
const &cb,
181 total += cur->num_sectors;
182 cur = cur->next.get();
185 if (total > _size - sector)
188 Dbg::trace(
"partition").printf(
"Sector on disk: 0x%llx\n", sector + _start);
189 return _parent->inout_data(sector + _start, blocks, cb, dir);
192 int flush(Inout_callback
const &cb)
override
194 return _parent->flush(cb);
197 void start_device_scan(Block_device::Errand::Callback
const &callback)
override
206 Device_type *parent()
const
207 {
return _parent.
get(); }
212 std::u16string _name;
213 char _partition_id[4];
Dummy class used when the device class is not derived from Device_discard_feature.
A partition device for the given device interface.
l4_uint64_t Dma_addr
Data type for DMA addresses.
Direction
Direction of the DMA transfers.
Region of driver memory, that shall be managed locally.
A reference-counting pointer with automatic cleanup.
T * get() const noexcept)
Return a raw pointer to the object this shared pointer points to.
Allocation free string class with explicit length field.
Index start() const
Pointer to first character.
Index end() const
Pointer to first byte behind the string.
char const * rfind(char const *c) const
Find right-most character. Return end() if not found.
unsigned int l4_size_t
Unsigned size type.
unsigned long l4_addr_t
Address type.
unsigned long long l4_uint64_t
Unsigned 64bit value.
@ L4_EINVAL
Invalid argument.
long chksys(long err, char const *extra="", long ret=0)
Generate C++ exception on error.
Description of an inout block to be sent to the device.
l4_uint64_t sector
Initial sector. Used only by DISCARD / WRITE_ZEROES requests.
Opaque type for representing a notification domain.
Information about a single partition.
char guid[37]
ID of the partition.
l4_uint64_t last
Last valid sector.
l4_uint64_t first
First valid sector.
std::u16string name
UTF16 name of the partition.