The Pedigree Project  0.1
ScsiCommands.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "modules/drivers/common/scsi/ScsiCommands.h"
21 #include "pedigree/kernel/utilities/utility.h"
22 
23 ScsiCommand::ScsiCommand() = default;
24 ScsiCommand::~ScsiCommand() = default;
25 
26 namespace ScsiCommands
27 {
28 Inquiry::Inquiry(
29  uint16_t len, bool enableVitalData, uint8_t pageCode, uint8_t ctl)
30 {
31  ByteSet(&command, 0, sizeof(command));
32  command.opcode = 0x12;
33  command.epvd = enableVitalData;
34  if (enableVitalData)
35  command.pageCode = pageCode;
36  command.len = HOST_TO_BIG16(len);
37  command.control = ctl;
38 }
39 
40 size_t Inquiry::serialise(uintptr_t &addr)
41 {
42  addr = reinterpret_cast<uintptr_t>(&command);
43  return sizeof(command);
44 }
45 
46 UnitReady::UnitReady(uint8_t ctl)
47 {
48  ByteSet(&command, 0, sizeof(command));
49  command.opcode = 0;
50  command.control = ctl;
51 }
52 
53 size_t UnitReady::serialise(uintptr_t &addr)
54 {
55  addr = reinterpret_cast<uintptr_t>(&command);
56  return sizeof(command);
57 }
58 
59 ReadSense::ReadSense(uint8_t desc, uint8_t len, uint8_t ctl)
60 {
61  ByteSet(&command, 0, sizeof(command));
62  command.opcode = 0x03;
63  command.desc = desc;
64  command.len = len;
65  command.control = ctl;
66 }
67 
68 size_t ReadSense::serialise(uintptr_t &addr)
69 {
70  addr = reinterpret_cast<uintptr_t>(&command);
71  return sizeof(command);
72 }
73 
74 StartStop::StartStop(
75  bool imm, uint8_t newpower, bool eject_load, bool start, uint8_t ctl)
76 {
77  ByteSet(&command, 0, sizeof(command));
78  command.opcode = 0x1b;
79  command.imm = imm ? 1 : 0;
80  command.setup =
81  (start ? 1 : 0) | ((eject_load ? 1 : 0) << 1) | (newpower << 4);
82  command.control = ctl;
83 }
84 
85 size_t StartStop::serialise(uintptr_t &addr)
86 {
87  addr = reinterpret_cast<uintptr_t>(&command);
88  return sizeof(command);
89 }
90 
91 SendDiagnostic::SendDiagnostic(
92  bool selfTest, uint8_t selfTestCode, uintptr_t params, size_t paramLen,
93  bool deviceOffline, bool unitOffline, uint8_t ctl)
94 {
95  ByteSet(&command, 0, sizeof(command));
96  command.opcode = 0x1d;
97  command.unitOffline = unitOffline;
98  command.devOffline = deviceOffline;
99  command.selfTest = selfTest;
100  command.pf = 0;
101  command.selfTestCode = selfTestCode;
102  command.paramListLen = HOST_TO_BIG16(paramLen);
103  command.control = ctl;
104 }
105 
106 size_t SendDiagnostic::serialise(uintptr_t &addr)
107 {
108  addr = reinterpret_cast<uintptr_t>(&command);
109  return sizeof(command);
110 }
111 
112 ReadTocCommand::ReadTocCommand(uint16_t nativeBlockSize, uint8_t ctl)
113 {
114  ByteSet(&command, 0, sizeof(command));
115  command.opcode = 0x43;
116  command.len = HOST_TO_BIG16(nativeBlockSize);
117 }
118 
119 size_t ReadTocCommand::serialise(uintptr_t &addr)
120 {
121  addr = reinterpret_cast<uintptr_t>(&command);
122  return sizeof(command);
123 }
124 
125 ReadCapacity10::ReadCapacity10(uint8_t ctl)
126 {
127  ByteSet(&command, 0, sizeof(command));
128  command.opcode = 0x25;
129  command.control = ctl;
130 }
131 
132 size_t ReadCapacity10::serialise(uintptr_t &addr)
133 {
134  addr = reinterpret_cast<uintptr_t>(&command);
135  return sizeof(command);
136 }
137 
138 Read10::Read10(uint32_t nLba, uint32_t nSectors)
139 {
140  ByteSet(&command, 0, sizeof(command));
141  command.nOpCode = 0x28;
142  command.nLba = HOST_TO_BIG32(nLba);
143  command.nSectors = HOST_TO_BIG16(nSectors);
144 }
145 
146 size_t Read10::serialise(uintptr_t &addr)
147 {
148  addr = reinterpret_cast<uintptr_t>(&command);
149  return sizeof(command);
150 }
151 
152 Read12::Read12(uint32_t nLba, uint32_t nSectors)
153 {
154  ByteSet(&command, 0, sizeof(command));
155  command.nOpCode = 0xa8;
156  command.nLba = HOST_TO_BIG32(nLba);
157  command.nSectors = HOST_TO_BIG32(nSectors);
158 }
159 
160 size_t Read12::serialise(uintptr_t &addr)
161 {
162  addr = reinterpret_cast<uintptr_t>(&command);
163  return sizeof(command);
164 }
165 
166 Read16::Read16(uint32_t nLba, uint32_t nSectors)
167 {
168  ByteSet(&command, 0, sizeof(command));
169  command.nOpCode = 0x88;
170  command.nLba = HOST_TO_BIG64(nLba);
171  command.nSectors = HOST_TO_BIG32(nSectors);
172 }
173 
174 size_t Read16::serialise(uintptr_t &addr)
175 {
176  addr = reinterpret_cast<uintptr_t>(&command);
177  return sizeof(command);
178 }
179 
180 Write10::Write10(uint32_t nLba, uint32_t nSectors)
181 {
182  ByteSet(&command, 0, sizeof(command));
183  command.nOpCode = 0x2A;
184  command.nLba = HOST_TO_BIG32(nLba);
185  command.nSectors = HOST_TO_BIG16(nSectors);
186 }
187 
188 size_t Write10::serialise(uintptr_t &addr)
189 {
190  addr = reinterpret_cast<uintptr_t>(&command);
191  return sizeof(command);
192 }
193 
194 Write12::Write12(uint32_t nLba, uint32_t nSectors)
195 {
196  ByteSet(&command, 0, sizeof(command));
197  command.nOpCode = 0xAA;
198  command.nLba = HOST_TO_BIG32(nLba);
199  command.nSectors = HOST_TO_BIG32(nSectors);
200 }
201 
202 size_t Write12::serialise(uintptr_t &addr)
203 {
204  addr = reinterpret_cast<uintptr_t>(&command);
205  return sizeof(command);
206 }
207 
208 Write16::Write16(uint32_t nLba, uint32_t nSectors)
209 {
210  ByteSet(&command, 0, sizeof(command));
211  command.nOpCode = 0x8A;
212  command.nLba = HOST_TO_BIG64(nLba);
213  command.nSectors = HOST_TO_BIG32(nSectors);
214 }
215 
216 size_t Write16::serialise(uintptr_t &addr)
217 {
218  addr = reinterpret_cast<uintptr_t>(&command);
219  return sizeof(command);
220 }
221 
222 Synchronise10::Synchronise10(uint32_t nLba, uint32_t nSectors)
223 {
224  ByteSet(&command, 0, sizeof(command));
225  command.nOpCode = 0x35;
226  command.nLba = HOST_TO_BIG32(nLba);
227  command.nBlocks = HOST_TO_BIG16(nSectors);
228 }
229 
230 size_t Synchronise10::serialise(uintptr_t &addr)
231 {
232  addr = reinterpret_cast<uintptr_t>(&command);
233  return sizeof(command);
234 }
235 
236 Synchronise16::Synchronise16(uint32_t nLba, uint32_t nSectors)
237 {
238  ByteSet(&command, 0, sizeof(command));
239  command.nOpCode = 0x91;
240  command.nLba = HOST_TO_BIG64(nLba);
241  command.nBlocks = HOST_TO_BIG32(nSectors);
242 }
243 
244 size_t Synchronise16::serialise(uintptr_t &addr)
245 {
246  addr = reinterpret_cast<uintptr_t>(&command);
247  return sizeof(command);
248 }
249 } // namespace ScsiCommands