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