On Wed, 21 Feb 2024 10:16:00 -0800 nifan....@gmail.com wrote: > From: Fan Ni <fan...@samsung.com> > > Add dynamic capacity extent list representative to the definition of > CXLType3Dev and add get DC extent list mailbox command per > CXL.spec.3.1:.8.2.9.9.9.2. > > Signed-off-by: Fan Ni <fan...@samsung.com> Follow on from earlier comment on my preference for anonymous structure types when we only use them in one place.
> +/* > + * CXL r3.1 section 8.2.9.9.9.2: > + * Get Dynamic Capacity Extent List (Opcode 4801h) > + */ > +static CXLRetCode cmd_dcd_get_dyn_cap_ext_list(const struct cxl_cmd *cmd, > + uint8_t *payload_in, > + size_t len_in, > + uint8_t *payload_out, > + size_t *len_out, > + CXLCCI *cci) > +{ > + CXLType3Dev *ct3d = CXL_TYPE3(cci->d); > + struct get_dyn_cap_ext_list_in_pl { > + uint32_t extent_cnt; > + uint32_t start_extent_id; > + } QEMU_PACKED; > + > + struct get_dyn_cap_ext_list_out_pl { > + uint32_t count; > + uint32_t total_extents; > + uint32_t generation_num; > + uint8_t rsvd[4]; > + CXLDCExtentRaw records[]; > + } QEMU_PACKED; > + > + struct get_dyn_cap_ext_list_in_pl *in = (void *)payload_in; > + struct get_dyn_cap_ext_list_out_pl *out = (void *)payload_out; As for earlier patches, I think anonymous struct types are fine for these and lead to shorter code. > + uint16_t record_count = 0, i = 0, record_done = 0; > + CXLDCExtentList *extent_list = &ct3d->dc.extents; > + CXLDCExtent *ent; > + uint16_t out_pl_len; > + uint32_t start_extent_id = in->start_extent_id; > + > + if (start_extent_id > ct3d->dc.total_extent_count) { > + return CXL_MBOX_INVALID_INPUT; > + } > + > + record_count = MIN(in->extent_cnt, > + ct3d->dc.total_extent_count - start_extent_id); > + > + out_pl_len = sizeof(*out) + record_count * sizeof(out->records[0]); > + assert(out_pl_len <= CXL_MAILBOX_MAX_PAYLOAD_SIZE); > + > + stl_le_p(&out->count, record_count); > + stl_le_p(&out->total_extents, ct3d->dc.total_extent_count); > + stl_le_p(&out->generation_num, ct3d->dc.ext_list_gen_seq); > + > + if (record_count > 0) { > + QTAILQ_FOREACH(ent, extent_list, node) { > + if (i++ < start_extent_id) { > + continue; > + } > + stq_le_p(&out->records[record_done].start_dpa, ent->start_dpa); > + stq_le_p(&out->records[record_done].len, ent->len); > + memcpy(&out->records[record_done].tag, ent->tag, 0x10); > + stw_le_p(&out->records[record_done].shared_seq, ent->shared_seq); > + record_done++; > + if (record_done == record_count) { > + break; > + } > + } > + } > + > + *len_out = out_pl_len; > + return CXL_MBOX_SUCCESS; > +} > +