Skip to content

Commit

Permalink
Issues 1179 and 1182 (#1232)
Browse files Browse the repository at this point in the history
* Update logging

* Remove duplicate code

* Update unit tests

* Clean up includes

* Merge ProtobufSerializer into protobuf_util namespace

* Precompile regex

* Add const

* Add Split() convenience method, update log level/ID parsing

* Move log.h to legacy folder

* Elimininate gotos

* Fixes for gcc 13

* Update compiler flags

* Update default folder handling

* Use references instead of pointers

* Move code for better encapsulation

* Move code

* Remove unused method argument

* Move device logger

* Remove redundant to_string

* Rename for consistency

* Update handling of protobuf pointers

* Simplify protobuf usage

* Memory handling update

* Add hasher
  • Loading branch information
uweseimet authored Oct 15, 2023
1 parent c1f6f3f commit 41bdcd4
Show file tree
Hide file tree
Showing 161 changed files with 4,706 additions and 5,089 deletions.
40 changes: 15 additions & 25 deletions cpp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,39 +7,28 @@
CROSS_COMPILE =

CXX = $(CROSS_COMPILE)g++
AR = $(CROSS_COMPILE)ar
RANLIB = $(CROSS_COMPILE)ranlib

## DEBUG=1 : A Debug build includes the debugger symbols
## and disables compiler optimization. Typically,
## this is only used by developers.
DEBUG ?= 0
ifeq ($(DEBUG), 1)
# Debug compiler flags
CXXFLAGS += -O0 -g -Wall -Wextra -DDEBUG
BUILD_TYPE = Debug
CXXFLAGS += -Og -g -Wall -Wextra -DDEBUG
else
# Release compiler flags
CXXFLAGS += -O3 -Wall -Werror -Wextra -DNDEBUG
BUILD_TYPE = Release
endif
ifeq ("$(shell uname -s)","Linux")
# -Wno-psabi might not work on non-Linux platforms
CXXFLAGS += -Wno-psabi
endif

# Depending on the GCC version the compilation flags differ
GCCVERSION10 := $(shell expr `$(CXX) -dumpversion` \>= 10)

CXXFLAGS += -std=c++17 -iquote . -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -MD -MP
CXXFLAGS += -std=c++20 -iquote . -D_FILE_OFFSET_BITS=64 -DFMT_HEADER_ONLY -DSPDLOG_FMT_EXTERNAL -MD -MP

## EXTRA_FLAGS : Can be used to pass special purpose flags
CXXFLAGS += $(EXTRA_FLAGS)

ifeq "$(GCCVERSION10)" "1"
CXXFLAGS += -DFMT_HEADER_ONLY
endif


## CONNECT_TYPE=FULLSPEC : Specify the type of PiSCSI board type
## that you are using. The typical options are
Expand Down Expand Up @@ -86,12 +75,12 @@ SRC_PROTOC = piscsi_interface.proto
SRC_GENERATED = $(GENERATED_DIR)/piscsi_interface.pb.cpp

SRC_PROTOBUF = \
shared/protobuf_util.cpp \
shared/protobuf_serializer.cpp
shared/protobuf_util.cpp

SRC_SHARED = \
shared/piscsi_version.cpp \
shared/piscsi_util.cpp
shared/piscsi_util.cpp \
shared/network_util.cpp

SRC_PISCSI_CORE = $(shell find ./piscsi -name '*.cpp')
SRC_PISCSI_CORE += $(shell find ./controllers -name '*.cpp')
Expand Down Expand Up @@ -167,7 +156,7 @@ $(SRC_GENERATED) : $(SRC_PROTOC)
protoc --cpp_out=$(GENERATED_DIR) $(SRC_PROTOC)
mv $(GENERATED_DIR)/piscsi_interface.pb.cc $@

$(OBJ_GENERATED) : $(SRC_GENERATED)
$(OBJ_GENERATED) : $(SRC_GENERATED) | $(OBJDIR)
$(CXX) $(CXXFLAGS) -c $< -o $@

## Build Targets:
Expand All @@ -180,10 +169,11 @@ $(OBJ_GENERATED) : $(SRC_GENERATED)
## Note that you have to run 'make clean' before switching
## between coverage and non-coverage builds.
.DEFAULT_GOAL := all
.PHONY: all ALL docs test coverage lcov
all: $(BIN_ALL) docs
.PHONY: all docs test coverage lcov

all: $(SRC_GENERATED) $(BIN_ALL) docs

test: $(BINDIR)/$(PISCSI_TEST)
test: $(SRC_GENERATED) $(BINDIR)/$(PISCSI_TEST)
$(BINDIR)/$(PISCSI_TEST)

coverage: CXXFLAGS += --coverage
Expand All @@ -198,10 +188,10 @@ docs: $(DOC_DIR)/piscsi_man_page.txt $(DOC_DIR)/scsictl_man_page.txt $(DOC_DIR)/

$(SRC_PISCSI_CORE) $(SRC_SCSICTL_CORE) : $(OBJ_GENERATED)

$(BINDIR)/$(PISCSI): $(SRC_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs
$(BINDIR)/$(PISCSI): $(OBJ_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_PISCSI) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf

$(BINDIR)/$(SCSICTL): $(SRC_GENERATED) $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(BINDIR)/$(SCSICTL): $(OBJ_GENERATED) $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SCSICTL_CORE) $(OBJ_SCSICTL) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lprotobuf

$(BINDIR)/$(SCSIDUMP): $(OBJ_SCSIDUMP) $(OBJ_SHARED) | $(BINDIR)
Expand All @@ -213,8 +203,8 @@ $(BINDIR)/$(SCSIMON): $(OBJ_SCSIMON) $(OBJ_SHARED) | $(BINDIR)
$(BINDIR)/$(SCSILOOP): $(OBJ_SHARED) $(OBJ_SCSILOOP) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $(OBJ_SHARED) $(OBJ_SCSILOOP)

$(BINDIR)/$(PISCSI_TEST): $(SRC_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SCSICTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TEST_WRAPS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lstdc++fs -lgmock -lgtest
$(BINDIR)/$(PISCSI_TEST): $(OBJ_GENERATED) $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SCSICTL_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) | $(BINDIR)
$(CXX) $(CXXFLAGS) $(LDFLAGS) $(TEST_WRAPS) -o $@ $(OBJ_PISCSI_CORE) $(OBJ_SCSICTL_CORE) $(OBJ_PISCSI_TEST) $(OBJ_SHARED) $(OBJ_PROTOBUF) $(OBJ_GENERATED) -lpthread -lpcap -lprotobuf -lgmock -lgtest

# Phony rules for building individual utilities
.PHONY: $(PISCSI) $(SCSICTL) $(SCSIDUMP) $(SCSIMON) $(PISCSI_TEST) $(SCSILOOP)
Expand Down
109 changes: 40 additions & 69 deletions cpp/controllers/abstract_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,22 @@
// SCSI Target Emulator PiSCSI
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
// Copyright (C) 2022-2023 Uwe Seimet
//
//---------------------------------------------------------------------------

#include "shared/piscsi_exceptions.h"
#include "devices/primary_device.h"
#include "abstract_controller.h"
#include <ranges>

using namespace scsi_defs;

AbstractController::AbstractController(BUS& bus, int target_id, int max_luns) : bus(bus), target_id(target_id), max_luns(max_luns)
{
device_logger.SetIdAndLun(target_id, -1);
}

void AbstractController::AllocateCmd(size_t size)
{
if (size > ctrl.cmd.size()) {
Expand Down Expand Up @@ -40,9 +46,8 @@ unordered_set<shared_ptr<PrimaryDevice>> AbstractController::GetDevices() const
{
unordered_set<shared_ptr<PrimaryDevice>> devices;

for (const auto& [id, lun] : luns) {
devices.insert(lun);
}
// "luns | views:values" is not supported by the bullseye compiler
ranges::transform(luns, inserter(devices, devices.begin()), [] (const auto& l) { return l.second; } );

return devices;
}
Expand All @@ -56,100 +61,66 @@ void AbstractController::Reset()
{
SetPhase(phase_t::busfree);

ctrl.status = status::GOOD;
ctrl.message = 0x00;
ctrl.blocks = 0;
ctrl.next = 0;
ctrl.offset = 0;
ctrl.length = 0;
ctrl = {};

SetByteTransfer(false);

// Reset all LUNs
for (const auto& [lun, device] : luns) {
for (const auto& [_, device] : luns) {
device->Reset();
}

GetBus().Reset();
}

void AbstractController::ProcessPhase()
void AbstractController::ProcessOnController(int id_data)
{
switch (GetPhase()) {
case phase_t::busfree:
BusFree();
break;

case phase_t::selection:
Selection();
break;

case phase_t::dataout:
DataOut();
break;

case phase_t::datain:
DataIn();
break;

case phase_t::command:
Command();
break;

case phase_t::status:
Status();
break;

case phase_t::msgout:
MsgOut();
break;

case phase_t::msgin:
MsgIn();
break;

default:
throw scsi_exception(sense_key::ABORTED_COMMAND);
break;
device_logger.SetIdAndLun(GetTargetId(), -1);

const int initiator_id = ExtractInitiatorId(id_data);
if (initiator_id != UNKNOWN_INITIATOR_ID) {
LogTrace("++++ Starting processing for initiator ID " + to_string(initiator_id));
}
else {
LogTrace("++++ Starting processing for unknown initiator ID");
}

while (Process(initiator_id)) {
// Handle bus phases until the bus is free for the next command
}
}

bool AbstractController::AddDevice(shared_ptr<PrimaryDevice> device)
{
if (device->GetLun() < 0 || device->GetLun() >= GetMaxLuns() || HasDeviceForLun(device->GetLun())) {
const int lun = device->GetLun();

if (lun < 0 || lun >= GetMaxLuns() || HasDeviceForLun(lun) || device->GetController()) {
return false;
}

luns[device->GetLun()] = device;
device->SetController(shared_from_this());
luns[lun] = device;
device->SetController(this);

return true;
}

bool AbstractController::RemoveDevice(shared_ptr<PrimaryDevice> device)
bool AbstractController::RemoveDevice(PrimaryDevice& device)
{
device->SetController(nullptr);
device.CleanUp();

return luns.erase(device->GetLun()) == 1;
return luns.erase(device.GetLun()) == 1;
}

bool AbstractController::HasDeviceForLun(int lun) const
{
return luns.find(lun) != luns.end();
return luns.contains(lun);
}

int AbstractController::ExtractInitiatorId(int id_data) const
{
int initiator_id = UNKNOWN_INITIATOR_ID;

if (int tmp = id_data - (1 << target_id); tmp) {
initiator_id = 0;
for (int j = 0; j < 8; j++) {
tmp >>= 1;
if (tmp) {
initiator_id++;
}
else {
break;
}
}
if (const int id_data_without_target = id_data - (1 << target_id); id_data_without_target) {
return static_cast<int>(log2(id_data_without_target & -id_data_without_target));
}

return initiator_id;
return UNKNOWN_INITIATOR_ID;
}
Loading

0 comments on commit 41bdcd4

Please sign in to comment.