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

📄 scsi_bus.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
      (req->buscycles > 0))    {      old = req->reply_type;      req->reply_type = SCSI_REP_CONNECT;      /* check if initiator device exists -----------------------------------*/      if ((req->initiator < 0) ||	  (req->initiator >= SCSI_WIDTH * 8))	YS__errmsg(psbus->node_id,		   "SCSI %i.%i: Illegal initiator ID in request at %.1f\n",		   psbus->node_id, psbus->bus_id, YS__Simtime);      if ((psbus->devices[req->initiator] == NULL) ||	  (psbus->devices[req->initiator]->response_callback == NULL))	YS__errmsg(psbus->node_id,		   "SCSI %i.%i: No response callback registered for module %i\n",		   psbus->node_id, psbus->bus_id, req->initiator);            /* deliver response to initiator --------------------------------------*/      psbus->devices[req->initiator]->response_callback(psbus->devices[req->initiator]->device, req);      req->reply_type = old;    }  delay = req->buscycles;  psbus->utilization += delay * SCSI_FREQ_RATIO;  if (IsNotScheduled(psbus->send_response))    schedule_event(psbus->send_response,		   YS__Simtime + delay * SCSI_FREQ_RATIO);}/*===========================================================================*//* Deliver SCSI Response to initiator. Called by send_response event which   *//* is scheduled by the request routine. Call the initiators response         *//* callback function and schedule next arbitration event after BUS_FREE +    *//* ARB_DELAY cycles.                                                         *//*===========================================================================*/void SCSI_bus_send_response(){  SCSI_BUS *psbus = (SCSI_BUS*)EventGetArg(NULL);  SCSI_REQ *req = psbus->current_req;  psbus->num_trans++;  /* check if initiator device exists ---------------------------------------*/  if ((req->initiator < 0) ||      (req->initiator >= SCSI_WIDTH * 8))    YS__errmsg(psbus->node_id,	       "SCSI %i.%i: Illegal initiator ID in request at %.1f\n",	       psbus->node_id, psbus->bus_id, YS__Simtime);  if ((psbus->devices[req->initiator] == NULL) ||      (psbus->devices[req->initiator]->response_callback == NULL))    YS__errmsg(psbus->node_id,	       "SCSI %i.%i: No response callback registered for module %i\n",	       psbus->node_id, psbus->bus_id, req->initiator);  /* deliver response to initiator ------------------------------------------*/        psbus->devices[req->initiator]->response_callback(psbus->devices[req->initiator]->device, req);  schedule_event(psbus->arbitrate,		 YS__Simtime +		 (SCSI_ARB_DELAY + SCSI_BUS_FREE) * SCSI_FREQ_RATIO);}/*===========================================================================*//* Create a generic SCSI device on a particular bus.                         *//* Takes the bus pointer, device ID and a pointer to device-specific storage *//* and the request/response/statistics callback functions as arguments.      *//* Creates a device structure in the buses device list and initializes it.   *//*===========================================================================*/SCSI_DEV *SCSI_device_init(SCSI_BUS *psbus, int device_id,			   void *device,			   void (*wonbus_callback)(void*, SCSI_REQ*),			   void (*request_callback)(void*, SCSI_REQ*),			   void (*response_callback)(void*, SCSI_REQ*),			   void (*perform_callback)(void*, SCSI_REQ*),			   void (*stat_report)(void*),			   void (*stat_clear)(void*),			   void (*dump)(void*)){  SCSI_DEV *scsi_dev;    if (psbus->devices == NULL)    YS__errmsg(psbus->node_id,	       "SCSI Bus must be initialized before adding devices");  if ((device_id < 0) || (device_id >= SCSI_WIDTH * 8))    YS__errmsg(psbus->node_id,	       "SCSI %i:%i: Attempt to register illegal device ID %i\n",	       psbus->node_id, psbus->bus_id, device_id);    if (psbus->devices[device_id] != NULL)    YS__errmsg(psbus->node_id,	       "SCSI %i:%i: Device %i already registered\n",	       psbus->node_id, psbus->bus_id, device_id);  scsi_dev = (SCSI_DEV*)malloc(sizeof(SCSI_DEV));  if (scsi_dev == NULL)    YS__errmsg(psbus->node_id,	       "Malloc failed at %s:%i", __FILE__, __LINE__);  psbus->devices[device_id] = scsi_dev;  psbus->devices[device_id]->device            = device;  psbus->devices[device_id]->dev_id            = device_id;  psbus->devices[device_id]->req               = NULL;  psbus->devices[device_id]->wonbus_callback   = wonbus_callback;  psbus->devices[device_id]->request_callback  = request_callback;  psbus->devices[device_id]->response_callback = response_callback;  psbus->devices[device_id]->perform_callback  = perform_callback;  psbus->devices[device_id]->stat_report       = stat_report;  psbus->devices[device_id]->stat_clear        = stat_clear;  psbus->devices[device_id]->dump              = dump;  psbus->devices[device_id]->scsi_bus = psbus;  return(scsi_dev);}/*===========================================================================*//* A SCSI device issues a request: insert request in devices req pointer.    *//* If bus is idle (not arbitrating or busy), set state to arbitrate and      *//* schedule arbitration event. Setting the state prevents the next requestor *//* from scheduling the event again. If the bus is not idle, no event is      *//* scheduled as this will be done at the end of the current transfer.        *//*===========================================================================*/int SCSI_device_request(SCSI_DEV *me, SCSI_REQ *req){  if (me->req != NULL)    return(0);  me->req = req;  if (me->scsi_bus->state == SCSI_BUS_IDLE)    {      me->scsi_bus->state = SCSI_BUS_ARBITRATE;      schedule_event(me->scsi_bus->arbitrate,		     YS__Simtime + SCSI_ARB_DELAY * SCSI_FREQ_RATIO);    }  return(1);}/*===========================================================================*//* Perform a SCSI Request - call the callback functions for read or write    *//*===========================================================================*/void SCSI_bus_perform(SCSI_BUS *pbus, SCSI_REQ *req){  if (((req->orig_request == SCSI_REQ_READ) ||       (req->orig_request == SCSI_REQ_WRITE)) &&      (pbus->devices[req->target]->perform_callback != NULL))	pbus->devices[req->target]->perform_callback(pbus->devices[req->target], req);}/*===========================================================================*//* Print SCSI bus parameters.                                                *//*===========================================================================*/void SCSI_bus_print_params(int nid){  double scsi_cycle;    scsi_cycle = (double)(1.0 / SCSI_FREQUENCY);  YS__statmsg(nid, "SCSI Bus Configuration\n");  YS__statmsg(nid, "  Number of devices:\t%5i\n", SCSI_WIDTH * 8);  YS__statmsg(nid, "  Width:\t\t%5i\t\t  Frequency:\t\t%8.2f MHz\n",	      SCSI_WIDTH * 8, (float)SCSI_FREQUENCY);  YS__statmsg(nid, "  Arbitration Delay:\t%8.2f us\t",	      SCSI_ARB_DELAY * scsi_cycle);  YS__statmsg(nid, "  Bus Free Delay:\t%8.2f us\n",	      SCSI_BUS_FREE * scsi_cycle);  YS__statmsg(nid, "  Request Delay:\t%8.2f us\t",	      SCSI_REQ_DELAY * scsi_cycle);  YS__statmsg(nid, "  Select Timeout:\t%8.2f us\n\n",	      SCSI_SEL_TIMEOUT * scsi_cycle);}/*===========================================================================*//* Print SCSI bus statistics, and call the statistics function for all       *//* attached devices, if one exists.                                          *//*===========================================================================*/void SCSI_bus_stat_report(SCSI_BUS *psbus){  int n;    YS__statmsg(psbus->node_id,	      "  Utilization: %.3f%%\t%lld transaction%c\n\n",	      (100.0 * (double)psbus->utilization) / (YS__Simtime - psbus->last_clear),	      psbus->num_trans,	      psbus->num_trans == 1 ? ' ' : 's');    for (n = 0; n < SCSI_WIDTH * 8; n++)    if ((psbus->devices[n] != NULL) &&	(psbus->devices[n]->stat_report != NULL))      psbus->devices[n]->stat_report(psbus->devices[n]->device);}/*===========================================================================*//* Clear bus statistics and call the the clear_stat function for all         *//* attached devices.                                                         *//*===========================================================================*/void SCSI_bus_stat_clear(SCSI_BUS *psbus){  int n;    psbus->utilization = 0.0;  psbus->num_trans = 0;  psbus->last_clear = YS__Simtime;  for (n = 0; n < SCSI_WIDTH * 8; n++)    if ((psbus->devices[n] != NULL) &&	(psbus->devices[n]->stat_clear != NULL))      psbus->devices[n]->stat_clear(psbus->devices[n]->device);}/*===========================================================================*//* Dump SCSI bus debug information                                           *//*===========================================================================*/void SCSI_req_dump(SCSI_REQ *req, int flags, int nid){  YS__logmsg(nid, "  request_type(%s), reply_type(%s)\n",             SCSI_ReqName[req->request_type], SCSI_RepName[req->reply_type]);  YS__logmsg(nid, "  initiator(%d), target(%d), lun(%d)\n",              req->initiator, req->target, req->lun);  YS__logmsg(nid, "  lba(%d), length(%d), imm_flag(%d)\n",             req->lba, req->length, req->imm_flag);  YS__logmsg(nid, "  queue_msg(%d), queue_tag(%d), aux(%d)\n",             req->queue_msg, req->queue_tag, req->aux);  YS__logmsg(nid, "  orig_request(%s), start_block(%d), current_length(%d)\n",             SCSI_ReqName[req->orig_request], req->start_block, req->current_length);  YS__logmsg(nid, "  transferred(%d), cache_segment(%d), current_data_size(%d)\n",             req->transferred, req->cache_segment, req->current_data_size);  YS__logmsg(nid, "  buscycles(%d)\n", req->buscycles);       }void SCSI_bus_dump(SCSI_BUS *psbus){  int nid = psbus->node_id;  int n;  YS__logmsg(nid, "\n============== SCSI BUS %d ==============\n",	     psbus->bus_id);  YS__logmsg(nid, "state(%d)\n", psbus->state);  YS__logmsg(nid, "attached devices: ");  for (n = 0; n < SCSI_WIDTH*8; n++)    if (psbus->devices[n])      YS__logmsg(nid, "%i ", n);  YS__logmsg(nid, "\ncurrent_req\n");  if (psbus->current_req)    SCSI_req_dump(psbus->current_req, 0, nid);  else    YS__logmsg(nid, "  NULL\n");  for (n = 0; n < SCSI_WIDTH*8; n++)    if ((psbus->devices[n]) && (psbus->devices[n]->req))      {        YS__logmsg(nid, "device %i arbitrating\n", n);        SCSI_req_dump(psbus->devices[n]->req, 0, nid);      }  YS__logmsg(nid, "arbitrate scheduled: %s\n",             IsScheduled(psbus->arbitrate) ? "yes" : "no");  YS__logmsg(nid, "send_request scheduled: %s\n",             IsScheduled(psbus->send_request) ? "yes" : "no");  YS__logmsg(nid, "send_response scheduled: %s\n",             IsScheduled(psbus->send_response) ? "yes" : "no");  for (n = 0; n < SCSI_WIDTH * 8; n++)    if ((psbus->devices[n] != NULL) &&	(psbus->devices[n]->dump != NULL))      psbus->devices[n]->dump(psbus->devices[n]->device);}

⌨️ 快捷键说明

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