-hba_alloc_slot(struct hba_port* port,
- struct hba_cmdt** cmdt,
- struct hba_cmdh** cmdh,
- uint16_t header_options)
+hba_bind_sbuf(struct hba_cmdh* cmdh, struct hba_cmdt* cmdt, struct membuf mbuf)
+{
+ assert_msg(mbuf.size <= 0x400000U, "HBA: Buffer too big");
+ cmdh->prdt_len = 1;
+ cmdt->entries[0] =
+ (struct hba_prdte){ .data_base = vmm_v2p((ptr_t)mbuf.buffer),
+ .byte_count = mbuf.size - 1 };
+
+ return 0;
+}
+
+int
+hba_bind_vbuf(struct hba_cmdh* cmdh, struct hba_cmdt* cmdt, struct vecbuf* vbuf)
+{
+ size_t i = 0;
+ struct vecbuf* pos = vbuf;
+
+ do {
+ assert_msg(i < HBA_MAX_PRDTE, "HBA: Too many PRDTEs");
+ assert_msg(pos->buf.size <= 0x400000U, "HBA: Buffer too big");
+ assert_msg(pos->buf.size, "HBA: expect a non-zero buffer size");
+
+ cmdt->entries[i++] =
+ (struct hba_prdte){ .data_base = vmm_v2p((ptr_t)pos->buf.buffer),
+ .byte_count = pos->buf.size - 1 };
+ pos = list_entry(pos->components.next, struct vecbuf, components);
+ } while (pos != vbuf);
+
+ cmdh->prdt_len = i + 1;
+
+ return 0;
+}
+
+int
+hba_prepare_cmd(struct hba_port* port,
+ struct hba_cmdt** cmdt,
+ struct hba_cmdh** cmdh)