Support VMS 5.5_2 mode page bits.
[SCSI2SD-V6.git] / software / scsi2sd-util / scsi2sd-util.cc
index c608e325edbf8b481c4dc2f3334b8728771ab286..a5ec3eeb893f9b76a571f122e5e8d2f070c62f1b 100644 (file)
@@ -41,6 +41,7 @@
 #include "Firmware.hh"
 
 #include <algorithm>
+#include <iomanip>
 #include <vector>
 #include <set>
 #include <sstream>
@@ -135,7 +136,8 @@ public:
        AppFrame() :
                wxFrame(NULL, wxID_ANY, "scsi2sd-util", wxPoint(50, 50), wxSize(600, 650)),
                myInitialConfig(false),
-               myTickCounter(0)
+               myTickCounter(0),
+               myLastPollTime(0)
        {
                wxMenu *menuFile = new wxMenu();
                menuFile->Append(
@@ -155,17 +157,23 @@ public:
                        "Show &Log",
                        "Show debug log window");
 
+               wxMenu *menuDebug = new wxMenu();
+               mySCSILogChk = menuDebug->AppendCheckItem(
+                       ID_SCSILog,
+                       "Log SCSI data",
+                       "Log SCSI commands");
+
                wxMenu *menuHelp = new wxMenu();
                menuHelp->Append(wxID_ABOUT);
 
                wxMenuBar *menuBar = new wxMenuBar();
                menuBar->Append( menuFile, "&File" );
+               menuBar->Append( menuDebug, "&Debug" );
                menuBar->Append( menuWindow, "&Window" );
                menuBar->Append( menuHelp, "&Help" );
                SetMenuBar( menuBar );
 
                CreateStatusBar();
-               wxLogStatus(this, "Searching for SCSI2SD");
 
                {
                        wxPanel* cfgPanel = new wxPanel(this);
@@ -208,16 +216,19 @@ public:
                //Fit(); // Needed to reduce window size on Windows
                FitInside(); // Needed on Linux to prevent status bar overlap
 
-               myTimer = new wxTimer(this, ID_Timer);
-               myTimer->Start(1000); //ms
-
                myLogWindow = new wxLogWindow(this, wxT("scsi2sd-util debug log"), true);
+               myLogWindow->PassMessages(false); // Prevent messagebox popups
+
+               myTimer = new wxTimer(this, ID_Timer);
+               myTimer->Start(16); //ms, suitable for scsi debug logging
        }
+
 private:
        wxLogWindow* myLogWindow;
        std::vector<TargetPanel*> myTargets;
        wxButton* myLoadButton;
        wxButton* mySaveButton;
+       wxMenuItem* mySCSILogChk;
        wxTimer* myTimer;
        shared_ptr<HID> myHID;
        shared_ptr<Bootloader> myBootloader;
@@ -225,6 +236,16 @@ private:
 
        uint8_t myTickCounter;
 
+       time_t myLastPollTime;
+
+       void mmLogStatus(const std::string& msg)
+       {
+               // We set PassMessages to false on our log window to prevent popups, but
+               // this also prevents wxLogStatus from updating the status bar.
+               SetStatusText(msg);
+               wxLogMessage(this, "%s", msg.c_str());
+       }
+
        void onConfigChanged(wxCommandEvent& event)
        {
                evaluate();
@@ -307,7 +328,8 @@ private:
                ID_Notebook,
                ID_BtnLoad,
                ID_BtnSave,
-               ID_LogWindow
+               ID_LogWindow,
+               ID_SCSILog
        };
 
        void OnID_ConfigDefaults(wxCommandEvent& event)
@@ -350,7 +372,7 @@ private:
                                this,
                                wxPD_AUTO_HIDE | wxPD_CAN_ABORT)
                                );
-               wxLogStatus(this, "Searching for bootloader");
+               mmLogStatus("Searching for bootloader");
                while (true)
                {
                        try
@@ -358,7 +380,7 @@ private:
                                if (!myHID) myHID.reset(HID::Open());
                                if (myHID)
                                {
-                                       wxLogStatus(this, "Resetting SCSI2SD into bootloader");
+                                       mmLogStatus("Resetting SCSI2SD into bootloader");
 
                                        myHID->enterBootloader();
                                        myHID.reset();
@@ -370,7 +392,7 @@ private:
                                        myBootloader.reset(Bootloader::Open());
                                        if (myBootloader)
                                        {
-                                               wxLogStatus(this, "Bootloader found");
+                                               mmLogStatus("Bootloader found");
                                                break;
                                        }
                                }
@@ -380,19 +402,19 @@ private:
                                        // Verify the USB HID connection is valid
                                        if (!myBootloader->ping())
                                        {
-                                               wxLogStatus(this, "Bootloader ping failed");
+                                               mmLogStatus("Bootloader ping failed");
                                                myBootloader.reset();
                                        }
                                        else
                                        {
-                                               wxLogStatus(this, "Bootloader found");
+                                               mmLogStatus("Bootloader found");
                                                break;
                                        }
                                }
                        }
                        catch (std::exception& e)
                        {
-                               wxLogStatus(this, "%s", e.what());
+                               mmLogStatus(e.what());
                                myHID.reset();
                                myBootloader.reset();
                        }
