in host/tcp.c [649:697]
static int nvme_tcp_recv_pdu(struct nvme_tcp_queue *queue, struct sk_buff *skb,
unsigned int *offset, size_t *len)
{
struct nvme_tcp_hdr *hdr;
char *pdu = queue->pdu;
size_t rcv_len = min_t(size_t, *len, queue->pdu_remaining);
int ret;
ret = skb_copy_bits(skb, *offset,
&pdu[queue->pdu_offset], rcv_len);
if (unlikely(ret))
return ret;
queue->pdu_remaining -= rcv_len;
queue->pdu_offset += rcv_len;
*offset += rcv_len;
*len -= rcv_len;
if (queue->pdu_remaining)
return 0;
hdr = queue->pdu;
if (queue->hdr_digest) {
ret = nvme_tcp_verify_hdgst(queue, queue->pdu, hdr->hlen);
if (unlikely(ret))
return ret;
}
if (queue->data_digest) {
ret = nvme_tcp_check_ddgst(queue, queue->pdu);
if (unlikely(ret))
return ret;
}
switch (hdr->type) {
case nvme_tcp_c2h_data:
return nvme_tcp_handle_c2h_data(queue, (void *)queue->pdu);
case nvme_tcp_rsp:
nvme_tcp_init_recv_ctx(queue);
return nvme_tcp_handle_comp(queue, (void *)queue->pdu);
case nvme_tcp_r2t:
nvme_tcp_init_recv_ctx(queue);
return nvme_tcp_handle_r2t(queue, (void *)queue->pdu);
default:
dev_err(queue->ctrl->ctrl.device,
"unsupported pdu type (%d)\n", hdr->type);
return -EINVAL;
}
}