Add new "blind write" option to increase write command performance. This causes issue...
[SCSI2SD-V6.git] / src / scsi2sd-util6 / BoardPanel.cc
1 // Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
2 //
3 // This file is part of SCSI2SD.
4 //
5 // SCSI2SD is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // SCSI2SD is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with SCSI2SD. If not, see <http://www.gnu.org/licenses/>.
17
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include <wx/wxprec.h>
20 #ifndef WX_PRECOMP
21 #include <wx/wx.h>
22 #endif
23
24 #include <wx/wrapsizer.h>
25
26 #include "ConfigUtil.hh"
27 #include "BoardPanel.hh"
28
29 #include <limits>
30 #include <sstream>
31
32 #include <math.h>
33 #include <string.h>
34
35 using namespace SCSI2SD;
36
37 namespace
38 {
39 template<typename IntType, class WXCTRL> std::pair<IntType, bool>
40 CtrlGetValue(WXCTRL* ctrl)
41 {
42 IntType value;
43 std::stringstream conv;
44 conv << ctrl->GetValue();
45 conv >> value;
46 return std::make_pair(value, static_cast<bool>(conv));
47 }
48
49 }
50
51 BoardPanel::BoardPanel(wxWindow* parent, const S2S_BoardCfg& initialConfig) :
52 wxPanel(parent),
53 myParent(parent),
54 myDelayValidator(new wxIntegerValidator<uint8_t>)
55 {
56 wxFlexGridSizer *fgs = new wxFlexGridSizer(13, 2, 9, 25);
57
58 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
59 myTermCtrl =
60 new wxCheckBox(
61 this,
62 ID_termCtrl,
63 _("Enable SCSI terminator"));
64 myTermCtrl->SetToolTip(_("Enable active terminator. Both ends of the SCSI chain must be terminated."));
65 fgs->Add(myTermCtrl);
66
67 fgs->Add(new wxStaticText(this, wxID_ANY, _("SCSI Speed Limit")));
68 wxString speeds[] = {
69 wxT("No limit (safe)"),
70 wxT("Async, 1.5MB/s"),
71 wxT("Async, 3.3MB/s"),
72 wxT("Async, 5 MB/s"),
73 wxT("Sync, 5 MB/s"),
74 wxT("Sync, 10 MB/s"),
75 wxT("Turbo (less reliable)")};
76
77 myScsiSpeedCtrl =
78 new wxChoice(
79 this,
80 ID_scsiSpeedCtrl,
81 wxDefaultPosition,
82 wxDefaultSize,
83 sizeof(speeds) / sizeof(wxString),
84 speeds
85 );
86 myScsiSpeedCtrl->SetToolTip(_("Limit SCSI interface speed"));
87 fgs->Add(myScsiSpeedCtrl);
88
89 fgs->Add(new wxStaticText(this, wxID_ANY, _("Startup Delay (seconds)")));
90 myStartDelayCtrl =
91 new wxTextCtrl(
92 this,
93 ID_startDelayCtrl,
94 "0",
95 wxDefaultPosition,
96 wxDefaultSize,
97 0,
98 *myDelayValidator);
99 myStartDelayCtrl->SetToolTip(_("Extra delay on power on, normally set to 0"));
100 fgs->Add(myStartDelayCtrl);
101
102
103 fgs->Add(new wxStaticText(this, wxID_ANY, _("SCSI Selection Delay (ms, 255 = auto)")));
104 mySelDelayCtrl =
105 new wxTextCtrl(
106 this,
107 ID_selDelayCtrl,
108 "255",
109 wxDefaultPosition,
110 wxDefaultSize,
111 0,
112 *myDelayValidator);
113 mySelDelayCtrl->SetToolTip(_("Delay before responding to SCSI selection. SCSI1 hosts usually require 1ms delay, however some require no delay"));
114 fgs->Add(mySelDelayCtrl);
115
116 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
117 myParityCtrl =
118 new wxCheckBox(
119 this,
120 ID_parityCtrl,
121 _("Enable Parity"));
122 myParityCtrl->SetToolTip(_("Enable to require valid SCSI parity bits when receiving data. Some hosts don't provide parity. SCSI2SD always outputs valid parity bits."));
123 fgs->Add(myParityCtrl);
124
125 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
126 myUnitAttCtrl =
127 new wxCheckBox(
128 this,
129 ID_unitAttCtrl,
130 _("Enable Unit Attention"));
131 myUnitAttCtrl->SetToolTip(_("Enable this to inform the host of changes after hot-swapping SD cards. Causes problems with Mac Plus."));
132 fgs->Add(myUnitAttCtrl);
133
134 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
135 myScsi2Ctrl =
136 new wxCheckBox(
137 this,
138 ID_scsi2Ctrl,
139 _("Enable SCSI2 Mode"));
140 myScsi2Ctrl->SetToolTip(_("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
141 fgs->Add(myScsi2Ctrl);
142
143 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
144 mySelLatchCtrl =
145 new wxCheckBox(
146 this,
147 ID_selLatchCtrl,
148 _("Respond to short SCSI selection pulses"));
149 mySelLatchCtrl->SetToolTip(_("Respond to very short duration selection attempts. This supports non-standard hardware, but is generally safe to enable. Required for Philips P2000C."));
150 fgs->Add(mySelLatchCtrl);
151
152 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
153 myMapLunsCtrl =
154 new wxCheckBox(
155 this,
156 ID_mapLunsCtrl,
157 _("Map LUNS to SCSI IDs"));
158 myMapLunsCtrl->SetToolTip(_("Treat LUNS as IDs instead. Supports multiple drives on XEBEC S1410 SASI Bridge"));
159 fgs->Add(myMapLunsCtrl);
160
161
162 fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
163 myBlindWriteCtrl =
164 new wxCheckBox(
165 this,
166 ID_blindWriteCtrl,
167 _("Enable Blind Writes"));
168 myBlindWriteCtrl->SetToolTip(_("Enable writing to the SD card before all the SCSI data has been received."));
169 fgs->Add(myBlindWriteCtrl);
170
171 wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);
172 hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
173 this->SetSizer(hbox);
174 Centre();
175
176 setConfig(initialConfig);
177 }
178
179
180 S2S_BoardCfg
181 BoardPanel::getConfig() const
182 {
183 S2S_BoardCfg config;
184
185 // Try and keep unknown/unused fields as-is to support newer firmware
186 // versions.
187 memcpy(&config, &myConfig, sizeof(config));
188
189 config.flags =
190 (myParityCtrl->IsChecked() ? S2S_CFG_ENABLE_PARITY : 0) |
191 (myUnitAttCtrl->IsChecked() ? S2S_CFG_ENABLE_UNIT_ATTENTION : 0) |
192 (myScsi2Ctrl->IsChecked() ? S2S_CFG_ENABLE_SCSI2 : 0) |
193 (mySelLatchCtrl->IsChecked() ? S2S_CFG_ENABLE_SEL_LATCH : 0) |
194 (myMapLunsCtrl->IsChecked() ? S2S_CFG_MAP_LUNS_TO_IDS : 0);
195
196 config.flags6 = (myTermCtrl->IsChecked() ? S2S_CFG_ENABLE_TERMINATOR : 0);
197 config.flags6 = (myBlindWriteCtrl->IsChecked() ? S2S_CFG_ENABLE_BLIND_WRITES : 0);
198
199 config.startupDelay = CtrlGetValue<unsigned int>(myStartDelayCtrl).first;
200 config.selectionDelay = CtrlGetValue<unsigned int>(mySelDelayCtrl).first;
201 config.scsiSpeed = myScsiSpeedCtrl->GetSelection();
202 return config;
203 }
204
205 void
206 BoardPanel::setConfig(const S2S_BoardCfg& config)
207 {
208 memcpy(&myConfig, &config, sizeof(config));
209
210 myParityCtrl->SetValue(config.flags & S2S_CFG_ENABLE_PARITY);
211 myUnitAttCtrl->SetValue(config.flags & S2S_CFG_ENABLE_UNIT_ATTENTION);
212 myScsi2Ctrl->SetValue(config.flags & S2S_CFG_ENABLE_SCSI2);
213 myTermCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_TERMINATOR);
214 myBlindWriteCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_BLIND_WRITES);
215 mySelLatchCtrl->SetValue(config.flags & S2S_CFG_ENABLE_SEL_LATCH);
216 myMapLunsCtrl->SetValue(config.flags & S2S_CFG_MAP_LUNS_TO_IDS);
217
218 {
219 std::stringstream conv;
220 conv << static_cast<unsigned int>(config.startupDelay);
221 myStartDelayCtrl->ChangeValue(conv.str());
222 }
223 {
224 std::stringstream conv;
225 conv << static_cast<unsigned int>(config.selectionDelay);
226 mySelDelayCtrl->ChangeValue(conv.str());
227 }
228 myScsiSpeedCtrl->SetSelection(config.scsiSpeed);
229 }
230
231