]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/VirtioFsDxe/FuseInit.c
OvmfPkg: Apply uncrustify changes
[mirror_edk2.git] / OvmfPkg / VirtioFsDxe / FuseInit.c
CommitLineData
fa97e372
LE
1/** @file\r
2 FUSE_INIT wrapper for the Virtio Filesystem device.\r
3\r
4 Copyright (C) 2020, Red Hat, Inc.\r
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7**/\r
8\r
9#include "VirtioFsDxe.h"\r
10\r
11/**\r
12 Send a FUSE_INIT request to the Virtio Filesystem device, for starting the\r
13 FUSE session.\r
14\r
15 From virtio-v1.1-cs01-87fa6b5d8155, 5.11.5 Device Initialization: "On\r
16 initialization the driver first discovers the device's virtqueues. The FUSE\r
17 session is started by sending a FUSE_INIT request as defined by the FUSE\r
18 protocol on one request virtqueue."\r
19\r
20 The function may only be called after VirtioFsInit() returns successfully and\r
21 before VirtioFsUninit() is called.\r
22\r
23 @param[in,out] VirtioFs The Virtio Filesystem device to send the FUSE_INIT\r
24 request to. The FUSE request counter\r
6f7bc719
LE
25 "VirtioFs->RequestId" is set to 1 on output. The\r
26 maximum write buffer size exposed in the FUSE_INIT\r
27 response is saved in "VirtioFs->MaxWrite", on\r
28 output.\r
fa97e372
LE
29\r
30 @retval EFI_SUCCESS The FUSE session has been started.\r
31\r
d98d7e30
LE
32 @retval EFI_UNSUPPORTED FUSE interface version or feature negotiation\r
33 failed.\r
fa97e372
LE
34\r
35 @return The "errno" value mapped to an EFI_STATUS code, if\r
36 the Virtio Filesystem device explicitly reported an\r
37 error.\r
38\r
39 @return Error codes propagated from\r
40 VirtioFsSgListsValidate(), VirtioFsFuseNewRequest(),\r
41 VirtioFsSgListsSubmit(),\r
42 VirtioFsFuseCheckResponse().\r
43**/\r
44EFI_STATUS\r
45VirtioFsFuseInitSession (\r
ac0a286f 46 IN OUT VIRTIO_FS *VirtioFs\r
fa97e372
LE
47 )\r
48{\r
ac0a286f
MK
49 VIRTIO_FS_FUSE_REQUEST CommonReq;\r
50 VIRTIO_FS_FUSE_INIT_REQUEST InitReq;\r
51 VIRTIO_FS_IO_VECTOR ReqIoVec[2];\r
52 VIRTIO_FS_SCATTER_GATHER_LIST ReqSgList;\r
53 VIRTIO_FS_FUSE_RESPONSE CommonResp;\r
54 VIRTIO_FS_FUSE_INIT_RESPONSE InitResp;\r
55 VIRTIO_FS_IO_VECTOR RespIoVec[2];\r
56 VIRTIO_FS_SCATTER_GATHER_LIST RespSgList;\r
57 EFI_STATUS Status;\r
fa97e372
LE
58\r
59 //\r
60 // Initialize the FUSE request counter.\r
61 //\r
62 VirtioFs->RequestId = 1;\r
63\r
64 //\r
65 // Set up the scatter-gather lists.\r
66 //\r
67 ReqIoVec[0].Buffer = &CommonReq;\r
68 ReqIoVec[0].Size = sizeof CommonReq;\r
69 ReqIoVec[1].Buffer = &InitReq;\r
70 ReqIoVec[1].Size = sizeof InitReq;\r
71 ReqSgList.IoVec = ReqIoVec;\r
72 ReqSgList.NumVec = ARRAY_SIZE (ReqIoVec);\r
73\r
74 RespIoVec[0].Buffer = &CommonResp;\r
75 RespIoVec[0].Size = sizeof CommonResp;\r
76 RespIoVec[1].Buffer = &InitResp;\r
77 RespIoVec[1].Size = sizeof InitResp;\r
78 RespSgList.IoVec = RespIoVec;\r
79 RespSgList.NumVec = ARRAY_SIZE (RespIoVec);\r
80\r
81 //\r
82 // Validate the scatter-gather lists; calculate the total transfer sizes.\r
83 //\r
84 Status = VirtioFsSgListsValidate (VirtioFs, &ReqSgList, &RespSgList);\r
85 if (EFI_ERROR (Status)) {\r
86 return Status;\r
87 }\r
88\r
89 //\r
90 // Populate the common request header.\r
91 //\r
ac0a286f
MK
92 Status = VirtioFsFuseNewRequest (\r
93 VirtioFs,\r
94 &CommonReq,\r
95 ReqSgList.TotalSize,\r
96 VirtioFsFuseOpInit,\r
97 0\r
98 );\r
fa97e372
LE
99 if (EFI_ERROR (Status)) {\r
100 return Status;\r
101 }\r
102\r
103 //\r
104 // Populate the FUSE_INIT-specific fields.\r
105 //\r
106 InitReq.Major = VIRTIO_FS_FUSE_MAJOR;\r
107 InitReq.Minor = VIRTIO_FS_FUSE_MINOR;\r
108 InitReq.MaxReadahead = 0;\r
d98d7e30 109 InitReq.Flags = VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS;\r
fa97e372
LE
110\r
111 //\r
112 // Submit the request.\r
113 //\r
114 Status = VirtioFsSgListsSubmit (VirtioFs, &ReqSgList, &RespSgList);\r
115 if (EFI_ERROR (Status)) {\r
116 return Status;\r
117 }\r
118\r
119 //\r
120 // Verify the response (all response buffers are fixed size).\r
121 //\r
122 Status = VirtioFsFuseCheckResponse (&RespSgList, CommonReq.Unique, NULL);\r
123 if (EFI_ERROR (Status)) {\r
124 if (Status == EFI_DEVICE_ERROR) {\r
ac0a286f
MK
125 DEBUG ((\r
126 DEBUG_ERROR,\r
127 "%a: Label=\"%s\" Errno=%d\n",\r
128 __FUNCTION__,\r
129 VirtioFs->Label,\r
130 CommonResp.Error\r
131 ));\r
fa97e372
LE
132 Status = VirtioFsErrnoToEfiStatus (CommonResp.Error);\r
133 }\r
ac0a286f 134\r
fa97e372
LE
135 return Status;\r
136 }\r
137\r
138 //\r
d98d7e30 139 // Check FUSE interface version / feature compatibility.\r
fa97e372 140 //\r
ac0a286f
MK
141 if ((InitResp.Major < InitReq.Major) ||\r
142 ((InitResp.Major == InitReq.Major) && (InitResp.Minor < InitReq.Minor)) ||\r
143 ((InitResp.Flags & VIRTIO_FS_FUSE_INIT_REQ_F_DO_READDIRPLUS) == 0) ||\r
144 (InitResp.MaxWrite < SIZE_4KB))\r
145 {\r
fa97e372
LE
146 return EFI_UNSUPPORTED;\r
147 }\r
148\r
6f7bc719
LE
149 //\r
150 // Save the maximum write buffer size for FUSE_WRITE requests.\r
151 //\r
152 VirtioFs->MaxWrite = InitResp.MaxWrite;\r
fa97e372
LE
153 return EFI_SUCCESS;\r
154}\r