@@ -414,19 +436,19 @@ private:
                        {
                                if (myBootloader->isCorrectFirmware((*it)->getPath()))
                                {
-                                       wxLogStatus(this,
-                                               "Found firmware entry %s within archive %s",
-                                               (*it)->getPath(),
-                                               filename);
+                                       std::stringstream msg;
+                                       msg << "Found firmware entry " << (*it)->getPath() <<
+                                               " within archive " << filename;
+                                       mmLogStatus(msg.str());
                                        tmpFile =
                                                wxFileName::CreateTempFileName(
                                                        wxT("SCSI2SD_Firmware"), static_cast<wxFile*>(NULL)
                                                        );
                                        zipper::FileWriter out(tmpFile);
                                        (*it)->decompress(out);
-                                       wxLogStatus(this,
-                                               "Firmware extracted to %s",
-                                               tmpFile);
+                                       msg.clear();
+                                       msg << "Firmware extracted to " << tmpFile;
+                                       mmLogStatus(msg.str());
                                        break;
                                }
                        }
@@ -446,7 +468,7 @@ private:
                }
                catch (std::exception& e)
                {
-                       wxLogStatus(this, "%s", e.what());
+                       mmLogStatus(e.what());
                        std::stringstream msg;
                        msg << "Could not open firmware file: " << e.what();
                        wxMessageBox(
@@ -469,7 +491,9 @@ private:
                        TheProgressWrapper.setProgressDialog(progress, totalFlashRows);
                }
 
-               wxLogStatus(this, "Upgrading firmware from file: %s", tmpFile);
+               std::stringstream msg;
+               msg << "Upgrading firmware from file: " << tmpFile;
+               mmLogStatus(msg.str());
 
                try
                {
@@ -480,7 +504,7 @@ private:
                                "Firmware update successful",
                                "Firmware OK",
                                wxOK);
-                       wxLogStatus(this, "Firmware update successful");
+                       mmLogStatus("Firmware update successful");
 
 
                        myHID.reset();
@@ -489,7 +513,7 @@ private:
                catch (std::exception& e)
                {
                        TheProgressWrapper.clearProgressDialog();
-                       wxLogStatus(this, "%s", e.what());
+                       mmLogStatus(e.what());
                        myHID.reset();
                        myBootloader.reset();
 
@@ -502,8 +526,42 @@ private:
                }
        }
 
+       void logSCSI()
+       {
+               if (!mySCSILogChk->IsChecked() ||
+                       !myHID)
+               {
+                       return;
+               }
+               try
+               {
+                       std::vector<uint8_t> info(HID::HID_PACKET_SIZE);
+                       if (myHID->readSCSIDebugInfo(info))
+                       {
+                               std::stringstream msg;
+                               msg << std::hex;
+                               for (size_t i = 0; i < 32 && i < info.size(); ++i)
+                               {
+                                       msg << std::setfill('0') << std::setw(2) <<
+                                               static_cast<int>(info[i]) << ' ';
+                               }
+                               wxLogMessage(this, msg.str().c_str());
+                       }
+               }
+               catch (std::exception& e)
+               {
+                       wxLogWarning(this, e.what());
+                       myHID.reset();
+               }
+       }
+
        void OnID_Timer(wxTimerEvent& event)
        {
+               logSCSI();
+               time_t now = time(NULL);
+               if (now == myLastPollTime) return;
+               myLastPollTime = now;
+
                // Check if we are connected to the HID device.
                // AND/or bootloader device.
                try
@@ -523,7 +581,7 @@ private:
 
                                if (myBootloader)
                                {
-                                       wxLogStatus(this, "%s", "SCSI2SD Bootloader Ready");
+                                       mmLogStatus("SCSI2SD Bootloader Ready");
                                }
                        }
 
