コード例 #1
0
ファイル: inia100.c プロジェクト: iPodLinux/linux-2.6.7-ipod
/*****************************************************************************
 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);
}
コード例 #2
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);
}
コード例 #3
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;
}