⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scsi_disk.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
  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 + -