]> localhost Git - SCSI2SD.git/commitdiff
Support VMS 5.5_2 mode page bits. v4.01.00
authorMichael McMaster <michael@codesrc.com>
Sun, 1 Feb 2015 09:13:33 +0000 (19:13 +1000)
committerMichael McMaster <michael@codesrc.com>
Sun, 1 Feb 2015 09:13:33 +0000 (19:13 +1000)
19 files changed:
CHANGELOG
hardware/gerber/scsi2sd.xy [deleted file]
software/SCSI2SD/src/mode.c
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/USBFS_descr.c
software/SCSI2SD/v3/SCSI2SD.cydsn/Generated_Source/PSoC5/cymetadata.c
software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch
software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit
software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyprj.Micha_000
software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit
software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit
software/build.sh
software/scsi2sd-debug/.gitignore [deleted file]
software/scsi2sd-debug/Makefile [deleted file]
software/scsi2sd-debug/build.sh [deleted file]
software/scsi2sd-debug/scsi2sd-debug.cc [deleted file]
software/scsi2sd-util/SCSI2SD_HID.cc
software/scsi2sd-util/SCSI2SD_HID.hh
software/scsi2sd-util/scsi2sd-util.cc

index d0652afcd77ab1fc930210b351cdbafde31dafbc..41398d903c9c7d156c926f9acef2e4871c02b50c 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
        drivers (openbsd, netbsd, and others) set a byte-to-byte timeout which
        can be exceeded by SD card latency.
        - Upgrade to PSoC Creator 3.1 and gcc 4.8.4.
+       - Integrated scsi2sd-debug functionality with scsi2sd-util.
 
 20150108               4.0
        - Fix handling requests for LUNs other than 0 from SCSI-2 hosts.
