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
27static void
28scsi_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
46static void
47scsi_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
69static void
70beautify_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
87status_t
88scsi_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
156static scsi_device_info *
157scsi_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
191err:
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
203static status_t
204scsi_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
253err:
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
261static status_t
262scsi_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
347err:
348	scsi_free_device(device);
349	return res;
350}
351
352
353static void
354scsi_uninit_device(scsi_device_info *device)
355{
356	SHOW_FLOW0(3, "");
357
358	scsi_free_device(device);
359}
360
361
362static void
363scsi_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
380status_t
381scsi_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
433void
434scsi_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
452static uchar
453scsi_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
465static status_t
466scsi_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
477static status_t
478std_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
498scsi_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