📄 scsi_disk.c
字号:
if ((lqueue_empty(&(pdisk->inqueue))) && (pdisk->current_req == NULL)) return; if (pdisk->current_req == NULL) { lqueue_get(&(pdisk->inqueue), req); pdisk->current_req = req; } else req = pdisk->current_req;#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] %.0f Handle %s Sector %i %p\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, YS__Simtime, SCSI_ReqName[req->orig_request], req->start_block, req);#endif req->current_length = 0; /*=======================================================================*/ /* read or prefetch (both requested and triggered by a read) */ /* check cache: full hit - update cache LRU bits and return data */ /* partial hit - update cache LRU bits and start disk seek */ /* miss - start disk seek */ if ((req->orig_request == SCSI_REQ_READ) || (req->orig_request == SCSI_REQ_PREFETCH)) { /* abort read-induced prefetch if more requests are waiting ---------*/ if ((req->orig_request == SCSI_REQ_PREFETCH) && (req->request_type == SCSI_REQ_READ) && (!lqueue_empty(&(pdisk->inqueue)))) { YS__PoolReturnObj(&YS__ScsiReqPool, req); pdisk->current_req = NULL; if (IsNotScheduled(pdisk->request_event)) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead*SCSI_FREQ_RATIO); } /* check cache ------------------------------------------------------*/ hit_type = DISK_cache_hit(pdisk, req->start_block, req->length); req->cache_segment = DISK_cache_getsegment(pdisk, req->start_block, req->length, 0); if (hit_type == DISK_CACHE_HIT_FULL) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Full Cache Hit [%i]\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, req->cache_segment);#endif DISK_cache_touch(pdisk, req->start_block, req->length); if ((req->orig_request == SCSI_REQ_READ) || ((req->orig_request == SCSI_REQ_PREFETCH) && (req->request_type == SCSI_REQ_PREFETCH) && (!req->imm_flag))) { req->transferred = req->length; req->buscycles = req->length * SCSI_BLOCK_SIZE / SCSI_WIDTH; req->current_data_size = req->buscycles * SCSI_WIDTH; req->request_type = SCSI_REQ_RECONNECT; req->reply_type = SCSI_REP_COMPLETE; DISK_issue_request(pdisk, pdisk->current_req); } pdisk->current_req = NULL; pdisk->state = DISK_IDLE; if (IsNotScheduled(pdisk->request_event)) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead*SCSI_FREQ_RATIO); if (req->orig_request == SCSI_REQ_READ) pdisk->cache_hits_full++; return; } if (hit_type == DISK_CACHE_HIT_PARTIAL) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Partial Cache Hit [%i] (%i-%i) %i\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, req->cache_segment, pdisk->cache[req->cache_segment].start_block, pdisk->cache[req->cache_segment].end_block, req->start_block);#endif DISK_cache_touch(pdisk, req->start_block, pdisk->cache[req->cache_segment].end_block - req->length); req->current_length = pdisk->cache[req->cache_segment].end_block - req->start_block; DISK_do_seek(pdisk, req->start_block + req->current_length, 0); if (req->orig_request == SCSI_REQ_READ) pdisk->cache_hits_partial++; } if (hit_type == DISK_CACHE_MISS) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Cache Miss\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id);#endif DISK_do_seek(pdisk, req->start_block, 0); } } /*=======================================================================*/ /* seek request - initiate disk seek */ if (req->orig_request == SCSI_REQ_SEEK) { DISK_do_seek(pdisk, req->start_block, 0); } /*=======================================================================*/ if (req->orig_request == SCSI_REQ_WRITE) { DISK_cache_commit_write(pdisk, req->start_block, req->length); if ((pdisk->fast_writes) && (req->imm_flag) && (req->length == req->transferred)) { SCSI_REQ *qreq = lqueue_empty(&pdisk->inqueue) ? NULL : lqueue_head(&pdisk->inqueue); SCSI_REQ *sreq; if (req->buscycles > 0) { sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool); memcpy(sreq, req, sizeof(SCSI_REQ)); } else sreq = req;#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Committing Fast Write\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id);#endif if ((pdisk->state == DISK_IDLE) && ((lqueue_empty(&pdisk->inqueue)) || ((qreq != NULL) && (qreq->orig_request == SCSI_REQ_WRITE) && (qreq->transferred == 0)))) { sreq->start_block = 0; sreq->length = INT_MAX; sreq->cache_segment = DISK_cache_getwsegment(pdisk, &(sreq->start_block), &(sreq->length));#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Start Fast Write %i\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, sreq->cache_segment);#endif if (sreq != req) sreq->transferred = sreq->length; DISK_do_seek(pdisk, sreq->start_block, 1); pdisk->current_req = sreq; } else { YS__PoolReturnObj(&YS__ScsiReqPool, sreq); if (pdisk->state == DISK_IDLE) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Next Request\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id);#endif if (IsNotScheduled(pdisk->request_event)) schedule_event(pdisk->request_event, YS__Simtime); pdisk->current_req = NULL; } } } else { if (req->transferred == 0) { SCSI_REQ* sreq; req->transferred = DISK_cache_write(pdisk, req->start_block, req->length); DISK_cache_commit_write(pdisk, req->start_block, req->length); sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool); memcpy(sreq, req, sizeof(SCSI_REQ)); sreq->buscycles = req->transferred * SCSI_BLOCK_SIZE / SCSI_WIDTH; sreq->current_data_size = sreq->buscycles * SCSI_WIDTH; sreq->request_type = SCSI_REQ_RECONNECT; if (sreq->transferred == req->length) sreq->reply_type = SCSI_REP_COMPLETE; else sreq->reply_type = SCSI_REP_SAVE_DATA_POINTER; DISK_issue_request(pdisk, sreq); } req->cache_segment = DISK_cache_getsegment(pdisk, req->start_block, 0, 1);#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Start Write Segment %i\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, req->cache_segment);#endif DISK_do_seek(pdisk, req->start_block, 1); } } /*=======================================================================*/ /* sync-cache request: */ if (req->orig_request == SCSI_REQ_SYNC_CACHE) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Handle SYNC %i %i\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, req->start_block, req->length);#endif if (req->length > 0) req->length += (pdisk->cache_size * 1024 / SCSI_BLOCK_SIZE) / pdisk->cache_segments; else req->length = INT_MAX; req->cache_segment = DISK_cache_getwsegment(pdisk, &(req->start_block), &(req->length)); if (req->cache_segment < 0) { if (!req->imm_flag) { req->request_type = SCSI_REQ_RECONNECT; req->reply_type = SCSI_REP_COMPLETE; req->buscycles = 0; req->current_data_size = 0; DISK_issue_request(pdisk, req); } else YS__PoolReturnObj(&YS__ScsiReqPool, req); pdisk->current_req = NULL; pdisk->state = DISK_IDLE; if (IsNotScheduled(pdisk->request_event)) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead*SCSI_FREQ_RATIO); return; } #ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Flush %i %i\n", req->start_block, pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, req->length);#endif req->current_length = 0; DISK_do_seek(pdisk, req->start_block, 1); } /*=======================================================================*/ /* format request, if imm-flag is not set report completion */ if (req->orig_request == SCSI_REQ_FORMAT) { if (!req->imm_flag) { req->request_type = SCSI_REQ_RECONNECT; req->reply_type = SCSI_REP_COMPLETE; req->buscycles = 0; req->current_data_size = 0; DISK_issue_request(pdisk, req); } else YS__PoolReturnObj(&YS__ScsiReqPool, req); pdisk->current_req = NULL; pdisk->state = DISK_IDLE; if (IsNotScheduled(pdisk->request_event)) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead * SCSI_FREQ_RATIO); return; } }/*=========================================================================*//* Disk seek operation complete: finish a seek request, or start *//* transferring data. Scheduled by the request-event handler or the sector *//* event handler whenever a seek is necessary. *//*=========================================================================*/void DISK_seek_handler(){ SCSI_DISK *pdisk = (SCSI_DISK*)EventGetArg(NULL); SCSI_REQ *req = pdisk->current_req; if (pdisk->current_req == NULL) return;#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] Seek %.1f to %i\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id, YS__Simtime, DISK_sector_at_time(pdisk, pdisk->current_head, pdisk->current_cylinder, YS__Simtime));#endif /* seek request is complete at this point -------------------------------*/ if (req->orig_request == SCSI_REQ_SEEK) { if (!req->imm_flag) { req->request_type = SCSI_REQ_RECONNECT; req->reply_type = SCSI_REP_COMPLETE; req->buscycles = 0; req->current_data_size = 0; DISK_issue_request(pdisk, req); } pdisk->state = DISK_IDLE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -