1 /* 2 * Copyright 2004-2007, Haiku, Inc. All RightsReserved. 3 * Copyright 2002-2004, Thomas Kurschel. All rights reserved. 4 * 5 * Distributed under the terms of the MIT License. 6 */ 7 8 //! Part of Open SCSI bus manager 9 10 11 #include "scsi_internal.h" 12 #include "queuing.h" 13 14 #include <string.h> 15 16 #include <algorithm> 17 18 19 /** put request back in queue because of device/bus overflow */ 20 21 void 22 scsi_requeue_request(scsi_ccb *request, bool bus_overflow) 23 { 24 scsi_bus_info *bus = request->bus; 25 scsi_device_info *device = request->device; 26 bool was_servicable, start_retry; 27 28 SHOW_FLOW0(3, ""); 29 30 if (request->state != SCSI_STATE_SENT) { 31 panic("Unsent ccb was request to requeue\n"); 32 return; 33 } 34 35 request->state = SCSI_STATE_QUEUED; 36 37 ACQUIRE_BEN(&bus->mutex); 38 39 was_servicable = scsi_can_service_bus(bus); 40 41 if (bus->left_slots++ == 0) 42 scsi_unblock_bus_noresume(bus, false); 43 44 if (device->left_slots++ == 0 || request->ordered) 45 scsi_unblock_device_noresume(device, false); 46 47 // make sure it's the next request for this device 48 scsi_add_req_queue_first(request); 49 50 if (bus_overflow) { 51 // bus has overflown 52 scsi_set_bus_overflow(bus); 53 // add device to queue as last - other devices may be waiting already 54 scsi_add_device_queue_last(device); 55 // don't change device overflow condition as the device has never seen 56 // this request 57 } else { 58 // device has overflown 59 scsi_set_device_overflow(device); 60 scsi_remove_device_queue(device); 61 // either, the device has refused the request, i.e. it was transmitted 62 // over the bus - in this case, the bus cannot be overloaded anymore; 63 // or, the driver detected that the device can not be able to process 64 // further requests, because the driver knows its maximum queue depth 65 // or something - in this case, the bus state hasn't changed, but the 66 // driver will tell us about any overflow when we submit the next 67 // request, so the overflow state will be fixed automatically 68 scsi_clear_bus_overflow(bus); 69 } 70 71 start_retry = !was_servicable && scsi_can_service_bus(bus); 72 73 RELEASE_BEN(&bus->mutex); 74 75 // submit requests to other devices in case bus was overloaded 76 if (start_retry) 77 release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/); 78 } 79 80 81 /** restart request ASAP because something went wrong */ 82 83 void 84 scsi_resubmit_request(scsi_ccb *request) 85 { 86 scsi_bus_info *bus = request->bus; 87 scsi_device_info *device = request->device; 88 bool was_servicable, start_retry; 89 90 SHOW_FLOW0(3, ""); 91 92 if (request->state != SCSI_STATE_SENT) { 93 panic("Unsent ccb was asked to get resubmitted\n"); 94 return; 95 } 96 97 request->state = SCSI_STATE_QUEUED; 98 99 ACQUIRE_BEN(&bus->mutex); 100 101 was_servicable = scsi_can_service_bus(bus); 102 103 if (bus->left_slots++ == 0) 104 scsi_unblock_bus_noresume(bus, false); 105 106 if (device->left_slots++ == 0 || request->ordered) 107 scsi_unblock_device_noresume(device, false); 108 109 // if SIM reported overflow of device/bus, this should (hopefully) be over now 110 scsi_clear_device_overflow(device); 111 scsi_clear_bus_overflow(bus); 112 113 // we don't want to let anyone overtake this request 114 request->ordered = true; 115 116 // make it the next request submitted to SIM for this device 117 scsi_add_req_queue_first(request); 118 119 // if device is not blocked (anymore) add it to waiting list of bus 120 if (device->lock_count == 0) { 121 scsi_add_device_queue_first(device); 122 // as previous line does nothing if already queued, we force device 123 // to be the next one to get handled 124 bus->waiting_devices = device; 125 } 126 127 start_retry = !was_servicable && scsi_can_service_bus(bus); 128 129 RELEASE_BEN(&bus->mutex); 130 131 // let the service thread do the resubmit 132 if (start_retry) 133 release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/); 134 } 135 136 137 /** submit autosense for request */ 138 139 static void 140 submit_autosense(scsi_ccb *request) 141 { 142 scsi_device_info *device = request->device; 143 144 //snooze(1000000); 145 146 SHOW_FLOW0(3, "sending autosense"); 147 // we cannot use scsi_scsi_io but must insert it brute-force 148 149 // give SIM a well-defined first state 150 // WARNING: this is a short version of scsi_async_io, so if 151 // you change something there, do it here as well! 152 153 // no DMA buffer (we made sure that the data buffer fulfills all 154 // limitations) 155 request->buffered = false; 156 // don't let any request bypass us 157 request->ordered = true; 158 // initial SIM state for this request 159 request->sim_state = 0; 160 161 device->auto_sense_originator = request; 162 163 // make it next request to process 164 scsi_add_queued_request_first(device->auto_sense_request); 165 } 166 167 168 /** finish special auto-sense request */ 169 170 static void 171 finish_autosense(scsi_device_info *device) 172 { 173 scsi_ccb *orig_request = device->auto_sense_originator; 174 scsi_ccb *request = device->auto_sense_request; 175 176 SHOW_FLOW0(3, ""); 177 178 if (request->subsys_status == SCSI_REQ_CMP) { 179 int sense_len; 180 181 // we got sense data -> copy it to sense buffer 182 sense_len = std::min((uint32)SCSI_MAX_SENSE_SIZE, 183 request->data_length - request->data_resid); 184 185 SHOW_FLOW(3, "Got sense: %d bytes", sense_len); 186 187 memcpy(orig_request->sense, request->data, sense_len); 188 189 orig_request->sense_resid = SCSI_MAX_SENSE_SIZE - sense_len; 190 orig_request->subsys_status |= SCSI_AUTOSNS_VALID; 191 } else { 192 // failed to get sense 193 orig_request->subsys_status = SCSI_AUTOSENSE_FAIL; 194 } 195 196 // inform peripheral driver 197 release_sem_etc(orig_request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/); 198 } 199 200 201 /** device refused request because command queue is full */ 202 203 static void 204 scsi_device_queue_overflow(scsi_ccb *request, uint num_requests) 205 { 206 scsi_bus_info *bus = request->bus; 207 scsi_device_info *device = request->device; 208 int diff_max_slots; 209 210 // set maximum number of concurrent requests to number of 211 // requests running when QUEUE FULL condition occurred - 1 212 // (the "1" is the refused request) 213 --num_requests; 214 215 // at least one request at once must be possible 216 if (num_requests < 1) 217 num_requests = 1; 218 219 SHOW_INFO(2, "Restricting device queue to %d requests", num_requests); 220 221 // update slot count 222 ACQUIRE_BEN(&bus->mutex); 223 224 diff_max_slots = device->total_slots - num_requests; 225 device->total_slots = num_requests; 226 device->left_slots -= diff_max_slots; 227 228 RELEASE_BEN(&bus->mutex); 229 230 // requeue request, blocking further device requests 231 scsi_requeue_request(request, false); 232 } 233 234 235 /** finish scsi request */ 236 237 void 238 scsi_request_finished(scsi_ccb *request, uint num_requests) 239 { 240 scsi_device_info *device = request->device; 241 scsi_bus_info *bus = request->bus; 242 bool was_servicable, start_service, do_autosense; 243 244 SHOW_FLOW(3, "%p", request); 245 246 if (request->state != SCSI_STATE_SENT) { 247 panic("Unsent ccb %p was reported as done\n", request); 248 return; 249 } 250 251 if (request->subsys_status == SCSI_REQ_INPROG) { 252 panic("ccb %p with status \"Request in Progress\" was reported as done\n", 253 request); 254 return; 255 } 256 257 // check for queue overflow reported by device 258 if (request->subsys_status == SCSI_REQ_CMP_ERR 259 && request->device_status == SCSI_STATUS_QUEUE_FULL) { 260 scsi_device_queue_overflow(request, num_requests); 261 return; 262 } 263 264 request->state = SCSI_STATE_FINISHED; 265 266 ACQUIRE_BEN(&bus->mutex); 267 268 was_servicable = scsi_can_service_bus(bus); 269 270 // do pseudo-autosense if device doesn't support it and 271 // device reported a check condition state and auto-sense haven't 272 // been retrieved by SIM 273 // (last test is implicit as SIM adds SCSI_AUTOSNS_VALID to subsys_status) 274 do_autosense = device->manual_autosense 275 && (request->flags & SCSI_DIS_AUTOSENSE) == 0 276 && request->subsys_status == SCSI_REQ_CMP_ERR 277 && request->device_status == SCSI_STATUS_CHECK_CONDITION; 278 279 if (request->subsys_status != SCSI_REQ_CMP) { 280 SHOW_FLOW(3, "subsys=%x, device=%x, flags=%x, manual_auto_sense=%d", 281 request->subsys_status, request->device_status, (int)request->flags, 282 device->manual_autosense); 283 } 284 285 if (do_autosense) { 286 // queue auto-sense request after checking was_servicable but before 287 // releasing locks so no other request overtakes auto-sense 288 submit_autosense(request); 289 } 290 291 if (bus->left_slots++ == 0) 292 scsi_unblock_bus_noresume(bus, false); 293 294 if (device->left_slots++ == 0 || request->ordered) 295 scsi_unblock_device_noresume(device, false); 296 297 // if SIM reported overflow of device/bus, this should (hopefully) be over now 298 scsi_clear_device_overflow(device); 299 scsi_clear_bus_overflow(bus); 300 301 // if device is not blocked (anymore) and has pending requests, 302 // add it to waiting list of bus 303 if (device->lock_count == 0 && device->queued_reqs != NULL) 304 scsi_add_device_queue_last(device); 305 306 start_service = !was_servicable && scsi_can_service_bus(bus); 307 308 RELEASE_BEN(&bus->mutex); 309 310 // tell service thread to submit new requests to SIM 311 // (do this ASAP to keep bus/device busy) 312 if (start_service) 313 release_sem_etc(bus->start_service, 1, 0/*B_DO_NOT_RESCHEDULE*/); 314 315 if (request->emulated) 316 scsi_finish_emulation(request); 317 318 // copy data from buffer and release it 319 if (request->buffered) 320 scsi_release_dma_buffer(request); 321 322 // special treatment for finished auto-sense 323 if (request == device->auto_sense_request) 324 finish_autosense(device); 325 else { 326 // tell peripheral driver about completion 327 if (!do_autosense) 328 release_sem_etc(request->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/); 329 } 330 } 331 332 333 /** check whether request can be executed right now, enqueuing it if not, 334 * return: true if request can be executed 335 * side effect: updates device->last_sort 336 */ 337 338 static inline bool 339 scsi_check_enqueue_request(scsi_ccb *request) 340 { 341 scsi_bus_info *bus = request->bus; 342 scsi_device_info *device = request->device; 343 bool execute; 344 345 ACQUIRE_BEN(&bus->mutex); 346 347 // if device/bus is locked, or there are waiting requests 348 // or waiting devices (last condition makes sure we don't overtake 349 // requests that got queued because bus was full) 350 if (device->lock_count > 0 || device->queued_reqs != NULL 351 || bus->lock_count > 0 || bus->waiting_devices != NULL) { 352 SHOW_FLOW0(3, "bus/device is currently locked"); 353 scsi_add_queued_request(request); 354 execute = false; 355 } else { 356 // if bus is saturated, block it 357 if (--bus->left_slots == 0) { 358 SHOW_FLOW0(3, "bus is saturated, blocking further requests"); 359 scsi_block_bus_nolock(bus, false); 360 } 361 362 // if device saturated or blocking request, block device 363 if (--device->left_slots == 0 || request->ordered) { 364 SHOW_FLOW0( 3, "device is saturated/blocked by requests, blocking further requests" ); 365 scsi_block_device_nolock(device, false); 366 } 367 368 if (request->sort >= 0) { 369 device->last_sort = request->sort; 370 SHOW_FLOW(1, "%" B_PRId64, device->last_sort); 371 } 372 373 execute = true; 374 } 375 376 RELEASE_BEN(&bus->mutex); 377 378 return execute; 379 } 380 381 382 // size of SCSI command according to function group 383 int func_group_len[8] = { 384 6, 10, 10, 0, 16, 12, 0, 0 385 }; 386 387 388 /** execute scsi command asynchronously */ 389 390 void 391 scsi_async_io(scsi_ccb *request) 392 { 393 scsi_bus_info *bus = request->bus; 394 395 //SHOW_FLOW( 0, "path_id=%d", bus->path_id ); 396 397 //snooze( 1000000 ); 398 399 // do some sanity tests first 400 if (request->state != SCSI_STATE_FINISHED) 401 panic("Passed ccb to scsi_action that isn't ready (state = %d)\n", request->state); 402 403 if (request->cdb_length < func_group_len[request->cdb[0] >> 5]) { 404 SHOW_ERROR(3, "invalid command len (%d instead of %d)", 405 request->cdb_length, func_group_len[request->cdb[0] >> 5]); 406 407 request->subsys_status = SCSI_REQ_INVALID; 408 goto err; 409 } 410 411 if (!request->device->valid) { 412 SHOW_ERROR0( 3, "device got removed" ); 413 414 // device got removed meanwhile 415 request->subsys_status = SCSI_DEV_NOT_THERE; 416 goto err; 417 } 418 419 if ((request->flags & SCSI_DIR_MASK) != SCSI_DIR_NONE 420 && request->sg_list == NULL && request->data_length > 0) { 421 SHOW_ERROR( 3, "Asynchronous SCSI I/O requires S/G list (data is %d bytes)", 422 (int)request->data_length ); 423 request->subsys_status = SCSI_DATA_RUN_ERR; 424 goto err; 425 } 426 427 request->buffered = request->emulated = 0; 428 429 // make data DMA safe 430 // (S/G list must be created first to be able to verify DMA restrictions) 431 if ((request->flags & SCSI_DMA_SAFE) == 0 && request->data_length > 0) { 432 request->buffered = true; 433 if (!scsi_get_dma_buffer(request)) { 434 SHOW_ERROR0( 3, "cannot create DMA buffer for request - reduce data volume" ); 435 436 request->subsys_status = SCSI_DATA_RUN_ERR; 437 goto err; 438 } 439 } 440 441 // emulate command if not supported 442 if ((request->device->emulation_map[request->cdb[0] >> 3] 443 & (1 << (request->cdb[0] & 7))) != 0) { 444 request->emulated = true; 445 446 if (!scsi_start_emulation(request)) { 447 SHOW_ERROR(3, "cannot emulate SCSI command 0x%02x", request->cdb[0]); 448 goto err2; 449 } 450 } 451 452 // SCSI-1 uses 3 bits of command packet for LUN 453 // SCSI-2 uses identify message, but still needs LUN in command packet 454 // (though it won't fit, as LUNs can be 4 bits wide) 455 // SCSI-3 doesn't use command packet for LUN anymore 456 // ATAPI uses 3 bits of command packet for LUN 457 458 // currently, we always copy LUN into command packet as a safe bet 459 { 460 // abuse TUR to find proper spot in command packet for LUN 461 scsi_cmd_tur *cmd = (scsi_cmd_tur *)request->cdb; 462 463 cmd->lun = request->device->target_lun; 464 } 465 466 request->ordered = (request->flags & SCSI_ORDERED_QTAG) != 0; 467 468 SHOW_FLOW(3, "ordered=%d", request->ordered); 469 470 // give SIM a well-defined first state 471 request->sim_state = 0; 472 473 // make sure device/bus is not blocked 474 if (!scsi_check_enqueue_request(request)) 475 return; 476 477 bus = request->bus; 478 479 request->state = SCSI_STATE_SENT; 480 bus->interface->scsi_io(bus->sim_cookie, request); 481 return; 482 483 err2: 484 if (request->buffered) 485 scsi_release_dma_buffer(request); 486 err: 487 release_sem(request->completion_sem); 488 return; 489 } 490 491 492 /** execute SCSI command synchronously */ 493 494 void 495 scsi_sync_io(scsi_ccb *request) 496 { 497 bool tmp_sg = false; 498 499 // create scatter-gather list if required 500 if ((request->flags & SCSI_DIR_MASK) != SCSI_DIR_NONE 501 && request->sg_list == NULL && request->data_length > 0) { 502 tmp_sg = true; 503 if (!create_temp_sg(request)) { 504 SHOW_ERROR0( 3, "data is too much fragmented - you should use s/g list" ); 505 506 // ToDo: this means too much (fragmented) data 507 request->subsys_status = SCSI_DATA_RUN_ERR; 508 return; 509 } 510 } 511 512 scsi_async_io(request); 513 acquire_sem(request->completion_sem); 514 515 if (tmp_sg) 516 cleanup_tmp_sg(request); 517 } 518 519 520 uchar 521 scsi_term_io(scsi_ccb *ccb_to_terminate) 522 { 523 scsi_bus_info *bus = ccb_to_terminate->bus; 524 525 return bus->interface->term_io(bus->sim_cookie, ccb_to_terminate); 526 } 527 528 529 uchar 530 scsi_abort(scsi_ccb *req_to_abort) 531 { 532 scsi_bus_info *bus = req_to_abort->bus; 533 534 if (bus == NULL) { 535 // checking the validity of the request to abort is a nightmare 536 // this is just a beginning 537 return SCSI_REQ_INVALID; 538 } 539 540 ACQUIRE_BEN(&bus->mutex); 541 542 switch (req_to_abort->state) { 543 case SCSI_STATE_FINISHED: 544 case SCSI_STATE_SENT: 545 RELEASE_BEN(&bus->mutex); 546 break; 547 548 case SCSI_STATE_QUEUED: { 549 bool was_servicable, start_retry; 550 551 was_servicable = scsi_can_service_bus(bus); 552 553 // remove request from device queue 554 scsi_remove_queued_request(req_to_abort); 555 556 start_retry = scsi_can_service_bus(bus) && !was_servicable; 557 558 RELEASE_BEN(&bus->mutex); 559 560 req_to_abort->subsys_status = SCSI_REQ_ABORTED; 561 562 // finish emulation 563 if (req_to_abort->emulated) 564 scsi_finish_emulation(req_to_abort); 565 566 // release DMA buffer 567 if (req_to_abort->buffered) 568 scsi_release_dma_buffer(req_to_abort); 569 570 // tell peripheral driver about 571 release_sem_etc(req_to_abort->completion_sem, 1, 0/*B_DO_NOT_RESCHEDULE*/); 572 573 if (start_retry) 574 release_sem(bus->start_service); 575 576 break; 577 } 578 } 579 580 return SCSI_REQ_CMP; 581 } 582 583 584 /** submit pending request (at most one!) */ 585 586 bool 587 scsi_check_exec_service(scsi_bus_info *bus) 588 { 589 SHOW_FLOW0(3, ""); 590 ACQUIRE_BEN(&bus->mutex); 591 592 if (scsi_can_service_bus(bus)) { 593 scsi_ccb *request; 594 scsi_device_info *device; 595 596 SHOW_FLOW0(3, "servicing bus"); 597 598 //snooze( 1000000 ); 599 600 // handle devices in round-robin-style 601 device = bus->waiting_devices; 602 bus->waiting_devices = bus->waiting_devices->waiting_next; 603 604 request = device->queued_reqs; 605 scsi_remove_queued_request(request); 606 607 // if bus is saturated, block it 608 if (--bus->left_slots == 0) { 609 SHOW_FLOW0(3, "bus is saturated, blocking further requests"); 610 scsi_block_bus_nolock(bus, false); 611 } 612 613 // if device saturated or blocking request, block device 614 if (--device->left_slots == 0 || request->ordered) { 615 SHOW_FLOW0(3, "device is saturated/blocked by requests, blocking further requests"); 616 scsi_block_device_nolock(device, false); 617 } 618 619 if (request->sort >= 0) { 620 device->last_sort = request->sort; 621 SHOW_FLOW(1, "%" B_PRId64, device->last_sort); 622 } 623 624 RELEASE_BEN(&bus->mutex); 625 626 request->state = SCSI_STATE_SENT; 627 bus->interface->scsi_io(bus->sim_cookie, request); 628 629 return true; 630 } 631 632 RELEASE_BEN(&bus->mutex); 633 634 return false; 635 } 636