2 * Copyright 2002/03, Thomas Kurschel. All rights reserved.
3 * Distributed under the terms of the MIT License.
7 Part of Open SCSI bus manager
11 Whenever a controller driver publishes a new controller, a new SCSI bus
12 for public and internal use is registered in turn. After that, this
13 bus is told to rescan for devices. For each device, there is a
14 device registered for peripheral drivers. (see devices.c)
17 #include "scsi_internal.h"
23 // bus service should hurry up a bit - good controllers don't take much time
24 // but are very happy to be busy; don't make it realtime though as we
25 // don't really need that but would risk to steel processing power of
26 // realtime-demanding threads
27 #define BUS_SERVICE_PRIORITY B_URGENT_DISPLAY_PRIORITY
30 /** implementation of service thread:
31 * it handles DPC and pending requests
35 scsi_do_service(scsi_bus_info
*bus
)
40 // handle DPCs first as they are more urgent
41 if (scsi_check_exec_dpc(bus
))
44 if (scsi_check_exec_service(bus
))
52 /** main loop of service thread */
55 scsi_service_threadproc(void *arg
)
57 scsi_bus_info
*bus
= (scsi_bus_info
*)arg
;
58 int32 processed_notifications
= 0;
60 SHOW_FLOW(3, "bus = %p", bus
);
63 // we handle multiple requests in scsi_do_service at once;
64 // to save time, we will acquire all notifications that are sent
66 // (Sadly, there is no "set semaphore to zero" function, so this
67 // is a poor-man emulation)
68 acquire_sem_etc(bus
->start_service
, processed_notifications
+ 1, 0, 0);
72 if (bus
->shutting_down
)
75 // get number of notifications _before_ servicing to make sure no new
76 // notifications are sent after do_service()
77 get_sem_count(bus
->start_service
, &processed_notifications
);
86 static scsi_bus_info
*
87 scsi_create_bus(device_node
*node
, uint8 path_id
)
94 bus
= (scsi_bus_info
*)malloc(sizeof(*bus
));
98 memset(bus
, 0, sizeof(*bus
));
100 bus
->path_id
= path_id
;
102 if (pnp
->get_attr_uint32(node
, SCSI_DEVICE_MAX_TARGET_COUNT
, &bus
->max_target_count
, true) != B_OK
)
103 bus
->max_target_count
= MAX_TARGET_ID
+ 1;
104 if (pnp
->get_attr_uint32(node
, SCSI_DEVICE_MAX_LUN_COUNT
, &bus
->max_lun_count
, true) != B_OK
)
105 bus
->max_lun_count
= MAX_LUN_ID
+ 1;
107 // our scsi_ccb only has a uchar for target_id
108 if (bus
->max_target_count
> 256)
109 bus
->max_target_count
= 256;
110 // our scsi_ccb only has a uchar for target_lun
111 if (bus
->max_lun_count
> 256)
112 bus
->max_lun_count
= 256;
115 bus
->lock_count
= bus
->blocked
[0] = bus
->blocked
[1] = 0;
116 bus
->sim_overflow
= 0;
117 bus
->shutting_down
= false;
119 bus
->waiting_devices
= NULL
;
120 //bus->resubmitted_req = NULL;
122 bus
->dpc_list
= NULL
;
124 if ((bus
->scan_lun_lock
= create_sem(1, "scsi_scan_lun_lock")) < 0) {
125 res
= bus
->scan_lun_lock
;
129 bus
->start_service
= create_sem(0, "scsi_start_service");
130 if (bus
->start_service
< 0) {
131 res
= bus
->start_service
;
135 res
= INIT_BEN(&bus
->mutex
, "scsi_bus_mutex");
139 spinlock_irq_init(&bus
->dpc_lock
);
141 res
= scsi_init_ccb_alloc(bus
);
145 bus
->service_thread
= spawn_kernel_thread(scsi_service_threadproc
,
146 "scsi_bus_service", BUS_SERVICE_PRIORITY
, bus
);
148 if (bus
->service_thread
< 0) {
149 res
= bus
->service_thread
;
153 resume_thread(bus
->service_thread
);
158 scsi_uninit_ccb_alloc(bus
);
160 DELETE_BEN(&bus
->mutex
);
162 delete_sem(bus
->start_service
);
164 delete_sem(bus
->scan_lun_lock
);
172 scsi_destroy_bus(scsi_bus_info
*bus
)
176 // noone is using this bus now, time to clean it up
177 bus
->shutting_down
= true;
178 release_sem(bus
->start_service
);
180 wait_for_thread(bus
->service_thread
, &retcode
);
182 delete_sem(bus
->start_service
);
183 DELETE_BEN(&bus
->mutex
);
184 delete_sem(bus
->scan_lun_lock
);
186 scsi_uninit_ccb_alloc(bus
);
193 scsi_init_bus(device_node
*node
, void **cookie
)
201 if (pnp
->get_attr_uint8(node
, SCSI_BUS_PATH_ID_ITEM
, &path_id
, false) != B_OK
)
204 bus
= scsi_create_bus(node
, path_id
);
208 // extract controller/protocoll restrictions from node
209 if (pnp
->get_attr_uint32(node
, B_DMA_ALIGNMENT
, &bus
->dma_params
.alignment
,
211 bus
->dma_params
.alignment
= 0;
212 if (pnp
->get_attr_uint32(node
, B_DMA_MAX_TRANSFER_BLOCKS
,
213 &bus
->dma_params
.max_blocks
, true) != B_OK
)
214 bus
->dma_params
.max_blocks
= 0xffffffff;
215 if (pnp
->get_attr_uint32(node
, B_DMA_BOUNDARY
,
216 &bus
->dma_params
.dma_boundary
, true) != B_OK
)
217 bus
->dma_params
.dma_boundary
= ~0;
218 if (pnp
->get_attr_uint32(node
, B_DMA_MAX_SEGMENT_BLOCKS
,
219 &bus
->dma_params
.max_sg_block_size
, true) != B_OK
)
220 bus
->dma_params
.max_sg_block_size
= 0xffffffff;
221 if (pnp
->get_attr_uint32(node
, B_DMA_MAX_SEGMENT_COUNT
,
222 &bus
->dma_params
.max_sg_blocks
, true) != B_OK
)
223 bus
->dma_params
.max_sg_blocks
= ~0;
225 // do some sanity check:
226 bus
->dma_params
.max_sg_block_size
&= ~bus
->dma_params
.alignment
;
228 if (bus
->dma_params
.alignment
> B_PAGE_SIZE
) {
229 SHOW_ERROR(0, "Alignment (0x%" B_PRIx32
") must be less then "
230 "B_PAGE_SIZE", bus
->dma_params
.alignment
);
235 if (bus
->dma_params
.max_sg_block_size
< 1) {
236 SHOW_ERROR(0, "Max s/g block size (0x%" B_PRIx32
") is too small",
237 bus
->dma_params
.max_sg_block_size
);
242 if (bus
->dma_params
.dma_boundary
< B_PAGE_SIZE
- 1) {
243 SHOW_ERROR(0, "DMA boundary (0x%" B_PRIx32
") must be at least "
244 "B_PAGE_SIZE", bus
->dma_params
.dma_boundary
);
249 if (bus
->dma_params
.max_blocks
< 1 || bus
->dma_params
.max_sg_blocks
< 1) {
250 SHOW_ERROR(0, "Max blocks (%" B_PRIu32
") and max s/g blocks (%"
251 B_PRIu32
") must be at least 1", bus
->dma_params
.max_blocks
,
252 bus
->dma_params
.max_sg_blocks
);
258 device_node
*parent
= pnp
->get_parent_node(node
);
259 pnp
->get_driver(parent
, (driver_module_info
**)&bus
->interface
,
260 (void **)&bus
->sim_cookie
);
261 pnp
->put_node(parent
);
263 bus
->interface
->set_scsi_bus(bus
->sim_cookie
, bus
);
266 // cache inquiry data
267 scsi_inquiry_path(bus
, &bus
->inquiry_data
);
269 // get max. number of commands on bus
270 bus
->left_slots
= bus
->inquiry_data
.hba_queue_size
;
271 SHOW_FLOW( 3, "Bus has %d slots", bus
->left_slots
);
278 scsi_destroy_bus(bus
);
284 scsi_uninit_bus(scsi_bus_info
*bus
)
286 scsi_destroy_bus(bus
);
291 scsi_inquiry_path(scsi_bus bus
, scsi_path_inquiry
*inquiry_data
)
293 SHOW_FLOW(4, "path_id=%d", bus
->path_id
);
294 return bus
->interface
->path_inquiry(bus
->sim_cookie
, inquiry_data
);
299 scsi_reset_bus(scsi_bus_info
*bus
)
301 return bus
->interface
->reset_bus(bus
->sim_cookie
);
306 scsi_bus_module_init(void)
309 return init_temp_sg();
314 scsi_bus_module_uninit(void)
324 std_ops(int32 op
, ...)
328 return scsi_bus_module_init();
329 case B_MODULE_UNINIT
:
330 return scsi_bus_module_uninit();
338 scsi_bus_interface scsi_bus_module
= {
341 SCSI_BUS_MODULE_NAME
,
346 NULL
, // supported devices
347 NULL
, // register node
349 (void (*)(void *))scsi_uninit_bus
,
350 (status_t (*)(void *))scsi_scan_bus
,
351 (status_t (*)(void *))scsi_scan_bus
,