/***************************************************************************** Function name : inia100_queue Description : Queue a command and setup interrupts for a free bus. Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block. *****************************************************************************/ static int inia100_queue(struct scsi_cmnd * SCpnt, void (*done) (struct scsi_cmnd *)) { register ORC_SCB *pSCB; ORC_HCS *pHCB; /* Point to Host adapter control block */ pHCB = (ORC_HCS *) SCpnt->device->host->hostdata; SCpnt->scsi_done = done; /* Get free SCSI control block */ if ((pSCB = orc_alloc_scb(pHCB)) == NULL) { inia100AppendSRBToQueue(pHCB, SCpnt); /* Buffer this request */ /* printk("inia100_entry: can't allocate SCB\n"); */ return (0); } inia100BuildSCB(pHCB, pSCB, SCpnt); orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ return (0); }
/***************************************************************************** Function name : inia100_queue Description : Queue a command and setup interrupts for a free bus. Input : pHCB - Pointer to host adapter structure Output : None. Return : pSRB - Pointer to SCSI request block. *****************************************************************************/ int inia100_queue(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *)) { register ORC_SCB *pSCB; ORC_HCS *pHCB; /* Point to Host adapter control block */ if (SCpnt->lun > 16) { SCpnt->result = (DID_TIME_OUT << 16); done(SCpnt); /* Notify system DONE */ return (0); } pHCB = (ORC_HCS *) SCpnt->host->base; SCpnt->scsi_done = done; /* Get free SCSI control block */ if ((pSCB = orc_alloc_scb(pHCB)) == NULL) { inia100AppendSRBToQueue(pHCB, SCpnt); /* Buffer this request */ /* printk("inia100_entry: can't allocate SCB\n"); */ return (0); } inia100BuildSCB(pHCB, pSCB, SCpnt); orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ return (0); }
/***************************************************************************** Function name : inia100SCBPost Description : This is callback routine be called when orc finish one SCSI command. Input : pHCB - Pointer to host adapter control block. pSCB - Pointer to SCSI control block. Output : None. Return : None. *****************************************************************************/ void inia100SCBPost(BYTE * pHcb, BYTE * pScb) { Scsi_Cmnd *pSRB; /* Pointer to SCSI request block */ ORC_HCS *pHCB; ORC_SCB *pSCB; ESCB *pEScb; pHCB = (ORC_HCS *) pHcb; pSCB = (ORC_SCB *) pScb; pEScb = pSCB->SCB_EScb; if ((pSRB = (Scsi_Cmnd *) pEScb->SCB_Srb) == 0) { printk("inia100SCBPost: SRB pointer is empty\n"); orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ return; } pEScb->SCB_Srb = NULL; switch (pSCB->SCB_HaStat) { case 0x0: case 0xa: /* Linked command complete without error and linked normally */ case 0xb: /* Linked command complete without error interrupt generated */ pSCB->SCB_HaStat = 0; break; case 0x11: /* Selection time out-The initiator selection or target reselection was not complete within the SCSI Time out period */ pSCB->SCB_HaStat = DID_TIME_OUT; break; case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus phase sequence was requested by the target. The host adapter will generate a SCSI Reset Condition, notifying the host with a SCRD interrupt */ pSCB->SCB_HaStat = DID_RESET; break; case 0x1a: /* SCB Aborted. 07/21/98 */ pSCB->SCB_HaStat = DID_ABORT; break; case 0x12: /* Data overrun/underrun-The target attempted to transfer more data than was allocated by the Data Length field or the sum of the Scatter / Gather Data Length fields. */ case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ case 0x16: /* Invalid CCB Operation Code-The first byte of the CCB was invalid. */ default: printk("inia100: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ break; } if (pSCB->SCB_TaStat == 2) { /* Check condition */ memcpy((unsigned char *) &pSRB->sense_buffer[0], (unsigned char *) &pEScb->ESCB_SGList[0], SENSE_SIZE); } pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); pSRB->scsi_done(pSRB); /* Notify system DONE */ /* Find the next pending SRB */ if ((pSRB = inia100PopSRBFromQueue(pHCB)) != NULL) { /* Assume resend will success */ /* Reuse old SCB */ inia100BuildSCB(pHCB, pSCB, pSRB); /* Create corresponding SCB */ orc_exec_scb(pHCB, pSCB); /* Start execute SCB */ } else { /* No Pending SRB */ orc_release_scb(pHCB, pSCB); /* Release SCB for current channel */ } return; }