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

📄 ncr53c406a.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
NCR53c406a_abort(Scsi_Cmnd *SCpnt){    DEB(printk("NCR53c406a_abort called\n"));    return SCSI_ABORT_SNOOZE;	/* Don't know how to abort */}int NCR53c406a_reset(Scsi_Cmnd *SCpnt, unsigned int ignored){    DEB(printk("NCR53c406a_reset called\n"));    outb(C4_IMG, CONFIG4);      /* Select reg set 0 */    outb(CHIP_RESET, CMD_REG);    outb(SCSI_NOP, CMD_REG);	/* required after reset */    outb(SCSI_RESET, CMD_REG);    chip_init();        rtrc(2);    if (irq_level)        return SCSI_RESET_PENDING; /* should get an interrupt */    else        return SCSI_RESET_WAKEUP; /* won't get any interrupts */}int NCR53c406a_biosparm(Scsi_Disk *disk, kdev_t dev, int* info_array){    int size;        DEB(printk("NCR53c406a_biosparm called\n"));        size = disk->capacity;    info_array[0] = 64;         /* heads */    info_array[1] = 32;         /* sectors */    info_array[2] = size>>11;   /* cylinders */    if (info_array[2] > 1024) {	/* big disk */      info_array[0] = 255;      info_array[1] = 63;      info_array[2] = size / (255*63);    }    return 0;  }          static voiddo_NCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){    unsigned long flags;    spin_lock_irqsave(&io_request_lock, flags);    NCR53c406a_intr(0, dev_id, regs);    spin_unlock_irqrestore(&io_request_lock, flags);}     static voidNCR53c406a_intr(int unused, void *dev_id, struct pt_regs *regs){    DEB(unsigned char fifo_size;)    DEB(unsigned char seq_reg;)    unsigned char status, int_reg;    unsigned long flags = 0;#if USE_PIO    unsigned char pio_status;     struct scatterlist *sglist;    unsigned int sgcount;#endif        VDEB(printk("NCR53c406a_intr called\n"));        save_flags(flags);    cli();#if USE_PIO    REG1;    pio_status = inb(PIO_STATUS);#endif    REG0;    status = inb(STAT_REG);    DEB(seq_reg = inb(SEQ_REG));    int_reg = inb(INT_REG);    DEB(fifo_size = inb(FIFO_FLAGS) & 0x1f);    restore_flags(flags);    #if NCR53C406A_DEBUG    printk("status=%02x, seq_reg=%02x, int_reg=%02x, fifo_size=%02x",            status, seq_reg, int_reg, fifo_size);#if (USE_DMA)    printk("\n");#else    printk(", pio=%02x\n", pio_status);#endif USE_DMA#endif NCR53C406A_DEBUG        if(int_reg & 0x80){         /* SCSI reset intr */        rtrc(3);        DEB(printk("NCR53c406a: reset intr received\n"));        current_SC->SCp.phase = idle;        current_SC->result = DID_RESET << 16;        current_SC->scsi_done(current_SC);        return;    }    #if USE_PIO    if(pio_status & 0x80) {        printk("NCR53C406A: Warning: PIO error!\n");        current_SC->SCp.phase = idle;        current_SC->result = DID_ERROR << 16;        current_SC->scsi_done(current_SC);        return;    }#endif USE_PIO        if(status & 0x20) {		/* Parity error */        printk("NCR53c406a: Warning: parity error!\n");        current_SC->SCp.phase = idle;        current_SC->result = DID_PARITY << 16;        current_SC->scsi_done(current_SC);        return;    }        if(status & 0x40) {		/* Gross error */        printk("NCR53c406a: Warning: gross error!\n");        current_SC->SCp.phase = idle;        current_SC->result = DID_ERROR << 16;        current_SC->scsi_done(current_SC);        return;    }        if(int_reg & 0x20){		/* Disconnect */        DEB(printk("NCR53c406a: disconnect intr received\n"));        if(current_SC->SCp.phase != message_in){ /* Unexpected disconnect */            current_SC->result = DID_NO_CONNECT << 16;        }        else{  /* Command complete, return status and message */            current_SC->result = (current_SC->SCp.Status & 0xff)                 | ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16);        }                rtrc(0);        current_SC->SCp.phase = idle;        current_SC->scsi_done( current_SC );        return;    }        switch(status & 0x07){	/* scsi phase */    case 0x00:			/* DATA-OUT */        if(int_reg & 0x10){     /* Target requesting info transfer */            rtrc(5);            current_SC->SCp.phase = data_out;            VDEB(printk("NCR53c406a: Data-Out phase\n"));            outb(FLUSH_FIFO, CMD_REG);            LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */#if USE_DMA			/* No s/g support for DMA */            NCR53c406a_dma_write(current_SC->request_buffer,                                  current_SC->request_bufflen);#endif USE_DMA            outb(TRANSFER_INFO | DMA_OP, CMD_REG); #if USE_PIO            if (!current_SC->use_sg) /* Don't use scatter-gather */                NCR53c406a_pio_write(current_SC->request_buffer,                                      current_SC->request_bufflen);            else {              /* use scatter-gather */                sgcount = current_SC->use_sg;                sglist = current_SC->request_buffer;                while( sgcount-- ) {                    NCR53c406a_pio_write(sglist->address, sglist->length);                    sglist++;                }            }            REG0;#endif USE_PIO        }        break;            case 0x01:			/* DATA-IN */        if(int_reg & 0x10){     /* Target requesting info transfer */            rtrc(6);            current_SC->SCp.phase = data_in;            VDEB(printk("NCR53c406a: Data-In phase\n"));            outb(FLUSH_FIFO, CMD_REG);            LOAD_DMA_COUNT(current_SC->request_bufflen); /* Max transfer size */#if USE_DMA			/* No s/g support for DMA */            NCR53c406a_dma_read(current_SC->request_buffer,                                 current_SC->request_bufflen);#endif USE_DMA            outb(TRANSFER_INFO | DMA_OP, CMD_REG); #if USE_PIO            if (!current_SC->use_sg) /* Don't use scatter-gather */                NCR53c406a_pio_read(current_SC->request_buffer,                                     current_SC->request_bufflen);            else {              /* Use scatter-gather */                sgcount = current_SC->use_sg;                sglist = current_SC->request_buffer;                while( sgcount-- ) {                    NCR53c406a_pio_read(sglist->address, sglist->length);                    sglist++;                }            }            REG0;#endif USE_PIO        }        break;            case 0x02:			/* COMMAND */        current_SC->SCp.phase = command_ph;        printk("NCR53c406a: Warning: Unknown interrupt occurred in command phase!\n");        break;            case 0x03:			/* STATUS */        rtrc(7);        current_SC->SCp.phase = status_ph;        VDEB(printk("NCR53c406a: Status phase\n"));        outb(FLUSH_FIFO, CMD_REG);        outb(INIT_CMD_COMPLETE, CMD_REG);        break;            case 0x04:			/* Reserved */    case 0x05:			/* Reserved */        printk("NCR53c406a: WARNING: Reserved phase!!!\n");        break;            case 0x06:			/* MESSAGE-OUT */        DEB(printk("NCR53c406a: Message-Out phase\n"));        current_SC->SCp.phase = message_out;        outb(SET_ATN, CMD_REG);	/* Reject the message */        outb(MSG_ACCEPT, CMD_REG);        break;            case 0x07:			/* MESSAGE-IN */        rtrc(4);        VDEB(printk("NCR53c406a: Message-In phase\n"));        current_SC->SCp.phase = message_in;                current_SC->SCp.Status = inb(SCSI_FIFO);            current_SC->SCp.Message = inb(SCSI_FIFO);                VDEB(printk("SCSI FIFO size=%d\n", inb(FIFO_FLAGS) & 0x1f));        DEB(printk("Status = %02x  Message = %02x\n",                    current_SC->SCp.Status, current_SC->SCp.Message));                if(current_SC->SCp.Message == SAVE_POINTERS ||            current_SC->SCp.Message == DISCONNECT) {            outb(SET_ATN, CMD_REG); /* Reject message */            DEB(printk("Discarding SAVE_POINTERS message\n"));        }        outb(MSG_ACCEPT, CMD_REG);        break;    }}#ifndef IRQ_LEVstatic int irq_probe(){    int irqs, irq;    int i;        inb(INT_REG);               /* clear the interrupt register */    irqs = probe_irq_on();        /* Invalid command will cause an interrupt */    REG0;    outb(0xff, CMD_REG);        /* Wait for the interrupt to occur */    i = jiffies + WATCHDOG;    while(time_after(i, jiffies) && !(inb(STAT_REG) & 0x80))        barrier();    if (time_before_eq(i, jiffies)) {		/* Timed out, must be hardware trouble */        probe_irq_off(irqs);        return -1;    }        irq = probe_irq_off(irqs);        /* Kick the chip */    outb(CHIP_RESET, CMD_REG);    outb(SCSI_NOP, CMD_REG);    chip_init();        return irq;}#endif IRQ_LEVstatic void chip_init(){    REG1;#if USE_DMA    outb(0x00, PIO_STATUS);#else  /* USE_PIO */    outb(0x01, PIO_STATUS);#endif    outb(0x00, PIO_FLAG);        outb(C4_IMG, CONFIG4);	/* REG0; */    outb(C3_IMG, CONFIG3);    outb(C2_IMG, CONFIG2);    outb(C1_IMG, CONFIG1);        outb(0x05, CLKCONV);        /* clock conversion factor */    outb(0x9C, SRTIMOUT);       /* Selection timeout */    outb(0x05, SYNCPRD);        /* Synchronous transfer period */    outb(SYNC_MODE, SYNCOFF);   /* synchronous mode */  }__initfunc(void calc_port_addr(void)){    /* Control Register Set 0 */    TC_LSB		= (port_base+0x00);    TC_MSB		= (port_base+0x01);    SCSI_FIFO		= (port_base+0x02);    CMD_REG		= (port_base+0x03);    STAT_REG		= (port_base+0x04);    DEST_ID		= (port_base+0x04);    INT_REG		= (port_base+0x05);    SRTIMOUT		= (port_base+0x05);    SEQ_REG		= (port_base+0x06);    SYNCPRD		= (port_base+0x06);    FIFO_FLAGS		= (port_base+0x07);    SYNCOFF		= (port_base+0x07);    CONFIG1		= (port_base+0x08);    CLKCONV		= (port_base+0x09);    /* TESTREG		= (port_base+0x0A); */    CONFIG2		= (port_base+0x0B);    CONFIG3		= (port_base+0x0C);    CONFIG4		= (port_base+0x0D);    TC_HIGH		= (port_base+0x0E);    /* FIFO_BOTTOM	= (port_base+0x0F); */        /* Control Register Set 1 */    /* JUMPER_SENSE	= (port_base+0x00);*/    /* SRAM_PTR		= (port_base+0x01);*/    /* SRAM_DATA	= (port_base+0x02);*/    PIO_FIFO		= (port_base+0x04);    /* PIO_FIFO1	= (port_base+0x05);*/    /* PIO_FIFO2	= (port_base+0x06);*/    /* PIO_FIFO3	= (port_base+0x07);*/    PIO_STATUS		= (port_base+0x08);    /* ATA_CMD		= (port_base+0x09);*/    /* ATA_ERR		= (port_base+0x0A);*/    PIO_FLAG		= (port_base+0x0B);    CONFIG5		= (port_base+0x0D);    /* SIGNATURE	= (port_base+0x0E);*/    /* CONFIG6		= (port_base+0x0F);*/}#ifdef MODULE/* Eventually this will go into an include file, but this will be later */Scsi_Host_Template driver_template = NCR53c406a;#include "scsi_module.c"#endif/* * Overrides for Emacs so that we get a uniform tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */

⌨️ 快捷键说明

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