1 /* 2 * Copyright 2002/03, Thomas Kurschel. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 /* 7 Part of Open SCSI bus manager 8 9 Bus node layer. 10 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) 15 */ 16 17 #include "scsi_internal.h" 18 19 #include <string.h> 20 #include <malloc.h> 21 22 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 28 29 30 /** implementation of service thread: 31 * it handles DPC and pending requests 32 */ 33 34 static void 35 scsi_do_service(scsi_bus_info *bus) 36 { 37 while (true) { 38 SHOW_FLOW0( 3, "" ); 39 40 // handle DPCs first as they are more urgent 41 if (scsi_check_exec_dpc(bus)) 42 continue; 43 44 if (scsi_check_exec_service(bus)) 45 continue; 46 47 break; 48 } 49 } 50 51 52 /** main loop of service thread */ 53 54 static int32 55 scsi_service_threadproc(void *arg) 56 { 57 scsi_bus_info *bus = (scsi_bus_info *)arg; 58 int32 processed_notifications = 0; 59 60 SHOW_FLOW(3, "bus = %p", bus); 61 62 while (true) { 63 // we handle multiple requests in scsi_do_service at once; 64 // to save time, we will acquire all notifications that are sent 65 // up to now at once. 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); 69 70 SHOW_FLOW0( 3, "1" ); 71 72 if (bus->shutting_down) 73 break; 74 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); 78 79 scsi_do_service(bus); 80 } 81 82 return 0; 83 } 84 85 86 static scsi_bus_info * 87 scsi_create_bus(device_node *node, uint8 path_id) 88 { 89 scsi_bus_info *bus; 90 int res; 91 92 SHOW_FLOW0(3, ""); 93 94 bus = (scsi_bus_info *)malloc(sizeof(*bus)); 95 if (bus == NULL) 96 return NULL; 97 98 memset(bus, 0, sizeof(*bus)); 99 100 bus->path_id = path_id; 101 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; 106 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; 113 114 bus->node = node; 115 bus->lock_count = bus->blocked[0] = bus->blocked[1] = 0; 116 bus->sim_overflow = 0; 117 bus->shutting_down = false; 118 119 bus->waiting_devices = NULL; 120 //bus->resubmitted_req = NULL; 121 122 bus->dpc_list = NULL; 123 124 if ((bus->scan_lun_lock = create_sem(1, "scsi_scan_lun_lock")) < 0) { 125 res = bus->scan_lun_lock; 126 goto err6; 127 } 128 129 bus->start_service = create_sem(0, "scsi_start_service"); 130 if (bus->start_service < 0) { 131 res = bus->start_service; 132 goto err4; 133 } 134 135 mutex_init(&bus->mutex, "scsi_bus_mutex"); 136 spinlock_irq_init(&bus->dpc_lock); 137 138 bus->service_thread = spawn_kernel_thread(scsi_service_threadproc, 139 "scsi_bus_service", BUS_SERVICE_PRIORITY, bus); 140 141 if (bus->service_thread < 0) { 142 res = bus->service_thread; 143 goto err1; 144 } 145 146 resume_thread(bus->service_thread); 147 148 return bus; 149 150 err1: 151 mutex_destroy(&bus->mutex); 152 delete_sem(bus->start_service); 153 err4: 154 delete_sem(bus->scan_lun_lock); 155 err6: 156 free(bus); 157 return NULL; 158 } 159 160 161 static status_t 162 scsi_destroy_bus(scsi_bus_info *bus) 163 { 164 // noone is using this bus now, time to clean it up 165 bus->shutting_down = true; 166 release_sem(bus->start_service); 167 168 status_t retcode; 169 wait_for_thread(bus->service_thread, &retcode); 170 171 delete_sem(bus->start_service); 172 mutex_destroy(&bus->mutex); 173 delete_sem(bus->scan_lun_lock); 174 175 return B_OK; 176 } 177 178 179 static status_t 180 scsi_init_bus(device_node *node, void **cookie) 181 { 182 uint8 path_id; 183 scsi_bus_info *bus; 184 status_t res; 185 186 SHOW_FLOW0( 3, "" ); 187 188 if (pnp->get_attr_uint8(node, SCSI_BUS_PATH_ID_ITEM, &path_id, false) != B_OK) 189 return B_ERROR; 190 191 bus = scsi_create_bus(node, path_id); 192 if (bus == NULL) 193 return B_NO_MEMORY; 194 195 // extract controller/protocoll restrictions from node 196 if (pnp->get_attr_uint32(node, B_DMA_ALIGNMENT, &bus->dma_params.alignment, 197 true) != B_OK) 198 bus->dma_params.alignment = 0; 199 if (pnp->get_attr_uint32(node, B_DMA_MAX_TRANSFER_BLOCKS, 200 &bus->dma_params.max_blocks, true) != B_OK) 201 bus->dma_params.max_blocks = 0xffffffff; 202 if (pnp->get_attr_uint32(node, B_DMA_BOUNDARY, 203 &bus->dma_params.dma_boundary, true) != B_OK) 204 bus->dma_params.dma_boundary = ~0; 205 if (pnp->get_attr_uint32(node, B_DMA_MAX_SEGMENT_BLOCKS, 206 &bus->dma_params.max_sg_block_size, true) != B_OK) 207 bus->dma_params.max_sg_block_size = 0xffffffff; 208 if (pnp->get_attr_uint32(node, B_DMA_MAX_SEGMENT_COUNT, 209 &bus->dma_params.max_sg_blocks, true) != B_OK) 210 bus->dma_params.max_sg_blocks = ~0; 211 if (pnp->get_attr_uint64(node, B_DMA_HIGH_ADDRESS, 212 &bus->dma_params.high_address, true) != B_OK) 213 bus->dma_params.high_address = ~0; 214 215 // do some sanity check: 216 bus->dma_params.max_sg_block_size &= ~bus->dma_params.alignment; 217 218 if (bus->dma_params.alignment > B_PAGE_SIZE) { 219 SHOW_ERROR(0, "Alignment (0x%" B_PRIx32 ") must be less then " 220 "B_PAGE_SIZE", bus->dma_params.alignment); 221 res = B_ERROR; 222 goto err; 223 } 224 225 if (bus->dma_params.max_sg_block_size < 1) { 226 SHOW_ERROR(0, "Max s/g block size (0x%" B_PRIx32 ") is too small", 227 bus->dma_params.max_sg_block_size); 228 res = B_ERROR; 229 goto err; 230 } 231 232 if (bus->dma_params.dma_boundary < B_PAGE_SIZE - 1) { 233 SHOW_ERROR(0, "DMA boundary (0x%" B_PRIx32 ") must be at least " 234 "B_PAGE_SIZE", bus->dma_params.dma_boundary); 235 res = B_ERROR; 236 goto err; 237 } 238 239 if (bus->dma_params.max_blocks < 1 || bus->dma_params.max_sg_blocks < 1) { 240 SHOW_ERROR(0, "Max blocks (%" B_PRIu32 ") and max s/g blocks (%" 241 B_PRIu32 ") must be at least 1", bus->dma_params.max_blocks, 242 bus->dma_params.max_sg_blocks); 243 res = B_ERROR; 244 goto err; 245 } 246 247 { 248 device_node *parent = pnp->get_parent_node(node); 249 pnp->get_driver(parent, (driver_module_info **)&bus->interface, 250 (void **)&bus->sim_cookie); 251 pnp->put_node(parent); 252 253 bus->interface->set_scsi_bus(bus->sim_cookie, bus); 254 } 255 256 // cache inquiry data 257 scsi_inquiry_path(bus, &bus->inquiry_data); 258 259 // get max. number of commands on bus 260 bus->left_slots = bus->inquiry_data.hba_queue_size; 261 SHOW_FLOW( 3, "Bus has %d slots", bus->left_slots ); 262 263 *cookie = bus; 264 265 return B_OK; 266 267 err: 268 scsi_destroy_bus(bus); 269 return res; 270 } 271 272 273 static void 274 scsi_uninit_bus(scsi_bus_info *bus) 275 { 276 scsi_destroy_bus(bus); 277 } 278 279 280 uchar 281 scsi_inquiry_path(scsi_bus bus, scsi_path_inquiry *inquiry_data) 282 { 283 SHOW_FLOW(4, "path_id=%d", bus->path_id); 284 return bus->interface->path_inquiry(bus->sim_cookie, inquiry_data); 285 } 286 287 288 static uchar 289 scsi_reset_bus(scsi_bus_info *bus) 290 { 291 return bus->interface->reset_bus(bus->sim_cookie); 292 } 293 294 295 static status_t 296 scsi_bus_module_init(void) 297 { 298 SHOW_FLOW0(4, ""); 299 300 status_t status = init_ccb_alloc(); 301 if (status != B_OK) 302 return status; 303 return init_temp_sg(); 304 } 305 306 307 static status_t 308 scsi_bus_module_uninit(void) 309 { 310 SHOW_INFO0(4, ""); 311 312 uninit_ccb_alloc(); 313 uninit_temp_sg(); 314 return B_OK; 315 } 316 317 318 static status_t 319 std_ops(int32 op, ...) 320 { 321 switch (op) { 322 case B_MODULE_INIT: 323 return scsi_bus_module_init(); 324 case B_MODULE_UNINIT: 325 return scsi_bus_module_uninit(); 326 327 default: 328 return B_ERROR; 329 } 330 } 331 332 333 scsi_bus_interface scsi_bus_module = { 334 { 335 { 336 SCSI_BUS_MODULE_NAME, 337 0, 338 std_ops 339 }, 340 341 NULL, // supported devices 342 NULL, // register node 343 scsi_init_bus, 344 (void (*)(void *))scsi_uninit_bus, 345 (status_t (*)(void *))scsi_scan_bus, 346 (status_t (*)(void *))scsi_scan_bus, 347 NULL 348 }, 349 350 scsi_inquiry_path, 351 scsi_reset_bus, 352 }; 353