@@ -551,24 +609,49 @@ private:
                                                if (!supressLog)
                                                {
                                                        // Oh dear, old firmware
-                                                       wxLogStatus(
-                                                               this,
-                                                               "Firmware update required. Version %s",
-                                                               myHID->getFirmwareVersionStr());
+                                                       std::stringstream msg;
+                                                       msg << "Firmware update required. Version " <<
+                                                               myHID->getFirmwareVersionStr();
+                                                       mmLogStatus(msg.str());
                                                }
                                        }
                                        else
                                        {
-                                               wxLogStatus(
-                                                       this,
-                                                       "SCSI2SD Ready, firmware version %s",
-                                                       myHID->getFirmwareVersionStr());
+                                               std::stringstream msg;
+                                               msg << "SCSI2SD Ready, firmware version " <<
+                                                       myHID->getFirmwareVersionStr();
+                                               mmLogStatus(msg.str());
+
+                                               std::vector<uint8_t> csd(myHID->getSD_CSD());
+                                               std::vector<uint8_t> cid(myHID->getSD_CID());
+                                               std::stringstream sdinfo;
+                                               sdinfo << "SD Capacity (512-byte sectors): " <<
+                                                       myHID->getSDCapacity() << std::endl;
+
+                                               sdinfo << "SD CSD Register: ";
+                                               for (size_t i = 0; i < csd.size(); ++i)
+                                               {
+                                                       sdinfo <<
+                                                               std::hex << std::setfill('0') << std::setw(2) <<
+                                                               static_cast<int>(csd[i]);
+                                               }
+                                               sdinfo << std::endl;
+                                               sdinfo << "SD CID Register: ";
+                                               for (size_t i = 0; i < cid.size(); ++i)
+                                               {
+                                                       sdinfo <<
+                                                               std::hex << std::setfill('0') << std::setw(2) <<
+                                                               static_cast<int>(cid[i]);
+                                               }
+
+                                               wxLogMessage(this, "%s", sdinfo.str());
 
                                                if (!myInitialConfig)
                                                {
                                                        wxCommandEvent loadEvent(wxEVT_NULL, ID_BtnLoad);
                                                        GetEventHandler()->AddPendingEvent(loadEvent);
                                                }
+
                                        }
                                }
                                else
@@ -583,7 +666,8 @@ private:
                }
                catch (std::runtime_error& e)
                {
-                       wxLogStatus(this, "%s", e.what());
+                       std::cerr << e.what() << std::endl;
+                       mmLogStatus(e.what());
                }
 
                evaluate();
@@ -594,7 +678,7 @@ private:
                TimerLock lock(myTimer);
                if (!myHID) return;
 
-               wxLogStatus(this, "Loading configuration");
+               mmLogStatus("Loading configuration");
 
                wxWindowPtr<wxGenericProgressDialog> progress(
                        new wxGenericProgressDialog(
@@ -619,7 +703,7 @@ private:
                                std::stringstream ss;
                                ss << "Reading flash array " << SCSI_CONFIG_ARRAY <<
                                        " row " << (flashRow + j);
-                               wxLogStatus(this, "%s", ss.str());
+                               mmLogStatus(ss.str());
                                currentProgress += 1;
                                if (!progress->Update(
                                                (100 * currentProgress) / totalProgress,
@@ -640,7 +724,7 @@ private:
                                }
                                catch (std::runtime_error& e)
                                {
-                                       wxLogStatus(this, "%s", e.what());
+                                       mmLogStatus(e.what());
                                        goto err;
                                }
 
@@ -653,7 +737,7 @@ private:
                }
 
                myInitialConfig = true;
-               wxLogStatus(this, "%s", "Load Complete");
+               mmLogStatus("Load Complete");
                while (progress->Update(100, "Load Complete"))
                {
                        // Wait for the user to click "Close"
@@ -662,7 +746,7 @@ private:
                goto out;
 
        err:
-               wxLogStatus(this, "%s", "Load failed");
+               mmLogStatus("Load failed");
                while (progress->Update(100, "Load failed"))
                {
                        // Wait for the user to click "Close"
@@ -671,7 +755,7 @@ private:
                goto out;
 
        abort:
-               wxLogStatus(this, "Load Aborted");
+               mmLogStatus("Load Aborted");
 
        out:
                return;
@@ -682,7 +766,7 @@ private:
                TimerLock lock(myTimer);
                if (!myHID) return;
 
-               wxLogStatus(this, "Saving configuration");
+               mmLogStatus("Saving configuration");
 
                wxWindowPtr<wxGenericProgressDialog> progress(
                        new wxGenericProgressDialog(
@@ -708,7 +792,7 @@ private:
                                std::stringstream ss;
                                ss << "Programming flash array " << SCSI_CONFIG_ARRAY <<
                                        " row " << (flashRow + j);
-                               wxLogStatus(this, "%s", ss.str());
+                               mmLogStatus(ss.str());
                                currentProgress += 1;
                                if (!progress->Update(
                                                (100 * currentProgress) / totalProgress,
@@ -731,7 +815,7 @@ private:
                                }
                                catch (std::runtime_error& e)
                                {
-                                       wxLogStatus(this, "%s", e.what());
+                                       mmLogStatus(e.what());
                                        goto err;
                                }
                        }
@@ -741,7 +825,7 @@ private:
                myHID->enterBootloader();
                myHID.reset();
 
-               wxLogStatus(this, "Save Complete");
+               mmLogStatus("Save Complete");
                while (progress->Update(100, "Save Complete"))
                {
                        // Wait for the user to click "Close"
@@ -750,7 +834,7 @@ private:
                goto out;
 
        err:
-               wxLogStatus(this, "Save failed");
+               mmLogStatus("Save failed");
                while (progress->Update(100, "Save failed"))
                {
                        // Wait for the user to click "Close"
@@ -759,10 +843,10 @@ private:
                goto out;
 
        abort:
-               wxLogStatus(this, "Save Aborted");
+               mmLogStatus("Save Aborted");
 
        out:
-               (void) true; // empty statement.
+               return;
        }
 
        void OnExit(wxCommandEvent& event)