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

📄 scsi_disk.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
		     pdisk->scsi_me->scsi_bus->bus_id+1,		     pdisk->scsi_me->dev_id,		     req->current_length, req->length,		     DISK_estimate_access_time(pdisk, req->start_block+req->current_length,					       req->length - req->current_length),		     DISK_estimate_access_time(pdisk, req->start_block+req->current_length,					       req->length - req->current_length) * pdisk->ticks_per_ms,		     YS__Simtime + rint(DISK_rotation_time(pdisk, 1) *					pdisk->ticks_per_ms));#endif	}      else	{	  DISK_do_seek(pdisk, req->start_block + req->current_length,		       req->orig_request == SCSI_REQ_WRITE);#ifdef SCSI_DISK_TRACE	  YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		     "[%i:%i]  More Seek\n",		     pdisk->scsi_me->scsi_bus->bus_id+1,		     pdisk->scsi_me->dev_id);#endif	}    }    /* all blocks transferred -----------------------------------------------*/  else    {      /* prefetch is complete ---------------------------------------------*/      if ((req->orig_request == SCSI_REQ_PREFETCH) ||	  (req->request_type == SCSI_REQ_PREFETCH))	{#ifdef SCSI_DISK_TRACE	  YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		     "[%i:%i] %.0f: DISK Prefetch %s %s %i\n",		     pdisk->scsi_me->scsi_bus->bus_id+1,		     pdisk->scsi_me->dev_id,		     YS__Simtime,		     SCSI_ReqName[req->request_type],		     SCSI_ReqName[req->orig_request],		     req->imm_flag);#endif	  	  if ((req->orig_request == SCSI_REQ_PREFETCH) && (!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);	}            /* read complete: start prefetch if queue is empty ------------------*/      if ((req->orig_request == SCSI_REQ_READ) &&	  (req->request_type != SCSI_REQ_PREFETCH))	if ((lqueue_empty(&(pdisk->inqueue))) &&	    (!DISK_cache_segment_full(pdisk, req->cache_segment)) &&	    (pdisk->prefetch))	  {            sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool);	    memcpy(sreq, req, sizeof(SCSI_REQ));	    sreq->orig_request  = SCSI_REQ_PREFETCH;	    sreq->request_type  = SCSI_REQ_READ;	    sreq->start_block   = req->start_block + req->length;	    sreq->length        = req->length;      /* configure length @@ */	    sreq->imm_flag      = 1;#ifdef SCSI_DISK_TRACE	    YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		       "[%i:%i]   Start Prefetch %p %i\n",		       pdisk->scsi_me->scsi_bus->bus_id+1,		       pdisk->scsi_me->dev_id,		       sreq,		       sreq->start_block);#endif	    	    pdisk->current_req  = sreq;	    pdisk->state        = DISK_IDLE;	  }	else	  {	    pdisk->state        = DISK_IDLE;	    pdisk->current_req  = NULL;	  }            /* write complete: issue response if not fast-write -----------------*/      if (req->orig_request == SCSI_REQ_WRITE)	{	  if ((!pdisk->fast_writes) || (!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;	  pdisk->current_req = NULL;	}#ifdef SCSI_DISK_TRACE      YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		 "[%i:%i]  Done\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);    }}/*=========================================================================*//* Issue a SCSI reply transaction on the bus. Arbitrate for bus if output  *//* queue is empty, otherwise just put it in the queue.                     *//*=========================================================================*/int DISK_issue_request(SCSI_DISK *pdisk, SCSI_REQ* req){  if (lqueue_full(&(pdisk->outqueue)))    return(0);  if (lqueue_empty(&(pdisk->outqueue)))    {      if (SCSI_device_request(pdisk->scsi_me, req) == 1)	return(1);    }  lqueue_add(&(pdisk->outqueue), req, pdisk->scsi_me->scsi_bus->node_id);  return(1);}/*=========================================================================*//* Callback function for when the disk wins the bus. Arbitrate again if    *//* more requests are pending in the outqueue.                              *//*=========================================================================*/void DISK_wonbus(void *ptr, SCSI_REQ *req){  SCSI_DISK *pdisk = (SCSI_DISK*)ptr;  SCSI_REQ  *next_req;  if (!lqueue_empty(&(pdisk->outqueue)))    {      lqueue_get(&(pdisk->outqueue), next_req);      SCSI_device_request(pdisk->scsi_me, next_req);    }}/*=========================================================================*//* Callback function for when the disk receives a request. Check validity. *//* Reject if invalid block number, or non-queue request and queue is full. *//* Enqueue reads and disconnect. Enqueue writes, transfer data until write *//* segments are full and return disconnect, save_data_ptr, busy or         *//* complete. Enqueue other requests. Fill in return data structure for     *//* inquiry and read_capacity requests.                                     *//* Schedule request-event if disk is idle and event is not yet scheduled.  *//*=========================================================================*/void DISK_request(void *ptr, SCSI_REQ *req){  SCSI_DISK            *pdisk = (SCSI_DISK*)ptr;  SCSI_REQ             *sreq;  int                   rc;  req->orig_request  = req->request_type;  req->start_block   = req->lba;  req->transferred   = 0;  req->buscycles     = pdisk->cntl_overhead;#ifdef SCSI_DISK_TRACE  YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,	     "[%i:%i] DISK %.1f Request %s Block %i Length %i\n",	     pdisk->scsi_me->scsi_bus->bus_id+1,	     pdisk->scsi_me->dev_id,	     YS__Simtime,	     SCSI_ReqName[req->request_type],	     req->start_block,	     req->length);#endif  /*-----------------------------------------------------------------------*/  /* check block number and length                                         */  if ((req->request_type == SCSI_REQ_READ) ||      (req->request_type == SCSI_REQ_WRITE) ||      (req->request_type == SCSI_REQ_PREFETCH) ||      (req->request_type == SCSI_REQ_SEEK))    {      if ((req->start_block < 0) ||	  (req->start_block >=	   pdisk->cylinders*pdisk->heads*pdisk->sectors) ||	  (req->start_block + req->length < 0) ||	  (req->start_block + req->length >	   pdisk->cylinders*pdisk->heads*pdisk->sectors))	{	  req->reply_type = SCSI_REP_REJECT;	  	  pdisk->sense_data[req->initiator].error      = 0x70;	  pdisk->sense_data[req->initiator].segment    = 0;	  pdisk->sense_data[req->initiator].key        = SCSI_SENSE_ILLEGAL_REQUEST;	  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;	}    }  if ((req->request_type != SCSI_REQ_INQUIRY) &&      (req->request_type != SCSI_REQ_MISC) &&      (req->lun != 0))    {      req->reply_type = SCSI_REP_REJECT;            pdisk->sense_data[req->initiator].error      = 0x70;      pdisk->sense_data[req->initiator].segment    = 0;      pdisk->sense_data[req->initiator].key        = SCSI_SENSE_ILLEGAL_REQUEST;      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;    }  if (req->request_type != SCSI_REQ_REQUEST_SENSE)    {      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;    }  /*-----------------------------------------------------------------------*/  /* simple (non-queue) request and queue is not empty - reject            */  if ((req->queue_msg == NO_QUEUE) &&      ((!lqueue_empty(&(pdisk->inqueue))) ||       (pdisk->current_req != NULL)))    {      if ((pdisk->current_req != NULL) &&	  (((pdisk->current_req->orig_request == SCSI_REQ_PREFETCH) &&	    (pdisk->current_req->request_type == SCSI_REQ_READ)) ||	   ((pdisk->current_req->orig_request == SCSI_REQ_WRITE) &&	    (pdisk->current_req->imm_flag) &&	    (pdisk->fast_writes))))	{	  if (!((pdisk->current_req->orig_request == SCSI_REQ_WRITE) &&		((req->request_type == SCSI_REQ_SYNC_CACHE) ||		 (req->request_type == SCSI_REQ_WRITE))))	    {#ifdef SCSI_DISK_TRACE	      YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,			 "[%i:%i]   Abort Current Request %s\n",			 pdisk->scsi_me->scsi_bus->bus_id+1,			 pdisk->scsi_me->dev_id,			 SCSI_ReqName[pdisk->current_req->orig_request]);#endif	      YS__PoolReturnObj(&YS__ScsiReqPool, pdisk->current_req);	      pdisk->current_req = NULL;	      pdisk->state = DISK_IDLE;	    }	}      else	{#ifdef SCSI_DISK_TRACE	  YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		     "[%i:%i]   Queue not empty\n",		     pdisk->scsi_me->scsi_bus->bus_id+1,		     pdisk->scsi_me->dev_id);	  if (pdisk->current_req != NULL)	    YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		       "[%i:%i]   Current: %s %s %i %p\n",		       pdisk->scsi_me->scsi_bus->bus_id+1,		       pdisk->scsi_me->dev_id,		       SCSI_ReqName[pdisk->current_req->request_type],		       SCSI_ReqName[pdisk->current_req->orig_request],		       pdisk->current_req->start_block, pdisk->current_req);	  else	    YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		       "[%i:%i]   Size: %i\n",		       pdisk->scsi_me->scsi_bus->bus_id+1,		       pdisk->scsi_me->dev_id,		       pdisk->inqueue.size);#endif	            req->reply_type = SCSI_REP_BUSY;	  return;	}    }    /*-----------------------------------------------------------------------*/  /* queue request and queue is full - reject                              */  if ((req->queue_msg != NO_QUEUE) &&      (lqueue_full(&(pdisk->inqueue))))    {#ifdef SCSI_DISK_TRACE      YS__logmsg(pdisk->scsi_me->scsi_bus->node_id,		 "[%i:%i]   Queue full\n",		 pdisk->scsi_me->scsi_bus->bus_id+1,		 pdisk->scsi_me->dev_id);#endif            req->reply_type = SCSI_REP_BUSY;      return;    }    /*-----------------------------------------------------------------------*/  /* read request: disconnect, put in queue and schedule handler           */  if (req->request_type == SCSI_REQ_READ)    {      sreq = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool);      memcpy(sreq, req, sizeof(SCSI_REQ));      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 (IsNotScheduled(pdisk->request_event))	schedule_event(pdisk->request_event, YS__Simtime +	               0 );		       /* pdisk->cntl_overhead * SCSI_FREQ_RATIO); */        req->reply_type = SCSI_REP_DISCONNECT;      pdisk->requests_read++;      pdisk->blocks_read += req->length;      return;    }    /*-----------------------------------------------------------------------*/  /* write request: disconnect, put in cache and in queue, schedule handler*/    if (req->request_type == SCSI_REQ_WRITE)    {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -