1 /*
2 * Copyright 2009, Michael Lotz, mmlr@mlotz.ch.
3 * Copyright 2008, Marcus Overhagen.
4 * Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
5 * Copyright 2002-2003, Thomas Kurschel.
6 *
7 * Distributed under the terms of the MIT License.
8 */
9
10 #include "ATAPrivate.h"
11
12
13 scsi_for_sim_interface *gSCSIModule = NULL;
14 device_manager_info *gDeviceManager = NULL;
15
16
17 static status_t
ata_sim_init_bus(device_node * node,void ** cookie)18 ata_sim_init_bus(device_node *node, void **cookie)
19 {
20 ATAChannel *channel = new(std::nothrow) ATAChannel(node);
21 if (channel == NULL)
22 return B_NO_MEMORY;
23
24 status_t result = channel->InitCheck();
25 if (result != B_OK) {
26 TRACE_ERROR("failed to set up ata channel object\n");
27 delete channel;
28 return result;
29 }
30
31 *cookie = channel;
32 return B_OK;
33 }
34
35
36 static void
ata_sim_uninit_bus(void * cookie)37 ata_sim_uninit_bus(void *cookie)
38 {
39 ATAChannel *channel = (ATAChannel *)cookie;
40 delete channel;
41 }
42
43
44 static void
ata_sim_bus_removed(void * cookie)45 ata_sim_bus_removed(void *cookie)
46 {
47 ATAChannel *channel = (ATAChannel *)cookie;
48 if (channel->Bus() != NULL) {
49 gSCSIModule->block_bus(channel->Bus());
50 channel->SetBus(NULL);
51 }
52 }
53
54
55 static void
ata_sim_set_scsi_bus(scsi_sim_cookie cookie,scsi_bus bus)56 ata_sim_set_scsi_bus(scsi_sim_cookie cookie, scsi_bus bus)
57 {
58 ATAChannel *channel = (ATAChannel *)cookie;
59 channel->SetBus(bus);
60 channel->ScanBus();
61 }
62
63
64 static void
ata_sim_scsi_io(scsi_sim_cookie cookie,scsi_ccb * ccb)65 ata_sim_scsi_io(scsi_sim_cookie cookie, scsi_ccb *ccb)
66 {
67 ATAChannel *channel = (ATAChannel *)cookie;
68 if (channel->Bus() == NULL) {
69 ccb->subsys_status = SCSI_NO_HBA;
70 gSCSIModule->finished(ccb, 1);
71 return;
72 }
73
74 if (channel->ExecuteIO(ccb) == B_BUSY)
75 gSCSIModule->requeue(ccb, true);
76 }
77
78
79 static uchar
ata_sim_abort(scsi_sim_cookie cookie,scsi_ccb * ccb)80 ata_sim_abort(scsi_sim_cookie cookie, scsi_ccb *ccb)
81 {
82 ATAChannel *channel = (ATAChannel *)cookie;
83 if (channel->Bus() == NULL)
84 return SCSI_NO_HBA;
85
86 // aborting individual commands is not possible
87 return SCSI_REQ_CMP;
88 }
89
90
91 static uchar
ata_sim_reset_device(scsi_sim_cookie cookie,uchar targetId,uchar targetLun)92 ata_sim_reset_device(scsi_sim_cookie cookie, uchar targetId, uchar targetLun)
93 {
94 ATAChannel *channel = (ATAChannel *)cookie;
95 if (channel->Bus() == NULL)
96 return SCSI_NO_HBA;
97
98 // TODO: implement
99 return SCSI_REQ_INVALID;
100 }
101
102
103 static uchar
ata_sim_term_io(scsi_sim_cookie cookie,scsi_ccb * ccb)104 ata_sim_term_io(scsi_sim_cookie cookie, scsi_ccb *ccb)
105 {
106 ATAChannel *channel = (ATAChannel *)cookie;
107 if (channel->Bus() == NULL)
108 return SCSI_NO_HBA;
109
110 // we don't terminate commands, ignore
111 return SCSI_REQ_CMP;
112 }
113
114
115 static uchar
ata_sim_path_inquiry(scsi_sim_cookie cookie,scsi_path_inquiry * info)116 ata_sim_path_inquiry(scsi_sim_cookie cookie, scsi_path_inquiry *info)
117 {
118 ATAChannel *channel = (ATAChannel *)cookie;
119 if (channel->Bus() == NULL)
120 return SCSI_NO_HBA;
121
122 channel->PathInquiry(info);
123 return SCSI_REQ_CMP;
124 }
125
126
127 static uchar
ata_sim_rescan_bus(scsi_sim_cookie cookie)128 ata_sim_rescan_bus(scsi_sim_cookie cookie)
129 {
130 // TODO: implement
131 return SCSI_REQ_CMP;
132 }
133
134
135 static uchar
ata_sim_reset_bus(scsi_sim_cookie cookie)136 ata_sim_reset_bus(scsi_sim_cookie cookie)
137 {
138 ATAChannel *channel = (ATAChannel *)cookie;
139 if (channel->Bus() == NULL)
140 return SCSI_NO_HBA;
141
142 //channel->Reset();
143 panic("asking for trouble");
144 return SCSI_REQ_CMP;
145 }
146
147
148 static void
ata_sim_get_restrictions(scsi_sim_cookie cookie,uchar targetID,bool * isATAPI,bool * noAutoSense,uint32 * maxBlocks)149 ata_sim_get_restrictions(scsi_sim_cookie cookie, uchar targetID,
150 bool *isATAPI, bool *noAutoSense, uint32 *maxBlocks)
151 {
152 ATAChannel *channel = (ATAChannel *)cookie;
153 channel->GetRestrictions(targetID, isATAPI, noAutoSense, maxBlocks);
154 }
155
156
157 static status_t
ata_sim_control(scsi_sim_cookie cookie,uchar targetID,uint32 op,void * buffer,size_t length)158 ata_sim_control(scsi_sim_cookie cookie, uchar targetID, uint32 op, void *buffer,
159 size_t length)
160 {
161 ATAChannel *channel = (ATAChannel *)cookie;
162 return channel->Control(targetID, op, buffer, length);
163 }
164
165
166 status_t
ata_channel_added(device_node * parent)167 ata_channel_added(device_node *parent)
168 {
169 const char *controllerName;
170 if (gDeviceManager->get_attr_string(parent,
171 ATA_CONTROLLER_CONTROLLER_NAME_ITEM, &controllerName, true) != B_OK) {
172 TRACE_ERROR("controller name missing\n");
173 return B_ERROR;
174 }
175
176 int32 channelID = gDeviceManager->create_id(ATA_CHANNEL_ID_GENERATOR);
177 if (channelID < 0) {
178 TRACE_ERROR("out of channel ids\n");
179 return B_ERROR;
180 }
181
182 device_attr attributes[] = {
183 {
184 B_DEVICE_FIXED_CHILD, B_STRING_TYPE,
185 { .string = SCSI_FOR_SIM_MODULE_NAME }
186 },
187
188 {
189 SCSI_DESCRIPTION_CONTROLLER_NAME, B_STRING_TYPE,
190 { .string = controllerName }
191 },
192
193 // maximum number of blocks per transmission:
194 // - ATAPI uses packets, i.e. normal SCSI limits apply
195 // but I'm not sure about controller restrictions
196 // - ATA allows up to 256 blocks for LBA28 and 65535 for LBA48
197 // to fix specific drive bugs use ATAChannel::GetRestrictions()
198 { B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { .ui32 = 0xffff } },
199 { ATA_CHANNEL_ID_ITEM, B_UINT32_TYPE, { .ui32 = (uint32)channelID } },
200 { NULL }
201 };
202
203 return gDeviceManager->register_node(parent, ATA_SIM_MODULE_NAME,
204 attributes, NULL, NULL);
205 }
206
207
208 status_t
ata_interrupt_handler(void * cookie,uint8 status)209 ata_interrupt_handler(void *cookie, uint8 status)
210 {
211 ATAChannel *channel = (ATAChannel *)cookie;
212 return channel->Interrupt(status);
213 }
214
215
216 static status_t
std_ops(int32 op,...)217 std_ops(int32 op, ...)
218 {
219 switch (op) {
220 case B_MODULE_INIT:
221 case B_MODULE_UNINIT:
222 return B_OK;
223
224 default:
225 break;
226 }
227
228 return B_ERROR;
229 }
230
231
232 scsi_sim_interface ata_sim_module = {
233 {
234 {
235 ATA_SIM_MODULE_NAME,
236 0,
237 std_ops
238 },
239
240 NULL, // supported devices
241 NULL, // register node
242 ata_sim_init_bus,
243 ata_sim_uninit_bus,
244 NULL, // register child devices
245 NULL, // rescan
246 ata_sim_bus_removed,
247 NULL, // suspend
248 NULL, // resume
249 },
250
251 ata_sim_set_scsi_bus,
252 ata_sim_scsi_io,
253 ata_sim_abort,
254 ata_sim_reset_device,
255 ata_sim_term_io,
256 ata_sim_path_inquiry,
257 ata_sim_rescan_bus,
258 ata_sim_reset_bus,
259 ata_sim_get_restrictions,
260 ata_sim_control
261 };
262
263 ata_for_controller_interface ata_for_controller_module = {
264 {
265 {
266 ATA_FOR_CONTROLLER_MODULE_NAME,
267 0,
268 &std_ops
269 },
270
271 NULL, // supported devices
272 ata_channel_added,
273 NULL,
274 NULL,
275 NULL
276 },
277
278 ata_interrupt_handler
279 };
280
281
282 module_dependency module_dependencies[] = {
283 { SCSI_FOR_SIM_MODULE_NAME, (module_info **)&gSCSIModule },
284 { B_DEVICE_MANAGER_MODULE_NAME, (module_info **)&gDeviceManager },
285 {}
286 };
287
288 module_info *modules[] = {
289 (module_info *)&ata_for_controller_module,
290 (module_info *)&ata_sim_module,
291 NULL
292 };
293