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

📄 ahc.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
{  SCSI_REQ *req;  int       length = 0;  if (scb->tcl & SELBUSB)    YS__errmsg(ahc->scsi_me->nodeid,	       "AHC[%i]: Attempt to issue SCSI command on bus B",	       ahc->scsi_me->mid);  req = (SCSI_REQ*)YS__PoolGetObj(&YS__ScsiReqPool);  req->initiator    = ahc->scsi_id;  req->target       = scb->tcl >> 4;  req->lun          = scb->tcl & 0x07;  req->parent       = NULL;    if (scb->control & DISCENB)    req->imm_flag   = SCSI_FLAG_TRUE;  else    req->imm_flag   = SCSI_FLAG_FALSE;  if (scb->control & TAG_ENB)    {      if ((scb->control & SCB_TAG_TYPE) == 0x00)	req->queue_msg = SIMPLE_QUEUE;      if ((scb->control & SCB_TAG_TYPE) == 0x01)	req->queue_msg = HEAD_OF_QUEUE;      if ((scb->control & SCB_TAG_TYPE) == 0x02)	req->queue_msg = ORDER_QUEUE;      if ((scb->control & SCB_TAG_TYPE) == 0x03)	YS__errmsg(ahc->scsi_me->nodeid,		   "AHC[%i]: Invalid queue type in SCSI command",		   ahc->scsi_me->mid);    }  else    req->queue_msg = NO_QUEUE;  req->queue_tag   = scb->tag;  /* decode command -------------------------------------------------------*/  switch (scb->command[0])    {    case TEST_UNIT_READY:    case START_STOP:    case PREVENT_ALLOW:      req->request_type           = SCSI_REQ_MISC;      req->length                 = 0;      req->lba                    = 0;      break;    case REQUEST_SENSE:      req->request_type           = SCSI_REQ_REQUEST_SENSE;      req->length                 = scb->command[4];      req->lba                    = 0;      req->aux                    = 0;      scb->write                  = 1;      length                      = req->length;      break;          case SCSI_READ_COMMAND:      req->request_type           = SCSI_REQ_READ;      req->length                 = scb->command[4] > 0 ? scb->command[4]:256;      req->lba                    =	((scb->command[1] & 0x1F) << 16) |	(scb->command[2] << 8) |	scb->command[3];      scb->write                  = 1;      length                      = req->length * SCSI_BLOCK_SIZE;      break;          case SCSI_WRITE_COMMAND:      req->request_type           = SCSI_REQ_WRITE;      req->length                 = scb->command[4] > 0 ? scb->command[4]:256;      req->lba                    =	((scb->command[1] & 0x1F) << 16) |	(scb->command[2] << 8) |	scb->command[3];      scb->write                  = 0;      length                      = req->length * SCSI_BLOCK_SIZE;      break;          case INQUIRY:      req->request_type           = SCSI_REQ_INQUIRY;      req->length                 = scb->command[4];      req->lba                    = 0;      scb->write                  = 1;      length                      = req->length;      break;    case SCSI_MODE_SENSE:      req->request_type           = SCSI_REQ_MODE_SENSE;      req->length                 = scb->command[4];      req->lba                    = 0;      req->aux                    = scb->command[2];      scb->write                  = 1;      length                      = req->length;      break;          case READ_CAPACITY:      req->request_type           = SCSI_REQ_READ_CAPACITY;      req->length                 = 8;      req->lba                    =	(scb->command[2] << 24) | (scb->command[3] << 16) |	(scb->command[4] << 8) | (scb->command[5]);      scb->write                  = 1;      length                      = req->length;      break;          case READ_BIG:      req->request_type           = SCSI_REQ_READ;      req->length                 = (scb->command[7] << 8) | scb->command[8];      req->lba                    =	(scb->command[2] << 24) | (scb->command[3] << 16) |	(scb->command[4] << 8) | scb->command[5];      scb->write                  = 1;      length                      = req->length * SCSI_BLOCK_SIZE;      break;    case WRITE_BIG:      req->request_type           = SCSI_REQ_WRITE;      req->length                 = (scb->command[7] << 8) | scb->command[8];      req->lba                    =	(scb->command[2] << 24) | (scb->command[3] << 16) |	(scb->command[4] << 8) | scb->command[5];      scb->write                  = 0;      length                      = req->length * SCSI_BLOCK_SIZE;      break;    case SCSI_SYNCHRONIZE_CACHE:      req->request_type           = SCSI_REQ_SYNC_CACHE;      req->length                 = (scb->command[7] << 8) | scb->command[8];      req->lba                    =	(scb->command[2] << 24) | (scb->command[3] << 16) |	(scb->command[4] << 8) | scb->command[5];      req->imm_flag               = scb->command[1] & 0x02;      scb->write                  = 0;      length                      = 0;      break;    default:      YS__errmsg(ahc->scsi_me->nodeid,		 "AHC[%i]: Invalid SCSI command 0x%02X",		 ahc->scsi_me->mid, scb->command[0]);    }  /* allocate buffer if data length greater then 0 ------------------------*/    if (length > 0)    scb->data = malloc(length);  else    scb->data = NULL;  req->buf = (char*)scb->data;#ifdef AHC_TRACE  YS__logmsg(ahc->scsi_me->nodeid,	     "[%i] %.0f: Start SCSI Command %s (0x%02X) Target %i Lun %i Sector %i Size %i\n",	     ahc->scsi_me->mid, YS__Simtime,	     SCSI_ReqName[req->request_type], req->request_type, req->target,	     req->lun, req->lba, req->length);#endif    return(SCSI_device_request(ahc->scsi_me->scsi_me, req));}/*=========================================================================*//* SCSI adapter won bus - do nothing right now                             *//*=========================================================================*/void ahc_scsi_wonbus(void *controller, SCSI_REQ *req){  ahc_t         *ahc = (ahc_t*)controller;}/*=========================================================================*//* Request sent to SCSI adapter - not supported                            *//*=========================================================================*/void ahc_scsi_request(void *controller, SCSI_REQ *req){  ahc_t         *ahc = (ahc_t*)controller;  YS__errmsg(ahc->scsi_me->nodeid,	     "AHC[%i]: Request to SCSI controller not supported",	     ahc->scsi_me->mid);}/*=========================================================================*//* SCSI adapter received response:                                         *//*=========================================================================*/void ahc_scsi_response(void *controller, SCSI_REQ *req){  ahc_t         *ahc = (ahc_t*)controller;  ahc_scb_t     *scb;  int            n;  unsigned char  tcl;  unsigned char *regs = ahc->regs;#ifdef AHC_TRACE  YS__logmsg(ahc->scsi_me->nodeid,	     "[%i] %.0f AHC: Response %s %i %i (%s)\n",	     ahc->scsi_me->mid, YS__Simtime,	     SCSI_RepName[req->reply_type],	     req->start_block,	     req->current_data_size,	     SCSI_ReqName[req->orig_request]);#endif    tcl = req->target << 4 | req->lun;  scb = NULL;  for (n = 0; n < ahc->max_scbs; n++)    if (req->queue_msg == NO_QUEUE)      {	if ((ahc->scbs[n].status != SCB_INACTIVE) &&	    (ahc->scbs[n].tcl == tcl))	  {	    scb = &ahc->scbs[n];	    break;	  }      }    else      {	if ((ahc->scbs[n].status != SCB_INACTIVE) &&	    (ahc->scbs[n].tag == req->queue_tag) &&	    (ahc->scbs[n].tcl == tcl))	  {	    scb = &ahc->scbs[n];	    break;	  }      }  if (scb == NULL)    YS__errmsg(ahc->scsi_me->nodeid,	       "AHC[%i]: SCSI Response to non-existent SCB (%02X)",	       ahc->scsi_me->mid, tcl);    switch (req->reply_type)    {    case SCSI_REP_COMPLETE:      if (IsNotScheduled(ahc->sequencer))	schedule_event(ahc->sequencer,		       YS__Simtime + ahc->seq_cycle_fast);      /* ahc->seq_state = SEQ_RESPONSE; */      /*      ahc_shiftin_queue(ahc->reconnect_scbs, scb - ahc->scbs); */      scb->status = SCB_COMPLETE;      scb->req    = req;      break;    case SCSI_REP_TIMEOUT:    case SCSI_REP_REJECT:      scb->status = SCB_ERROR;      scb->req    = req;      break;    case SCSI_REP_BUSY:      scb->status = SCB_BUSY;      scb->req    = req;      break;          case SCSI_REP_CONNECT:      if (req->request_type == SCSI_REQ_RECONNECT)	{#ifdef AHC_TRACE	  YS__logmsg(ahc->scsi_me->nodeid,		     "[%i] %.0f: AHC Reconnect %i %i %i %i\n",		     ahc->scsi_me->mid, YS__Simtime,		     IsNotScheduled(ahc->sequencer),		     ahc->seq_state, ahc->seq_scb, n);#endif	  if (IsNotScheduled(ahc->sequencer))	    {	      schedule_event(ahc->sequencer,			     YS__Simtime + ahc->seq_cycle_fast);	    }	  if (!((ahc->seq_state == SEQ_DATA) && (ahc->seq_scb == n)))            {  	      ahc_queue_shiftin(ahc->reconnect_scbs, n);            }	}      scb->status           = SCB_CONNECT;      scb->dma_length      += req->current_data_size;      scb->dma_length_done += req->current_data_size;      scb->req              = req;      if ((req->orig_request == SCSI_REQ_READ) &&	  (req->reply_type == SCSI_REP_CONNECT))	SCSI_bus_perform(ahc->scsi_me->scsi_bus, req);        break;                case SCSI_REP_SAVE_DATA_POINTER:    case SCSI_REP_DISCONNECT:      scb->status = SCB_DISCONNECT;      scb->req    = req;      if (req->orig_request == SCSI_REQ_READ)	SCSI_bus_perform(ahc->scsi_me->scsi_bus, req);        if (req->reply_type == SCSI_REP_DISCONNECT)	{	  YS__PoolReturnObj(&YS__ScsiReqPool, req);	  scb->req = NULL;	}      break;    default:      YS__errmsg(ahc->scsi_me->nodeid,		 "AHC[%i]: Unknown SCSI response %i",		 ahc->scsi_me->mid, req->reply_type);    }}/*=========================================================================*//* Complete a request: insert it into the output FIFO if successful,       *//* interrupt host in any case (if interrupts are enabled) and compute      *//* statistics. Free internal buffers and return request to pool.           *//* If request was rejected with 'busy' status return it to the head of the *//* input FIFO.                                                             *//*=========================================================================*/int ahc_scsi_complete(ahc_t *ahc, ahc_scb_t *scb){  unsigned char *regs = ahc->regs;  double lat;  if (scb->status == SCB_COMPLETE)    {      if (!(regs[INTSTAT] & INT_PEND) && (regs[HCNTRL] & INTEN))	{	  SCSI_cntl_host_interrupt(ahc->scsi_me);	  ahc->intr_cmpl_count++;	  ahc->intr_cmpl_start    = YS__Simtime;	  ahc->intr_cmpl_lat_done = 0;	  ahc->intr_cmpl_clr_done = 0;#ifdef AHC_TRACE	  YS__logmsg(ahc->scsi_me->nodeid,		     "[%i] %.0f: Complete Interrupt\n",		     ahc->scsi_me->mid, YS__Simtime);#endif	}      regs[INTSTAT] |= CMDCMPLT;      ahc_queue_shiftin(ahc->qout_fifo, ahc->seq_scb);      regs[QOUTCNT] = ahc_queue_size(ahc->qout_fifo);      regs[QOUTFIFO] = ahc_queue_head(ahc->qout_fifo);      if (scb->req->orig_request == SCSI_REQ_WRITE)	SCSI_bus_perform(ahc->scsi_me->scsi_bus, scb->req);      ahc->request_complete_count++;    }  if (scb->status == SCB_ERROR)    {      switch (scb->req->reply_type)	{	case SCSI_REP_TIMEOUT:	  if (!(regs[INTSTAT] & INT_PEND) &&	      (regs[HCNTRL] & INTEN) &&	      (regs[SIMODE1] & ENSELTIMO))	    {	      SCSI_cntl_host_interrupt(ahc->scsi_me);	      ahc->intr_scsi_count++;	      ahc->intr_scsi_start    = YS__Simtime;	      ahc->intr_scsi_lat_done = 0;	      ahc->intr_scsi_clr_done = 0;#ifdef AHC_TRACE	      YS__logmsg(ahc->scsi_me->nodeid,			 "[%i] %.0f: SCSI Interrupt\n",			 ahc->scsi_me->mid, YS__Simtime);#endif	    }	  regs[INTSTAT] |= SCSIINT;	  regs[SSTAT1] |= SELTO;			  ahc->seq_pause = 1;      	  break;	case SCSI_REP_REJECT:	  if (!(regs[INTSTAT] & INT_PEND) && (regs[HCNTRL] & INTEN))	    {	      SCSI_cntl_host_interrupt(ahc->scsi_me);	      ahc->intr_seq_count++;	      ahc->intr_seq_start    = YS__Simtime;

⌨️ 快捷键说明

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