• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "scsi_peripheral_api.h"
17 #include <cerrno>
18 #include <iproxy_broker.h>
19 #include <memory.h>
20 #include <mutex>
21 #include <scsi/sg.h>
22 #include <securec.h>
23 #include <string>
24 #include <sys/mman.h>
25 #include <unistd.h>
26 #include <vector>
27 #include <unordered_map>
28 
29 #include "edm_errors.h"
30 #include "hilog_wrapper.h"
31 #include "ipc_error_code.h"
32 #include "scsi_peripheral_types.h"
33 #include "v1_0/scsi_peripheral_ddk_service.h"
34 
35 using namespace OHOS;
36 using namespace OHOS::ExternalDeviceManager;
37 namespace {
38 OHOS::sptr<OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk> g_ddk = nullptr;
39 static OHOS::sptr<IRemoteObject::DeathRecipient> recipient_ = nullptr;
40 std::mutex g_mutex;
41 
42 constexpr uint8_t ONE_BYTE = 1;
43 constexpr uint8_t TWO_BYTE = 2;
44 constexpr uint8_t THREE_BYTE = 3;
45 constexpr uint8_t FOUR_BYTE = 4;
46 constexpr uint8_t FIVE_BYTE = 5;
47 constexpr uint8_t SIX_BYTE = 6;
48 constexpr uint8_t SEVEN_BYTE = 7;
49 constexpr uint8_t EIGHT_BYTE = 8;
50 constexpr uint8_t FIFTEEN_BYTE = 15;
51 constexpr uint8_t EIGHT_BIT = 8;
52 constexpr uint8_t SIXTEEN_BIT = 16;
53 constexpr uint8_t TWENTY_FOUR_BIT = 24;
54 constexpr uint8_t THIRTY_TWO_BIT = 32;
55 constexpr uint8_t FORTY_BIT = 40;
56 constexpr uint8_t FORTY_EIGHT_BIT = 48;
57 constexpr uint8_t FIFTY_SIX_BIT = 56;
58 constexpr uint8_t DESCRIPTOR_TYPE_INFORMATION = 0x00;
59 constexpr uint8_t DESCRIPTOR_TYPE_COMMAND_SPECIFIC_INFORMATION = 0x01;
60 constexpr uint8_t DESCRIPTOR_TYPE_SENSE_KEY_SPECIFIC = 0x02;
61 constexpr uint8_t ADDITIONAL_LENGTH_TEN = 0x0A;
62 constexpr uint8_t ADDITIONAL_LENGTH_SIX = 0x06;
63 constexpr uint8_t VALID_BIT = 0x80;
64 constexpr uint8_t MAST_RESPONSE_CODE = 0x7F;
65 constexpr uint8_t RESPONSE_CODE_70H = 0x70;
66 constexpr uint8_t RESPONSE_CODE_71H = 0x71;
67 constexpr uint8_t RESPONSE_CODE_72H = 0x72;
68 constexpr uint8_t RESPONSE_CODE_73H = 0x73;
69 constexpr uint32_t MASK_SENSE_KEY_SPECIFIC = 0x007FFFFF;
70 } // namespace
71 
72 struct ScsiPeripheral_Device {
73     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralDevice impl;
74     int memMapFd = -1;
75 
ScsiPeripheral_DeviceScsiPeripheral_Device76     ScsiPeripheral_Device()
77     {
78         impl.devFd = -1;
79         impl.memMapFd = -1;
80         impl.lbLength = 0;
81     }
82 } __attribute__ ((aligned(8)));
83 
NewScsiPeripheralDevice()84 ScsiPeripheral_Device *NewScsiPeripheralDevice()
85 {
86     return new ScsiPeripheral_Device;
87 }
88 
DeleteScsiPeripheralDevice(ScsiPeripheral_Device ** dev)89 void DeleteScsiPeripheralDevice(ScsiPeripheral_Device **dev)
90 {
91     if (*dev != nullptr) {
92         delete *dev;
93         *dev = nullptr;
94     }
95 }
96 
SetDdk(OHOS::sptr<OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk> & ddk)97 void SetDdk(OHOS::sptr<OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk> &ddk)
98 {
99     g_ddk = ddk;
100 }
101 
TransToDdkErrCode(int32_t ret)102 static int32_t TransToDdkErrCode(int32_t ret)
103 {
104     if (ret == HDF_SUCCESS) {
105         return SCSIPERIPHERAL_DDK_SUCCESS;
106     }
107     if (ret >= OH_IPC_ERROR_CODE_BASE && ret <= OH_IPC_ERROR_CODE_MAX) {
108         return SCSIPERIPHERAL_DDK_SERVICE_ERROR;
109     }
110     return ret;
111 }
112 
GetUint24(unsigned char * buf,int start)113 static inline uint32_t GetUint24(unsigned char *buf, int start)
114 {
115     return (
116         (static_cast<uint32_t>(buf[start]) << SIXTEEN_BIT) |
117         (static_cast<uint32_t>(buf[start + ONE_BYTE]) << EIGHT_BIT) |
118         (static_cast<uint32_t>(buf[start + TWO_BYTE]))
119     );
120 }
121 
GetUint32(unsigned char * buf,int start)122 static inline uint32_t GetUint32(unsigned char *buf, int start)
123 {
124     return (
125         (static_cast<uint32_t>(buf[start]) << TWENTY_FOUR_BIT) |
126         (static_cast<uint32_t>(buf[start + ONE_BYTE]) << SIXTEEN_BIT) |
127         (static_cast<uint32_t>(buf[start + TWO_BYTE]) << EIGHT_BIT) |
128         (static_cast<uint32_t>(buf[start + THREE_BYTE]))
129     );
130 }
131 
GetUint64(unsigned char * buf,int start)132 static inline uint64_t GetUint64(unsigned char *buf, int start)
133 {
134     return (
135         (static_cast<uint64_t>(buf[start]) << FIFTY_SIX_BIT) |
136         (static_cast<uint64_t>(buf[start + ONE_BYTE]) << FORTY_EIGHT_BIT) |
137         (static_cast<uint64_t>(buf[start + TWO_BYTE]) << FORTY_BIT) |
138         (static_cast<uint64_t>(buf[start + THREE_BYTE]) << THIRTY_TWO_BIT) |
139         (static_cast<uint64_t>(buf[start + FOUR_BYTE]) << TWENTY_FOUR_BIT) |
140         (static_cast<uint64_t>(buf[start + FIVE_BYTE]) << SIXTEEN_BIT) |
141         (static_cast<uint64_t>(buf[start + SIX_BYTE]) << EIGHT_BIT) |
142         (static_cast<uint64_t>(buf[start + SEVEN_BYTE]))
143     );
144 }
145 
CopyDataToArray(const std::vector<uint8_t> & data,char * arr,uint32_t arrLen)146 static bool CopyDataToArray(const std::vector<uint8_t> &data, char *arr, uint32_t arrLen)
147 {
148     if (arr == nullptr || data.size() > arrLen) {
149         return false;
150     }
151 
152     size_t i = 0;
153     while (i < data.size()) {
154         arr[i] = data[i];
155         ++i;
156     }
157     arr[arrLen - 1] = '\0';
158 
159     return true;
160 }
161 
CopyResponse(const OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse & srcResp,ScsiPeripheral_Response * desResp)162 static int32_t CopyResponse(const OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse &srcResp,
163     ScsiPeripheral_Response *desResp)
164 {
165     errno_t err = memcpy_s(desResp->senseData, sizeof(desResp->senseData), srcResp.senseData.data(),
166         srcResp.senseData.size());
167     if (err != EOK) {
168         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "memcpy_s failed, err=%{public}d, srcSize=%{public}zu, desSize=%{public}zu",
169             err, srcResp.senseData.size(), sizeof(desResp->senseData));
170         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
171     }
172 
173     desResp->status = static_cast<ScsiPeripheral_Status>(srcResp.status);
174     desResp->maskedStatus = srcResp.maskedStatus;
175     desResp->msgStatus = srcResp.msgStatus;
176     desResp->sbLenWr = srcResp.sbLenWr;
177     desResp->hostStatus = srcResp.hostStatus;
178     desResp->driverStatus = srcResp.driverStatus;
179     desResp->resId = srcResp.resId;
180     desResp->duration = srcResp.duration;
181 
182     return SCSIPERIPHERAL_DDK_SUCCESS;
183 }
184 
ToHdi(ScsiPeripheral_IORequest * request,OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralIORequest & hdiRequest)185 static void ToHdi(ScsiPeripheral_IORequest *request, OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralIORequest &hdiRequest)
186 {
187     hdiRequest.lbAddress = request->lbAddress;
188     hdiRequest.transferLength = request->transferLength;
189     hdiRequest.control = request->control;
190     hdiRequest.byte1 = request->byte1;
191     hdiRequest.byte6 = request->byte6;
192     hdiRequest.memMapSize = request->data->size;
193     hdiRequest.timeout = request->timeout;
194 }
195 
ParseDescriptorFormatSense(uint8_t * senseData,uint8_t senseDataLen,ScsiPeripheral_BasicSenseInfo * senseInfo)196 static int32_t ParseDescriptorFormatSense(uint8_t *senseData, uint8_t senseDataLen,
197     ScsiPeripheral_BasicSenseInfo *senseInfo)
198 {
199     if (senseDataLen < SCSIPERIPHERAL_MIN_DESCRIPTOR_FORMAT_SENSE) {
200         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "sense data len is invalid");
201         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
202     }
203 
204     uint8_t additionalSenseLen = senseData[EIGHT_BYTE - 1];
205     if (senseDataLen > additionalSenseLen + EIGHT_BYTE) {
206         senseDataLen = additionalSenseLen + EIGHT_BYTE;
207     }
208 
209     uint8_t idx;
210     uint8_t descLen;
211 
212     for (idx = EIGHT_BYTE; idx < senseDataLen; idx += descLen + TWO_BYTE) {
213         uint8_t descType = senseData[idx];
214         descLen = senseData[idx + 1];
215 
216         if (idx + descLen + TWO_BYTE > senseDataLen) {
217             break;
218         }
219 
220         switch (descType) {
221             case DESCRIPTOR_TYPE_INFORMATION:
222                 if (descLen == ADDITIONAL_LENGTH_TEN) {
223                     senseInfo->valid = senseData[idx + TWO_BYTE] & VALID_BIT;
224                     senseInfo->information = GetUint64(senseData, idx + FOUR_BYTE);
225                 }
226                 break;
227             case DESCRIPTOR_TYPE_COMMAND_SPECIFIC_INFORMATION:
228                 if (descLen == ADDITIONAL_LENGTH_TEN) {
229                     senseInfo->commandSpecific = GetUint64(senseData, idx + FOUR_BYTE);
230                 }
231                 break;
232             case DESCRIPTOR_TYPE_SENSE_KEY_SPECIFIC:
233                 if (descLen == ADDITIONAL_LENGTH_SIX) {
234                     senseInfo->sksv = senseData[idx + FOUR_BYTE] & VALID_BIT;
235                     senseInfo->senseKeySpecific = GetUint24(senseData, idx + FOUR_BYTE) & MASK_SENSE_KEY_SPECIFIC;
236                 }
237                 break;
238             default:
239                 break;
240         }
241     }
242 
243     return SCSIPERIPHERAL_DDK_SUCCESS;
244 }
245 
ParseFixedFormatSense(uint8_t * senseData,uint8_t senseDataLen,ScsiPeripheral_BasicSenseInfo * senseInfo)246 static int32_t ParseFixedFormatSense(uint8_t *senseData, uint8_t senseDataLen, ScsiPeripheral_BasicSenseInfo *senseInfo)
247 {
248     if (senseDataLen < SCSIPERIPHERAL_MIN_FIXED_FORMAT_SENSE) {
249         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "sense data len is invalid");
250         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
251     }
252 
253     senseInfo->valid = senseData[0] & VALID_BIT;
254 
255     if (senseInfo->valid) {
256         senseInfo->information = GetUint32(senseData, THREE_BYTE);
257     }
258     senseInfo->commandSpecific = GetUint32(senseData, EIGHT_BYTE);
259     senseInfo->sksv = senseData[FIFTEEN_BYTE] & VALID_BIT;
260     senseInfo->senseKeySpecific = GetUint24(senseData, FIFTEEN_BYTE) & MASK_SENSE_KEY_SPECIFIC;
261 
262     return SCSIPERIPHERAL_DDK_SUCCESS;
263 }
264 
265 class ScsiPeripheralDeathRecipient : public IRemoteObject::DeathRecipient {
266 public:
267     void OnRemoteDied(const wptr<IRemoteObject> &object) override;
268 };
269 
OnRemoteDied(const wptr<IRemoteObject> & object)270 void ScsiPeripheralDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
271 {
272     std::lock_guard<std::mutex> lock(g_mutex);
273     EDM_LOGI(MODULE_SCSIPERIPHERAL_DDK, "scsi_ddk remote died");
274     if (g_ddk == nullptr) {
275         return;
276     }
277     auto remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk>(g_ddk);
278     remote->RemoveDeathRecipient(recipient_);
279     recipient_.clear();
280     g_ddk = nullptr;
281     EDM_LOGI(MODULE_SCSIPERIPHERAL_DDK, "remove death recipient success");
282 }
283 
OH_ScsiPeripheral_Init(void)284 int32_t OH_ScsiPeripheral_Init(void)
285 {
286     auto ddk = OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk::Get();
287     SetDdk(ddk);
288     if (g_ddk == nullptr) {
289         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "get ddk failed");
290         return SCSIPERIPHERAL_DDK_INIT_ERROR;
291     }
292     recipient_ = new ScsiPeripheralDeathRecipient();
293     sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Usb::ScsiDdk::V1_0::IScsiPeripheralDdk>(g_ddk);
294     if (!remote->AddDeathRecipient(recipient_)) {
295         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "add DeathRecipient failed");
296         return SCSIPERIPHERAL_DDK_INIT_ERROR;
297     }
298     return TransToDdkErrCode(g_ddk->Init());
299 }
300 
OH_ScsiPeripheral_Release(void)301 int32_t OH_ScsiPeripheral_Release(void)
302 {
303     if (g_ddk == nullptr) {
304         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "ddk is null");
305         return SCSIPERIPHERAL_DDK_INIT_ERROR;
306     }
307     int32_t ret = g_ddk->Release();
308     g_ddk.clear();
309 
310     return TransToDdkErrCode(ret);
311 }
312 
OH_ScsiPeripheral_Open(uint64_t deviceId,uint8_t interfaceIndex,ScsiPeripheral_Device ** dev)313 int32_t OH_ScsiPeripheral_Open(uint64_t deviceId, uint8_t interfaceIndex, ScsiPeripheral_Device **dev)
314 {
315     if (g_ddk == nullptr) {
316         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
317         return SCSIPERIPHERAL_DDK_INIT_ERROR;
318     }
319     if (dev == nullptr) {
320         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
321         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
322     }
323 
324     *dev = NewScsiPeripheralDevice();
325     if (*dev == nullptr) {
326         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK,  "malloc failed, errno=%{public}d", errno);
327         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
328     }
329 
330     return TransToDdkErrCode(g_ddk->Open(deviceId, interfaceIndex, (*dev)->impl, (*dev)->memMapFd));
331 }
332 
OH_ScsiPeripheral_Close(ScsiPeripheral_Device ** dev)333 int32_t OH_ScsiPeripheral_Close(ScsiPeripheral_Device **dev)
334 {
335     if (g_ddk == nullptr) {
336         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
337         return SCSIPERIPHERAL_DDK_INIT_ERROR;
338     }
339     if (dev == nullptr || *dev == nullptr) {
340         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
341         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
342     }
343 
344     int32_t ret = TransToDdkErrCode(g_ddk->Close((*dev)->impl));
345     if (close((*dev)->memMapFd)) {
346         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "close memMapFd failed, errno=%{public}d", errno);
347         if (ret == SCSIPERIPHERAL_DDK_SUCCESS) {
348             ret = SCSIPERIPHERAL_DDK_IO_ERROR;
349         }
350     }
351     DeleteScsiPeripheralDevice(dev);
352     return ret;
353 }
354 
OH_ScsiPeripheral_TestUnitReady(ScsiPeripheral_Device * dev,ScsiPeripheral_TestUnitReadyRequest * request,ScsiPeripheral_Response * response)355 int32_t OH_ScsiPeripheral_TestUnitReady(ScsiPeripheral_Device *dev, ScsiPeripheral_TestUnitReadyRequest *request,
356     ScsiPeripheral_Response *response)
357 {
358     if (g_ddk == nullptr) {
359         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
360         return SCSIPERIPHERAL_DDK_INIT_ERROR;
361     }
362     if (dev == nullptr || request == nullptr || response == nullptr) {
363         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
364         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
365     }
366 
367     auto hdiRequest = reinterpret_cast<OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralTestUnitReadyRequest *>(request);
368     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
369     hdiResponse.senseData.resize(sizeof(response->senseData));
370     int32_t ret = TransToDdkErrCode(g_ddk->TestUnitReady(dev->impl, *hdiRequest, hdiResponse));
371     if (ret != SCSIPERIPHERAL_DDK_SUCCESS) {
372         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "test unit ready failed");
373         return ret;
374     }
375 
376     return CopyResponse(hdiResponse, response);
377 }
378 
OH_ScsiPeripheral_Inquiry(ScsiPeripheral_Device * dev,ScsiPeripheral_InquiryRequest * request,ScsiPeripheral_InquiryInfo * inquiryInfo,ScsiPeripheral_Response * response)379 int32_t OH_ScsiPeripheral_Inquiry(ScsiPeripheral_Device *dev, ScsiPeripheral_InquiryRequest *request,
380     ScsiPeripheral_InquiryInfo *inquiryInfo, ScsiPeripheral_Response *response)
381 {
382     if (g_ddk == nullptr) {
383         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
384         return SCSIPERIPHERAL_DDK_INIT_ERROR;
385     }
386     if (dev == nullptr || request == nullptr || inquiryInfo == nullptr || inquiryInfo->data == nullptr ||
387         response == nullptr) {
388         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
389         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
390     }
391 
392     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralInquiryRequest hdiInquiryRequest;
393     hdiInquiryRequest.pageCode = request->pageCode;
394     hdiInquiryRequest.allocationLength = request->allocationLength;
395     hdiInquiryRequest.control = request->control;
396     hdiInquiryRequest.byte1 = request->byte1;
397     hdiInquiryRequest.memMapSize = inquiryInfo->data->size;
398     hdiInquiryRequest.timeout = request->timeout;
399 
400     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralInquiryInfo hdiInquiryInfo;
401     hdiInquiryInfo.idVendor.resize(SCSIPERIPHERAL_VENDOR_ID_LEN);
402     hdiInquiryInfo.idProduct.resize(sizeof(inquiryInfo->idProduct));
403     hdiInquiryInfo.revProduct.resize(sizeof(inquiryInfo->revProduct));
404     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
405     hdiResponse.senseData.resize(sizeof(response->senseData));
406 
407     int32_t ret = TransToDdkErrCode(g_ddk->Inquiry(dev->impl, hdiInquiryRequest, hdiInquiryInfo, hdiResponse));
408     if (ret != SCSIPERIPHERAL_DDK_SUCCESS) {
409         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "inquiry failed");
410         return ret;
411     }
412 
413     inquiryInfo->deviceType = hdiInquiryInfo.deviceType;
414     if (!CopyDataToArray(hdiInquiryInfo.idVendor, inquiryInfo->idVendor, sizeof(inquiryInfo->idVendor))) {
415         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "copy idVendor failed");
416         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
417     }
418     if (!CopyDataToArray(hdiInquiryInfo.idProduct, inquiryInfo->idProduct, sizeof(inquiryInfo->idProduct))) {
419         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "copy idProduct failed");
420         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
421     }
422     if (!CopyDataToArray(hdiInquiryInfo.revProduct, inquiryInfo->revProduct, sizeof(inquiryInfo->revProduct))) {
423         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "copy revProduct failed");
424         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
425     }
426     inquiryInfo->data->transferredLength = hdiResponse.transferredLength;
427 
428     return CopyResponse(hdiResponse, response);
429 }
430 
OH_ScsiPeripheral_ReadCapacity10(ScsiPeripheral_Device * dev,ScsiPeripheral_ReadCapacityRequest * request,ScsiPeripheral_CapacityInfo * capacityInfo,ScsiPeripheral_Response * response)431 int32_t OH_ScsiPeripheral_ReadCapacity10(ScsiPeripheral_Device *dev, ScsiPeripheral_ReadCapacityRequest *request,
432     ScsiPeripheral_CapacityInfo *capacityInfo, ScsiPeripheral_Response *response)
433 {
434     if (g_ddk == nullptr) {
435         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
436         return SCSIPERIPHERAL_DDK_INIT_ERROR;
437     }
438     if (dev == nullptr || request == nullptr || capacityInfo == nullptr || response == nullptr) {
439         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
440         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
441     }
442 
443     auto hdiRequest = reinterpret_cast<OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralReadCapacityRequest *>(request);
444     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralCapacityInfo hdiCapacityInfo;
445     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
446     hdiResponse.senseData.resize(sizeof(response->senseData));
447 
448     int32_t ret = TransToDdkErrCode(g_ddk->ReadCapacity10(dev->impl, *hdiRequest, hdiCapacityInfo,
449         hdiResponse));
450     if (ret != SCSIPERIPHERAL_DDK_SUCCESS) {
451         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "readcapacity10 failed");
452         return ret;
453     }
454 
455     capacityInfo->lbAddress = hdiCapacityInfo.lbAddress;
456     capacityInfo->lbLength = hdiCapacityInfo.lbLength;
457 
458     return CopyResponse(hdiResponse, response);
459 }
460 
OH_ScsiPeripheral_RequestSense(ScsiPeripheral_Device * dev,ScsiPeripheral_RequestSenseRequest * request,ScsiPeripheral_Response * response)461 int32_t OH_ScsiPeripheral_RequestSense(ScsiPeripheral_Device *dev, ScsiPeripheral_RequestSenseRequest *request,
462     ScsiPeripheral_Response *response)
463 {
464     if (g_ddk == nullptr) {
465         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
466         return SCSIPERIPHERAL_DDK_INIT_ERROR;
467     }
468     if (dev == nullptr || request == nullptr || response == nullptr) {
469         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
470         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
471     }
472 
473     auto hdiRequest = reinterpret_cast<OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralRequestSenseRequest *>(request);
474     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
475     hdiResponse.senseData.resize(sizeof(response->senseData));
476     int32_t ret = TransToDdkErrCode(g_ddk->RequestSense(dev->impl, *hdiRequest, hdiResponse));
477     if (ret != SCSIPERIPHERAL_DDK_SUCCESS) {
478         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "request sense failed");
479         return ret;
480     }
481 
482     return CopyResponse(hdiResponse, response);
483 }
484 
OH_ScsiPeripheral_Read10(ScsiPeripheral_Device * dev,ScsiPeripheral_IORequest * request,ScsiPeripheral_Response * response)485 int32_t OH_ScsiPeripheral_Read10(ScsiPeripheral_Device *dev, ScsiPeripheral_IORequest *request,
486     ScsiPeripheral_Response *response)
487 {
488     EDM_LOGD(MODULE_SCSIPERIPHERAL_DDK, "Read10 start");
489     if (g_ddk == nullptr) {
490         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
491         return SCSIPERIPHERAL_DDK_INIT_ERROR;
492     }
493     if (dev == nullptr || request == nullptr || request->data ==nullptr || response == nullptr) {
494         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
495         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
496     }
497 
498     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralIORequest hdiIORequest;
499     ToHdi(request, hdiIORequest);
500     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
501     hdiResponse.senseData.resize(sizeof(response->senseData));
502 
503     int32_t ret = TransToDdkErrCode(g_ddk->Read10(dev->impl, hdiIORequest, hdiResponse));
504     if (ret !=  SCSIPERIPHERAL_DDK_SUCCESS) {
505         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "read10 failed");
506         return ret;
507     }
508 
509     request->data->transferredLength = hdiResponse.transferredLength;
510 
511     return CopyResponse(hdiResponse, response);
512 }
513 
OH_ScsiPeripheral_Write10(ScsiPeripheral_Device * dev,ScsiPeripheral_IORequest * request,ScsiPeripheral_Response * response)514 int32_t OH_ScsiPeripheral_Write10(ScsiPeripheral_Device *dev, ScsiPeripheral_IORequest *request,
515     ScsiPeripheral_Response *response)
516 {
517     if (g_ddk == nullptr) {
518         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
519         return SCSIPERIPHERAL_DDK_INIT_ERROR;
520     }
521     if (dev == nullptr || request == nullptr || request->data ==nullptr || response == nullptr) {
522         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
523         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
524     }
525 
526     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralIORequest hdiIORequest;
527     ToHdi(request, hdiIORequest);
528     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
529     hdiResponse.senseData.resize(sizeof(response->senseData));
530 
531     int32_t ret = TransToDdkErrCode(g_ddk->Write10(dev->impl, hdiIORequest, hdiResponse));
532     if (ret !=  SCSIPERIPHERAL_DDK_SUCCESS) {
533         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "write10 failed");
534         return ret;
535     }
536 
537     request->data->transferredLength = hdiResponse.transferredLength;
538 
539     return CopyResponse(hdiResponse, response);
540 }
541 
OH_ScsiPeripheral_Verify10(ScsiPeripheral_Device * dev,ScsiPeripheral_VerifyRequest * request,ScsiPeripheral_Response * response)542 int32_t OH_ScsiPeripheral_Verify10(ScsiPeripheral_Device *dev, ScsiPeripheral_VerifyRequest *request,
543     ScsiPeripheral_Response *response)
544 {
545     if (g_ddk == nullptr) {
546         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
547         return SCSIPERIPHERAL_DDK_INIT_ERROR;
548     }
549     if (dev == nullptr || request == nullptr || response == nullptr) {
550         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
551         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
552     }
553 
554     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralVerifyRequest hdiVerifyRequest;
555     hdiVerifyRequest.lbAddress = request->lbAddress;
556     hdiVerifyRequest.verificationLength = request->verificationLength;
557     hdiVerifyRequest.control = request->control;
558     hdiVerifyRequest.byte1 = request->byte1;
559     hdiVerifyRequest.byte6 = request->byte6;
560     hdiVerifyRequest.timeout = request->timeout;
561     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
562     hdiResponse.senseData.resize(sizeof(response->senseData));
563 
564     int32_t ret = TransToDdkErrCode(g_ddk->Verify10(dev->impl, hdiVerifyRequest, hdiResponse));
565     if (ret != SCSIPERIPHERAL_DDK_SUCCESS) {
566         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "verify10 failed");
567         return ret;
568     }
569 
570     return CopyResponse(hdiResponse, response);
571 }
572 
OH_ScsiPeripheral_SendRequestByCdb(ScsiPeripheral_Device * dev,ScsiPeripheral_Request * request,ScsiPeripheral_Response * response)573 int32_t OH_ScsiPeripheral_SendRequestByCdb(ScsiPeripheral_Device *dev, ScsiPeripheral_Request *request,
574     ScsiPeripheral_Response *response)
575 {
576     EDM_LOGD(MODULE_SCSIPERIPHERAL_DDK, "SendRequestByCDB start");
577     if (g_ddk == nullptr) {
578         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "invalid obj");
579         return SCSIPERIPHERAL_DDK_INIT_ERROR;
580     }
581     if (dev == nullptr || request == nullptr || request->data ==nullptr || response == nullptr) {
582         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
583         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
584     }
585     if (request->cdbLength == 0) {
586         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "cdb length is 0");
587         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
588     }
589 
590     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralRequest hdiRequest;
591     hdiRequest.commandDescriptorBlock.assign(request->commandDescriptorBlock,
592         request->commandDescriptorBlock + request->cdbLength);
593     hdiRequest.dataTransferDirection = request->dataTransferDirection;
594     hdiRequest.memMapSize = request->data->size;
595     hdiRequest.timeout = request->timeout;
596     OHOS::HDI::Usb::ScsiDdk::V1_0::ScsiPeripheralResponse hdiResponse;
597     hdiResponse.senseData.resize(sizeof(response->senseData));
598 
599     int32_t ret = TransToDdkErrCode(g_ddk->SendRequestByCDB(dev->impl, hdiRequest, hdiResponse));
600     if (ret !=  SCSIPERIPHERAL_DDK_SUCCESS) {
601         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "send request by cdb failed");
602         return ret;
603     }
604 
605     request->data->transferredLength = hdiResponse.transferredLength;
606 
607     return CopyResponse(hdiResponse, response);
608 }
609 
OH_ScsiPeripheral_CreateDeviceMemMap(ScsiPeripheral_Device * dev,size_t size,ScsiPeripheral_DeviceMemMap ** devMmap)610 int32_t OH_ScsiPeripheral_CreateDeviceMemMap(ScsiPeripheral_Device *dev, size_t size,
611     ScsiPeripheral_DeviceMemMap **devMmap)
612 {
613     if (dev == nullptr || devMmap == nullptr) {
614         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
615         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
616     }
617     if (dev->memMapFd < 0) {
618         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "memMapFd is invalid");
619         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
620     }
621 
622     ftruncate(dev->memMapFd, size);
623     auto buffer = static_cast<uint8_t *>(mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_SHARED, dev->memMapFd, 0));
624     if (buffer == MAP_FAILED) {
625         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "mmap failed, errno=%{public}d", errno);
626         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
627     }
628 
629     ScsiPeripheral_DeviceMemMap *memMap = new ScsiPeripheral_DeviceMemMap({buffer, size, 0, size, 0});
630     if (memMap == nullptr) {
631         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "alloc dev mem failed, errno=%{public}d", errno);
632         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
633     }
634 
635     *devMmap = memMap;
636     return SCSIPERIPHERAL_DDK_SUCCESS;
637 }
638 
OH_ScsiPeripheral_DestroyDeviceMemMap(ScsiPeripheral_DeviceMemMap * devMmap)639 int32_t OH_ScsiPeripheral_DestroyDeviceMemMap(ScsiPeripheral_DeviceMemMap *devMmap)
640 {
641     if (devMmap == nullptr) {
642         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "devMmap is nullptr");
643         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
644     }
645 
646     if (munmap(devMmap->address, devMmap->size) != 0) {
647         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "munmap failed, errno=%{public}d", errno);
648         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
649     }
650     delete devMmap;
651     devMmap = nullptr;
652     return SCSIPERIPHERAL_DDK_SUCCESS;
653 }
654 
OH_ScsiPeripheral_ParseBasicSenseInfo(uint8_t * senseData,uint8_t senseDataLen,ScsiPeripheral_BasicSenseInfo * senseInfo)655 int32_t OH_ScsiPeripheral_ParseBasicSenseInfo(uint8_t *senseData, uint8_t senseDataLen,
656     ScsiPeripheral_BasicSenseInfo *senseInfo)
657 {
658     if (senseData == nullptr || senseInfo == nullptr) {
659         EDM_LOGE(MODULE_SCSIPERIPHERAL_DDK, "param is null");
660         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
661     }
662 
663     senseInfo->responseCode = senseData[0] & MAST_RESPONSE_CODE;
664 
665     if (senseInfo->responseCode == RESPONSE_CODE_70H || senseInfo->responseCode == RESPONSE_CODE_71H) {
666         return ParseFixedFormatSense(senseData, senseDataLen, senseInfo);
667     } else if (senseInfo->responseCode == RESPONSE_CODE_72H || senseInfo->responseCode == RESPONSE_CODE_73H) {
668         return ParseDescriptorFormatSense(senseData, senseDataLen, senseInfo);
669     }
670 
671     return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
672 }
673