diff --git a/hardware/gerber/scsi2sd.xy b/hardware/gerber/scsi2sd.xy
deleted file mode 100644 (file)
index 444b04c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-# PcbXY Version 1.0
-# Date: Tue 09 Dec 2014 09:51:33 GMT UTC
-# Author: Michael McMaster
-# Title: (unknown) - PCB X-Y
-# RefDes, Description, Value, X, Y, rotation, top/bottom
-# X,Y in mil.  rotation in degrees.
-# --------------------------------------------
-Q1,"SOT23_MOSFET","unknown",3327.09,2042.42,90,top
-U4,"SO14","unknown",2243.00,2414.50,270,top
-C22,"cap_0402","100nF",2940.94,188.00,180,top
-U3,"SO14","unknown",2820.00,2412.00,270,top
-U5,"SO14","unknown",1742.00,2410.50,270,top
-R5,"SMD_SIMPLE-80-50","22?",2266.41,1116.78,0,top
-J5,"fci-10118192-0001LF","unknown",1952.25,128.13,0,top
-R4,"SMD_SIMPLE-80-50","22?",2226.00,1211.00,0,top
-C2,"SMD_SIMPLE-80-50","10uF",1845.00,1252.00,0,top
-C9,"cap_0402","100nF",1949.69,1352.00,0,top
-C8,"cap_0402","1uF",2369.68,1217.00,180,top
-C20,"cap_0402","1uF",2397.06,1296.82,90,top
-C21,"cap_0402","100nF",2770.31,2007.00,180,top
-C11,"cap_0402","100nF",1970.00,2306.68,270,top
-C3,"cap_0402","100nF",3045.00,2306.68,270,top
-C19,"cap_0402","100nF",2355.00,2141.68,270,top
-C23,"cap_0402","100nF",2345.63,1297.32,90,top
-C10,"cap_0402","100nF",2465.00,2306.68,270,top
-C17,"cap_0402","100nF",2030.00,2112.31,270,top
-C28,"cap_0402","100nF",2705.00,1347.32,90,top
-D2,"diode-DO-214AA-SMB","unknown",190.00,2882.35,90,top
-F1,"SMD_SIMPLE-120-60","1.5A Hold",146.00,3203.00,270,top
-D1,"diode-DO-214AA-SMB","unknown",925.00,2881.65,90,top
-F2,"SMD_SIMPLE-120-60","500mA Hold",1624.00,164.00,180,top
-D3,"diode-DO-214AA-SMB","unknown",1355.35,207.00,0,top
-R3,"SMD_SIMPLE-80-50","1600",3108.59,2124.22,180,top
-C26,"cap_0402","1uF",2815.00,1756.68,270,top
-C24,"cap_0402","100nF",2750.00,1757.31,270,top
-C27,"cap_0402","1uF",2815.00,1662.32,90,top
-U1,"TQFP100_14_reflow","unknown",2339.53,1723.95,0,top
-C13,"SMD_SIMPLE-80-50","10uF",2977.20,334.06,180,top
-U6,"DPAK","unknown",725.00,812.00,0,top
-C12,"SMD_SIMPLE-80-50","10uF",497.06,584.80,0,top
-U2,"DPAK","unknown",725.00,1987.00,0,top
-C5,"SMD_SIMPLE-80-50","10uF",548.23,1752.12,180,top
-J6,"wurth-microsd","unknown",2542.10,257.35,180,top
-R6,"SMD_SIMPLE-80-50","22?",3330.00,1907.00,0,top
-R7,"SMD_SIMPLE-80-50","56?",3325.00,2202.00,0,top
-C6,"SMD_SIMPLE-80-50","10uF",410.00,2312.00,0,top
-R9,"SMD_SIMPLE-80-50","154?",410.00,2217.00,0,top
-R8,"SMD_SIMPLE-80-50","120?",570.00,2217.00,0,top
-C16,"cap_0402","0.1uF",1335.00,2886.68,270,top
-C15,"cap_0402","0.1uF",2410.35,2886.03,270,top
-C14,"SMD_SIMPLE-120-60","47uF",785.00,1047.00,0,top
-C4,"SMD_SIMPLE-120-60","47uF",185.00,2622.00,0,top
-C7,"SMD_SIMPLE-120-60","47uF",845.00,1752.00,0,top
-C1,"SMD_SIMPLE-120-60","47uF",1225.00,2949.00,270,top
-LED1,"SMD_DIODE-80-50","unknown",3109.00,2015.00,0,top
index 56f34d7bbffae266ac5a3843ee4be168989e9ae0..e748b1bad61cc46f1619c7183c0539f699148274 100755 (executable)
@@ -27,7 +27,18 @@ static const uint8 ReadWriteErrorRecoveryPage[] =
 {\r
 0x01, // Page code\r
 0x0A, // Page length\r
-0x00, // No error recovery options for now\r
+\r
+// VMS 5.5-2 is very particular regarding the mode page values.\r
+// The required values for a SCSI2/NoTCQ device are:\r
+// AWRE=0 ARRE=0 TB=1 RC=0 EER=? PER=1 DTE=1 DCR=?\r
+// See ftp://www.digiater.nl/openvms/decus/vms94b/net94b/scsi_params_dkdriver.txt\r
+// X-Newsgroups: comp.os.vms\r
+// Subject: Re: VMS 6.1 vs. Seagate Disk Drives\r
+// Message-Id: <32g87h$8q@nntpd.lkg.dec.com>\r
+// From: weber@evms.enet.dec.com (Ralph O. Weber -- OpenVMS AXP)\r
+// Date: 12 Aug 1994 16:32:49 GMT\r
+0x26,\r
+\r
 0x00, // Don't try recovery algorithm during reads\r
 0x00, // Correction span 0\r
 0x00, // Head offset count 0,\r
@@ -305,7 +316,7 @@ static void doModeSense(
                case 0x0A:\r
                        pageIn(pc, idx, ControlModePage, sizeof(ControlModePage));\r
                        idx += sizeof(ControlModePage);\r
-                       break;\r
+                       if (pageCode != 0x3f) break;\r
 \r
                case 0x30:\r
                        pageIn(pc, idx, AppleVendorPage, sizeof(AppleVendorPage));\r
index 3144a039336f354133ec022a350e5e4307b3b904..ccd6a78275b60b141f20d5b610f2577c5f59c678 100644 (file)
@@ -94,7 +94,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
 /*  bEndpointAddress                       */ 0x01u,\r
 /*  bmAttributes                           */ 0x03u,\r
 /*  wMaxPacketSize                         */ 0x40u, 0x00u,\r
-/*  bInterval                              */ 0x80u,\r
+/*  bInterval                              */ 0x20u,\r
 /*********************************************************************\r
 * Endpoint Descriptor\r
 *********************************************************************/\r
@@ -103,7 +103,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
 /*  bEndpointAddress                       */ 0x82u,\r
 /*  bmAttributes                           */ 0x03u,\r
 /*  wMaxPacketSize                         */ 0x40u, 0x00u,\r
-/*  bInterval                              */ 0x40u,\r
+/*  bInterval                              */ 0x20u,\r
 /*********************************************************************\r
 * Interface Descriptor\r
 *********************************************************************/\r
@@ -135,7 +135,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
 /*  bEndpointAddress                       */ 0x03u,\r
 /*  bmAttributes                           */ 0x03u,\r
 /*  wMaxPacketSize                         */ 0x40u, 0x00u,\r
-/*  bInterval                              */ 0x80u,\r
+/*  bInterval                              */ 0x20u,\r
 /*********************************************************************\r
 * Endpoint Descriptor\r
 *********************************************************************/\r
@@ -144,7 +144,7 @@ const uint8 CYCODE USBFS_DEVICE0_CONFIGURATION0_DESCR[73u] = {
 /*  bEndpointAddress                       */ 0x84u,\r
 /*  bmAttributes                           */ 0x03u,\r
 /*  wMaxPacketSize                         */ 0x40u, 0x00u,\r
-/*  bInterval                              */ 0x40u\r
+/*  bInterval                              */ 0x20u\r
 };\r
 \r
 /*********************************************************************\r
index dfdc40aec12fcd86bca0761bfac3b81d98af3f54..acda16c7f5f303154b0455f3dd923533524aa7fd 100644 (file)
@@ -28,7 +28,7 @@ __attribute__ ((__section__(".cyloadablemeta"), used))
 const uint8 cy_meta_loadable[] = {\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
-    0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x05u, 0x04u,\r
+    0x00u, 0x00u, 0x00u, 0x00u, 0x5Cu, 0xD1u, 0x10u, 0x04u,\r
     0x01u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
     0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u, 0x00u,\r
index 3040c7e1815467830dec8687fd89b69fc07e4420..cf48a6b0b3ab9adb3892062f7dfd54ffadeb7042 100644 (file)
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v3/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 8bbd6de39a111db395a0e0b5a173c69b8ef04e6d..6a33d2e201b1f0d46c677eb74c20420b306a64f2 100755 (executable)
Binary files a/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch and b/software/SCSI2SD/v3/SCSI2SD.cydsn/TopDesign/TopDesign.cysch differ
index 953ab81d3da040558f03bdfbd01de5015ff7a876..c2bb61e3b2f8b1de4af6e4ee30e409e8bcfee614 100644 (file)
Binary files a/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit and b/software/SCSI2SD/v3/USB_Bootloader.cydsn/USB_Bootloader.cyfit differ
index 688eb60e58a6574f8f3cb22127b0b9388bc505cb..cbfc68cace86ee8e860cec5d2263875c55cb2e9e 100755 (executable)
 <name_val_pair name="Z:\projects\SCSI2SD\git-parity\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\CortexM3\ARM_GCC_473\Release\USB_Bootloader.hex" v="&quot;-mthumb &quot;&quot;-march=armv7-m &quot;&quot;-mfix-cortex-m3-ldrd &quot;&quot;-T &quot;&quot;.\Generated_Source\PSoC5\cm3gcc.ld &quot;&quot;-g &quot;&quot;-Wl,-Map,${OutputDir}\${ProjectShortName}.map &quot;&quot;-specs=nano.specs &quot;&quot;-Wl,--gc-sections &quot;" />\r
 <name_val_pair name="Z:\projects\SCSI2SD\git-timeout\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\CortexM3\ARM_GCC_473\Release\USB_Bootloader.hex" v="&quot;-mthumb &quot;&quot;-march=armv7-m &quot;&quot;-mfix-cortex-m3-ldrd &quot;&quot;-T &quot;&quot;.\Generated_Source\PSoC5\cm3gcc.ld &quot;&quot;-g &quot;&quot;-Wl,-Map,${OutputDir}\${ProjectShortName}.map &quot;&quot;-specs=nano.specs &quot;&quot;-Wl,--gc-sections &quot;" />\r
 <name_val_pair name="Z:\projects\SCSI2SD\git-cache\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\CortexM3\ARM_GCC_484\Release\USB_Bootloader.hex" v="-mthumb -march=armv7-m -mfix-cortex-m3-ldrd -Wl,-Map,${OutputDir}/${ProjectShortName}.map -T .\Generated_Source\PSoC5\cm3gcc.ld -g -specs=nano.specs &quot;-u _printf_float&quot; &quot;&quot; -Wl,--gc-sections" />\r
+<name_val_pair name="Z:\projects\SCSI2SD\git\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\CortexM3\ARM_GCC_484\Release\USB_Bootloader.hex" v="-mthumb -march=armv7-m -mfix-cortex-m3-ldrd -Wl,-Map,${OutputDir}/${ProjectShortName}.map -T .\Generated_Source\PSoC5\cm3gcc.ld -g -specs=nano.specs &quot;-u _printf_float&quot; &quot;&quot; -Wl,--gc-sections" />\r
 </name>\r
 <name v="c9323d49-d323-40b8-9b59-cc008d68a989@Debug@CortexM3">\r
 <name_val_pair name=".\main.c" v="&quot;-I. &quot;&quot;-I./Generated_Source/PSoC5 &quot;&quot;-Wno-main &quot;&quot;-mcpu=cortex-m3 &quot;&quot;-mthumb &quot;&quot;-Wall &quot;&quot;-g &quot;&quot;-D &quot;&quot;DEBUG &quot;&quot;-Wa,-alh=${OutputDir}\${CompileFile}.lst &quot;&quot;-ffunction-sections &quot;" />\r
 <name_val_pair name="W:\SCSI2SD\software\SCSI2SD\USB_Bootloader.cydsn\CortexM3\ARM_GCC_473\Debug\USB_Bootloader.hex" v="&quot;-mthumb &quot;&quot;-march=armv7-m &quot;&quot;-mfix-cortex-m3-ldrd &quot;&quot;-T &quot;&quot;.\Generated_Source\PSoC5\cm3gcc.ld &quot;&quot;-g &quot;&quot;-Wl,-Map,${OutputDir}\${ProjectShortName}.map &quot;&quot;-specs=nano.specs &quot;&quot;-Wl,--gc-sections &quot;" />\r
 </name>\r
 </genericCmdLineData>\r
-<codeGenCmdLineTag v="-.appdatapath &quot;C:\Users\Micha_000\AppData\Local\Cypress Semiconductor\PSoC Creator\3.1&quot; -.fdsnotice -.fdswarpdepfile=warp_dependencies.txt -.fdselabdepfile=elab_dependencies.txt -.fdsbldfile=generated_files.txt -p Z:\projects\SCSI2SD\git-cache\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\USB_Bootloader.cyprj -d CY8C5267AXI-LP051 -s Z:\projects\SCSI2SD\git-cache\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\Generated_Source\PSoC5 -- -yv2 -q10 -ygs -o2 -v3 -.fftcfgtype=LE" />\r
+<codeGenCmdLineTag v="-.appdatapath &quot;C:\Users\Micha_000\AppData\Local\Cypress Semiconductor\PSoC Creator\3.1&quot; -.fdsnotice -.fdswarpdepfile=warp_dependencies.txt -.fdselabdepfile=elab_dependencies.txt -.fdsbldfile=generated_files.txt -p Z:\projects\SCSI2SD\git\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\USB_Bootloader.cyprj -d CY8C5267AXI-LP051 -s Z:\projects\SCSI2SD\git\SCSI2SD\software\SCSI2SD\v3\USB_Bootloader.cydsn\Generated_Source\PSoC5 -- -yv2 -q10 -ygs -o2 -v3 -.fftcfgtype=LE" />\r
 </CyGuid_b0374e30-ce3a-47f2-ad85-821643292c68>\r
 </dataGuid>\r
 <dataGuid v="597c5b74-0c46-4204-8b7f-96f3570671dc">\r
 <v>C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\psoc\content\cyprimitives\CyPrimitives.cylib\ZeroTerminal\ZeroTerminal.v</v>\r
 <v>C:\Program Files (x86)\Cypress\PSoC Creator\3.1\PSoC Creator\warp\lib\common\stdlogic\rtlpkg.vif</v>\r
 </warp_dep>\r
-<deps_time v="130664015022693971" />\r
+<deps_time v="130672400716827656" />\r
 <top_block v="TopDesign" />\r
-<last_generation v="1" />\r
+<last_generation v="2" />\r
 </CyGuid_925cc1e1-309e-4e08-b0a1-09a83c35b157>\r
 </dataGuid>\r
 <dataGuid v="769d31ea-68b1-4f0c-b90a-7c10a43ee563">\r
 <CyGuid_769d31ea-68b1-4f0c-b90a-7c10a43ee563 type_name="CyDesigner.Common.ProjMgmt.Model.CyLinkCustomData" version="1">\r
-<deps_time v="130664016042069689" />\r
+<deps_time v="130672401534806618" />\r
 </CyGuid_769d31ea-68b1-4f0c-b90a-7c10a43ee563>\r
 </dataGuid>\r
 <dataGuid v="bf610382-39c6-441f-80b8-b04622ea7845">\r
index 1dbc822a1dfd3dee3c2205cd31bedad1595e4a95..67548f73dae046027e243d6b59ea296859747575 100644 (file)
Binary files a/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit and b/software/SCSI2SD/v4/SCSI2SD.cydsn/SCSI2SD.cyfit differ
index 8d65665b47c6ecb30232ec38c226295c09b2af1b..73330abf5d10839a9cdeac86d9a9348f1b783f16 100644 (file)
Binary files a/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit and b/software/SCSI2SD/v4/USB_Bootloader.cydsn/USB_Bootloader.cyfit differ
index d437f60dad6180fa692fc48c6d4b9b8af669bb11..883460783520246317053e27369140201909b6a2 100755 (executable)
@@ -5,8 +5,7 @@ Linux)
        # Builds all of the utilities (not firmware) under Linux.
        # Requires mingw installed to cross-compile Windows targets.
 
-       (cd scsi2sd-util && ./build.sh) &&
-       (cd scsi2sd-debug && ./build.sh)
+       (cd scsi2sd-util && ./build.sh)
 
        if [ $? -eq 0 ]; then
                mkdir -p build/linux
@@ -14,25 +13,20 @@ Linux)
                mkdir -p build/windows/32bit
 
                cp scsi2sd-util/build/linux/scsi2sd-util build/linux
-               cp scsi2sd-debug/build/linux/scsi2sd-debug build/linux
 
                cp scsi2sd-util/build/windows/32bit/scsi2sd-util.exe build/windows/32bit
-               cp scsi2sd-debug/build/windows/32bit/scsi2sd-debug.exe build/windows/32bit
 
                cp scsi2sd-util/build/windows/64bit/scsi2sd-util.exe build/windows/64bit
-               cp scsi2sd-debug/build/windows/64bit/scsi2sd-debug.exe build/windows/64bit
        fi
 ;;
 
 Darwin)
-       make -C scsi2sd-util &&
-       make -C scsi2sd-debug
+       make -C scsi2sd-util
 
        if [ $? -eq 0 ]; then
                mkdir -p build/mac
 
                cp scsi2sd-util/build/mac/scsi2sd-util build/mac
-               cp scsi2sd-debug/build/mac/scsi2sd-debug build/mac
        fi
 
 esac
diff --git a/software/scsi2sd-debug/.gitignore b/software/scsi2sd-debug/.gitignore
deleted file mode 100644 (file)
index 567609b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-build/
diff --git a/software/scsi2sd-debug/Makefile b/software/scsi2sd-debug/Makefile
deleted file mode 100644 (file)
index 5690879..0000000
+++ /dev/null
@@ -1,63 +0,0 @@
-
-CPPFLAGS = -I ../bootloaderhost/hidapi/hidapi -I ../bootloaderhost
-CFLAGS += -Wall -Wno-pointer-sign -O2
-CXXFLAGS += -Wall -O2
-VPATH += ../bootloaderhost
-
-TARGET ?= $(shell uname -s)
-ifeq ($(TARGET),Win32)
-       VPATH += hidapi/windows
-       LDFLAGS += -static -mconsole -mwindows -lsetupapi -lws2_32
-       BUILD = build/windows/32bit
-       CC=i686-w64-mingw32-gcc
-       CXX=i686-w64-mingw32-g++
-       EXE=.exe
-endif
-ifeq ($(TARGET),Win64)
-       VPATH += hidapi/windows
-       LDFLAGS += -static -mconsole -mwindows -lsetupapi -lws2_32
-       BUILD = build/windows/64bit
-       CC=x86_64-w64-mingw32-gcc
-       CXX=x86_64-w64-mingw32-g++
-       EXE=.exe
-endif
-ifeq ($(TARGET),Linux)
-       VPATH += hidapi/linux
-       LDFLAGS += -ludev
-       BUILD = build/linux
-endif
-ifeq ($(TARGET),Darwin)
-       # Should match OSX
-       VPATH += ../bootloaderhost/hidapi-mac
-       LDFLAGS += -framework IOKit -framework CoreFoundation
-       CFLAGS += -mmacosx-version-min=10.7
-       CXXFLAGS += -stdlib=libc++ -mmacosx-version-min=10.7 -std=c++0x
-       CC=clang
-       CXX=clang++
-       BUILD=build/mac
-endif
-
-all:  $(BUILD)/scsi2sd-debug$(EXE)
-
-HIDAPI = \
-       $(BUILD)/hid.o \
-
-OBJ = \
-       $(HIDAPI) \
-       $(BUILD)/scsi2sd-debug.o \
-       $(BUILD)/SCSI2SD_HID.o \
-
-$(BUILD)/%.o: %.c
-       mkdir -p $(dir $@)
-       $(CC) $(CPPFLAGS) $(CFLAGS) $^ -c -o $@
-
-$(BUILD)/%.o: %.cc
-       mkdir -p $(dir $@)
-       $(CXX) $(CPPFLAGS) $(CXXFLAGS) $^ -c -o $@
-
-$(BUILD)/scsi2sd-debug$(EXE): $(OBJ)
-       mkdir -p $(dir $@)
-       $(CXX) $(CXXFLAGS) $^ $(LDFLAGS) -o $@
-
-clean:
-       rm $(BUILD)/scsi2sd-debug$(EXE) $(OBJ)
diff --git a/software/scsi2sd-debug/build.sh b/software/scsi2sd-debug/build.sh
deleted file mode 100755 (executable)
index 64b4eea..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh
-
-rm -rf build/
-make && \
-       make TARGET=Win32 &&
-       make TARGET=Win64
-
diff --git a/software/scsi2sd-debug/scsi2sd-debug.cc b/software/scsi2sd-debug/scsi2sd-debug.cc
deleted file mode 100644 (file)
index 542f162..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-//     Copyright (C) 2014 Michael McMaster <michael@codesrc.com>
-//
-//     This file is part of SCSI2SD.
-//
-//     SCSI2SD is free software: you can redistribute it and/or modify
-//     it under the terms of the GNU General Public License as published by
-//     the Free Software Foundation, either version 3 of the License, or
-//     (at your option) any later version.
-//
-//     SCSI2SD is distributed in the hope that it will be useful,
-//     but WITHOUT ANY WARRANTY; without even the implied warranty of
-//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//     GNU General Public License for more details.
-//
-//     You should have received a copy of the GNU General Public License
-//     along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
-
-#include <getopt.h>
-#include <inttypes.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-// htonl/ntohl includes.
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-#include <arpa/inet.h>
-#endif
-
-#include "hidapi.h"
-
-#define MIN(a,b) (a < b ? a : b)
-
-FILE* logfile = NULL;
-
-static void readConfig(hid_device* handle)
-{
-       // First byte is the report ID (0)
-       unsigned char buf[65];
-       memset(buf, 0, sizeof(buf));
-       int result = hid_read(handle, buf, sizeof(buf));
-
-       if (result < 0)
-       {
-               fprintf(stderr, "USB HID Read Failure: %ls\n", hid_error(handle));
-       }
-       int i;
-       for (i = 0; i < 32; ++i)
-       {
-               fprintf(logfile, "%02x ", buf[i]);
-       }
-       fprintf(logfile, "\n");
-       fflush(logfile);
-}
-
-static void usage()
-{
-       printf("Usage: scsi2sd-debug outputfile\n");
-       printf("\n");
-       printf("outputfile\tPath to the output log file.\n\n");
-       printf("\n\n");
-       exit(1);
-}
-
-
-int main(int argc, char* argv[])
-{
-       printf("SCSI2SD Debug Utility.\n");
-       printf("Copyright (C) 2014 Michael McMaster <michael@codesrc.com>\n\n");
-
-       if (argc != 2)
-       {
-               usage();
-               exit(1);
-       }
-
-       logfile = fopen(argv[1], "w");
-       if (!logfile)
-       {
-               fprintf(stderr, "Could not write to file %s.\n", argv[1]);
-               exit(1);
-       }
-
-
-       uint16_t vendorId = 0x04B4; // Cypress
-       uint16_t productId = 0x1337; // SCSI2SD
-
-       printf(
-               "USB device parameters\n\tVendor ID:\t0x%04X\n\tProduct ID:\t0x%04X\n",
-               vendorId,
-               productId);
-
-       // Enumerate and print the HID devices on the system
-       struct hid_device_info *dev = hid_enumerate(vendorId, productId);
-
-       if (!dev)
-       {
-               fprintf(stderr, "ERROR: SCSI2SD USB device not found.\n");
-               exit(1);
-       }
-
-       // We need the SECOND interface for debug data
-       while (dev && dev->interface_number != 1)
-       {
-               dev = dev->next;
-       }
-       if (!dev)
-       {
-               fprintf(stderr, "ERROR: SCSI2SD Debug firmware not enabled.\n");
-               exit(1);
-       }
-
-       printf("USB Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls",
-               dev->vendor_id, dev->product_id, dev->path, dev->serial_number);
-       printf("\n");
-       printf("  Manufacturer: %ls\n", dev->manufacturer_string);
-       printf("  Product:      %ls\n", dev->product_string);
-       printf("\n");
-
-       hid_device* handle = hid_open_path(dev->path);
-       if (!handle)
-       {
-               fprintf(
-                       stderr,
-                       "ERROR: Could not open device %s. Check permissions.\n", dev->path
-                       );
-               exit(1);
-       }
-
-
-       while (1)
-       {
-               readConfig(handle);
-       }
-
-       return 0;
-}
-
index e81821b815a84b6ae9786b052bd713ee15c3c92a..6944b83c6bdc50c5d3dac11ff25f2fc51439fd2d 100644 (file)
@@ -90,7 +90,7 @@ HID::HID(hid_device_info* hidInfo) :
                                for (int i = 0; i < 4; ++i)
                                {
                                        buf[0] = 0; // report id
-                                       hid_read(dev, buf, HID_PACKET_SIZE);
+                                       hid_read_timeout(dev, buf, HID_PACKET_SIZE, HID_TIMEOUT_MS);
                                        if (watchVal == -1) watchVal = buf[25];
                                        configIntFound = configIntFound && (buf[25] == watchVal);
                                }
@@ -177,7 +177,7 @@ HID::enterBootloader()
                };
 
                int result = hid_write(myDebugHandle, hidBuf, sizeof(hidBuf));
-               if (result < 0)
+               if (result <= 0)
                {
                        const wchar_t* err = hid_error(myDebugHandle);
                        std::stringstream ss;
@@ -196,7 +196,7 @@ HID::readFlashRow(int array, int row, std::vector<uint8_t>& out)
                static_cast<uint8_t>(array),
                static_cast<uint8_t>(row)
        };
-       sendHIDPacket(cmd, out);
+       sendHIDPacket(cmd, out, HIDPACKET_MAX_LEN / 62);
 }
 
 void
@@ -208,7 +208,7 @@ HID::writeFlashRow(int array, int row, const std::vector<uint8_t>& in)
        cmd.push_back(static_cast<uint8_t>(array));
        cmd.push_back(static_cast<uint8_t>(row));
        std::vector<uint8_t> out;
-       sendHIDPacket(cmd, out);
+       sendHIDPacket(cmd, out, 1);
        if ((out.size() < 1) || (out[0] != CONFIG_STATUS_GOOD))
        {
                std::stringstream ss;
@@ -217,6 +217,30 @@ HID::writeFlashRow(int array, int row, const std::vector<uint8_t>& in)
        }
 }
 
+bool
+HID::readSCSIDebugInfo(std::vector<uint8_t>& buf)
+{
+       buf[0] = 0; // report id
+       hid_set_nonblocking(myDebugHandle, 1);
+       int result =
+               hid_read_timeout(
+                       myDebugHandle,
+                       &buf[0],
+                       HID_PACKET_SIZE,
+                       HID_TIMEOUT_MS);
+       hid_set_nonblocking(myDebugHandle, 0);
+
+       if (result <= 0)
+       {
+               const wchar_t* err = hid_error(myDebugHandle);
+               std::stringstream ss;
+               ss << "USB HID read failure: " << err;
+               throw std::runtime_error(ss.str());
+       }
+       return result > 0;
+}
+
+
 void
 HID::readHID(uint8_t* buffer, size_t len)
 {
@@ -224,9 +248,9 @@ HID::readHID(uint8_t* buffer, size_t len)
        buffer[0] = 0; // report id
 
        int result = -1;
-       for (int retry = 0; retry < 3 && result < 0; ++retry)
+       for (int retry = 0; retry < 3 && result <= 0; ++retry)
        {
-               result = hid_read(myConfigHandle, buffer, len);
+               result = hid_read_timeout(myConfigHandle, buffer, len, HID_TIMEOUT_MS);
        }
 
        if (result < 0)
@@ -243,9 +267,14 @@ HID::readDebugData()
 {
        uint8_t buf[HID_PACKET_SIZE];
        buf[0] = 0; // report id
-       int result = hid_read(myDebugHandle, buf, HID_PACKET_SIZE);
-
-       if (result < 0)
+       int result =
+               hid_read_timeout(
+                       myDebugHandle,
+                       buf,
+                       HID_PACKET_SIZE,
+                       HID_TIMEOUT_MS);
+
+       if (result <= 0)
        {
                const wchar_t* err = hid_error(myDebugHandle);
                std::stringstream ss;
@@ -292,7 +321,7 @@ HID::ping()
        std::vector<uint8_t> out;
        try
        {
-               sendHIDPacket(cmd, out);
+               sendHIDPacket(cmd, out, 1);
        }
        catch (std::runtime_error& e)
        {
@@ -302,26 +331,66 @@ HID::ping()
        return (out.size() >= 1) && (out[0] == CONFIG_STATUS_GOOD);
 }
 
+std::vector<uint8_t>
+HID::getSD_CSD()
+{
+       std::vector<uint8_t> cmd { CONFIG_SDINFO };
+       std::vector<uint8_t> out;
+       try
+       {
+               sendHIDPacket(cmd, out, 1);
+       }
+       catch (std::runtime_error& e)
+       {
+               return std::vector<uint8_t>(16);
+       }
+
+       out.resize(16);
+       return out;
+}
+
+std::vector<uint8_t>
+HID::getSD_CID()
+{
+       std::vector<uint8_t> cmd { CONFIG_SDINFO };
+       std::vector<uint8_t> out;
+       try
+       {
+               sendHIDPacket(cmd, out, 1);
+       }
+       catch (std::runtime_error& e)
+       {
+               return std::vector<uint8_t>(16);
+       }
+
+       std::vector<uint8_t> result(16);
+       for (size_t i = 0; i < 16; ++i) result[i] = out[16 + i];
+       return result;
+}
+
 void
-HID::sendHIDPacket(const std::vector<uint8_t>& cmd, std::vector<uint8_t>& out)
+HID::sendHIDPacket(
+       const std::vector<uint8_t>& cmd,
+       std::vector<uint8_t>& out,
+       size_t responseLength)
 {
        assert(cmd.size() <= HIDPACKET_MAX_LEN);
        hidPacket_send(&cmd[0], cmd.size());
 
        uint8_t hidBuf[HID_PACKET_SIZE];
        const uint8_t* chunk = hidPacket_getHIDBytes(hidBuf);
+
        while (chunk)
        {
                uint8_t reportBuf[HID_PACKET_SIZE + 1] = { 0x00 }; // Report ID
                memcpy(&reportBuf[1], chunk, HID_PACKET_SIZE);
                int result = -1;
-               for (int retry = 0; retry < 10 && result < 0; ++retry)
+               for (int retry = 0; retry < 10 && result <= 0; ++retry)
                {
                        result = hid_write(myConfigHandle, reportBuf, sizeof(reportBuf));
-                       if (result < 0) wxMilliSleep(8);
                }
 
-               if (result < 0)
+               if (result <= 0)
                {
                        const wchar_t* err = hid_error(myConfigHandle);
                        std::stringstream ss;
@@ -335,16 +404,11 @@ HID::sendHIDPacket(const std::vector<uint8_t>& cmd, std::vector<uint8_t>& out)
        size_t respLen;
        resp = hidPacket_getPacket(&respLen);
 
-       // We need to poll quick enough to not skip packets
-       // This depends on the USB HID device poll rate parameter.
-       // SCSI2SD uses a 32ms poll rate, so we check for new chunks at 4x
-       // that rate.
-       for (int retry = 0; retry < (HIDPACKET_MAX_LEN / 62) * 30 && !resp; ++retry)
+       for (int retry = 0; retry < responseLength * 2 && !resp; ++retry)
        {
-               readHID(hidBuf, sizeof(hidBuf));
+               readHID(hidBuf, sizeof(hidBuf)); // Will block
                hidPacket_recv(hidBuf, HID_PACKET_SIZE);
                resp = hidPacket_getPacket(&respLen);
-               if (!resp) wxMilliSleep(8);
        }
 
        if (!resp)
index 98d62ed9564d8cdf38f47c7a0b17b89aef316b0b..443b3df73bdc0115ea4b8042ea805742f917c7e2 100644 (file)
@@ -43,6 +43,11 @@ public:
 
        static const size_t HID_PACKET_SIZE = 64;
 
+       // HID intervals for 4.0.3 firmware: <= 128ms
+       // > 4.0.3 = 32ms.
+       static const size_t HID_TIMEOUT_MS = 256; // 2x HID Interval.
+
+
        static HID* Open();
 
        ~HID();
@@ -50,19 +55,26 @@ public:
        uint16_t getFirmwareVersion() const { return myFirmwareVersion; }
        std::string getFirmwareVersionStr() const;
        uint32_t getSDCapacity() const { return mySDCapacity; }
+       std::vector<uint8_t> getSD_CSD();
+       std::vector<uint8_t> getSD_CID();
 
        void enterBootloader();
 
        void readFlashRow(int array, int row, std::vector<uint8_t>& out);
        void writeFlashRow(int array, int row, const std::vector<uint8_t>& in);
        bool ping();
+
+       bool readSCSIDebugInfo(std::vector<uint8_t>& buf);
+
 private:
        HID(hid_device_info* hidInfo);
        void destroy();
        void readDebugData();
        void readHID(uint8_t* buffer, size_t len);
        void sendHIDPacket(
-               const std::vector<uint8_t>& cmd, std::vector<uint8_t>& out
+               const std::vector<uint8_t>& cmd,
+               std::vector<uint8_t>& out,
+               size_t responseLength
                );
 
        hid_device_info* myHidInfo;
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)