2 * Copyright 2004-2006, Haiku, Inc. All RightsReserved.
3 * Copyright 2002/03, Thomas Kurschel. All rights reserved.
5 * Distributed under the terms of the MIT License.
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
16 #include "scsi_internal.h"
25 /** free autosense request of device */
28 scsi_free_autosense_request(scsi_device_info
*device
)
32 if (device
->auto_sense_request
!= NULL
) {
33 scsi_free_ccb(device
->auto_sense_request
);
34 device
->auto_sense_request
= NULL
;
37 if (device
->auto_sense_area
> 0) {
38 delete_area(device
->auto_sense_area
);
39 device
->auto_sense_area
= 0;
44 /** free all data of device */
47 scsi_free_device(scsi_device_info
*device
)
51 scsi_free_emulation_buffer(device
);
52 scsi_free_autosense_request(device
);
54 unregister_kernel_daemon(scsi_dma_buffer_daemon
, device
);
56 scsi_dma_buffer_free(&device
->dma_buffer
);
58 DELETE_BEN(&device
->dma_buffer_lock
);
59 delete_sem(device
->dma_buffer_owner
);
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
70 beautify_string(char *dst
, char *src
, int dst_size
)
74 memcpy(dst
, src
, dst_size
- 1);
76 for (i
= dst_size
- 2; i
>= 0; --i
) {
85 /** register new device */
88 scsi_register_device(scsi_bus_info
*bus
, uchar target_id
,
89 uchar target_lun
, scsi_res_inquiry
*inquiry_data
)
91 bool is_atapi
, manual_autosense
;
92 uint32 orig_max_blocks
, max_blocks
;
96 // ask for restrictions
97 bus
->interface
->get_restrictions(bus
->sim_cookie
,
98 target_id
, &is_atapi
, &manual_autosense
, &max_blocks
);
100 dprintf("WARNING: SCSI target %d lun %d getting restrictions without lun\n",
101 target_id
, target_lun
);
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
,
109 max_blocks
= std::min(max_blocks
, orig_max_blocks
);
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
[] = {
117 { SCSI_DEVICE_TARGET_ID_ITEM
, B_UINT8_TYPE
, { ui8
: target_id
}},
118 { SCSI_DEVICE_TARGET_LUN_ITEM
, B_UINT8_TYPE
, { ui8
: target_lun
}},
120 // inquiry data (used for both identification and information)
121 { SCSI_DEVICE_INQUIRY_ITEM
, B_RAW_TYPE
,
122 { raw
: { inquiry_data
, sizeof( *inquiry_data
) }}},
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
}},
130 // description of peripheral drivers
131 { B_DEVICE_BUS
, B_STRING_TYPE
, { string
: "scsi" }},
133 // extra restriction of maximum number of blocks per transfer
134 { B_DMA_MAX_TRANSFER_BLOCKS
, B_UINT32_TYPE
, { ui32
: max_blocks
}},
137 { SCSI_DEVICE_IS_ATAPI_ITEM
, B_UINT8_TYPE
, { ui8
: is_atapi
}},
139 { SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM
, B_UINT8_TYPE
, { ui8
: manual_autosense
}},
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
));
147 return pnp
->register_node(bus
->node
, SCSI_DEVICE_MODULE_NAME
, attrs
,
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
)
160 scsi_device_info
*device
;
164 device
= (scsi_device_info
*)malloc(sizeof(*device
));
168 memset(device
, 0, sizeof(*device
));
170 device
->lock_count
= device
->blocked
[0] = device
->blocked
[1] = 0;
171 device
->sim_overflow
= 0;
172 device
->queued_reqs
= NULL
;
174 device
->target_id
= target_id
;
175 device
->target_lun
= target_lun
;
176 device
->valid
= true;
179 scsi_dma_buffer_init(&device
->dma_buffer
);
181 if (INIT_BEN(&device
->dma_buffer_lock
, "dma_buffer") < 0)
184 device
->dma_buffer_owner
= create_sem(1, "dma_buffer");
185 if (device
->dma_buffer_owner
< 0)
188 register_kernel_daemon(scsi_dma_buffer_daemon
, device
, 5 * 10);
193 DELETE_BEN(&device
->dma_buffer_lock
);
200 /** prepare autosense request.
201 * this cannot be done on demand but during init as we may
202 * have run out of ccbs when we need it
206 scsi_create_autosense_request(scsi_device_info
*device
)
209 unsigned char *buffer
;
210 scsi_cmd_request_sense
*cmd
;
215 device
->auto_sense_request
= request
= scsi_alloc_ccb(device
);
216 if (device
->auto_sense_request
== NULL
)
219 total_size
= SCSI_MAX_SENSE_SIZE
+ sizeof(physical_entry
);
220 total_size
= (total_size
+ B_PAGE_SIZE
- 1) & ~(B_PAGE_SIZE
- 1);
222 // allocate buffer for space sense data and S/G list
223 device
->auto_sense_area
= create_area("auto_sense", (void**)&buffer
,
224 B_ANY_KERNEL_ADDRESS
, B_PAGE_SIZE
, B_32_BIT_FULL_LOCK
, 0);
225 // TODO: Use B_FULL_LOCK, if addresses >= 4 GB are supported!
226 if (device
->auto_sense_area
< 0)
229 request
->data
= buffer
;
230 request
->data_length
= SCSI_MAX_SENSE_SIZE
;
231 request
->sg_list
= (physical_entry
*)(buffer
+ SCSI_MAX_SENSE_SIZE
);
232 request
->sg_count
= 1;
234 get_memory_map(buffer
, SCSI_MAX_SENSE_SIZE
,
235 (physical_entry
*)request
->sg_list
, 1);
237 // disable auto-autosense, just in case;
238 // make sure no other request overtakes sense request;
239 // buffer is/must be DMA safe as we cannot risk trouble with
240 // dynamically allocated DMA buffer
241 request
->flags
= SCSI_DIR_IN
| SCSI_DIS_AUTOSENSE
|
242 SCSI_ORDERED_QTAG
| SCSI_DMA_SAFE
;
244 cmd
= (scsi_cmd_request_sense
*)request
->cdb
;
245 request
->cdb_length
= sizeof(*cmd
);
247 memset(cmd
, 0, sizeof(*cmd
));
248 cmd
->opcode
= SCSI_OP_REQUEST_SENSE
;
249 cmd
->lun
= device
->target_lun
;
250 cmd
->allocation_length
= SCSI_MAX_SENSE_SIZE
;
255 scsi_free_ccb(request
);
260 #define SET_BIT(field, bit) field[(bit) >> 3] |= 1 << ((bit) & 7)
263 scsi_init_device(device_node
*node
, void **cookie
)
265 const scsi_res_inquiry
*inquiry_data
= NULL
;
266 uint8 target_id
, target_lun
, path_id
;
268 scsi_device_info
*device
;
270 size_t inquiry_data_len
;
271 uint8 is_atapi
, manual_autosense
;
275 if (pnp
->get_attr_uint8( node
, SCSI_DEVICE_TARGET_ID_ITEM
, &target_id
, false) != B_OK
276 || pnp
->get_attr_uint8( node
, SCSI_DEVICE_TARGET_LUN_ITEM
, &target_lun
, false) != B_OK
277 || pnp
->get_attr_uint8( node
, SCSI_DEVICE_IS_ATAPI_ITEM
, &is_atapi
, false) != B_OK
278 || pnp
->get_attr_uint8( node
, SCSI_DEVICE_MANUAL_AUTOSENSE_ITEM
, &manual_autosense
, false) != B_OK
279 || pnp
->get_attr_raw( node
, SCSI_DEVICE_INQUIRY_ITEM
,
280 (const void **)&inquiry_data
, &inquiry_data_len
, false) != B_OK
281 || inquiry_data_len
!= sizeof(*inquiry_data
)) {
286 device_node
*parent
= pnp
->get_parent_node(node
);
287 pnp
->get_driver(parent
, NULL
, (void **)&bus
);
288 pnp
->put_node(parent
);
291 device
= scsi_create_device(node
, bus
, target_id
, target_lun
);
295 // never mind if there is no path - it might be an emulated controller
298 pnp
->get_attr_uint8(node
, SCSI_BUS_PATH_ID_ITEM
, &path_id
, true);
300 device
->inquiry_data
= *inquiry_data
;
303 device
->is_atapi
= is_atapi
;
304 device
->manual_autosense
= manual_autosense
;
306 // size of device queue must be detected by trial and error, so
307 // we start with a really high number and see when the device chokes
308 device
->total_slots
= 4096;
310 // disable queuing if bus doesn't support it
311 if ((bus
->inquiry_data
.hba_inquiry
& SCSI_PI_TAG_ABLE
) == 0)
312 device
->total_slots
= 1;
314 // if there is no autosense, disable queuing to make sure autosense is
315 // not overtaken by other requests
316 if (device
->manual_autosense
)
317 device
->total_slots
= 1;
319 device
->left_slots
= device
->total_slots
;
321 // get autosense request if required
322 if (device
->manual_autosense
) {
323 if (scsi_create_autosense_request(device
) != B_OK
) {
329 // if this is an ATAPI device, we need an emulation buffer
330 if (scsi_init_emulation_buffer(device
, SCSI_ATAPI_BUFFER_SIZE
) != B_OK
) {
335 memset(device
->emulation_map
, 0, sizeof(device
->emulation_map
));
337 if (device
->is_atapi
) {
338 SET_BIT(device
->emulation_map
, SCSI_OP_READ_6
);
339 SET_BIT(device
->emulation_map
, SCSI_OP_WRITE_6
);
340 SET_BIT(device
->emulation_map
, SCSI_OP_MODE_SENSE_6
);
341 SET_BIT(device
->emulation_map
, SCSI_OP_MODE_SELECT_6
);
342 SET_BIT(device
->emulation_map
, SCSI_OP_INQUIRY
);
349 scsi_free_device(device
);
355 scsi_uninit_device(scsi_device_info
*device
)
359 scsi_free_device(device
);
364 scsi_device_removed(scsi_device_info
*device
)
371 // this must be atomic as no lock is used
372 device
->valid
= false;
376 /** get device info; create a temporary one if it's not registered
377 * (used during detection)
378 * on success, scan_lun_lock of bus is hold
382 scsi_force_get_device(scsi_bus_info
*bus
, uchar target_id
,
383 uchar target_lun
, scsi_device_info
**res_device
)
385 device_attr attrs
[] = {
386 { SCSI_DEVICE_TARGET_ID_ITEM
, B_UINT8_TYPE
, { ui8
: target_id
}},
387 { SCSI_DEVICE_TARGET_LUN_ITEM
, B_UINT8_TYPE
, { ui8
: target_lun
}},
392 driver_module_info
*driver_interface
;
397 // very important: only one can use a forced device to avoid double detection
398 acquire_sem(bus
->scan_lun_lock
);
400 // check whether device registered already
402 pnp
->get_next_child_node(bus
->node
, attrs
, &node
);
404 SHOW_FLOW(3, "%p", node
);
407 // TODO: have a second look a this one!
408 // there is one - get it
409 res
= pnp
->get_driver(node
, &driver_interface
, (void **)&device
);
413 // device doesn't exist yet - create a temporary one
414 device
= scsi_create_device(NULL
, bus
, target_id
, target_lun
);
421 *res_device
= device
;
424 release_sem(bus
->scan_lun_lock
);
430 /** cleanup device received from scsi_force_get_device
431 * on return, scan_lun_lock of bus is released
435 scsi_put_forced_device(scsi_device_info
*device
)
437 scsi_bus_info
*bus
= device
->bus
;
441 if (device
->node
!= NULL
) {
442 // device is registered
443 pnp
->put_node(device
->node
);
445 // device is temporary
446 scsi_free_device(device
);
449 release_sem(bus
->scan_lun_lock
);
454 scsi_reset_device(scsi_device_info
*device
)
458 if (device
->node
== NULL
)
459 return SCSI_DEV_NOT_THERE
;
461 return device
->bus
->interface
->reset_device(device
->bus
->sim_cookie
,
462 device
->target_id
, device
->target_lun
);
467 scsi_ioctl(scsi_device_info
*device
, uint32 op
, void *buffer
, size_t length
)
469 if (device
->bus
->interface
->ioctl
!= NULL
) {
470 return device
->bus
->interface
->ioctl(device
->bus
->sim_cookie
,
471 device
->target_id
, op
, buffer
, length
);
474 return B_DEV_INVALID_IOCTL
;
479 std_ops(int32 op
, ...)
485 // SCSI device driver must have SCSI bus loaded, but it calls its functions
486 // directly instead via official interface, so this pointer is never read.
488 return get_module(SCSI_BUS_MODULE_NAME
, &dummy
);
490 case B_MODULE_UNINIT
:
491 return put_module(SCSI_BUS_MODULE_NAME
);
499 scsi_device_interface scsi_device_module
= {
502 SCSI_DEVICE_MODULE_NAME
,
507 NULL
, // supported devices
508 NULL
, // register node
510 (void (*)(void *)) scsi_uninit_device
,
511 NULL
, // register child devices
513 (void (*)(void *)) scsi_device_removed