conflicting types for ‘copy_file_range’

本文介绍了解决QIHUA-X40I编译时遇到的类型冲突错误的方法。错误出现在create_inode.c文件中,与copy_file_range函数的声明冲突。解决方式是在create_inode.c文件中屏蔽掉#include<unistd.h>。

编译 QIHUA-X40I 报错如下:

./…/misc/create_inode.c:395:18: error: conflicting types for ‘copy_file_range’
static errcode_t copy_file_range(ext2_filsys fs, int fd, ext2_file_t e2_file,
^
In file included from ./…/misc/create_inode.c:19:0:
/usr/include/unistd.h:1110:9: note: previous declaration of ‘copy_file_range’ was here
ssize_t copy_file_range (int __infd, __off64_t *__pinoff,
^

解决办法:
buildroot-2017.02.3/output/build/host-e2fsprogs-1.43.3/misc/create_inode.c
屏蔽掉 #include <unistd.h>
在这里插入图片描述

// 按车道序列号排序 (lane_seq从左到右递增) std::sort(section_lanes.begin(), section_lanes.end(), [](ConstLaneInfo a, ConstLaneInfo b) { return a->lane_seq < b->lane_seq; }); /usr/include/c++/9/bits/stl_algo.h:1973:25: required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)> >]’ /usr/include/c++/9/bits/stl_algo.h:4905:18: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)>]’ modules/perception/env/src/lib/sd_navigation/SdNavigationHighway.cpp:1974:16: required from here /usr/include/c++/9/bits/stl_heap.h:225:29: error: assignment of read-only location ‘__first.__gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >::operator+(__holeIndex).__gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >::operator*()’ 225 | *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild)); | ^ /usr/include/c++/9/bits/stl_heap.h:231:29: error: assignment of read-only location ‘__first.__gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >::operator+(__holeIndex).__gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >::operator*()’ 231 | *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first | ^ In file included from /usr/include/c++/9/bits/stl_tree.h:63, from /usr/include/c++/9/map:60, from modules/perception/env/src/lib/sd_navigation/SdNavigationHighway.h:4, from modules/perception/env/src/lib/sd_navigation/SdNavigationHighway.cpp:1: /usr/include/c++/9/bits/stl_algobase.h: In instantiation of ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true; _BI1 = const cem::message::env_model::LaneInfo* const*; _BI2 = const cem::message::env_model::LaneInfo* const*]’: /usr/include/c++/9/bits/stl_algobase.h:617:5: required from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true; _BI1 = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _BI2 = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >]’ /usr/include/c++/9/bits/stl_algobase.h:686:48: required from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _BI2 = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >]’ /usr/include/c++/9/bits/stl_algo.h:1856:8: required from ‘void std::__insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)> >]’ /usr/include/c++/9/bits/stl_algo.h:1890:25: required from ‘void std::__final_insertion_sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)> >]’ /usr/include/c++/9/bits/stl_algo.h:1976:31: required from ‘void std::__sort(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = __gnu_cxx::__ops::_Iter_comp_iter<cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)> >]’ /usr/include/c++/9/bits/stl_algo.h:4905:18: required from ‘void std::sort(_RAIter, _RAIter, _Compare) [with _RAIter = __gnu_cxx::__normal_iterator<const cem::message::env_model::LaneInfo* const*, std::vector<const cem::message::env_model::LaneInfo* const> >; _Compare = cem::fusion::navigation::SdNavigationHighway::GetEmergencyLaneInfo()::<lambda(ConstLaneInfo, ConstLaneInfo)>]’ modules/perception/env/src/lib/sd_navigation/SdNavigationHighway.cpp:1974:16: required from here /usr/include/c++/9/bits/stl_algobase.h:606:37: error: no matching function for call to ‘std::__copy_move_backward<true, true, std::random_access_iterator_tag>::__copy_move_b(const cem::message::env_model::LaneInfo* const*&, const cem::message::env_model::LaneInfo* const*&, const cem::message::env_model::LaneInfo* const*&)’ 605 | return std::__copy_move_backward<_IsMove, __simple, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | _Category>::__copy_move_b(__first, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~ 607 | __last, | ~~~~~~~ 608 | __result); | ~~~~~~~~~ /usr/include/c++/9/bits/stl_algobase.h:577:2: note: candidate: ‘template<class _Tp> static _Tp* std::__copy_move_backward<_IsMove, true, std::random_access_iterator_tag>::__copy_move_b(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = true]’ 577 | __copy_move_b(const _Tp* __first, const _Tp* __last, _Tp* __result) | ^~~~~~~~~~~~~ /usr/include/c++/9/bits/stl_algobase.h:577:2: note: template argument deduction/substitution failed: /usr/include/c++/9/bits/stl_algobase.h:606:37: note: deduced conflicting types for parameter ‘_Tp’ (‘const cem::message::env_model::LaneInfo*’ and ‘const cem::message::env_model::LaneInfo* const’) 605 | return std::__copy_move_backward<_IsMove, __simple, | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 606 | _Category>::__copy_move_b(__first, | ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~ 607 | __last, | ~~~~~~~ 608 | __result); | ~~~~~~~~~
08-28
import contextlib from copy import copy from pathlib import Path import cv2 import numpy as np import pytest import torch import yaml from PIL import Image from torchvision.transforms import ToTensor from ultralytics import RTDETR, YOLO from ultralytics.cfg import TASK2DATA from ultralytics.data.build import load_inference_source from ultralytics.utils import ( ASSETS, DEFAULT_CFG, DEFAULT_CFG_PATH, LINUX, MACOS, ONLINE, ROOT, WEIGHTS_DIR, WINDOWS, Retry, checks, is_dir_writeable, ) from ultralytics.utils.downloads import download from ultralytics.utils.torch_utils import TORCH_1_9, TORCH_1_13 MODEL = WEIGHTS_DIR / "path with spaces" / "yolov8n.pt" # test spaces in path CFG = "yolov8n.yaml" SOURCE = ASSETS / "bus.jpg" TMP = (ROOT / "../tests/tmp").resolve() # temp directory for test files IS_TMP_WRITEABLE = is_dir_writeable(TMP) def test_model_forward(): """Test the forward pass of the YOLO model.""" model = YOLO(CFG) model(source=None, imgsz=32, augment=True) # also test no source and augment def test_model_methods(): """Test various methods and properties of the YOLO model.""" model = YOLO(MODEL) # Model methods model.info(verbose=True, detailed=True) model = model.reset_weights() model = model.load(MODEL) model.to("cpu") model.fuse() model.clear_callback("on_train_start") model.reset_callbacks() # Model properties _ = model.names _ = model.device _ = model.transforms _ = model.task_map def test_model_profile(): """Test profiling of the YOLO model with 'profile=True' argument.""" from ultralytics.nn.tasks import DetectionModel model = DetectionModel() # build model im = torch.randn(1, 3, 64, 64) # requires min imgsz=64 _ = model.predict(im, profile=True) @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable") def test_predict_txt(): """Test YOLO predictions with sources (file, dir, glob, recursive glob) specified in a text file.""" txt_file = TMP / "sources.txt" with open(txt_file, "w") as f: for x in [ASSETS / "bus.jpg", ASSETS, ASSETS / "*", ASSETS / "**/*.jpg"]: f.write(f"{x}\n") _ = YOLO(MODEL)(source=txt_file, imgsz=32) def test_predict_img(): """Test YOLO prediction on various types of image sources.""" model = YOLO(MODEL) seg_model = YOLO(WEIGHTS_DIR / "yolov8n-seg.pt") cls_model = YOLO(WEIGHTS_DIR / "yolov8n-cls.pt") pose_model = YOLO(WEIGHTS_DIR / "yolov8n-pose.pt") obb_model = YOLO(WEIGHTS_DIR / "yolov8n-obb.pt") im = cv2.imread(str(SOURCE)) assert len(model(source=Image.open(SOURCE), save=True, verbose=True, imgsz=32)) == 1 # PIL assert len(model(source=im, save=True, save_txt=True, imgsz=32)) == 1 # ndarray assert len(model(source=[im, im], save=True, save_txt=True, imgsz=32)) == 2 # batch assert len(list(model(source=[im, im], save=True, stream=True, imgsz=32))) == 2 # stream assert len(model(torch.zeros(320, 640, 3).numpy(), imgsz=32)) == 1 # tensor to numpy batch = [ str(SOURCE), # filename Path(SOURCE), # Path "https://ultralytics.com/images/zidane.jpg" if ONLINE else SOURCE, # URI cv2.imread(str(SOURCE)), # OpenCV Image.open(SOURCE), # PIL np.zeros((320, 640, 3)), ] # numpy assert len(model(batch, imgsz=32)) == len(batch) # multiple sources in a batch # Test tensor inference im = cv2.imread(str(SOURCE)) # OpenCV t = cv2.resize(im, (32, 32)) t = ToTensor()(t) t = torch.stack([t, t, t, t]) results = model(t, imgsz=32) assert len(results) == t.shape[0] results = seg_model(t, imgsz=32) assert len(results) == t.shape[0] results = cls_model(t, imgsz=32) assert len(results) == t.shape[0] results = pose_model(t, imgsz=32) assert len(results) == t.shape[0] results = obb_model(t, imgsz=32) assert len(results) == t.shape[0] def test_predict_grey_and_4ch(): """Test YOLO prediction on SOURCE converted to greyscale and 4-channel images.""" im = Image.open(SOURCE) directory = TMP / "im4" directory.mkdir(parents=True, exist_ok=True) source_greyscale = directory / "greyscale.jpg" source_rgba = directory / "4ch.png" source_non_utf = directory / "non_UTF_测试文件_tést_image.jpg" source_spaces = directory / "image with spaces.jpg" im.convert("L").save(source_greyscale) # greyscale im.convert("RGBA").save(source_rgba) # 4-ch PNG with alpha im.save(source_non_utf) # non-UTF characters in filename im.save(source_spaces) # spaces in filename # Inference model = YOLO(MODEL) for f in source_rgba, source_greyscale, source_non_utf, source_spaces: for source in Image.open(f), cv2.imread(str(f)), f: results = model(source, save=True, verbose=True, imgsz=32) assert len(results) == 1 # verify that an image was run f.unlink() # cleanup @pytest.mark.slow @pytest.mark.skipif(not ONLINE, reason="environment is offline") @Retry(times=3, delay=10) def test_youtube(): """ Test YouTube inference. Marked --slow to reduce YouTube API rate limits risk. """ model = YOLO(MODEL) model.predict("https://youtu.be/G17sBkb38XQ", imgsz=96, save=True) @pytest.mark.skipif(not ONLINE, reason="environment is offline") @pytest.mark.skipif(not IS_TMP_WRITEABLE, reason="directory is not writeable") def test_track_stream(): """ Test streaming tracking (short 10 frame video) with non-default ByteTrack tracker. Note imgsz=160 required for tracking for higher confidence and better matches """ video_url = "https://ultralytics.com/assets/decelera_portrait_min.mov" model = YOLO(MODEL) model.track(video_url, imgsz=160, tracker="bytetrack.yaml") model.track(video_url, imgsz=160, tracker="botsort.yaml", save_frames=True) # test frame saving also # Test Global Motion Compensation (GMC) methods for gmc in "orb", "sift", "ecc": with open(ROOT / "cfg/trackers/botsort.yaml", encoding="utf-8") as f: data = yaml.safe_load(f) tracker = TMP / f"botsort-{gmc}.yaml" data["gmc_method"] = gmc with open(tracker, "w", encoding="utf-8") as f: yaml.safe_dump(data, f) model.track(video_url, imgsz=160, tracker=tracker) def test_val(): """Test the validation mode of the YOLO model.""" YOLO(MODEL).val(data="coco8.yaml", imgsz=32, save_hybrid=True) def test_train_scratch(): """Test training the YOLO model from scratch.""" model = YOLO(CFG) model.train(data="coco8.yaml", epochs=2, imgsz=32, cache="disk", batch=-1, close_mosaic=1, name="model") model(SOURCE) def test_train_pretrained(): """Test training the YOLO model from a pre-trained state.""" model = YOLO(WEIGHTS_DIR / "yolov8n-seg.pt") model.train(data="coco8-seg.yaml", epochs=1, imgsz=32, cache="ram", copy_paste=0.5, mixup=0.5, name=0) model(SOURCE) def test_export_torchscript(): """Test exporting the YOLO model to TorchScript format.""" f = YOLO(MODEL).export(format="torchscript", optimize=False) YOLO(f)(SOURCE) # exported model inference def test_export_onnx(): """Test exporting the YOLO model to ONNX format.""" f = YOLO(MODEL).export(format="onnx", dynamic=True) YOLO(f)(SOURCE) # exported model inference @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="OpenVINO not supported in Python 3.12") @pytest.mark.skipif(not TORCH_1_13, reason="OpenVINO requires torch>=1.13") def test_export_openvino(): """Test exporting the YOLO model to OpenVINO format.""" f = YOLO(MODEL).export(format="openvino") YOLO(f)(SOURCE) # exported model inference @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="CoreML not supported in Python 3.12") def test_export_coreml(): """Test exporting the YOLO model to CoreML format.""" if not WINDOWS: # RuntimeError: BlobWriter not loaded with coremltools 7.0 on windows if MACOS: f = YOLO(MODEL).export(format="coreml") YOLO(f)(SOURCE) # model prediction only supported on macOS for nms=False models else: YOLO(MODEL).export(format="coreml", nms=True) def test_export_tflite(enabled=False): """ Test exporting the YOLO model to TFLite format. Note TF suffers from install conflicts on Windows and macOS. """ if enabled and LINUX: model = YOLO(MODEL) f = model.export(format="tflite") YOLO(f)(SOURCE) def test_export_pb(enabled=False): """ Test exporting the YOLO model to *.pb format. Note TF suffers from install conflicts on Windows and macOS. """ if enabled and LINUX: model = YOLO(MODEL) f = model.export(format="pb") YOLO(f)(SOURCE) def test_export_paddle(enabled=False): """ Test exporting the YOLO model to Paddle format. Note Paddle protobuf requirements conflicting with onnx protobuf requirements. """ if enabled: YOLO(MODEL).export(format="paddle") @pytest.mark.slow def test_export_ncnn(): """Test exporting the YOLO model to NCNN format.""" f = YOLO(MODEL).export(format="ncnn") YOLO(f)(SOURCE) # exported model inference def test_all_model_yamls(): """Test YOLO model creation for all available YAML configurations.""" for m in (ROOT / "cfg" / "models").rglob("*.yaml"): if "rtdetr" in m.name: if TORCH_1_9: # torch<=1.8 issue - TypeError: __init__() got an unexpected keyword argument 'batch_first' _ = RTDETR(m.name)(SOURCE, imgsz=640) # must be 640 else: YOLO(m.name) def test_workflow(): """Test the complete workflow including training, validation, prediction, and exporting.""" model = YOLO(MODEL) model.train(data="coco8.yaml", epochs=1, imgsz=32, optimizer="SGD") model.val(imgsz=32) model.predict(SOURCE, imgsz=32) model.export(format="onnx") # export a model to ONNX format def test_predict_callback_and_setup(): """Test callback functionality during YOLO prediction.""" def on_predict_batch_end(predictor): """Callback function that handles operations at the end of a prediction batch.""" path, im0s, _ = predictor.batch im0s = im0s if isinstance(im0s, list) else [im0s] bs = [predictor.dataset.bs for _ in range(len(path))] predictor.results = zip(predictor.results, im0s, bs) # results is List[batch_size] model = YOLO(MODEL) model.add_callback("on_predict_batch_end", on_predict_batch_end) dataset = load_inference_source(source=SOURCE) bs = dataset.bs # noqa access predictor properties results = model.predict(dataset, stream=True, imgsz=160) # source already setup for r, im0, bs in results: print("test_callback", im0.shape) print("test_callback", bs) boxes = r.boxes # Boxes object for bbox outputs print(boxes) def test_results(): """Test various result formats for the YOLO model.""" for m in "yolov8n-pose.pt", "yolov8n-seg.pt", "yolov8n.pt", "yolov8n-cls.pt": results = YOLO(WEIGHTS_DIR / m)([SOURCE, SOURCE], imgsz=160) for r in results: r = r.cpu().numpy() r = r.to(device="cpu", dtype=torch.float32) r.save_txt(txt_file=TMP / "runs/tests/label.txt", save_conf=True) r.save_crop(save_dir=TMP / "runs/tests/crops/") r.tojson(normalize=True) r.plot(pil=True) r.plot(conf=True, boxes=True) print(r, len(r), r.path) def test_labels_and_crops(): """Test output from prediction args for saving detection labels and crops.""" imgs = [SOURCE, ASSETS / "zidane.jpg"] results = YOLO(WEIGHTS_DIR / "yolov8n.pt")(imgs, imgsz=160, save_txt=True, save_crop=True) save_path = Path(results[0].save_dir) for r in results: im_name = Path(r.path).stem cls_idxs = r.boxes.cls.int().tolist() # Check label path labels = save_path / f"labels/{im_name}.txt" assert labels.exists() # Check detections match label count assert len(r.boxes.data) == len([l for l in labels.read_text().splitlines() if l]) # Check crops path and files crop_dirs = [p for p in (save_path / "crops").iterdir()] crop_files = [f for p in crop_dirs for f in p.glob("*")] # Crop directories match detections assert all([r.names.get(c) in [d.name for d in crop_dirs] for c in cls_idxs]) # Same number of crops as detections assert len([f for f in crop_files if im_name in f.name]) == len(r.boxes.data) @pytest.mark.skipif(not ONLINE, reason="environment is offline") def test_data_utils(): """Test utility functions in ultralytics/data/utils.py.""" from ultralytics.data.utils import HUBDatasetStats, autosplit from ultralytics.utils.downloads import zip_directory # from ultralytics.utils.files import WorkingDirectory # with WorkingDirectory(ROOT.parent / 'tests'): for task in "detect", "segment", "pose", "classify": file = Path(TASK2DATA[task]).with_suffix(".zip") # i.e. coco8.zip download(f"https://github.com/ultralytics/hub/raw/main/example_datasets/{file}", unzip=False, dir=TMP) stats = HUBDatasetStats(TMP / file, task=task) stats.get_json(save=True) stats.process_images() autosplit(TMP / "coco8") zip_directory(TMP / "coco8/images/val") # zip @pytest.mark.skipif(not ONLINE, reason="environment is offline") def test_data_converter(): """Test dataset converters.""" from ultralytics.data.converter import coco80_to_coco91_class, convert_coco file = "instances_val2017.json" download(f"https://github.com/ultralytics/yolov5/releases/download/v1.0/{file}", dir=TMP) convert_coco(labels_dir=TMP, save_dir=TMP / "yolo_labels", use_segments=True, use_keypoints=False, cls91to80=True) coco80_to_coco91_class() def test_data_annotator(): """Test automatic data annotation.""" from ultralytics.data.annotator import auto_annotate auto_annotate( ASSETS, det_model=WEIGHTS_DIR / "yolov8n.pt", sam_model=WEIGHTS_DIR / "mobile_sam.pt", output_dir=TMP / "auto_annotate_labels", ) def test_events(): """Test event sending functionality.""" from ultralytics.hub.utils import Events events = Events() events.enabled = True cfg = copy(DEFAULT_CFG) # does not require deepcopy cfg.mode = "test" events(cfg) def test_cfg_init(): """Test configuration initialization utilities.""" from ultralytics.cfg import check_dict_alignment, copy_default_cfg, smart_value with contextlib.suppress(SyntaxError): check_dict_alignment({"a": 1}, {"b": 2}) copy_default_cfg() (Path.cwd() / DEFAULT_CFG_PATH.name.replace(".yaml", "_copy.yaml")).unlink(missing_ok=False) [smart_value(x) for x in ["none", "true", "false"]] def test_utils_init(): """Test initialization utilities.""" from ultralytics.utils import get_git_branch, get_git_origin_url, get_ubuntu_version, is_github_action_running get_ubuntu_version() is_github_action_running() get_git_origin_url() get_git_branch() def test_utils_checks(): """Test various utility checks.""" checks.check_yolov5u_filename("yolov5n.pt") checks.git_describe(ROOT) checks.check_requirements() # check requirements.txt checks.check_imgsz([600, 600], max_dim=1) checks.check_imshow() checks.check_version("ultralytics", "8.0.0") checks.print_args() # checks.check_imshow(warn=True) def test_utils_benchmarks(): """Test model benchmarking.""" from ultralytics.utils.benchmarks import ProfileModels ProfileModels(["yolov8n.yaml"], imgsz=32, min_time=1, num_timed_runs=3, num_warmup_runs=1).profile() def test_utils_torchutils(): """Test Torch utility functions.""" from ultralytics.nn.modules.conv import Conv from ultralytics.utils.torch_utils import get_flops_with_torch_profiler, profile, time_sync x = torch.randn(1, 64, 20, 20) m = Conv(64, 64, k=1, s=2) profile(x, [m], n=3) get_flops_with_torch_profiler(m) time_sync() @pytest.mark.slow @pytest.mark.skipif(not ONLINE, reason="environment is offline") def test_utils_downloads(): """Test file download utilities.""" from ultralytics.utils.downloads import get_google_drive_file_info get_google_drive_file_info("https://drive.google.com/file/d/1cqT-cJgANNrhIHCrEufUYhQ4RqiWG_lJ/view?usp=drive_link") def test_utils_ops(): """Test various operations utilities.""" from ultralytics.utils.ops import ( ltwh2xywh, ltwh2xyxy, make_divisible, xywh2ltwh, xywh2xyxy, xywhn2xyxy, xywhr2xyxyxyxy, xyxy2ltwh, xyxy2xywh, xyxy2xywhn, xyxyxyxy2xywhr, ) make_divisible(17, torch.tensor([8])) boxes = torch.rand(10, 4) # xywh torch.allclose(boxes, xyxy2xywh(xywh2xyxy(boxes))) torch.allclose(boxes, xyxy2xywhn(xywhn2xyxy(boxes))) torch.allclose(boxes, ltwh2xywh(xywh2ltwh(boxes))) torch.allclose(boxes, xyxy2ltwh(ltwh2xyxy(boxes))) boxes = torch.rand(10, 5) # xywhr for OBB boxes[:, 4] = torch.randn(10) * 30 torch.allclose(boxes, xyxyxyxy2xywhr(xywhr2xyxyxyxy(boxes)), rtol=1e-3) def test_utils_files(): """Test file handling utilities.""" from ultralytics.utils.files import file_age, file_date, get_latest_run, spaces_in_path file_age(SOURCE) file_date(SOURCE) get_latest_run(ROOT / "runs") path = TMP / "path/with spaces" path.mkdir(parents=True, exist_ok=True) with spaces_in_path(path) as new_path: print(new_path) @pytest.mark.slow def test_utils_patches_torch_save(): """Test torch_save backoff when _torch_save throws RuntimeError.""" from unittest.mock import patch, MagicMock from ultralytics.utils.patches import torch_save mock = MagicMock(side_effect=RuntimeError) with patch("ultralytics.utils.patches._torch_save", new=mock): with pytest.raises(RuntimeError): torch_save(torch.zeros(1), TMP / "test.pt") assert mock.call_count == 4, "torch_save was not attempted the expected number of times" def test_nn_modules_conv(): """Test Convolutional Neural Network modules.""" from ultralytics.nn.modules.conv import CBAM, Conv2, ConvTranspose, DWConvTranspose2d, Focus c1, c2 = 8, 16 # input and output channels x = torch.zeros(4, c1, 10, 10) # BCHW # Run all modules not otherwise covered in tests DWConvTranspose2d(c1, c2)(x) ConvTranspose(c1, c2)(x) Focus(c1, c2)(x) CBAM(c1)(x) # Fuse ops m = Conv2(c1, c2) m.fuse_convs() m(x) def test_nn_modules_block(): """Test Neural Network block modules.""" from ultralytics.nn.modules.block import C1, C3TR, BottleneckCSP, C3Ghost, C3x c1, c2 = 8, 16 # input and output channels x = torch.zeros(4, c1, 10, 10) # BCHW # Run all modules not otherwise covered in tests C1(c1, c2)(x) C3x(c1, c2)(x) C3TR(c1, c2)(x) C3Ghost(c1, c2)(x) BottleneckCSP(c1, c2)(x) @pytest.mark.skipif(not ONLINE, reason="environment is offline") def test_hub(): """Test Ultralytics HUB functionalities.""" from ultralytics.hub import export_fmts_hub, logout from ultralytics.hub.utils import smart_request export_fmts_hub() logout() smart_request("GET", "https://github.com", progress=True) @pytest.fixture def image(): """Loads an image from a predefined source using OpenCV.""" return cv2.imread(str(SOURCE)) @pytest.mark.parametrize( "auto_augment, erasing, force_color_jitter", [ (None, 0.0, False), ("randaugment", 0.5, True), ("augmix", 0.2, False), ("autoaugment", 0.0, True), ], ) def test_classify_transforms_train(image, auto_augment, erasing, force_color_jitter): """Tests classification transforms during training with various augmentation settings.""" import torchvision.transforms as T from ultralytics.data.augment import classify_augmentations transform = classify_augmentations( size=224, mean=(0.5, 0.5, 0.5), std=(0.5, 0.5, 0.5), scale=(0.08, 1.0), ratio=(3.0 / 4.0, 4.0 / 3.0), hflip=0.5, vflip=0.5, auto_augment=auto_augment, hsv_h=0.015, hsv_s=0.4, hsv_v=0.4, force_color_jitter=force_color_jitter, erasing=erasing, interpolation=T.InterpolationMode.BILINEAR, ) transformed_image = transform(Image.fromarray(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))) assert transformed_image.shape == (3, 224, 224) assert torch.is_tensor(transformed_image) assert transformed_image.dtype == torch.float32 @pytest.mark.slow @pytest.mark.skipif(not ONLINE, reason="environment is offline") def test_model_tune(): """Tune YOLO model for performance.""" YOLO("yolov8n-pose.pt").tune(data="coco8-pose.yaml", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu") YOLO("yolov8n-cls.pt").tune(data="imagenet10", plots=False, imgsz=32, epochs=1, iterations=2, device="cpu") def test_model_embeddings(): """Test YOLO model embeddings.""" model_detect = YOLO(MODEL) model_segment = YOLO(WEIGHTS_DIR / "yolov8n-seg.pt") for batch in [SOURCE], [SOURCE, SOURCE]: # test batch size 1 and 2 assert len(model_detect.embed(source=batch, imgsz=32)) == len(batch) assert len(model_segment.embed(source=batch, imgsz=32)) == len(batch) @pytest.mark.skipif(checks.IS_PYTHON_3_12, reason="YOLOWorld with CLIP is not supported in Python 3.12") def test_yolo_world(): model = YOLO("yolov8s-world.pt") # no YOLOv8n-world model yet model.set_classes(["tree", "window"]) model(ASSETS / "bus.jpg", conf=0.01)
08-13
/* * Copyright (c) HiSilicon (Shanghai) Technologies Co., Ltd. 2020-2020. All rights reserved. * Description: * Create: 2020/04/15 */ #include <linux/module.h> #include <linux/delay.h> #include <linux/platform_device.h> #include <linux/of_address.h> #include <linux/of_pci.h> #include <linux/platform_device.h> #include <linux/of_device.h> #include <linux/pci.h> #include <linux/pci-ecam.h> #include <linux/kallsyms.h> #include <linux/err.h> #include <linux/irqchip/chained_irq.h> #include <linux/irq.h> #include <linux/msi.h> #include <linux/fwnode.h> #include <linux/acpi.h> #include <linux/idr.h> #include <linux/version.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 10, 0) #include <linux/reset-controller.h> #include <linux/reset.h> #else #include "../subctrl/include.linux/reset-controller.h" #include "../subctrl/include.linux/reset.h" #endif #include <linux/clk.h> #include <linux/version.h> #include "pcie_udrv.h" #include <linux/cpu.h> #include <linux/irq.h> #include <linux/io.h> #include <asm/sysreg.h> // 添加ARM64系统寄存器支持 LIST_HEAD(pcie_host_list); static int udrv_pcie_host_ep_init(struct platform_device *pdev); static void udrv_pcie_bottm_mask(struct irq_data *data); static void udrv_pcie_bottm_unmask(struct irq_data *data); #define copy_resource(dst, src, name_) do { \ (dst)->start = (src)->start; \ (dst)->end = (src)->end; \ (dst)->flags = (src)->flags; \ (dst)->name = name_; \ } while (0) #define RTL_MSI_BASE 0x700010 #define RTL_CPU_SHIFT 2 #define UDRV_MAX_PCIE_HOST_NUM 16 #define PCIE_DP_PORT 2 #define PCIE_UP_PORT 3 #define PCIE_MAX_FMEA_DEV_NUM 12 DEFINE_IDR(pcie_idr); static void udrv_pcie_msi_mask_irq(struct irq_data *data) { pci_msi_mask_irq(data); irq_chip_mask_parent(data); } static void udrv_pcie_msi_unmask_irq(struct irq_data *data) { pci_msi_unmask_irq(data); irq_chip_unmask_parent(data); } static struct irq_chip udrv_pcie_msi_irq_chip = { .name = "udrv_msi", .irq_mask = udrv_pcie_msi_mask_irq, .irq_unmask = udrv_pcie_msi_unmask_irq, }; static struct msi_domain_info udrv_pcie_msi_domain_info = { .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI), .chip = &udrv_pcie_msi_irq_chip, }; static void udrv_pcie_handle_msi_irq(struct udrv_pcie_host *pcie) { uint32_t status = 0; unsigned long bit_pos = 0, status_u64 = 0; uint32_t irq; handle pf_handle = pcie->host_info.pf_handle; uint32_t ret = ndrv_pcie_host_get_msi_status(pf_handle, &status); if ((ret != 0) || (status == 0)) { return; } status_u64 = (unsigned long)status; (void)ndrv_pcie_host_msi_mask_all(pf_handle, 0xFFFFFFFF); while ((bit_pos = find_next_bit(&status_u64, UDRV_MAX_MSI_IRQS, bit_pos)) != UDRV_MAX_MSI_IRQS) { irq = irq_find_mapping(pcie->msi.irq_domain, bit_pos); (void)ndrv_pcie_host_msi_clear(pf_handle, (u32)bit_pos); generic_handle_irq(irq); bit_pos++; } (void)ndrv_pcie_host_msi_mask_all(pf_handle, 0); } static void udrv_pcie_handle_chained_msi_irq(struct irq_desc *desc) { struct udrv_pcie_host *pcie = NULL; struct irq_chip *chip = irq_desc_get_chip(desc); chained_irq_enter(chip, desc); pcie = irq_desc_get_handler_data(desc); udrv_pcie_handle_msi_irq(pcie); chained_irq_exit(chip, desc); } static void udrv_pcie_compose_msi_msg(struct irq_data *data, struct msi_msg *msg) { struct udrv_pcie_host *pcie = irq_data_get_irq_chip_data(data); struct udrv_pcie_host_msi_info *msi = &pcie->msi; // msg->address_lo = lower_32_bits(msi->msi_addr); msg->address_lo = lower_32_bits(msi->dynamic_msi_addr); msg->address_hi = upper_32_bits(msi->msi_addr); msg->data = (u32)data->hwirq; dev_info(pcie->dev, "[iWare][Info] msi#%d address_hi %#x address_lo %#x\n", (int)data->hwirq, msg->address_hi, msg->address_lo); } // static int udrv_pcie_msi_set_affinity(struct irq_data *irq_data, const struct cpumask *mask, bool force) // { // unsigned long flags; // struct udrv_pcie_host *pcie = irq_data_get_irq_chip_data(irq_data); // struct cpumask online_mask; // unsigned int cpu; // u64 new_addr; // uint32_t status; // 声明提前到代码块开头 // int ret = 0; // // 1. 验证并选择目标CPU // cpumask_and(&online_mask, dest_mask, cpu_online_mask); // if (cpumask_empty(&online_mask)) { // dev_err(pcie->dev, "No online CPU in affinity mask\n"); // return -EINVAL; // } // // 使用拓扑感知的CPU选择 // cpu = cpumask_first(&online_mask); // 简化选择逻辑 // // 2. 加锁保护 // raw_spin_lock_irqsave(&pcie->msi.lock, flags); // // 3. 临时屏蔽中断并清除状态 // ndrv_pcie_host_msi_mask_all(pcie->host_info.pf_handle, 0xFFFFFFFF); // // 4. 清除挂起状态 // ndrv_pcie_host_get_msi_status(pcie->host_info.pf_handle, &status); // ndrv_pcie_host_msi_clear(pcie->host_info.pf_handle, status); // // 5. 构建符合规范的MSI地址 // /* 根据PCIe规范设置地址 */ // new_addr = pcie->msi.msi_addr & ~0x1FUL; // 清除低5位 // new_addr |= (cpu & 0x7) << 4; // 将CPU ID放置在bit[6:4] // dev_info(pcie->dev, "Fixed MSI addr: CPU%d → 0x%llx (was 0x%llx)\n", cpu, new_addr, pcie->msi.msi_addr); // // 6. 更新硬件地址 // ret = ndrv_pcie_host_set_msi_addr(pcie->host_info.pf_handle, new_addr); // if (ret) { // dev_err(pcie->dev, "Set MSI addr failed: %d\n", ret); // goto cleanup; // } // // 7. 更新软件状态 // pcie->msi.dynamic_msi_addr = new_addr; // irq_data_update_effective_affinity(irq_data, cpumask_of(cpu)); // // 8. 调试信息(包含完整地址) // dev_info(pcie->dev, "MSI affinity set to CPU%d (addr=0x%llx)\n", // cpu, new_addr); // cleanup: // // 9. 解除屏蔽 // ndrv_pcie_host_msi_mask_all(pcie->host_info.pf_handle, 0); // // 10. 使用标准内存屏障替代专用函数 // wmb(); // 写内存屏障保证顺序 // raw_spin_unlock_irqrestore(&pcie->msi.lock, flags); // return ret ? ret : IRQ_SET_MASK_OK; // } // static int udrv_pcie_msi_set_affinity(struct irq_data *irq_data, const struct cpumask *mask, bool force) // { // int target_cpu = cpumask_first(mask); // int curr_cpu; // curr_cpu = hwirq_to_cpu(irq_data->hwirq); // if (curr_cpu == target_cpu) // return IRQ_SET_MASK_OK_DONE; // /* Update MSI number to target the new CPU */ // irq_data->hwirq = hwirq_to_canonical_hwirq(irq_data->hwirq) + target_cpu; // return IRQ_SET_MASK_OK; // } static int udrv_pcie_msi_set_affinity(struct irq_data *irq_data, const struct cpumask *mask, bool force) { int target_cpu = cpumask_first(mask); int curr_cpu; curr_cpu = hwirq_to_cpu(irqdata->hwirq); if (curr_cpu == target_cpu) return IRQ_SET_MASK_OK_DONE; /* Update MSI number to target the new CPU */ irqdata->hwirq = hwirq_to_canonical_hwirq(irqdata->hwirq) + target_cpu; return IRQ_SET_MASK_OK; } static int hwirq_to_cpu(unsigned long hwirq) { return (hwirq % pcie_msi_ctrl.num_cpus); } static unsigned long hwirq_to_canonical_hwirq(unsigned long hwirq) { return (hwirq - hwirq_to_cpu(hwirq)); } static void udrv_pcie_bottm_mask(struct irq_data *data) { struct udrv_pcie_host *pcie = irq_data_get_irq_chip_data(data); struct udrv_pcie_host_msi_info *msi = &pcie->msi; handle pf_handle = pcie->host_info.pf_handle; unsigned long flags; raw_spin_lock_irqsave(&msi->lock, flags); ndrv_pcie_host_msi_mask_one(pf_handle, (u32)data->hwirq, 1); raw_spin_unlock_irqrestore(&msi->lock, flags); } static void udrv_pcie_bottm_unmask(struct irq_data *data) { struct udrv_pcie_host *pcie = irq_data_get_irq_chip_data(data); struct udrv_pcie_host_msi_info *msi = &pcie->msi; handle pf_handle = pcie->host_info.pf_handle; unsigned long flags; raw_spin_lock_irqsave(&msi->lock, flags); ndrv_pcie_host_msi_mask_one(pf_handle, (u32)data->hwirq, 0); raw_spin_unlock_irqrestore(&msi->lock, flags); } static struct irq_chip udrv_pcie_msi_bottom_irq_chip = { .name = "udrv_bottom_msi", .irq_compose_msi_msg = udrv_pcie_compose_msi_msg, .irq_set_affinity = udrv_pcie_msi_set_affinity, .irq_mask = udrv_pcie_bottm_mask, .irq_unmask = udrv_pcie_bottm_unmask, }; static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int num_irqs, void *args) { unsigned long flags; struct udrv_pcie_host *pcie = domain->host_data; struct udrv_pcie_host_msi_info *msi = &pcie->msi; int bit; uint32_t i; raw_spin_lock_irqsave(&msi->lock, flags); bit = bitmap_find_free_region(msi->msi_irq_in_use_bits, UDRV_MAX_MSI_IRQS, order_base_2(num_irqs)); raw_spin_unlock_irqrestore(&msi->lock, flags); if (bit < 0) { return -ENOSPC; } for (i = 0; i < num_irqs; i++) { irq_domain_set_info(domain, virq + i, bit + i, &udrv_pcie_msi_bottom_irq_chip, pcie, handle_level_irq, NULL, NULL); } return 0; } static void udrv_pcie_irq_domain_free(struct irq_domain *domain, unsigned int virq, unsigned int num_irqs) { unsigned long flags; struct udrv_pcie_host *pcie = domain->host_data; struct udrv_pcie_host_msi_info *msi = &pcie->msi; struct irq_data *data = irq_domain_get_irq_data(domain, virq); uint32_t i; raw_spin_lock_irqsave(&msi->lock, flags); bitmap_release_region(msi->msi_irq_in_use_bits, (u32)data->hwirq, order_base_2(num_irqs)); raw_spin_unlock_irqrestore(&msi->lock, flags); for (i = 0; i < num_irqs; i++) { data = irq_domain_get_irq_data(domain, virq + i); irq_domain_reset_irq_data(data); } } static const struct irq_domain_ops udrv_pcie_msi_domain_ops = { .alloc = dw_pcie_irq_domain_alloc, .free = udrv_pcie_irq_domain_free, }; static void udrv_pcie_remove_msi(struct udrv_pcie_host *pcie) { handle pf_handle = pcie->host_info.pf_handle; struct udrv_pcie_host_msi_info *msi = &pcie->msi; (void)ndrv_pcie_host_msi_mask_all(pf_handle, 0xFFFFFFFF); if (msi->msi_trans_type == MSI_ITS) { return; } irq_set_chained_handler((u32)msi->irq, NULL); irq_set_handler_data((u32)msi->irq, NULL); irq_domain_remove(msi->msi_domain); irq_domain_remove(msi->irq_domain); } static int udrv_pcie_allocate_msi_domains(struct udrv_pcie_host *pcie) { struct udrv_pcie_host_msi_info *msi = &pcie->msi; struct fwnode_handle *fwnode = of_node_to_fwnode(pcie->dev->of_node); msi->irq_domain = irq_domain_create_linear(fwnode, UDRV_MAX_MSI_IRQS, &udrv_pcie_msi_domain_ops, pcie); if (!msi->irq_domain) { dev_err(pcie->dev, "[iWare][Error] irq_domain_create_linear fail\n"); return -ENOMEM; } msi->msi_domain = pci_msi_create_irq_domain(fwnode, &udrv_pcie_msi_domain_info, msi->irq_domain); if (!msi->msi_domain) { irq_domain_remove(msi->irq_domain); dev_err(pcie->dev, "[iWare][Error] pci_msi_create_irq_domain fail\n"); return -ENOMEM; } return 0; } static int udrv_pcie_get_msi_info_from_dt(struct udrv_pcie_host *pcie) { struct device *dev = pcie->dev; struct udrv_pcie_host_msi_info *msi = &pcie->msi; struct resource *res = NULL; struct platform_device *pdev = to_platform_device(dev); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "msi"); if (!res) { dev_err(dev, "[iWare][Error] get msi address fail\n"); return -EINVAL; } if (of_property_read_u32(dev->of_node, "msi-trans-type", (u32 *)(uintptr_t)(&msi->msi_trans_type)) != 0) { msi->msi_trans_type = MSI_ITS; } msi->msi_addr = res->start; if (msi->msi_trans_type == MSI_ITS) { return 0; } msi->irq = platform_get_irq(pdev, 0); if (msi->irq <= 0) { dev_info(dev, "[iWare][Info] no msi irq,now jump\n"); return 0; } return 0; } static void udrv_pcie_free_atu_info(struct udrv_pcie_host *pcie) { struct list_head *head = &pcie->host_info.atu_info.entry; struct udrv_pcie_atu_info *tmp = NULL; struct udrv_pcie_atu_info *pos = NULL; list_for_each_entry_safe(pos, tmp, head, entry) { list_del(&pos->entry); kfree(pos); } } static void udrv_pcie_free_port_info(struct udrv_pcie_host *pcie) { struct list_head *head = &pcie->port_info.entry; struct udrv_pcie_port_info *tmp = NULL; struct udrv_pcie_port_info *pos = NULL; list_for_each_entry_safe(pos, tmp, head, entry) { if (pos->idr >= 0) { idr_remove(&pcie_idr, pos->idr); } list_del(&pos->entry); kfree(pos); } } static int udrv_pcie_get_atu_info_from_dt(struct udrv_pcie_host *pcie) { struct device *dev = pcie->dev; struct udrv_pcie_atu_info *atu_info = NULL; struct list_head *head = &pcie->host_info.atu_info.entry; struct of_pci_range_parser parser; struct of_pci_range range; int ret = of_pci_range_parser_init(&parser, dev->of_node); if (ret != 0) { dev_err(dev, "[iWare][Error] parser range failed\n"); goto err_range; } for_each_of_pci_range(&parser, &range) { if (((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_IO) && ((range.flags & IORESOURCE_TYPE_BITS) != IORESOURCE_MEM)) { continue; } atu_info = kzalloc(sizeof(struct udrv_pcie_atu_info), GFP_KERNEL); if (atu_info == NULL) { ret = -ENOMEM; goto fail; } atu_info->cpu_addr = range.cpu_addr; atu_info->pcie_addr = range.pci_addr; atu_info->size = range.size; atu_info->atu_mode = ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM) ? 0 : 1; list_add_tail(&atu_info->entry, head); } return 0; fail: udrv_pcie_free_atu_info(pcie); err_range: ndrv_pcie_close_pf(pcie->host_info.pf_handle, pcie->host_info.core_version); return ret; } static int udrv_pcie_get_host_property_info_from_dt(struct device *dev, struct udrv_pcie_host_info *host_info) { if (of_property_read_u32(dev->of_node, "type-support", (u32 *)(uintptr_t)(&host_info->type_support_mask)) != 0) { dev_info(dev, "[iWare] no declare type support, default rp mode\n"); set_bit(NDRV_PCIE_RP_MODE, &(host_info->type_support_mask)); } if (of_property_read_u32(dev->of_node, "clocks_num", &host_info->clk_num) != 0) { dev_err(dev, "[iWare][Error] Faild read clk_num\n"); return -EINVAL; } if (of_property_read_u32(dev->of_node, "resets_num", &host_info->rst_num) != 0) { dev_err(dev, "[iWare][Error] Faild read rsts_num\n"); return -EINVAL; } if (of_property_read_u32(dev->of_node, "core-version", &host_info->core_version) != 0) { dev_err(dev, "[iWare][Error] Faild to read core version\n"); return -EINVAL; } if (of_property_read_u32(dev->of_node, "rc_mode", (u32 *)(uintptr_t)(&host_info->rc_mode)) != 0) { host_info->rc_mode = NDRV_PCIE_RC_NORMAL; } return 0; } static int udrv_pcie_get_host_info_from_dt(struct udrv_pcie_host *pcie) { struct device *dev = pcie->dev; struct platform_device *pdev = to_platform_device(dev); struct udrv_pcie_host_info *host_info = &pcie->host_info; struct resource *apb_res = NULL; struct io_region region; int ret; if (of_property_read_u32(dev->of_node, "linux,pci-domain", &host_info->host_id) != 0) { dev_err(dev, "[iWare][Error] Faild read pci-domain\n"); return -EINVAL; } if (host_info->host_id >= UDRV_MAX_PCIE_HOST_NUM) { dev_err(dev, "[iWare][Error] Invalid domain nr = 0x%x\n", host_info->host_id); return -EINVAL; } ret = udrv_pcie_get_host_property_info_from_dt(dev, host_info); if (ret != 0) { return ret; } apb_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); if (apb_res == NULL) { dev_err(dev, "[iWare][Error] Faild to get dbi address\n"); return -EINVAL; } host_info->apb_base = devm_pci_remap_cfgspace(dev, apb_res->start, resource_size(apb_res)); host_info->apb_paddr = apb_res->start; host_info->apb_size = (u32)resource_size(apb_res); if (IS_ERR(host_info->apb_base)) { dev_err(dev, "[iWare][Error] Faild to remap apb_base\n"); return -EINVAL; } region.io_base = host_info->apb_base; region.io_size = host_info->apb_size; host_info->pf_handle = ndrv_pcie_open_pf(&region, host_info->core_version, host_info->rc_mode); if (host_info->pf_handle == NULL) { dev_err(pcie->dev, "[iWare][Error] ndrv pcie_open_pf fail\n"); return -EINVAL; } return udrv_pcie_get_atu_info_from_dt(pcie); } static int udrv_pcie_host_init(struct udrv_pcie_host *pcie) { u32 ret; u32 atu_id = 0; struct ndrv_pcie_ecam_cfg_info ecam_cfg; struct ndrv_pcie_atu_cfg_info atu_cfg; struct udrv_pcie_host_info *host_info = &pcie->host_info; struct udrv_pcie_atu_info *pos = NULL; struct list_head *head = &pcie->host_info.atu_info.entry; /* 仅支持RP的host,需要初始化TX atu和ecam */ if (test_bit(NDRV_PCIE_RP_MODE, &(host_info->type_support_mask)) != 0) { list_for_each_entry(pos, head, entry) { atu_cfg.tx_src_base_addr = pos->cpu_addr; atu_cfg.tx_dst_base_addr = pos->pcie_addr; atu_cfg.tx_region_size = pos->size; atu_cfg.atu_mode = pos->atu_mode; ret = ndrv_pcie_host_ap_atu_init(host_info->pf_handle, &atu_cfg, atu_id); ++atu_id; if (ret != 0) { pr_err("[iWare][Error] init atu:0x%x failed, ret=%u\n", atu_id, ret); return -EINVAL; } } ecam_cfg.ecam_base_addr_l = (u32)(host_info->ecam_res.start); ecam_cfg.ecam_base_addr_h = (u32)(host_info->ecam_res.start >> 32); /* 高32bit */ ecam_cfg.ecam_base_size = (u32)resource_size(&host_info->ecam_res); ecam_cfg.ecam_start_bus_no = (u32)host_info->bus_res.start; ret = ndrv_pcie_host_ap_ecam_init(host_info->pf_handle, &ecam_cfg); if (ret != 0) { pr_err("[iWare][Error] init ap ecam failed, ret=%u\n", ret); return -EINVAL; } } ret = ndrv_pcie_host_ap_enable(host_info->pf_handle, 1); if (ret != 0) { pr_err("[iWare][Error] ap enable failed, ret=%u\n", ret); return -EINVAL; } return 0; } #ifdef CONFIG_UDRV_FMEA static int pcie_fmea_init(struct udrv_pcie_host *pcie) { int ret; struct fmea_dev_info dev_info; const struct ndrv_fmea_item_info *item_table; struct ndrv_pcie_fmea_open_cfg cfg; dev_info.dev = pcie->dev; dev_info.pdev_id = pcie->host_info.host_id; dev_info.name = FMEA_MODULE_NAME(pcie); cfg.paddr = pcie->host_info.apb_paddr; item_table = ndrv_pcie_pf_get_fmea_table(pcie->host_info.pf_handle, &cfg); if (item_table == NULL) { dev_err(pcie->dev, "[iWare][Error] pcie get_fmea_table fail\n"); return -EINVAL; } ret = kdrv_fmea_iomm_unit_list_init(&dev_info, item_table, &pcie->iomm_info); if (ret != 0) { dev_err(pcie->dev, "[iWare][Error] kdrv fmea_iomm_unit_list_init fail\n"); return -EINVAL; } return 0; } static void pcie_fmea_deinit(struct udrv_pcie_host *pcie) { kdrv_fmea_iomm_unit_list_deinit(&pcie->iomm_info); } int kdrv_pcie_fmea_entry(u32 pcie_id, u32 group_id, u64 *err_info, u32 *alm_flg, char *buf, u32 size) { struct udrv_pcie_host *pcie = NULL; struct fmea_iomm_unit *pcie_fmobj = NULL; pcie = hisi_pcie_get_by_host_id(pcie_id); if (pcie == NULL) { pr_err("[iWare][Error] [pcie fmea entry], get pcie failed\n"); return -ENODEV; } if (group_id >= pcie->iomm_info.group_num) { return -ERANGE; } pcie_fmobj = &pcie->iomm_info.iomms[group_id]; if (!pcie_fmobj) { return -ENODEV; } return kdrv_fmea_entry(pcie_fmobj, err_info, alm_flg, buf, size); } EXPORT_SYMBOL(kdrv_pcie_fmea_entry); int kdrv_pcie_get_fmea_group_num_(struct udrv_pcie_host *pcie, uint32_t *num) { if (pcie == NULL || num == NULL) { return -EINVAL; } *num = pcie->iomm_info.group_num; return 0; } int kdrv_pcie_get_fmea_dev_num_(struct udrv_pcie_host *pcie, uint32_t *num) { if (pcie == NULL || num == NULL) { return -EINVAL; } *num = PCIE_MAX_FMEA_DEV_NUM; return 0; } #endif static int udrv_pcie_host_ecam_init(struct pci_config_window *cfg_w) { int ret; struct platform_device *pdev = to_platform_device(cfg_w->parent); struct udrv_pcie_host *pcie = platform_get_drvdata(pdev); struct udrv_pcie_host_info *host_info = &pcie->host_info; struct resource *cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config"); if (!cfg_res) { pr_err("[iWare]cfg_res is null\n"); return -EINVAL; } copy_resource(&host_info->ecam_res, cfg_res, "config"); copy_resource(&host_info->bus_res, &cfg_w->busr, "bus"); #ifdef CONFIG_UDRV_DEBUG udrv_pcie_show_host_info(pcie); #endif ret = pcie->ops->port_ops->init(pcie); if (ret != 0) { pr_err("[iWare][Error] port init failed,ret=%d\n", ret); return ret; } ret = pcie->ops->host_ops->init(pcie); if (ret != 0) { pr_err("[iWare][Error] host init failed,ret=%d\n", ret); return ret; } ret = pcie->ops->msi_ops->init(pcie); if (ret != 0) { pr_err("[iWare][Error] msi init failed,ret=%d\n", ret); } return ret; } /* host仅支持ep场景,仅初始化芯片 */ static int udrv_pcie_host_ep_init(struct platform_device *pdev) { int ret; struct udrv_pcie_host *pcie = platform_get_drvdata(pdev); #ifdef CONFIG_UDRV_DEBUG udrv_pcie_show_host_info(pcie); #endif ret = pcie->ops->port_ops->init(pcie); if (ret != 0) { return ret; } ret = pcie->ops->host_ops->init(pcie); if (ret != 0) { return ret; } ret = pcie->ops->msi_ops->init(pcie); return ret; } static int udrv_pcie_get_switch_info(struct device *dev, struct device_node *child, struct udrv_pcie_port_info *port_info) { if (of_property_read_u32(child, "switch-core-id", &port_info->switch_core_id) != 0) { dev_err(dev, "[iWare][Error] Faild to read switch-core-id\n"); return -EINVAL; } if (of_property_read_u32(child, "core-0-1-dp-bitmap", &port_info->core_0_1_dp_bitmap) != 0) { dev_err(dev, "[iWare][Error] Faild to read core-0-1-dp-bitmap\n"); return -EINVAL; } if (of_property_read_u32(child, "core-2-3-dp-bitmap", &port_info->core_2_3_dp_bitmap) != 0) { dev_err(dev, "[iWare][Error] Faild to read core-2-3-dp-bitmap\n"); return -EINVAL; } if (of_property_read_u32(child, "up-core-id", &port_info->up_core_id) != 0) { dev_err(dev, "[iWare][Error] Faild to read up-core-id\n"); return -EINVAL; } return 0; } static int udrv_pcie_get_port_info_from_dts(struct device *dev, struct device_node *child, struct udrv_pcie_port_info *port_info) { if (of_property_read_u32(child, "port-type", &port_info->port_type) != 0) { dev_err(dev, "[iWare][Error] Faild to read port-type\n"); return -EINVAL; } if (port_info->port_type == NDRV_PCIE_EP_MODE) { if (of_property_read_u64(child, "ep-addr", &port_info->ep_addr) != 0) { dev_err(dev, "[iWare][Error] Faild to read ep_addr\n"); return -EINVAL; } if (of_property_read_u32(child, "ep-size", &port_info->ep_size) != 0) { dev_err(dev, "[iWare][Error] Faild to read ep_size\n"); return -EINVAL; } } if (of_property_read_u32(child, "port-id", &port_info->port_id) != 0) { dev_err(dev, "[iWare][Error] Faild to read port-id\n"); return -EINVAL; } if (of_property_read_u32(child, "lport-id", &port_info->lport_id) != 0) { dev_err(dev, "[iWare][Error] Faild to read lport-id\n"); return -EINVAL; } if (of_property_read_u32(child, "pri_bus", &port_info->pri_bus) != 0) { port_info->pri_bus = 0; } if (of_property_read_u32(child, "sec_bus", &port_info->sec_bus) != 0) { port_info->sec_bus = 0; } if (of_property_read_u32(child, "sub_bus", &port_info->sub_bus) != 0) { port_info->sub_bus = 0; } return 0; } static int udrv_pcie_get_port_info_child_dt(struct device *dev, struct device_node *child, struct udrv_pcie_port_info *port_info) { int ret; ret = udrv_pcie_get_port_info_from_dts(dev, child, port_info); if (ret != 0) { return ret; } if (of_property_read_u32(child, "lanes-nums", &port_info->lane_num) != 0) { dev_err(dev, "[iWare][Error] Faild to read lanes\n"); return -EINVAL; } if (of_property_read_u32(child, "max-lanes", &port_info->max_lanes) != 0) { port_info->max_lanes = port_info->lane_num; } if (of_property_read_u32(child, "max-speed", &port_info->max_speed) != 0) { dev_err(dev, "[iWare][Error] Faild to read max-speed\n"); return -EINVAL; } if (of_property_read_u32(child, "target-speed", &port_info->target_speed) != 0) { port_info->target_speed = port_info->max_speed; } if (of_property_read_u32(child, "payload", &port_info->payload) != 0) { port_info->payload = NDRV_PCIE_PAYLOAD_128B; } if (of_property_read_u32(child, "read_req", &port_info->read_req) != 0) { port_info->read_req = NDRV_PCIE_PAYLOAD_512B; } if (of_property_read_u32(child, "pcs_clk", &port_info->pcs_clk) != 0) { port_info->pcs_clk = NDRV_PCIE_PCS_CLK_100M; } if (of_property_read_u32(child, "core-id", &port_info->core_id) != 0) { port_info->core_id = 0; } if (of_property_read_u32(child, "probe", &port_info->is_probe) != 0) { port_info->is_probe = 0; } if (of_property_read_u32(child, "aer_en", &port_info->aer_en) != 0) { port_info->aer_en = 0; } if (port_info->port_type == PCIE_DP_PORT || port_info->port_type == PCIE_UP_PORT) { return udrv_pcie_get_switch_info(dev, child, port_info); } return 0; } static int udrv_pcie_get_port_info_from_dt(struct udrv_pcie_host *pcie) { struct device *dev = pcie->dev; struct device_node *child = NULL; struct udrv_pcie_port_info *port_info = NULL; struct list_head *head = &pcie->port_info.entry; int ret; for_each_child_of_node(dev->of_node, child) { port_info = kzalloc(sizeof(struct udrv_pcie_port_info), GFP_KERNEL); if (!port_info) { ret = -ENOMEM; goto get_port_fail; } list_add_tail(&port_info->entry, head); ret = udrv_pcie_get_port_info_child_dt(dev, child, port_info); if (ret != 0) { dev_err(dev, "[iWare][Error] get child dt failed,ret:%d\n", ret); goto get_port_fail; } port_info->idr = (u32)idr_alloc(&pcie_idr, pcie, (int)port_info->lport_id, (int)port_info->lport_id + 1, GFP_KERNEL); if ((port_info->idr < 0) || (port_info->idr != port_info->lport_id)) { dev_err(dev, "[iWare][Error] idr_alloc fail, port_id:%d, idr:%d\n", port_info->port_id, port_info->idr); ret = -ENOSPC; goto get_port_fail; } } return 0; get_port_fail: udrv_pcie_free_port_info(pcie); return ret; } static int udrv_pcie_subctrl_dereset(struct udrv_pcie_host *pcie) { struct device *dev = pcie->dev; struct reset_control *rst = NULL; struct clk *clk = NULL; struct device_node *node = dev->of_node; int ret, i; u32 clk_num = pcie->host_info.clk_num; u32 rst_num = pcie->host_info.rst_num; for (i = 0; i < (int)rst_num; i++) { rst = of_reset_control_get_by_index(node, i); if (IS_ERR(rst)) { dev_err(dev, "[iWare][Error] [udrv pcie_subctrl_dereset] get rst failed\n"); return -EFAULT; } ret = reset_control_deassert(rst); if (ret != 0) { dev_err(dev, "[iWare][Error] [udrv pcie_subctrl_dereset] soft rst failed, ret=%d\n", ret); return ret; } reset_control_put(rst); } for (i = 0; i < (int)clk_num; i++) { clk = of_clk_get(node, i); if (IS_ERR(clk)) { dev_err(dev, "[iWare][Error] [udrv pcie_subctrl_dereset] get clk failed\n"); return -EFAULT; } ret = clk_prepare_enable(clk); if (ret != 0) { dev_err(dev, "[iWare][Error] [udrv pcie_subctrl_dereset] open clk failed, ret=%d\n", ret); return ret; } clk_put(clk); } return 0; } static void udrv_pcie_convert_port_cfg(struct ndrv_pcie_port_cfg_info *cfg, struct udrv_pcie_port_info *pos) { cfg->phy_port_id = pos->port_id; cfg->mode = pos->port_type; cfg->ep_addr = pos->ep_addr; cfg->ep_size = pos->ep_size; cfg->lane_num = pos->lane_num; cfg->target_speed = pos->target_speed; cfg->max_lane = pos->max_lanes; cfg->max_speed = pos->max_speed; cfg->core_id = pos->core_id; cfg->payload = pos->payload; cfg->read_req = pos->read_req; cfg->pcs_clk = pos->pcs_clk; cfg->switch_info.switch_core_id = pos->switch_core_id; cfg->switch_info.core0_1_dp_bitmap = pos->core_0_1_dp_bitmap; cfg->switch_info.core2_3_dp_bitmap = pos->core_2_3_dp_bitmap; cfg->switch_info.up_core_id = pos->up_core_id; cfg->pri_bus = pos->pri_bus; cfg->sec_bus = pos->sec_bus; cfg->sub_bus = pos->sub_bus; cfg->aer_en = pos->aer_en; } static int udrv_pcie_port_init(struct udrv_pcie_host *pcie) { u32 u_ret; int ret; struct udrv_pcie_host_info *host_info = &pcie->host_info; struct udrv_pcie_port_info *pos = NULL; struct list_head *head = &pcie->port_info.entry; struct ndrv_pcie_port_cfg_info cfg; /* 打开时钟和解复位 */ ret = udrv_pcie_subctrl_dereset(pcie); if (ret != 0) { dev_err(pcie->dev, "[iWare][Error] host_id = %u, subctrl failed, ret = 0x%x\n", host_info->host_id, ret); return ret; } list_for_each_entry(pos, head, entry) { udrv_pcie_convert_port_cfg(&cfg, pos); u_ret = ndrv_pcie_host_port_init(host_info->pf_handle, &cfg); if (u_ret != 0) { dev_err(pcie->dev, "[iWare][Error] port_init fail, host_id = %u, ret = 0x%x\n", host_info->host_id, u_ret); return -EINVAL; } if (pos->is_probe != 0) { u_ret = ndrv_pcie_set_port_enable(host_info->pf_handle, pos->core_id, pos->port_id, 1); if (u_ret != 0) { return -EINVAL; } } } return 0; } static int udrv_pcie_msi_init(struct udrv_pcie_host *pcie) { struct udrv_pcie_host_msi_info *msi = &pcie->msi; handle pf_handle = pcie->host_info.pf_handle; u32 u_ret; int ret; pcie->msi.dynamic_msi_addr = pcie->msi.msi_addr; // 初始化为DT值 u_ret = ndrv_pcie_host_set_msi_addr(pf_handle, msi->dynamic_msi_addr); if (u_ret != 0) { return -EINVAL; } u_ret = ndrv_pcie_host_set_msi_enable(pf_handle, msi->msi_trans_type); if (u_ret != 0) { return -EINVAL; } if (msi->msi_trans_type == MSI_ITS) { return 0; } raw_spin_lock_init(&msi->lock); ret = udrv_pcie_allocate_msi_domains(pcie); if (ret != 0) { dev_err(pcie->dev, "[iWare][Error] allocate_msi_domains fail, ret = %d\n", ret); return ret; } irq_set_chained_handler_and_data((u32)msi->irq, udrv_pcie_handle_chained_msi_irq, pcie); return 0; } static void __iomem *udrv_pcie_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, int where) { u32 bus_no = bus->number; void __iomem *base = NULL; struct pci_config_window *config = bus->sysdata; u32 devfn_shift = config->ops->bus_shift - 8; // dev + func = 5 + 3 = 8 if ((bus_no < config->busr.start) || (bus_no > config->busr.end)) { return NULL; } bus_no -= (u32)config->busr.start; base = config->win + (bus_no << config->ops->bus_shift); return base + (devfn << devfn_shift) + where; } static int udrv_pcie_host_common_probe(struct platform_device *pdev, struct pci_ecam_ops *ops) { #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) return pci_host_common_probe(pdev, ops); #else struct udrv_pcie_host *pcie = platform_get_drvdata(pdev); int ret; ret = pci_host_common_probe(pdev); // 5.10调用完内核的probe之后drvdata会被设成bridge,需要设回来,同时保存bridge以便remove时使用 pcie->bridge = platform_get_drvdata(pdev); platform_set_drvdata(pdev, pcie); return ret; #endif } static int udrv_pcie_host_common_remove(struct platform_device *pdev) { #if LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0) return 0; // 早期版本的内核没有提供remove接口 #else struct udrv_pcie_host *pcie = platform_get_drvdata(pdev); // 调用内核的remove之前需要将drvdata设成框架要求的bridge platform_set_drvdata(pdev, pcie->bridge); return pci_host_common_remove(pdev); #endif } static int udrv_pcie_host_probe_for_dt(struct udrv_pcie_host *pcie) { struct platform_device *pdev = to_platform_device(pcie->dev); struct udrv_pcie_host_info *host_info = &pcie->host_info; /* host支持RC模式时,需要通过内核接口触发probe */ if (test_bit(NDRV_PCIE_RP_MODE, &(host_info->type_support_mask)) != 0) { return udrv_pcie_host_common_probe(pdev, &pcie->ops->host_ops->ecam_ops); } else { /* 不支持rc的host(ep or switch),不调用内核接口创建host,直接初始化芯片 */ return udrv_pcie_host_ep_init(pdev); } } static struct udrv_pcie_host_ops g_pcie_host_ops_for_dt = { .ecam_ops = { .bus_shift = 20, /* 20bus的起始bit */ .init = udrv_pcie_host_ecam_init, .pci_ops = { .map_bus = udrv_pcie_ecam_map_bus, .read = pci_generic_config_read, .write = pci_generic_config_write, } }, .probe = udrv_pcie_host_probe_for_dt, .get_info = udrv_pcie_get_host_info_from_dt, .init = udrv_pcie_host_init, }; static struct udrv_pcie_port_ops g_pcie_port_ops_for_dt = { .get_info = udrv_pcie_get_port_info_from_dt, .init = udrv_pcie_port_init, }; static struct udrv_pcie_msi_ops g_pcie_msi_ops_for_dt = { .get_info = udrv_pcie_get_msi_info_from_dt, .init = udrv_pcie_msi_init, }; static const struct udrv_pcie_ops g_pcie_ops_for_dt = { .port_ops = &g_pcie_port_ops_for_dt, .host_ops = &g_pcie_host_ops_for_dt, .msi_ops = &g_pcie_msi_ops_for_dt, }; static const struct of_device_id g_udrv_pcie_of_match[] = { { .compatible = "hisilicon,udrv-pcie-ecam-dt", .data = &g_pcie_host_ops_for_dt.ecam_ops, }, {}, }; MODULE_DEVICE_TABLE(of, g_udrv_pcie_of_match); static const struct udrv_pcie_ops *udrv_pcie_get_host_ops(struct device *dev) { return &g_pcie_ops_for_dt; } static int udrv_pcie_probe(struct platform_device *pdev) { int ret = 0; struct device *dev = &pdev->dev; struct udrv_pcie_host *pcie = NULL; const struct udrv_pcie_ops *ops = udrv_pcie_get_host_ops(dev); if (!ops) { dev_err(dev, "[iWare][Error] get ops fail\n"); return -EINVAL; } pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); if (!pcie) { dev_err(dev, "[iWare][Error] devm_kzalloc fail\n"); return -ENOMEM; } INIT_LIST_HEAD(&pcie->host_info.atu_info.entry); INIT_LIST_HEAD(&pcie->port_info.entry); pcie->ops = ops; pcie->dev = dev; platform_set_drvdata(pdev, pcie); list_add_tail(&pcie->node, &pcie_host_list); if ((ops->host_ops) && (ops->host_ops->get_info(pcie) != 0)) { pr_err("[iWare][Error] get host dts info failed \n"); ret = -EINVAL; goto err_host; } if ((ops->port_ops) && (ops->port_ops->get_info(pcie) != 0)) { pr_err("[iWare][Error] get port dts info failed \n"); ret = -EINVAL; goto err_port; } if ((ops->msi_ops) && (ops->msi_ops->get_info(pcie) != 0)) { pr_err("[iWare][Error] get msi dts info failed \n"); ret = -EINVAL; goto err_msi; } if ((ops->host_ops) && (ops->host_ops->probe(pcie) != 0)) { pr_err("[iWare][Error] pcie probe failed \n"); ret = -EINVAL; goto err_probe; } #ifdef CONFIG_UDRV_FMEA ret = pcie_fmea_init(pcie); if (ret != 0) { pr_err("[iWare][Error] fmea init failed,ret=%d\n", ret); goto err_fmea; } #endif #ifdef CONFIG_UDRV_KDRV_INFECTED ret = kdrv_pcie_probe_infected_callback(pcie); if (ret != 0) { pr_err("[iWare][Error] kdrv_pcie_probe_infected_callback fail %d\n", ret); goto err_infected_callback; } #endif return 0; #ifdef CONFIG_UDRV_KDRV_INFECTED err_infected_callback: #endif #ifdef CONFIG_UDRV_FMEA pcie_fmea_deinit(pcie); err_fmea: #endif /* 调用框架和probe对等的remove */ if (test_bit(NDRV_PCIE_RP_MODE, &(pcie->host_info.type_support_mask)) != 0) { (void)udrv_pcie_host_common_remove(pdev); } udrv_pcie_remove_msi(pcie); err_probe: err_msi: udrv_pcie_free_port_info(pcie); err_port: udrv_pcie_free_atu_info(pcie); ndrv_pcie_close_pf(pcie->host_info.pf_handle, pcie->host_info.core_version); err_host: list_del(&pcie->node); return ret; } static int udrv_pcie_remove(struct platform_device *pdev) { struct udrv_pcie_host *pcie = platform_get_drvdata(pdev); struct udrv_pcie_host_info *host_info = &pcie->host_info; #ifdef CONFIG_UDRV_KDRV_INFECTED kdrv_pcie_remove_infected_callback(pcie); #endif #ifdef CONFIG_UDRV_FMEA pcie_fmea_deinit(pcie); #endif /* 调用框架和probe对等的remove */ if (test_bit(NDRV_PCIE_RP_MODE, &(host_info->type_support_mask)) != 0) { (void)udrv_pcie_host_common_remove(pdev); } udrv_pcie_remove_msi(pcie); udrv_pcie_free_port_info(pcie); udrv_pcie_free_atu_info(pcie); ndrv_pcie_close_pf(pcie->host_info.pf_handle, pcie->host_info.core_version); list_del(&pcie->node); return 0; } static struct platform_driver g_udrv_pcie_dt_driver = { .probe = udrv_pcie_probe, .remove = udrv_pcie_remove, .driver = { .name = "udrv-pcie", .of_match_table = g_udrv_pcie_of_match, }, }; struct platform_driver *udrv_get_pcie_dt_driver(void) { return &g_udrv_pcie_dt_driver; } static struct platform_driver * const drivers[] = { &g_udrv_pcie_dt_driver, }; int find_pcie_host_by_id(struct device *dev, void *data) { struct pcie_find_data *pcie_search_info = (struct pcie_find_data *)data; struct udrv_pcie_host *pcie = dev_get_drvdata(dev); if (pcie->host_info.host_id == pcie_search_info->host_id) { pcie_search_info->pcie = pcie; return 1; // 找到了退出遍历dev } return 0; } struct udrv_pcie_host *hisi_pcie_get_by_host_id(uint32_t host_id) { int ret; struct pcie_find_data pcie_search_info = { 0 }; pcie_search_info.host_id = host_id; ret = driver_for_each_device(&g_udrv_pcie_dt_driver.driver, NULL, &pcie_search_info, find_pcie_host_by_id); if (pcie_search_info.pcie == NULL) { // 找没找到直接判断返回的hipcie,不依赖driver_for_each_device返回值 pr_err("[iWare][Error] find pcie fail: host_id = %u\n", host_id); return NULL; } return pcie_search_info.pcie; } static int __init udrv_pcie_init(void) { return platform_register_drivers(drivers, ARRAY_SIZE(drivers)); } static void __exit udrv_pcie_exit(void) { platform_unregister_drivers(drivers, ARRAY_SIZE(drivers)); } module_init(udrv_pcie_init); module_exit(udrv_pcie_exit); MODULE_LICENSE("Dual BSD/GPL"); 这是现在pcie的驱动代码,编译报错 “In file included from /home/g60098972/master/build/build_sdk/ko_compile/pcie/debug/pcie_debug.c:7: /home/g60098972/master/build/build_sdk/../../src/drivers/kerndrv/modules/pcie/pcie_udrv.h:99:24: error: 'pcie_msi_ctrl' defined but not used [-Werror=unused-variable] 99 | static struct pcie_msi pcie_msi_ctrl; | ^~~~~~~~~~~~~ In file included from /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_kern_api.c:8: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.h:99:24: error: 'pcie_msi_ctrl' defined but not used [-Werror=unused-variable] 99 | static struct pcie_msi pcie_msi_ctrl; | ^~~~~~~~~~~~~ cc1: all warnings being treated as errors make[3]: *** [/home/g60098972/master/open_source/linux5.10/scripts/Makefile.build:286: /home/g60098972/master/build/build_sdk/ko_compile/pcie/debug/pcie_debug.o] Error 1 make[3]: *** Waiting for unfinished jobs.... /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c: In function 'udrv_pcie_msi_set_affinity': /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:215:20: error: implicit declaration of function 'hwirq_to_cpu' [-Werror=implicit-function-declaration] 215 | curr_cpu = hwirq_to_cpu(irqdata->hwirq); | ^~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:215:33: error: 'irqdata' undeclared (first use in this function); did you mean 'irq_data'? 215 | curr_cpu = hwirq_to_cpu(irqdata->hwirq); | ^~~~~~~ | irq_data /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:215:33: note: each undeclared identifier is reported only once for each function it appears in /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:220:26: error: implicit declaration of function 'hwirq_to_canonical_hwirq' [-Werror=implicit-function-declaration] 220 | irqdata->hwirq = hwirq_to_canonical_hwirq(irqdata->hwirq) + target_cpu; | ^~~~~~~~~~~~~~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c: At top level: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:225:12: error: static declaration of 'hwirq_to_cpu' follows non-static declaration 225 | static int hwirq_to_cpu(unsigned long hwirq) | ^~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:215:20: note: previous implicit declaration of 'hwirq_to_cpu' with type 'int()' 215 | curr_cpu = hwirq_to_cpu(irqdata->hwirq); | ^~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:230:22: error: conflicting types for 'hwirq_to_canonical_hwirq'; have 'long unsigned int(long unsigned int)' 230 | static unsigned long hwirq_to_canonical_hwirq(unsigned long hwirq) | ^~~~~~~~~~~~~~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:220:26: note: previous implicit declaration of 'hwirq_to_canonical_hwirq' with type 'int()' 220 | irqdata->hwirq = hwirq_to_canonical_hwirq(irqdata->hwirq) + target_cpu; | ^~~~~~~~~~~~~~~~~~~~~~~~ In file included from /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_dfx_sbuf_api.c:7: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.h:99:24: error: 'pcie_msi_ctrl' defined but not used [-Werror=unused-variable] 99 | static struct pcie_msi pcie_msi_ctrl; | ^~~~~~~~~~~~~ /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.c:230:22: error: 'hwirq_to_canonical_hwirq' defined but not used [-Werror=unused-function] 230 | static unsigned long hwirq_to_canonical_hwirq(unsigned long hwirq) | ^~~~~~~~~~~~~~~~~~~~~~~~ cc1: all warnings being treated as errors make[3]: *** [/home/g60098972/master/open_source/linux5.10/scripts/Makefile.build:286: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_udrv.o] Error 1 cc1: all warnings being treated as errors make[3]: *** [/home/g60098972/master/open_source/linux5.10/scripts/Makefile.build:286: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_kern_api.o] Error 1 cc1: all warnings being treated as errors make[3]: *** [/home/g60098972/master/open_source/linux5.10/scripts/Makefile.build:286: /home/g60098972/master/build/build_sdk/ko_compile/pcie/pcie_dfx_sbuf_api.o] Error 1 make[2]: *** [/home/g60098972/master/open_source/linux5.10/Makefile:1848: /home/g60098972/master/build/build_sdk/ko_compile/pcie] Error 2 make[1]: *** [/home/g60098972/master/open_source/linux5.10/Makefile:194: __sub-make] Error 2 make[1]: Leaving directory '/home/g60098972/master/open_source/output' build ko! aarch64-openeuler-linux-strip: '*.ko': No such file make: *** [Makefile:43: ko] Error 1”
09-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值