• 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_ddk_service.h"
17 
18 #include <hdf_base.h>
19 #include <cerrno>
20 #include <cstdio>
21 #include <cstdlib>
22 #include <cstring>
23 #include <fcntl.h>
24 #include <sys/mman.h>
25 #include <securec.h>
26 #include <sys/ioctl.h>
27 #include <scsi/sg.h>
28 #include <unistd.h>
29 
30 #include "ddk_sysfs_dev_node.h"
31 #include "hdf_log.h"
32 #include "usbd_wrapper.h"
33 #include "usb_ddk_permission.h"
34 
35 #ifdef __LITEOS__
36 #include "scsi_liteos_adapter.h"
37 #else
38 #include "scsi_linux_adapter.h"
39 #endif
40 
41 #define HDF_LOG_TAG scsi_ddk_service
42 using namespace OHOS::HDI::Usb::Ddk;
43 
44 namespace OHOS {
45 namespace HDI {
46 namespace Usb {
47 namespace ScsiDdk {
48 namespace V1_0 {
49 
50 constexpr uint8_t THIRTY_TWO_BIT = 32;
51 constexpr uint8_t SCSIPERIPHERAL_MAX_SENSE_DATA_LEN = 252;
52 constexpr uint8_t SCSIPERIPHERAL_VENDOR_ID_LEN = 8;
53 constexpr uint8_t SCSIPERIPHERAL_PRODUCT_ID_LEN = 16;
54 constexpr uint8_t SCSIPERIPHERAL_PRODUCT_REV_LEN = 4;
55 constexpr uint8_t PATH_LEN = 50;
56 constexpr uint8_t ONE_BYTE = 1;
57 constexpr uint8_t TWO_BYTE = 2;
58 constexpr uint8_t THREE_BYTE = 3;
59 constexpr uint8_t FOUR_BYTE = 4;
60 constexpr uint8_t FIVE_BYTE = 5;
61 constexpr uint8_t SIX_BYTE = 6;
62 constexpr uint8_t SEVEN_BYTE = 7;
63 constexpr uint8_t EIGHT_BYTE = 8;
64 constexpr uint8_t NINE_BYTE = 9;
65 constexpr uint8_t SIXTEEN_BYTE = 16;
66 constexpr uint8_t THIRTY_TWO_BYTE = 32;
67 constexpr uint8_t EIGHT_BIT = 8;
68 constexpr uint8_t SIXTEEN_BIT = 16;
69 constexpr uint8_t TWENTY_FOUR_BIT = 24;
70 constexpr uint8_t BYTE_MASK = 0xFF;
71 constexpr uint32_t TIMEOUT = 5000;
72 constexpr uint8_t OPERATION_CODE_READCAPACITY10 = 0x25;
73 constexpr uint8_t OPERATION_CODE_TESTUNITREADY = 0x00;
74 constexpr uint8_t OPERATION_CODE_INQUIRY = 0x12;
75 constexpr uint8_t OPERATION_CODE_REQUEST_SENSE = 0x03;
76 constexpr uint8_t OPERATION_CODE_READ10 = 0x28;
77 constexpr uint8_t OPERATION_CODE_WRITE10 = 0x2A;
78 constexpr uint8_t OPERATION_CODE_VERIFY10 = 0x2F;
79 constexpr uint8_t CDB_LENGTH_SIX = 6;
80 constexpr uint8_t CDB_LENGTH_TEN = 10;
81 constexpr uint32_t MAX_TRANSFER_BYTES = UINT32_MAX;
82 constexpr uint32_t MAX_MEM_MAP_SIZE = UINT32_MAX;
83 constexpr const char* SCSIPERIPHERAL_DEVICE_MMAP_PATH = "/data/service/el1/public/usb/scsi";
84 static const std::string PERMISSION_NAME = "ohos.permission.ACCESS_DDK_SCSI_PERIPHERAL";
85 std::mutex g_memMapMutex;
86 
87 class MemMapFinalizer {
88 public:
MemMapFinalizer(uint8_t * buffer,uint32_t size)89     MemMapFinalizer(uint8_t *buffer, uint32_t size)
90         : buffer_(buffer), size_(size)
91     {
92     }
93 
~MemMapFinalizer()94     ~MemMapFinalizer()
95     {
96         munmap(buffer_, size_);
97     }
98 
99 private:
100     MemMapFinalizer(const MemMapFinalizer&);
101     void operator=(const MemMapFinalizer&);
102 
103 private:
104     uint8_t *buffer_ = nullptr;
105     uint32_t size_ = 0;
106 };
107 
108 template<typename Func, typename ResultType = decltype(std::declval<Func>()())>
TrackTime(Func && func,const char * desc="")109 ResultType TrackTime(Func&& func, const char* desc = "")
110 {
111     auto start = std::chrono::high_resolution_clock::now();
112     ResultType result = func();
113     auto end = std::chrono::high_resolution_clock::now();
114     auto duration_ms = std::chrono::duration<double, std::milli>(end - start);
115     HDF_LOGD("Function [%{public}s] took [%{public}.2f]ms with result [%{public}d]", desc, duration_ms.count(), result);
116     return result;
117 }
118 
GetBusNum(uint64_t devHandle)119 inline uint32_t GetBusNum(uint64_t devHandle)
120 {
121     return static_cast<uint32_t>(devHandle >> THIRTY_TWO_BIT);
122 }
123 
GetDevNum(uint64_t devHandle)124 inline uint32_t GetDevNum(uint64_t devHandle)
125 {
126     return static_cast<uint32_t>(devHandle & 0xFFFFFFFF);
127 }
128 
VerifyPermission(const std::string & permissionName)129 static bool VerifyPermission(const std::string &permissionName)
130 {
131     return DdkPermissionManager::VerifyPermission(permissionName);
132 }
133 
SetUint16(unsigned char * cdb,int start,uint16_t val)134 static inline void SetUint16(unsigned char *cdb, int start, uint16_t val)
135 {
136     cdb[start] = (val >> EIGHT_BIT) & BYTE_MASK;
137     cdb[start + ONE_BYTE] = val & BYTE_MASK;
138 }
139 
SetUint32(unsigned char * cdb,int start,uint32_t val)140 static inline void SetUint32(unsigned char *cdb, int start, uint32_t val)
141 {
142     cdb[start] = (val >> TWENTY_FOUR_BIT) & BYTE_MASK;
143     cdb[start + ONE_BYTE] = (val >> SIXTEEN_BIT) & BYTE_MASK;
144     cdb[start + TWO_BYTE] = (val >> EIGHT_BIT) & BYTE_MASK;
145     cdb[start + THREE_BYTE] = val & BYTE_MASK;
146 }
147 
GetUint32(unsigned char * buf,int start)148 static inline uint32_t GetUint32(unsigned char *buf, int start)
149 {
150     return (
151         (static_cast<uint32_t>(buf[start]) << TWENTY_FOUR_BIT) |
152         (static_cast<uint32_t>(buf[start + ONE_BYTE]) << SIXTEEN_BIT) |
153         (static_cast<uint32_t>(buf[start + TWO_BYTE]) << EIGHT_BIT) |
154         (static_cast<uint32_t>(buf[start + THREE_BYTE]))
155     );
156 }
157 
BuildCdbForReadAndWrite(const ScsiPeripheralIORequest & request,unsigned char cdb[CDB_LENGTH_TEN],uint8_t operationCode)158 static void BuildCdbForReadAndWrite(const ScsiPeripheralIORequest& request, unsigned char cdb[CDB_LENGTH_TEN],
159     uint8_t operationCode)
160 {
161     cdb[0] = operationCode;
162     cdb[ONE_BYTE] = request.byte1;
163     SetUint32(cdb, TWO_BYTE, request.lbAddress);
164     cdb[SIX_BYTE] = request.byte6;
165     SetUint16(cdb, SEVEN_BYTE, request.transferLength);
166     cdb[NINE_BYTE] = request.control;
167 }
168 
AllocateAndInitializeBuffer(const ScsiPeripheralDevice & dev,uint32_t memMapSize,uint8_t * & buffer,uint16_t allocationLength)169 static int32_t AllocateAndInitializeBuffer(const ScsiPeripheralDevice& dev, uint32_t memMapSize, uint8_t*& buffer,
170     uint16_t allocationLength)
171 {
172     if (memMapSize < allocationLength || memMapSize > MAX_MEM_MAP_SIZE) {
173         HDF_LOGE("%{public}s: memMapSize is invalid. memMapSize=%{public}d, allocationLength=%{public}d", __func__,
174             memMapSize, allocationLength);
175         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
176     }
177     buffer = static_cast<uint8_t *>(mmap(nullptr, memMapSize, PROT_READ | PROT_WRITE, MAP_SHARED, dev.memMapFd, 0));
178     if (buffer == MAP_FAILED) {
179         HDF_LOGE("%{public}s: mmap failed, errno=%{public}d, memMapFd=%{public}d, memMapSize=%{public}d", __func__,
180             errno, dev.memMapFd, memMapSize);
181         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
182     }
183 
184     int32_t ret = memset_s(buffer, memMapSize, 0, memMapSize);
185     if (ret != 0) {
186         HDF_LOGE("%{public}s memset_s(io_hdr) failed, ret=%{public}d", __func__, ret);
187         munmap(buffer, memMapSize);
188         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
189     }
190     return HDF_SUCCESS;
191 }
192 
UpdateResponseFromOsAdapter(ScsiPeripheralResponse & response,const Response & resp)193 static void UpdateResponseFromOsAdapter(ScsiPeripheralResponse& response, const Response& resp)
194 {
195     response.senseData.assign(resp.senseData.begin(), resp.senseData.end());
196     response.status = resp.status;
197     response.maskedStatus = resp.maskedStatus;
198     response.msgStatus = resp.msgStatus;
199     response.sbLenWr = resp.sbLenWr;
200     response.hostStatus = resp.hostStatus;
201     response.driverStatus = resp.driverStatus;
202     response.resId = resp.resId;
203     response.duration = resp.duration;
204     response.transferredLength = resp.transferredLength;
205 }
206 
ScsiPeripheralDdkImplGetInstance(void)207 extern "C" IScsiPeripheralDdk *ScsiPeripheralDdkImplGetInstance(void)
208 {
209     std::shared_ptr<ScsiOsAdapter> osAdapter;
210     #ifdef __LITEOS__
211         osAdapter = std::make_shared<LiteosScsiOsAdapter>();
212     #else
213         osAdapter = std::make_shared<LinuxScsiOsAdapter>();
214     #endif
215     return new (std::nothrow) ScsiDdkService(osAdapter);
216 }
217 
Init()218 int32_t ScsiDdkService::Init()
219 {
220     HDF_LOGD("ScsiDdkService::Init start");
221     if (!VerifyPermission(PERMISSION_NAME)) {
222         HDF_LOGI("%{public}s: no permission", __func__);
223         return SCSIPERIPHERAL_DDK_NO_PERM;
224     }
225 
226     return HDF_SUCCESS;
227 }
228 
Release()229 int32_t ScsiDdkService::Release()
230 {
231     HDF_LOGD("ScsiDdkService::Release start");
232     if (!VerifyPermission(PERMISSION_NAME)) {
233         HDF_LOGE("%{public}s: no permission", __func__);
234         return SCSIPERIPHERAL_DDK_NO_PERM;
235     }
236 
237     DdkPermissionManager::Reset();
238 
239     return HDF_SUCCESS;
240 }
241 
Open(uint64_t deviceId,uint8_t interfaceIndex,ScsiPeripheralDevice & dev,int & memMapFd)242 int32_t ScsiDdkService::Open(uint64_t deviceId, uint8_t interfaceIndex, ScsiPeripheralDevice& dev, int &memMapFd)
243 {
244     HDF_LOGD("ScsiDdkService::Open start");
245     if (!VerifyPermission(PERMISSION_NAME)) {
246         HDF_LOGI("%{public}s: no permission", __func__);
247         return SCSIPERIPHERAL_DDK_NO_PERM;
248     }
249 
250     uint16_t busNum = GetBusNum(deviceId);
251     uint16_t devNum = GetDevNum(deviceId);
252     SysfsDevNode devNode(busNum, devNum, interfaceIndex, "sg");
253     std::string path;
254     int32_t ret = devNode.FindPath(path);
255     if (ret != HDF_SUCCESS) {
256         HDF_LOGE("Get devNodePath ret: %{public}d\n", ret);
257         return SCSIPERIPHERAL_DDK_DEVICE_NOT_FOUND;
258     }
259 
260     int32_t fd = TrackTime([&]() {
261         return open(path.c_str(), O_RDWR);
262     }, __func__);
263     if (fd < 0) {
264         HDF_LOGE("%{public}s open failed, path=%{public}s, errno=%{public}d", __func__, path.c_str(), errno);
265         return SCSIPERIPHERAL_DDK_IO_ERROR;
266     }
267 
268     dev.devFd = fd;
269     HDF_LOGD("Open success, dev.devFd=%{public}d, path.c_str()=%{public}s", dev.devFd, path.c_str());
270 
271     ret = GetDeviceMemMapFd(busNum, devNum, interfaceIndex, memMapFd);
272     if (ret != HDF_SUCCESS) {
273         HDF_LOGE("GetDeviceMemMapFd failed, ret=%{public}d", ret);
274         return ret;
275     }
276     dev.memMapFd = memMapFd;
277 
278     ScsiPeripheralReadCapacityRequest request;
279     ScsiPeripheralCapacityInfo capacityInfo;
280     ScsiPeripheralResponse response;
281     request.lbAddress = 0;
282     request.byte8 = 0;
283     request.control = 0;
284     request.timeout = TIMEOUT;
285 
286     ret = ReadCapacity10(dev, request, capacityInfo, response);
287     if (ret != HDF_SUCCESS) {
288         HDF_LOGE("ReadCapacity10 failed, ret=%{public}d", ret);
289         return ret;
290     }
291 
292     dev.lbLength = capacityInfo.lbLength;
293     HDF_LOGD("ReadCapacity success, dev.lbLength=%{public}d", dev.lbLength);
294 
295     return HDF_SUCCESS;
296 }
297 
Close(const ScsiPeripheralDevice & dev)298 int32_t ScsiDdkService::Close(const ScsiPeripheralDevice& dev)
299 {
300     HDF_LOGD("ScsiDdkService::Close start");
301     if (!VerifyPermission(PERMISSION_NAME)) {
302         HDF_LOGE("%{public}s: no permission", __func__);
303         return SCSIPERIPHERAL_DDK_NO_PERM;
304     }
305 
306     int32_t ret = TrackTime([&]() {
307         return close(dev.devFd);
308     }, __func__);
309     if (ret == -1) {
310         HDF_LOGE("%{public}s close failed", __func__);
311         return SCSIPERIPHERAL_DDK_IO_ERROR;
312     }
313 
314     ret = TrackTime([&]() {
315         return close(dev.memMapFd);
316     }, __func__);
317     if (ret < 0) {
318         HDF_LOGE("%{public}s: close failed, memMapFd=%{public}d, errno=%{public}d", __func__, dev.memMapFd, errno);
319         return SCSIPERIPHERAL_DDK_IO_ERROR;
320     }
321 
322     return HDF_SUCCESS;
323 }
324 
ReadCapacity10(const ScsiPeripheralDevice & dev,const ScsiPeripheralReadCapacityRequest & request,ScsiPeripheralCapacityInfo & capacityInfo,ScsiPeripheralResponse & response)325 int32_t ScsiDdkService::ReadCapacity10(const ScsiPeripheralDevice& dev,
326     const ScsiPeripheralReadCapacityRequest& request, ScsiPeripheralCapacityInfo& capacityInfo,
327     ScsiPeripheralResponse& response)
328 {
329     HDF_LOGD("ScsiDdkService::ReadCapacity10 start");
330     if (!VerifyPermission(PERMISSION_NAME)) {
331         HDF_LOGE("%{public}s: no permission", __func__);
332         return SCSIPERIPHERAL_DDK_NO_PERM;
333     }
334 
335     Request req;
336     uint8_t cdb[CDB_LENGTH_TEN];
337     cdb[0] = OPERATION_CODE_READCAPACITY10;
338     SetUint32(cdb, TWO_BYTE, request.lbAddress);
339     cdb[EIGHT_BYTE] = request.byte8;
340     cdb[NINE_BYTE] = request.control;
341     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
342     req.dataTransferDirection = SG_DXFER_FROM_DEV;
343     req.timeout = request.timeout;
344     req.devFd = dev.devFd;
345 
346     if (osAdapter_ == nullptr) {
347         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
348         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
349     }
350 
351     std::vector<uint8_t> data(sizeof(capacityInfo));
352     Response resp;
353     int32_t ret = TrackTime([&]() {
354         return osAdapter_->SendRequest(req, data.data(), data.size(), resp);
355     }, __func__);
356     if (ret != HDF_SUCCESS) {
357         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
358         return ret;
359     }
360 
361     UpdateResponseFromOsAdapter(response, resp);
362 
363     capacityInfo.lbAddress = GetUint32(data.data(), 0);
364     capacityInfo.lbLength = GetUint32(data.data(), FOUR_BYTE);
365 
366     return HDF_SUCCESS;
367 }
368 
TestUnitReady(const ScsiPeripheralDevice & dev,const ScsiPeripheralTestUnitReadyRequest & request,ScsiPeripheralResponse & response)369 int32_t ScsiDdkService::TestUnitReady(const ScsiPeripheralDevice& dev,
370     const ScsiPeripheralTestUnitReadyRequest& request, ScsiPeripheralResponse& response)
371 {
372     HDF_LOGD("ScsiDdkService::TestUnitReady start");
373     if (!VerifyPermission(PERMISSION_NAME)) {
374         HDF_LOGE("%{public}s: no permission", __func__);
375         return SCSIPERIPHERAL_DDK_NO_PERM;
376     }
377 
378     Request req;
379     unsigned char cdb[CDB_LENGTH_SIX];
380     cdb[0] = OPERATION_CODE_TESTUNITREADY;
381     SetUint32(cdb, 1, 0);
382     cdb[FIVE_BYTE] = request.control;
383     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
384     req.dataTransferDirection = SG_DXFER_NONE;
385     req.timeout = request.timeout;
386     req.devFd = dev.devFd;
387 
388     if (osAdapter_ == nullptr) {
389         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
390         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
391     }
392 
393     Response resp;
394     int32_t ret = TrackTime([&]() {
395         return osAdapter_->SendRequest(req, nullptr, 0, resp);
396     }, __func__);
397     if (ret != HDF_SUCCESS) {
398         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
399         return ret;
400     }
401 
402     UpdateResponseFromOsAdapter(response, resp);
403 
404     return HDF_SUCCESS;
405 }
406 
Inquiry(const ScsiPeripheralDevice & dev,const ScsiPeripheralInquiryRequest & request,ScsiPeripheralInquiryInfo & inquiryInfo,ScsiPeripheralResponse & response)407 int32_t ScsiDdkService::Inquiry(const ScsiPeripheralDevice& dev, const ScsiPeripheralInquiryRequest& request,
408     ScsiPeripheralInquiryInfo& inquiryInfo, ScsiPeripheralResponse& response)
409 {
410     HDF_LOGD("ScsiDdkService::Inquiry start");
411     if (!VerifyPermission(PERMISSION_NAME)) {
412         HDF_LOGE("%{public}s: no permission", __func__);
413         return SCSIPERIPHERAL_DDK_NO_PERM;
414     }
415 
416     Request req;
417     uint8_t cdb[CDB_LENGTH_SIX];
418     cdb[0] = OPERATION_CODE_INQUIRY;
419     cdb[ONE_BYTE] = request.byte1;
420     cdb[TWO_BYTE] = request.pageCode;
421     SetUint16(cdb, THREE_BYTE, request.allocationLength);
422     cdb[FIVE_BYTE] = request.control;
423     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
424     req.dataTransferDirection = SG_DXFER_FROM_DEV;
425     req.timeout = request.timeout;
426     req.devFd = dev.devFd;
427 
428     std::lock_guard<std::mutex> lock(g_memMapMutex);
429     uint8_t* buffer = nullptr;
430     uint32_t memMapSize = request.memMapSize;
431     if (memMapSize < THIRTY_TWO_BYTE + SCSIPERIPHERAL_PRODUCT_REV_LEN) {
432         HDF_LOGE("%{public}s: memMapSize should be greater than %{public}d", __func__,
433             THIRTY_TWO_BYTE + SCSIPERIPHERAL_PRODUCT_REV_LEN);
434         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
435     }
436 
437     int32_t ret = AllocateAndInitializeBuffer(dev, memMapSize, buffer, request.allocationLength);
438     if (ret != HDF_SUCCESS) {
439         return ret;
440     }
441     MemMapFinalizer memMapFinalizer(buffer, memMapSize);
442 
443     if (osAdapter_ == nullptr) {
444         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
445         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
446     }
447 
448     Response resp;
449     ret = TrackTime([&]() {
450         return osAdapter_->SendRequest(req, buffer, request.allocationLength, resp);
451     }, __func__);
452     if (ret != HDF_SUCCESS) {
453         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
454         return ret;
455     }
456 
457     UpdateResponseFromOsAdapter(response, resp);
458 
459     inquiryInfo.deviceType = buffer[0] & 0x1f;
460     inquiryInfo.idVendor.assign(buffer + EIGHT_BYTE, buffer + EIGHT_BYTE + SCSIPERIPHERAL_VENDOR_ID_LEN);
461     inquiryInfo.idProduct.assign(buffer + SIXTEEN_BYTE, buffer + SIXTEEN_BYTE + SCSIPERIPHERAL_PRODUCT_ID_LEN);
462     inquiryInfo.revProduct.assign(buffer + THIRTY_TWO_BYTE, buffer + THIRTY_TWO_BYTE + SCSIPERIPHERAL_PRODUCT_REV_LEN);
463 
464     return HDF_SUCCESS;
465 }
466 
RequestSense(const ScsiPeripheralDevice & dev,const ScsiPeripheralRequestSenseRequest & request,ScsiPeripheralResponse & response)467 int32_t ScsiDdkService::RequestSense(const ScsiPeripheralDevice& dev,
468     const ScsiPeripheralRequestSenseRequest& request, ScsiPeripheralResponse& response)
469 {
470     HDF_LOGD("ScsiDdkService::RequestSense start");
471     if (!VerifyPermission(PERMISSION_NAME)) {
472         HDF_LOGE("%{public}s: no permission", __func__);
473         return SCSIPERIPHERAL_DDK_NO_PERM;
474     }
475 
476     Request req;
477     unsigned char cdb[CDB_LENGTH_SIX];
478     cdb[0] = OPERATION_CODE_REQUEST_SENSE;
479     cdb[ONE_BYTE] = request.byte1;
480     cdb[FOUR_BYTE] = request.allocationLength;
481     cdb[FIVE_BYTE] = request.control;
482     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
483     req.dataTransferDirection = SG_DXFER_FROM_DEV;
484     req.timeout = request.timeout;
485     req.devFd = dev.devFd;
486 
487     if (osAdapter_ == nullptr) {
488         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
489         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
490     }
491 
492     uint32_t bufferSize = request.allocationLength < SCSIPERIPHERAL_MAX_SENSE_DATA_LEN ? request.allocationLength :
493         SCSIPERIPHERAL_MAX_SENSE_DATA_LEN;
494     Response resp;
495     resp.senseData.resize(bufferSize);
496     int32_t ret = TrackTime([&]() {
497         return osAdapter_->SendRequest(req, resp.senseData.data(), bufferSize, resp);
498     }, __func__);
499     if (ret != HDF_SUCCESS) {
500         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
501         return ret;
502     }
503 
504     response.senseData.resize(SCSIPERIPHERAL_MAX_SENSE_DATA_LEN);
505     UpdateResponseFromOsAdapter(response, resp);
506 
507     return HDF_SUCCESS;
508 }
509 
Read10(const ScsiPeripheralDevice & dev,const ScsiPeripheralIORequest & request,ScsiPeripheralResponse & response)510 int32_t ScsiDdkService::Read10(const ScsiPeripheralDevice& dev,
511     const ScsiPeripheralIORequest& request, ScsiPeripheralResponse& response)
512 {
513     HDF_LOGD("ScsiDdkService::Read10 start");
514     if (!VerifyPermission(PERMISSION_NAME)) {
515         HDF_LOGE("%{public}s: no permission", __func__);
516         return SCSIPERIPHERAL_DDK_NO_PERM;
517     }
518 
519     if (request.transferLength * dev.lbLength * (uint64_t)1 > MAX_TRANSFER_BYTES) {
520         HDF_LOGE("%{public}s: The value of transferLength is too large", __func__);
521         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
522     }
523 
524     Request req;
525     unsigned char cdb[CDB_LENGTH_TEN];
526     BuildCdbForReadAndWrite(request, cdb, OPERATION_CODE_READ10);
527     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
528     req.dataTransferDirection = SG_DXFER_FROM_DEV;
529     req.timeout = request.timeout;
530     req.devFd = dev.devFd;
531 
532     std::lock_guard<std::mutex> lock(g_memMapMutex);
533     uint8_t* buffer = nullptr;
534     uint32_t memMapSize = request.memMapSize;
535     uint32_t bufferSize = request.transferLength * dev.lbLength;
536     int32_t ret = AllocateAndInitializeBuffer(dev, memMapSize, buffer, bufferSize);
537     if (ret != HDF_SUCCESS) {
538         return ret;
539     }
540     MemMapFinalizer memMapFinalizer(buffer, memMapSize);
541 
542     if (osAdapter_ == nullptr) {
543         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
544         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
545     }
546 
547     Response resp;
548     ret = TrackTime([&]() {
549         return osAdapter_->SendRequest(req, buffer, bufferSize, resp);
550     }, __func__);
551     if (ret != HDF_SUCCESS) {
552         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
553         return ret;
554     }
555     UpdateResponseFromOsAdapter(response, resp);
556 
557     return HDF_SUCCESS;
558 }
559 
Write10(const ScsiPeripheralDevice & dev,const ScsiPeripheralIORequest & request,ScsiPeripheralResponse & response)560 int32_t ScsiDdkService::Write10(const ScsiPeripheralDevice& dev,
561     const ScsiPeripheralIORequest& request, ScsiPeripheralResponse& response)
562 {
563     HDF_LOGD("ScsiDdkService::Write10 start");
564     if (!VerifyPermission(PERMISSION_NAME)) {
565         HDF_LOGE("%{public}s: no permission", __func__);
566         return SCSIPERIPHERAL_DDK_NO_PERM;
567     }
568 
569     if (request.transferLength * dev.lbLength * (uint64_t)1 > MAX_TRANSFER_BYTES) {
570         HDF_LOGE("%{public}s: The value of transferLength is too large", __func__);
571         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
572     }
573 
574     Request req;
575     unsigned char cdb[CDB_LENGTH_TEN];
576     BuildCdbForReadAndWrite(request, cdb, OPERATION_CODE_WRITE10);
577 
578     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
579     req.dataTransferDirection = SG_DXFER_TO_DEV;
580     req.timeout = request.timeout;
581     req.devFd = dev.devFd;
582 
583     std::lock_guard<std::mutex> lock(g_memMapMutex);
584     uint32_t memMapSize = request.memMapSize;
585     uint32_t bufferSize = request.transferLength * dev.lbLength;
586     if (memMapSize < bufferSize || memMapSize > MAX_MEM_MAP_SIZE) {
587         HDF_LOGE("%{public}s: memMapSize is invalid. memMapSize=%{public}d, bufferSize=%{public}d", __func__,
588             memMapSize, bufferSize);
589         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
590     }
591 
592     auto buffer = static_cast<uint8_t *>(mmap(nullptr, memMapSize, PROT_READ | PROT_WRITE, MAP_SHARED,
593         dev.memMapFd, 0));
594     if (buffer == MAP_FAILED) {
595         HDF_LOGE("%{public}s: mmap failed, errno=%{public}d, memMapFd=%{public}d, memMapSize=%{public}d", __func__,
596             errno, dev.memMapFd, memMapSize);
597         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
598     }
599     MemMapFinalizer memMapFinalizer(buffer, memMapSize);
600 
601     if (osAdapter_ == nullptr) {
602         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
603         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
604     }
605 
606     Response resp;
607     int32_t ret = TrackTime([&]() {
608         return osAdapter_->SendRequest(req, buffer, bufferSize, resp);
609     }, __func__);
610     if (ret != HDF_SUCCESS) {
611         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
612         return ret;
613     }
614 
615     UpdateResponseFromOsAdapter(response, resp);
616 
617     return HDF_SUCCESS;
618 }
619 
Verify10(const ScsiPeripheralDevice & dev,const ScsiPeripheralVerifyRequest & request,ScsiPeripheralResponse & response)620 int32_t ScsiDdkService::Verify10(const ScsiPeripheralDevice& dev,
621     const ScsiPeripheralVerifyRequest& request, ScsiPeripheralResponse& response)
622 {
623     HDF_LOGD("ScsiDdkService::Verify10 start");
624     if (!VerifyPermission(PERMISSION_NAME)) {
625         HDF_LOGE("%{public}s: no permission", __func__);
626         return SCSIPERIPHERAL_DDK_NO_PERM;
627     }
628 
629     Request req;
630     unsigned char cdb[CDB_LENGTH_TEN];
631     cdb[0] = OPERATION_CODE_VERIFY10;
632     cdb[ONE_BYTE] = request.byte1;
633     SetUint32(cdb, TWO_BYTE, request.lbAddress);
634     cdb[SIX_BYTE] = request.byte6;
635     SetUint16(cdb, SEVEN_BYTE, request.verificationLength);
636     cdb[NINE_BYTE] = request.control;
637     req.commandDescriptorBlock.assign(cdb, cdb + sizeof(cdb));
638     req.dataTransferDirection = SG_DXFER_NONE;
639     req.timeout = request.timeout;
640     req.devFd = dev.devFd;
641 
642     if (osAdapter_ == nullptr) {
643         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
644         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
645     }
646 
647     Response resp;
648     int32_t ret = TrackTime([&]() {
649         return osAdapter_->SendRequest(req, nullptr, 0, resp);
650     }, __func__);
651     if (ret != HDF_SUCCESS) {
652         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
653         return ret;
654     }
655 
656     UpdateResponseFromOsAdapter(response, resp);
657 
658     return HDF_SUCCESS;
659 }
660 
SendRequestByCDB(const ScsiPeripheralDevice & dev,const ScsiPeripheralRequest & request,ScsiPeripheralResponse & response)661 int32_t ScsiDdkService::SendRequestByCDB(const ScsiPeripheralDevice& dev,
662     const ScsiPeripheralRequest& request, ScsiPeripheralResponse& response)
663 {
664     HDF_LOGD("ScsiDdkService::SendRequestByCDB start");
665     if (!VerifyPermission(PERMISSION_NAME)) {
666         HDF_LOGE("%{public}s: no permission", __func__);
667         return SCSIPERIPHERAL_DDK_NO_PERM;
668     }
669 
670     Request req;
671     req.commandDescriptorBlock = request.commandDescriptorBlock;
672     req.dataTransferDirection = request.dataTransferDirection;
673     req.timeout = request.timeout;
674     req.devFd = dev.devFd;
675 
676     std::lock_guard<std::mutex> lock(g_memMapMutex);
677     uint32_t memMapSize = request.memMapSize;
678     if (memMapSize > MAX_MEM_MAP_SIZE) {
679         HDF_LOGE("%{public}s: memMapSize is too large. memMapSize=%{public}d, MAX_MEM_MAP_SIZE=%{public}d", __func__,
680             memMapSize, MAX_MEM_MAP_SIZE);
681         return SCSIPERIPHERAL_DDK_INVALID_PARAMETER;
682     }
683     auto buffer = static_cast<uint8_t *>(mmap(nullptr, memMapSize, PROT_READ | PROT_WRITE, MAP_SHARED,
684         dev.memMapFd, 0));
685     if (buffer == MAP_FAILED) {
686         HDF_LOGE("%{public}s: mmap failed, errno=%{public}d, memMapFd=%{public}d, memMapSize=%{public}d", __func__,
687             errno, dev.memMapFd, memMapSize);
688         return SCSIPERIPHERAL_DDK_MEMORY_ERROR;
689     }
690     MemMapFinalizer memMapFinalizer(buffer, memMapSize);
691 
692     if (osAdapter_ == nullptr) {
693         HDF_LOGE("%{public}s: osAdapter_ is null.", __func__);
694         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
695     }
696 
697     Response resp;
698     int32_t ret = TrackTime([&]() {
699         return osAdapter_->SendRequest(req, buffer, memMapSize, resp);
700     }, __func__);
701     if (ret != HDF_SUCCESS) {
702         HDF_LOGE("%{public}s: SendRequest failed, ret=%{public}d", __func__, ret);
703         return ret;
704     }
705     UpdateResponseFromOsAdapter(response, resp);
706 
707     return HDF_SUCCESS;
708 }
709 
GetDeviceMemMapFd(uint16_t busNum,uint16_t devAddr,uint8_t interfaceIndex,int & memMapFd)710 int32_t ScsiDdkService::GetDeviceMemMapFd(uint16_t busNum, uint16_t devAddr, uint8_t interfaceIndex, int &memMapFd)
711 {
712     char path[PATH_LEN];
713     (void)memset_s(path, PATH_LEN, 0, PATH_LEN);
714     HDF_LOGD("scsi GetDeviceMemMapFd busNum:%{public}u, devAddr:%{public}u", busNum, devAddr);
715     int32_t ret = sprintf_s(path, sizeof(path), "%s_%03u_%03u_%u", SCSIPERIPHERAL_DEVICE_MMAP_PATH, busNum, devAddr,
716         interfaceIndex);
717     if (ret < HDF_SUCCESS) {
718         HDF_LOGE("%{public}s: sprintf_s error, ret=%{public}d", __func__, ret);
719         return SCSIPERIPHERAL_DDK_INVALID_OPERATION;
720     }
721 
722     HDF_LOGD("%{public}s: path is %{public}s", __func__, path);
723     int32_t fd = TrackTime([&]() {
724         return open(path, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
725     }, __func__);
726     if (fd < 0) {
727         HDF_LOGE("%{public}s: open error, path=%{public}s, errno=%{public}d", __func__, path, errno);
728         return SCSIPERIPHERAL_DDK_IO_ERROR;
729     }
730 
731     memMapFd = fd;
732     HDF_LOGD("%{public}s: memMapFd:%{public}d", __func__, memMapFd);
733 
734     return HDF_SUCCESS;
735 }
736 } // V1_0
737 } // ScsiDdk
738 } // Usb
739 } // HDI
740 } // OHOS
741