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
23ScsiCommand::ScsiCommand() = default;
24ScsiCommand::~ScsiCommand() = default;
25
26namespace ScsiCommands {
27Inquiry::Inquiry(uint16_t len, bool enableVitalData, uint8_t pageCode, uint8_t ctl) {
28 ByteSet(&command, 0, sizeof(command));
29 command.opcode = 0x12;
30 command.epvd = enableVitalData;
31 if (enableVitalData)
32 command.pageCode = pageCode;
33 command.len = HOST_TO_BIG16(len);
34 command.control = ctl;
35}
36
37size_t Inquiry::serialise(uintptr_t& addr) {
38 addr = reinterpret_cast<uintptr_t>(&command);
39 return sizeof(command);
40}
41
42UnitReady::UnitReady(uint8_t ctl) {
43 ByteSet(&command, 0, sizeof(command));
44 command.opcode = 0;
45 command.control = ctl;
46}
47
48size_t UnitReady::serialise(uintptr_t& addr) {
49 addr = reinterpret_cast<uintptr_t>(&command);
50 return sizeof(command);
51}
52
53ReadSense::ReadSense(uint8_t desc, uint8_t len, uint8_t ctl) {
54 ByteSet(&command, 0, sizeof(command));
55 command.opcode = 0x03;
56 command.desc = desc;
57 command.len = len;
58 command.control = ctl;
59}
60
61size_t ReadSense::serialise(uintptr_t& addr) {
62 addr = reinterpret_cast<uintptr_t>(&command);
63 return sizeof(command);
64}
65
66StartStop::StartStop(bool imm, uint8_t newpower, bool eject_load, bool start, uint8_t ctl) {
67 ByteSet(&command, 0, sizeof(command));
68 command.opcode = 0x1b;
69 command.imm = imm ? 1 : 0;
70 command.setup = (start ? 1 : 0) | ((eject_load ? 1 : 0) << 1) | (newpower << 4);
71 command.control = ctl;
72}
73
74size_t StartStop::serialise(uintptr_t& addr) {
75 addr = reinterpret_cast<uintptr_t>(&command);
76 return sizeof(command);
77}
78
79SendDiagnostic::SendDiagnostic(bool selfTest, uint8_t selfTestCode, uintptr_t params,
80 size_t paramLen, bool deviceOffline, bool unitOffline, uint8_t ctl) {
81 ByteSet(&command, 0, sizeof(command));
82 command.opcode = 0x1d;
83 command.unitOffline = unitOffline;
84 command.devOffline = deviceOffline;
85 command.selfTest = selfTest;
86 command.pf = 0;
87 command.selfTestCode = selfTestCode;
88 command.paramListLen = HOST_TO_BIG16(paramLen);
89 command.control = ctl;
90}
91
92size_t SendDiagnostic::serialise(uintptr_t& addr) {
93 addr = reinterpret_cast<uintptr_t>(&command);
94 return sizeof(command);
95}
96
97ReadTocCommand::ReadTocCommand(uint16_t nativeBlockSize, uint8_t ctl) {
98 ByteSet(&command, 0, sizeof(command));
99 command.opcode = 0x43;
100 command.len = HOST_TO_BIG16(nativeBlockSize);
101}
102
103size_t ReadTocCommand::serialise(uintptr_t& addr) {
104 addr = reinterpret_cast<uintptr_t>(&command);
105 return sizeof(command);
106}
107
108ReadCapacity10::ReadCapacity10(uint8_t ctl) {
109 ByteSet(&command, 0, sizeof(command));
110 command.opcode = 0x25;
111 command.control = ctl;
112}
113
114size_t ReadCapacity10::serialise(uintptr_t& addr) {
115 addr = reinterpret_cast<uintptr_t>(&command);
116 return sizeof(command);
117}
118
119Read10::Read10(uint32_t nLba, uint32_t nSectors) {
120 ByteSet(&command, 0, sizeof(command));
121 command.nOpCode = 0x28;
122 command.nLba = HOST_TO_BIG32(nLba);
123 command.nSectors = HOST_TO_BIG16(nSectors);
124}
125
126size_t Read10::serialise(uintptr_t& addr) {
127 addr = reinterpret_cast<uintptr_t>(&command);
128 return sizeof(command);
129}
130
131Read12::Read12(uint32_t nLba, uint32_t nSectors) {
132 ByteSet(&command, 0, sizeof(command));
133 command.nOpCode = 0xa8;
134 command.nLba = HOST_TO_BIG32(nLba);
135 command.nSectors = HOST_TO_BIG32(nSectors);
136}
137
138size_t Read12::serialise(uintptr_t& addr) {
139 addr = reinterpret_cast<uintptr_t>(&command);
140 return sizeof(command);
141}
142
143Read16::Read16(uint64_t nLba, uint32_t nSectors) {
144 ByteSet(&command, 0, sizeof(command));
145 command.nOpCode = 0x88;
146 command.nLba = HOST_TO_BIG64(nLba);
147 command.nSectors = HOST_TO_BIG32(nSectors);
148}
149
150size_t Read16::serialise(uintptr_t& addr) {
151 addr = reinterpret_cast<uintptr_t>(&command);
152 return sizeof(command);
153}
154
155Write10::Write10(uint32_t nLba, uint32_t nSectors) {
156 ByteSet(&command, 0, sizeof(command));
157 command.nOpCode = 0x2A;
158 command.nLba = HOST_TO_BIG32(nLba);
159 command.nSectors = HOST_TO_BIG16(nSectors);
160}
161
162size_t Write10::serialise(uintptr_t& addr) {
163 addr = reinterpret_cast<uintptr_t>(&command);
164 return sizeof(command);
165}
166
167Write12::Write12(uint32_t nLba, uint32_t nSectors) {
168 ByteSet(&command, 0, sizeof(command));
169 command.nOpCode = 0xAA;
170 command.nLba = HOST_TO_BIG32(nLba);
171 command.nSectors = HOST_TO_BIG32(nSectors);
172}
173
174size_t Write12::serialise(uintptr_t& addr) {
175 addr = reinterpret_cast<uintptr_t>(&command);
176 return sizeof(command);
177}
178
179Write16::Write16(uint64_t nLba, uint32_t nSectors) {
180 ByteSet(&command, 0, sizeof(command));
181 command.nOpCode = 0x8A;
182 command.nLba = HOST_TO_BIG64(nLba);
183 command.nSectors = HOST_TO_BIG32(nSectors);
184}
185
186size_t Write16::serialise(uintptr_t& addr) {
187 addr = reinterpret_cast<uintptr_t>(&command);
188 return sizeof(command);
189}
190
191Synchronise10::Synchronise10(uint32_t nLba, uint32_t nSectors) {
192 ByteSet(&command, 0, sizeof(command));
193 command.nOpCode = 0x35;
194 command.nLba = HOST_TO_BIG32(nLba);
195 command.nBlocks = HOST_TO_BIG16(nSectors);
196}
197
198size_t Synchronise10::serialise(uintptr_t& addr) {
199 addr = reinterpret_cast<uintptr_t>(&command);
200 return sizeof(command);
201}
202
203Synchronise16::Synchronise16(uint64_t nLba, uint32_t nSectors) {
204 ByteSet(&command, 0, sizeof(command));
205 command.nOpCode = 0x91;
206 command.nLba = HOST_TO_BIG64(nLba);
207 command.nBlocks = HOST_TO_BIG32(nSectors);
208}
209
210size_t Synchronise16::serialise(uintptr_t& addr) {
211 addr = reinterpret_cast<uintptr_t>(&command);
212 return sizeof(command);
213}
214} // namespace ScsiCommands