xref: /haiku/src/add-ons/kernel/bus_managers/scsi/devices.cpp (revision 52c4471a3024d2eb81fe88e2c3982b9f8daa5e56)
1 /*
2  * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
3  * Copyright 2002/03, Thomas Kurschel. All rights reserved.
4  *
5  * Distributed under the terms of the MIT License.
6  */
7 
8 /*
9 	Device node layer.
10 
11 	When a SCSI bus is registered, this layer scans for SCSI devices
12 	and registers a node for each of them. Peripheral drivers are on
13 	top of these nodes.
14 */
15 
16 #include "scsi_internal.h"
17 
18 #include <string.h>
19 #include <stdlib.h>
20 #include <stdio.h>
21 
22 #include <algorithm>
23 
24 
25 /** free autosense request of device */
26 
27 static void
28 scsi_free_autosense_request(scsi_device_info *device)
29 {
30 	SHOW_FLOW0( 3, "" );
31 
32 	if (device->auto_sense_request != NULL) {
33 		scsi_free_ccb(device->auto_sense_request);
34 		device->auto_sense_request = NULL;
35 	}
36 
37 	if (device->auto_sense_area > 0) {
38 		delete_area(device->auto_sense_area);
39 		device->auto_sense_area = 0;
40 	}
41 }
42 
43 
44 /** free all data of device */
45 
46 static void
47 scsi_free_device(scsi_device_info *device)
48 {
49 	SHOW_FLOW0( 3, "" );
50 
51 	scsi_free_emulation_buffer(device);
52 	scsi_free_autosense_request(device);
53 
54 	unregister_kernel_daemon(scsi_dma_buffer_daemon, device);
55 
56 	scsi_dma_buffer_free(&device->dma_buffer);
57 
58 	mutex_destroy(&device->dma_buffer_lock);
59 	delete_sem(device->dma_buffer_owner);
60 
61 	free(device);
62 }
63 
64 
65 /**	copy string src without trailing zero to dst and remove trailing
66  *	spaces size of dst is dst_size, size of src is dst_size-1
67  */
68 
69 static void
70 beautify_string(char *dst, char *src, int dst_size)
71 {
72 	int i;
73 
74 	memcpy(dst, src, dst_size - 1);
75 
76 	for (i = dst_size - 2; i >= 0; --i) {
77 		if (dst[i] != ' ')
78 			break;
79 	}
80 
81 	dst[i + 1] = 0;
82 }
83 
84 
85 /** register new device */
86 
87 status_t
88 scsi_register_device(scsi_bus_info *bus, uchar target_id,
89 	uchar target_lun, scsi_res_inquiry *inquiry_data)
90 {
91 	bool is_atapi, manual_autosense;
92 	uint32 orig_max_blocks, max_blocks;
93 
94 	SHOW_FLOW0( 3, "" );
95 
96 	// ask for restrictions
97 	bus->interface->get_restrictions(bus->sim_cookie,
98 		target_id, &is_atapi, &manual_autosense, &max_blocks);
99 	if (target_lun != 0)
100 		dprintf("WARNING: SCSI target %d lun %d getting restrictions without lun\n",
101 			target_id, target_lun);
102 
103 	// find maximum transfer blocks
104 	// set default value to max (need something like ULONG_MAX here)
105 	orig_max_blocks = ~0;
106 	pnp->get_attr_uint32(bus->node, B_DMA_MAX_TRANSFER_BLOCKS, &orig_max_blocks,
107 		true);
108 
109 	max_blocks = std::min(max_blocks, orig_max_blocks);
110 
111 	{
112 		char vendor_ident[sizeof( inquiry_data->vendor_ident ) + 1];
113 		char product_ident[sizeof( inquiry_data->product_ident ) + 1];
114 		char product_rev[sizeof( inquiry_data->product_rev ) + 1];
115 		device_attr attrs[] = {
116 			// connection
117 			{ SCSI_DEVICE_TARGET_ID_ITEM, B_UINT8_TYPE, { .ui8 = target_id }},
118 			{ SCSI_DEVICE_TARGET_LUN_ITEM, B_UINT8_TYPE, { .ui8 = target_lun }},
119 
120 			// inquiry data (used for both identification and information)
121 			{ SCSI_DEVICE_INQUIRY_ITEM, B_RAW_TYPE,
122 				{ .raw = { inquiry_data, sizeof( *inquiry_data ) }}},
123 
124 			// some more info for driver loading
125 			{ SCSI_DEVICE_TYPE_ITEM, B_UINT8_TYPE, { .ui8 = inquiry_data->device_type }},
126 			{ SCSI_DEVICE_VENDOR_ITEM, B_STRING_TYPE, { .string = vendor_ident }},
127 			{ SCSI_DEVICE_PRODUCT_ITEM, B_STRING_TYPE, { .string = product_ident }},
128 			{ SCSI_DEVICE_REVISION_ITEM, B_STRING_TYPE, { .string = product_rev }},
129 
130 			// description of peripheral drivers
131 			{ B_DEVICE_BUS, B_STRING_TYPE, { .string = "scsi" }},
132 
133 			// extra restriction of maximum number of blocks per transfer
134 			{ B_DMA_MAX_TRANSFER_BLOCKS, B_UINT32_TYPE, { .ui32 = max_blocks }},
135 
136 			// atapi emulation
137 			{ SCSI_DEVICE_IS_ATAPI_ITEM, B_UINT8_TYPE, { .ui8 = is_atapi }},
138 			// manual autosense
139 			{ SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM, B_UINT8_TYPE, { .ui8 = manual_autosense }},
140 			{ NULL }
141 		};
142 
143 		beautify_string(vendor_ident, inquiry_data->vendor_ident, sizeof(vendor_ident));
144 		beautify_string(product_ident, inquiry_data->product_ident, sizeof(product_ident));
145 		beautify_string(product_rev, inquiry_data->product_rev, sizeof(product_rev));
146 
147 		return pnp->register_node(bus->node, SCSI_DEVICE_MODULE_NAME, attrs,
148 			NULL, NULL);
149 	}
150 
151 	return B_OK;
152 }
153 
154 
155 // create data structure for a device
156 static scsi_device_info *
157 scsi_create_device(device_node *node, scsi_bus_info *bus,
158 	int target_id, int target_lun)
159 {
160 	scsi_device_info *device;
161 
162 	SHOW_FLOW0( 3, "" );
163 
164 	device = (scsi_device_info *)malloc(sizeof(*device));
165 	if (device == NULL)
166 		return NULL;
167 
168 	memset(device, 0, sizeof(*device));
169 
170 	device->lock_count = device->blocked[0] = device->blocked[1] = 0;
171 	device->sim_overflow = 0;
172 	device->queued_reqs = NULL;
173 	device->bus = bus;
174 	device->target_id = target_id;
175 	device->target_lun = target_lun;
176 	device->valid = true;
177 	device->node = node;
178 
179 	scsi_dma_buffer_init(&device->dma_buffer);
180 
181 	mutex_init(&device->dma_buffer_lock, "dma_buffer");
182 
183 	device->dma_buffer_owner = create_sem(1, "dma_buffer");
184 	if (device->dma_buffer_owner < 0)
185 		goto err;
186 
187 	register_kernel_daemon(scsi_dma_buffer_daemon, device, 5 * 10);
188 
189 	return device;
190 
191 err:
192 	mutex_destroy(&device->dma_buffer_lock);
193 	free(device);
194 	return NULL;
195 }
196 
197 
198 /**	prepare autosense request.
199  *	this cannot be done on demand but during init as we may
200  *	have run out of ccbs when we need it
201  */
202 
203 static status_t
204 scsi_create_autosense_request(scsi_device_info *device)
205 {
206 	scsi_ccb *request;
207 	unsigned char *buffer;
208 	scsi_cmd_request_sense *cmd;
209 	size_t total_size;
210 
211 	SHOW_FLOW0( 3, "" );
212 
213 	device->auto_sense_request = request = scsi_alloc_ccb(device);
214 	if (device->auto_sense_request == NULL)
215 		return B_NO_MEMORY;
216 
217 	total_size = SCSI_MAX_SENSE_SIZE + sizeof(physical_entry);
218 	total_size = (total_size + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
219 
220 	// allocate buffer for space sense data and S/G list
221 	device->auto_sense_area = create_area("auto_sense", (void**)&buffer,
222 		B_ANY_KERNEL_ADDRESS, B_PAGE_SIZE, B_32_BIT_FULL_LOCK,
223 		B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
224 		// TODO: Use B_FULL_LOCK, if addresses >= 4 GB are supported!
225 	if (device->auto_sense_area < 0)
226 		goto err;
227 
228 	request->data = buffer;
229 	request->data_length = SCSI_MAX_SENSE_SIZE;
230 	request->sg_list = (physical_entry *)(buffer + SCSI_MAX_SENSE_SIZE);
231 	request->sg_count = 1;
232 
233 	get_memory_map(buffer, SCSI_MAX_SENSE_SIZE,
234 		(physical_entry *)request->sg_list, 1);
235 
236 	// disable auto-autosense, just in case;
237 	// make sure no other request overtakes sense request;
238 	// buffer is/must be DMA safe as we cannot risk trouble with
239 	// dynamically allocated DMA buffer
240 	request->flags = SCSI_DIR_IN | SCSI_DIS_AUTOSENSE |
241 		SCSI_ORDERED_QTAG | SCSI_DMA_SAFE;
242 
243 	cmd = (scsi_cmd_request_sense *)request->cdb;
244 	request->cdb_length = sizeof(*cmd);
245 
246 	memset(cmd, 0, sizeof(*cmd));
247 	cmd->opcode = SCSI_OP_REQUEST_SENSE;
248 	cmd->lun = device->target_lun;
249 	cmd->allocation_length = SCSI_MAX_SENSE_SIZE;
250 
251 	return B_OK;
252 
253 err:
254 	scsi_free_ccb(request);
255 	return B_NO_MEMORY;
256 }
257 
258 
259 #define SET_BIT(field, bit) field[(bit) >> 3] |= 1 << ((bit) & 7)
260 
261 static status_t
262 scsi_init_device(device_node *node, void **cookie)
263 {
264 	const scsi_res_inquiry *inquiry_data = NULL;
265 	uint8 target_id, target_lun, path_id;
266 	scsi_bus_info *bus;
267 	scsi_device_info *device;
268 	status_t res;
269 	size_t inquiry_data_len;
270 	uint8 is_atapi, manual_autosense;
271 
272 	SHOW_FLOW0(3, "");
273 
274 	if (pnp->get_attr_uint8( node, SCSI_DEVICE_TARGET_ID_ITEM, &target_id, false) != B_OK
275 		|| pnp->get_attr_uint8( node, SCSI_DEVICE_TARGET_LUN_ITEM, &target_lun, false) != B_OK
276 		|| pnp->get_attr_uint8( node, SCSI_DEVICE_IS_ATAPI_ITEM, &is_atapi, false) != B_OK
277 		|| pnp->get_attr_uint8( node, SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM, &manual_autosense, false) != B_OK
278 		|| pnp->get_attr_raw( node, SCSI_DEVICE_INQUIRY_ITEM,
279 				(const void **)&inquiry_data, &inquiry_data_len, false) != B_OK
280 		|| inquiry_data_len != sizeof(*inquiry_data)) {
281 		return B_ERROR;
282 	}
283 
284 	{
285 		device_node *parent = pnp->get_parent_node(node);
286 		pnp->get_driver(parent, NULL, (void **)&bus);
287 		pnp->put_node(parent);
288 	}
289 
290 	device = scsi_create_device(node, bus, target_id, target_lun);
291 	if (device == NULL)
292 		return B_NO_MEMORY;
293 
294 	// never mind if there is no path - it might be an emulated controller
295 	path_id = (uint8)-1;
296 
297 	pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &path_id, true);
298 
299 	device->inquiry_data = *inquiry_data;
300 
301 	// save restrictions
302 	device->is_atapi = is_atapi;
303 	device->manual_autosense = manual_autosense;
304 
305 	// size of device queue must be detected by trial and error, so
306 	// we start with a really high number and see when the device chokes
307 	device->total_slots = 4096;
308 
309 	// disable queuing if bus doesn't support it
310 	if ((bus->inquiry_data.hba_inquiry & SCSI_PI_TAG_ABLE) == 0)
311 		device->total_slots = 1;
312 
313 	// if there is no autosense, disable queuing to make sure autosense is
314 	// not overtaken by other requests
315 	if (device->manual_autosense)
316 		device->total_slots = 1;
317 
318 	device->left_slots = device->total_slots;
319 
320 	// get autosense request if required
321 	if (device->manual_autosense) {
322 		if (scsi_create_autosense_request(device) != B_OK) {
323 			res = B_NO_MEMORY;
324 			goto err;
325 		}
326 	}
327 
328 	// if this is an ATAPI device, we need an emulation buffer
329 	if (scsi_init_emulation_buffer(device, SCSI_ATAPI_BUFFER_SIZE) != B_OK) {
330 		res = B_NO_MEMORY;
331 		goto err;
332 	}
333 
334 	memset(device->emulation_map, 0, sizeof(device->emulation_map));
335 
336 	if (device->is_atapi) {
337 		SET_BIT(device->emulation_map, SCSI_OP_READ_6);
338 		SET_BIT(device->emulation_map, SCSI_OP_WRITE_6);
339 		SET_BIT(device->emulation_map, SCSI_OP_MODE_SENSE_6);
340 		SET_BIT(device->emulation_map, SCSI_OP_MODE_SELECT_6);
341 		SET_BIT(device->emulation_map, SCSI_OP_INQUIRY);
342 	}
343 
344 	*cookie = device;
345 	return B_OK;
346 
347 err:
348 	scsi_free_device(device);
349 	return res;
350 }
351 
352 
353 static void
354 scsi_uninit_device(scsi_device_info *device)
355 {
356 	SHOW_FLOW0(3, "");
357 
358 	scsi_free_device(device);
359 }
360 
361 
362 static void
363 scsi_device_removed(scsi_device_info *device)
364 {
365 	SHOW_FLOW0(3, "");
366 
367 	if (device == NULL)
368 		return;
369 
370 	// this must be atomic as no lock is used
371 	device->valid = false;
372 }
373 
374 
375 /**	get device info; create a temporary one if it's not registered
376  *	(used during detection)
377  *	on success, scan_lun_lock of bus is hold
378  */
379 
380 status_t
381 scsi_force_get_device(scsi_bus_info *bus, uchar target_id,
382 	uchar target_lun, scsi_device_info **res_device)
383 {
384 	device_attr attrs[] = {
385 		{ SCSI_DEVICE_TARGET_ID_ITEM, B_UINT8_TYPE, { .ui8 = target_id }},
386 		{ SCSI_DEVICE_TARGET_LUN_ITEM, B_UINT8_TYPE, { .ui8 = target_lun }},
387 		{ NULL }
388 	};
389 	device_node *node;
390 	status_t res;
391 	driver_module_info *driver_interface;
392 	scsi_device device;
393 
394 	SHOW_FLOW0(3, "");
395 
396 	// very important: only one can use a forced device to avoid double detection
397 	acquire_sem(bus->scan_lun_lock);
398 
399 	// check whether device registered already
400 	node = NULL;
401 	pnp->get_next_child_node(bus->node, attrs, &node);
402 
403 	SHOW_FLOW(3, "%p", node);
404 
405 	if (node != NULL) {
406 		// TODO: have a second look a this one!
407 		// there is one - get it
408 		res = pnp->get_driver(node, &driver_interface, (void **)&device);
409 		if (res != B_OK)
410 			pnp->put_node(node);
411 	} else {
412 		// device doesn't exist yet - create a temporary one
413 		device = scsi_create_device(NULL, bus, target_id, target_lun);
414 		if (device == NULL)
415 			res = B_NO_MEMORY;
416 		else
417 			res = B_OK;
418 	}
419 
420 	*res_device = device;
421 
422 	if (res != B_OK)
423 		release_sem(bus->scan_lun_lock);
424 
425 	return res;
426 }
427 
428 
429 /**	cleanup device received from scsi_force_get_device
430  *	on return, scan_lun_lock of bus is released
431  */
432 
433 void
434 scsi_put_forced_device(scsi_device_info *device)
435 {
436 	scsi_bus_info *bus = device->bus;
437 
438 	SHOW_FLOW0(3, "");
439 
440 	if (device->node != NULL) {
441 		// device is registered
442 		pnp->put_node(device->node);
443 	} else {
444 		// device is temporary
445 		scsi_free_device(device);
446 	}
447 
448 	release_sem(bus->scan_lun_lock);
449 }
450 
451 
452 static uchar
453 scsi_reset_device(scsi_device_info *device)
454 {
455 	SHOW_FLOW0(3, "");
456 
457 	if (device->node == NULL)
458 		return SCSI_DEV_NOT_THERE;
459 
460 	return device->bus->interface->reset_device(device->bus->sim_cookie,
461 		device->target_id, device->target_lun);
462 }
463 
464 
465 static status_t
466 scsi_ioctl(scsi_device_info *device, uint32 op, void *buffer, size_t length)
467 {
468 	if (device->bus->interface->ioctl != NULL) {
469 		return device->bus->interface->ioctl(device->bus->sim_cookie,
470 			device->target_id, op, buffer, length);
471 	}
472 
473 	return B_DEV_INVALID_IOCTL;
474 }
475 
476 
477 static status_t
478 std_ops(int32 op, ...)
479 {
480 	switch (op) {
481 		case B_MODULE_INIT:
482 		{
483 			// Link to SCSI bus.
484 			// SCSI device driver must have SCSI bus loaded, but it calls its functions
485 			// directly instead via official interface, so this pointer is never read.
486 			module_info *dummy;
487 			return get_module(SCSI_BUS_MODULE_NAME, &dummy);
488 		}
489 		case B_MODULE_UNINIT:
490 			return put_module(SCSI_BUS_MODULE_NAME);
491 
492 		default:
493 			return B_ERROR;
494 	}
495 }
496 
497 
498 scsi_device_interface scsi_device_module = {
499 	{
500 		{
501 			SCSI_DEVICE_MODULE_NAME,
502 			0,
503 			std_ops
504 		},
505 
506 		NULL,	// supported devices
507 		NULL,	// register node
508 		scsi_init_device,
509 		(void (*)(void *)) scsi_uninit_device,
510 		NULL,	// register child devices
511 		NULL,	// rescan
512 		(void (*)(void *)) scsi_device_removed
513 	},
514 
515 	scsi_alloc_ccb,
516 	scsi_free_ccb,
517 
518 	scsi_async_io,
519 	scsi_sync_io,
520 	scsi_abort,
521 	scsi_reset_device,
522 	scsi_term_io,
523 	scsi_ioctl,
524 };
525