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
scsi_free_autosense_request(scsi_device_info * device)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
scsi_free_device(scsi_device_info * device)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
beautify_string(char * dst,char * src,int dst_size)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
scsi_register_device(scsi_bus_info * bus,uchar target_id,uchar target_lun,scsi_res_inquiry * inquiry_data)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 *
scsi_create_device(device_node * node,scsi_bus_info * bus,int target_id,int target_lun)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
scsi_create_autosense_request(scsi_device_info * device)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
scsi_init_device(device_node * node,void ** cookie)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
scsi_uninit_device(scsi_device_info * device)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
scsi_device_removed(scsi_device_info * device)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
scsi_force_get_device(scsi_bus_info * bus,uchar target_id,uchar target_lun,scsi_device_info ** res_device)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
scsi_put_forced_device(scsi_device_info * device)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
scsi_reset_device(scsi_device_info * device)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
scsi_ioctl(scsi_device_info * device,uint32 op,void * buffer,size_t length)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
std_ops(int32 op,...)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