📄 scsi_disk.c
字号:
rc = DISK_cache_write(pdisk, req->start_block, req->length); if (rc == 0) {#ifdef SCSI_DISK_TRACE YS__logmsg(pdisk->scsi_me->scsi_bus->node_id, "[%i:%i] No write segment\n", pdisk->scsi_me->scsi_bus->bus_id+1, pdisk->scsi_me->dev_id);#endif if ((!req->imm_flag) || (!pdisk->fast_writes)) { req->reply_type = SCSI_REP_BUSY; return; } } req->transferred += rc; sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool); memcpy(sreq, req, sizeof(SCSI_REQ)); req->buscycles = sreq->buscycles = rc * SCSI_BLOCK_SIZE / SCSI_WIDTH; req->current_data_size = rc * SCSI_BLOCK_SIZE; if (rc == 0) req->reply_type = SCSI_REP_DISCONNECT; else if ((pdisk->fast_writes) && (req->imm_flag) && (req->transferred == req->length)) req->reply_type = SCSI_REP_COMPLETE; else req->reply_type = SCSI_REP_SAVE_DATA_POINTER; if (sreq->queue_msg == HEAD_OF_QUEUE) { lqueue_add_head(&(pdisk->inqueue), sreq, pdisk->scsi_me->scsi_bus->node_id); } else { lqueue_add(&(pdisk->inqueue), sreq, pdisk->scsi_me->scsi_bus->node_id); } if ((pdisk->state == DISK_IDLE) && (IsNotScheduled(pdisk->request_event))) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead * SCSI_FREQ_RATIO); pdisk->requests_write++; pdisk->blocks_written += sreq->length; return; } /*-----------------------------------------------------------------------*/ /* other requests: put in queue and return immediately */ if ((req->request_type == SCSI_REQ_PREFETCH) || (req->request_type == SCSI_REQ_SEEK) || (req->request_type == SCSI_REQ_FORMAT) || (req->request_type == SCSI_REQ_SYNC_CACHE)) { sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool); memcpy(sreq, req, sizeof(SCSI_REQ)); req->current_data_size = 0; if (req->imm_flag) req->reply_type = SCSI_REP_COMPLETE; else req->reply_type = SCSI_REP_DISCONNECT; if (sreq->queue_msg == HEAD_OF_QUEUE) { lqueue_add_head(&(pdisk->inqueue), sreq, pdisk->scsi_me->scsi_bus->node_id); } else { lqueue_add(&(pdisk->inqueue), sreq, pdisk->scsi_me->scsi_bus->node_id); } if ((pdisk->state == DISK_IDLE) && (IsNotScheduled(pdisk->request_event))) schedule_event(pdisk->request_event, YS__Simtime + pdisk->cntl_overhead * SCSI_FREQ_RATIO); pdisk->requests_other++; return; } /*-----------------------------------------------------------------------*/ /* test command: return status only */ if (req->request_type == SCSI_REQ_MISC) { req->current_data_size = 0; req->reply_type = SCSI_REP_COMPLETE; pdisk->requests_other++; return; } /*-----------------------------------------------------------------------*/ /* inquiry/capacity command: fill in return buffer */ if (req->request_type == SCSI_REQ_INQUIRY) { if (req->buf != NULL) { memcpy(req->buf, &pdisk->inquiry_data, min(req->length, sizeof(pdisk->inquiry_data))); if (req->lun != 0) req->buf[0] = 0x7F; } req->reply_type = SCSI_REP_COMPLETE; req->buscycles += req->length / SCSI_WIDTH; req->current_data_size = req->length; pdisk->requests_other++; return; } if (req->request_type == SCSI_REQ_MODE_SENSE) { if (req->aux != 4) YS__warnmsg(pdisk->scsi_me->scsi_bus->node_id, "Mode Sense Page %i not supported!", req->aux); if (req->buf != NULL) memcpy(req->buf, &pdisk->mode_sense_data, min(req->length, sizeof(pdisk->mode_sense_data))); req->reply_type = SCSI_REP_COMPLETE; req->buscycles += req->length / SCSI_WIDTH; req->current_data_size = req->length; pdisk->requests_other++; return; } if (req->request_type == SCSI_REQ_READ_CAPACITY) { if (req->buf != NULL) { int n = pdisk->cylinders*pdisk->heads*pdisk->sectors - 1; req->buf[0] = (n >> 24) & 0xFF; req->buf[1] = (n >> 16) & 0xFF; req->buf[2] = (n >> 8) & 0xFF; req->buf[3] = (n >> 0) & 0xFF; req->buf[4] = (SCSI_BLOCK_SIZE >> 24) & 0xFF; req->buf[5] = (SCSI_BLOCK_SIZE >> 16) & 0xFF; req->buf[6] = (SCSI_BLOCK_SIZE >> 8) & 0xFF; req->buf[7] = (SCSI_BLOCK_SIZE >> 0) & 0xFF; } req->reply_type = SCSI_REP_COMPLETE; req->buscycles += req->length / SCSI_WIDTH; req->current_data_size = req->length; pdisk->requests_other++; return; } if (req->request_type == SCSI_REQ_REQUEST_SENSE) { if (req->buf != NULL) memcpy(req->buf, &pdisk->sense_data[req->initiator], min(req->length, sizeof(pdisk->mode_sense_data))); req->reply_type = SCSI_REP_COMPLETE; req->buscycles += req->length / SCSI_WIDTH; req->current_data_size = req->length; pdisk->requests_other++; pdisk->sense_data[req->initiator].error = 0x70; pdisk->sense_data[req->initiator].segment = 0; pdisk->sense_data[req->initiator].key = SCSI_SENSE_NONE; pdisk->sense_data[req->initiator].info0 = 0; pdisk->sense_data[req->initiator].info1 = 0; pdisk->sense_data[req->initiator].info2 = 0; pdisk->sense_data[req->initiator].info3 = 0; pdisk->sense_data[req->initiator].add_length = 0; return; }}/*=========================================================================*//* Callback function for responses to the disk. Not supported! *//*=========================================================================*/void DISK_response(void *ptr, SCSI_REQ *req){ SCSI_DEV *pdev = (SCSI_DEV*)ptr; SCSI_DISK *pdisk = (SCSI_DISK*)pdev->device; YS__errmsg(pdisk->scsi_me->scsi_bus->node_id, "SCSI: Response to disk not supported\n");}/*=========================================================================*//*=========================================================================*/void DISK_perform(void *ptr, SCSI_REQ *req){ SCSI_DEV *pdev = (SCSI_DEV*)ptr; SCSI_DISK *pdisk = (SCSI_DISK*)pdev->device; if (req->orig_request == SCSI_REQ_READ) DISK_storage_read(pdisk, req->start_block, req->length, req->buf); if (req->orig_request == SCSI_REQ_WRITE) DISK_storage_write(pdisk, req->start_block, req->length, req->buf);}/*=========================================================================*//* Report configuration and statistics for a specific disk. *//*=========================================================================*/void DISK_stat_report(void *ptr){ SCSI_DISK *pdisk = (SCSI_DISK*)ptr; int nid = pdisk->scsi_me->scsi_bus->node_id; YS__statmsg(nid, "SCSI Disk %i Configuration - %s\n", pdisk->dev_id, pdisk->name); YS__statmsg(nid, "%i rpm, %i heads, %i cylinders\n", pdisk->rpm, pdisk->heads, pdisk->cylinders); YS__statmsg(nid, " %.2f ms Avg Seek; %.2f ms Full Seek; %.2f ms Track-to-Track Seek\n", pdisk->seek_avg, pdisk->seek_full, pdisk->seek_single); if (pdisk->cache_size == 0) YS__statmsg(nid, " No cache\n"); else YS__statmsg(nid, " %i KB cache; %i segments; %i write segments; fast-writes %s\n", pdisk->cache_size, pdisk->cache_segments, pdisk->cache_write_segments, pdisk->fast_writes == 1 ? "on" : "off"); YS__statmsg(nid, " Buffer Full Ratio: %.2f; Buffer Empty Ratio: %.2f\n", pdisk->buffer_full_ratio, pdisk->buffer_empty_ratio); YS__statmsg(nid, " Persistent disk storage:\n %s\n %s\n", pdisk->storage.index_file_name, pdisk->storage.data_file_name); YS__statmsg(nid, "\nSCSI Disk %i Statistics\n", pdisk->dev_id); YS__statmsg(nid, " %i requests; %i reads; %i writes; %i other\n", pdisk->requests_read + pdisk->requests_write + pdisk->requests_other, pdisk->requests_read, pdisk->requests_write, pdisk->requests_other); YS__statmsg(nid, " Full cache hits: %10i\tpartial cache hits: %10i\n", pdisk->cache_hits_full, pdisk->cache_hits_partial); YS__statmsg(nid, " Blocks read: %10i\tfrom media: %10i\n", pdisk->blocks_read, pdisk->blocks_read_media); YS__statmsg(nid, " Blocks written: %10i\tto media: %10i\n", pdisk->blocks_written, pdisk->blocks_written_media); YS__statmsg(nid, " Total seek time: %10.2f ms (%6.2f%%)\n", pdisk->seek_time, pdisk->seek_time * pdisk->ticks_per_ms * 100.0 / YS__Simtime); YS__statmsg(nid, " Total transfer time: %10.2f ms (%6.2f%%)\n", pdisk->transfer_time, pdisk->transfer_time * pdisk->ticks_per_ms * 100.0 / YS__Simtime); YS__statmsg(nid, " Idle time: %10.2f ms (%6.2f%%)\n", (YS__Simtime - (pdisk->seek_time + pdisk->transfer_time) * pdisk->ticks_per_ms) / pdisk->ticks_per_ms, 100.0 - (pdisk->seek_time + pdisk->transfer_time) * pdisk->ticks_per_ms * 100.0 / YS__Simtime); YS__statmsg(nid, "\n");}/*=========================================================================*//* Reset statistics counters for a disk. *//*=========================================================================*/void DISK_stat_clear(void *ptr){ SCSI_DISK *pdisk = (SCSI_DISK*)ptr; pdisk->requests_read = 0; pdisk->requests_write = 0; pdisk->requests_other = 0; pdisk->cache_hits_partial = 0; pdisk->cache_hits_full = 0; pdisk->blocks_read = 0; pdisk->blocks_written = 0; pdisk->blocks_read_media = 0; pdisk->blocks_written_media = 0; pdisk->seek_time = 0.0; pdisk->transfer_time = 0.0;}/*=========================================================================*//* Dump debug information *//*=========================================================================*/void DISK_dump(void *ptr){ SCSI_DISK *pdisk = (SCSI_DISK*)ptr; int n, nid = pdisk->scsi_me->scsi_bus->node_id; YS__logmsg(nid, "\n============== SCSI DISK %i %i ==============\n", pdisk->scsi_me->dev_id, pdisk->scsi_me->scsi_bus->bus_id); YS__logmsg(nid, "state(%d), current_cylinder(%d), current_head(%d)\n", pdisk->state, pdisk->current_cylinder, pdisk->current_head); YS__logmsg(nid, "previous_cylinder(%d), seek_target_sector(%d)\n", pdisk->previous_cylinder, pdisk->seek_target_sector); YS__logmsg(nid, "start_offset(%d), seek_start_time(%lf), seek_end_time(%lf)\n", pdisk->start_offset, pdisk->seek_start_time, pdisk->seek_end_time); YS__logmsg(nid, "current_req:\n"); if (pdisk->current_req) SCSI_req_dump(pdisk->current_req, 0, nid); else YS__logmsg(nid, " NULL\n"); YS__logmsg(nid, "request_event scheduled: %s\n", IsScheduled(pdisk->request_event) ? "yes" : "no"); YS__logmsg(nid, "seek_event scheduled: %s\n", IsScheduled(pdisk->seek_event) ? "yes" : "no"); YS__logmsg(nid, "sector_event scheduled: %s\n", IsScheduled(pdisk->sector_event) ? "yes" : "no"); DumpLinkQueue("inqueue", &(pdisk->inqueue), 0, SCSI_req_dump, nid); DumpLinkQueue("outqueue", &(pdisk->outqueue), 0, SCSI_req_dump, nid); for (n = 0; n < pdisk->cache_segments; n++) { YS__logmsg(nid, "cache seg[%02i] start_block(%d), end_block(%d), write(%d)\n", n, pdisk->cache[n].start_block, pdisk->cache[n].end_block, pdisk->cache[n].write); YS__logmsg(nid, " committed(%d), lru(%d)\n", pdisk->cache[n].committed, pdisk->cache[n].lru); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -