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

📄 ncr53c406a.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 3 页
字号:
    REG1;    while (reqlen) {        i = inb(PIO_STATUS);        /*    VDEB(printk("pio_status=%x\n", i)); */        if (i & 0x80)             return 0;                switch( i & 0x1e ) {        default:        case 0x10:            len=0; break;        case 0x0:            len=1; break;        case 0x8:            len=42; break;        case 0xc:            len=84; break;        case 0xe:            len=128; break;        }                if ((i & 0x40) && len == 0) { /* fifo empty and interrupt occurred */            return 0;        }                if (len) {            if( len > reqlen )                 len = reqlen;                        save_flags(flags);            cli();            if( fast_pio && len > 3 ) {                 insl(PIO_FIFO,request,len>>2);                 request += len & 0xfc;                 reqlen -= len & 0xfc;             }             else {                 while(len--) {                    *request++ = inb(PIO_FIFO);                    reqlen--;                }            }            restore_flags(flags);        }    }    return 0;}static __inline__ int NCR53c406a_pio_write(unsigned char *request,					   unsigned int reqlen) {    int	i = 0;    int	len;	/* current scsi fifo size */    unsigned long flags = 0;        REG1;    while (reqlen && !(i&0x40)) {        i = inb(PIO_STATUS);        /*    VDEB(printk("pio_status=%x\n", i)); */        if (i & 0x80)		/* error */            return 0;                switch( i & 0x1e ) {        case 0x10:            len=128; break;        case 0x0:            len=84; break;        case 0x8:            len=42; break;        case 0xc:            len=1; break;        default:        case 0xe:            len=0; break;        }                if (len) {            if( len > reqlen )                 len = reqlen;                        save_flags(flags);            cli();            if( fast_pio && len > 3 ) {                 outsl(PIO_FIFO,request,len>>2);                 request += len & 0xfc;                 reqlen -= len & 0xfc;             }             else {                 while(len--) {                    outb(*request++, PIO_FIFO);                    reqlen--;                }            }            restore_flags(flags);        }    }    return 0;}#endif USE_PIOint NCR53c406a_detect(Scsi_Host_Template * tpnt){    struct Scsi_Host *shpnt;#ifndef PORT_BASE    int i;#endif    #if USE_BIOS    int ii, jj;    bios_base = 0;    /* look for a valid signature */    for( ii=0; ii < ADDRESS_COUNT && !bios_base; ii++)        for( jj=0; (jj < SIGNATURE_COUNT) && !bios_base; jj++)            if(!memcmp((void *) addresses[ii]+signatures[jj].sig_offset,                       (void *) signatures[jj].signature,                       (int) signatures[jj].sig_length))                bios_base=addresses[ii];        if(!bios_base){        printk("NCR53c406a: BIOS signature not found\n");        return 0;    }        DEB(printk("NCR53c406a BIOS found at %X\n", (unsigned int) bios_base););#endif USE_BIOS    #ifdef PORT_BASE    if (check_region(port_base, 0x10)) /* ports already snatched */        port_base = 0;    #else  /* autodetect */    if (port_base) {		/* LILO override */        if (check_region(port_base, 0x10))            port_base = 0;    }    else {        for(i=0;  i<PORT_COUNT && !port_base; i++){            if(check_region(ports[i], 0x10)){                DEB(printk("NCR53c406a: port %x in use\n", ports[i]));            }            else {                VDEB(printk("NCR53c406a: port %x available\n", ports[i]));                outb(C5_IMG, ports[i] + 0x0d); /* reg set 1 */                if(   (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7                   && (inb(ports[i] + 0x0e) ^ inb(ports[i] + 0x0e)) == 7                   && (inb(ports[i] + 0x0e) & 0xf8) == 0x58 ) {                    VDEB(printk("NCR53c406a: Sig register valid\n"));                    VDEB(printk("port_base=%x\n", port_base));                    port_base = ports[i];                }            }        }    }#endif PORT_BASE        if(!port_base){		/* no ports found */        printk("NCR53c406a: no available ports found\n");        return 0;    }        DEB(printk("NCR53c406a detected\n"));        calc_port_addr();    chip_init();    #ifndef IRQ_LEV    if (irq_level < 0) {		/* LILO override if >= 0*/        irq_level=irq_probe();        if (irq_level < 0) {		/* Trouble */            printk("NCR53c406a: IRQ problem, irq_level=%d, giving up\n", irq_level);            return 0;        }    }#endif        DEB(printk("NCR53c406a: using port_base %x\n", port_base));    request_region(port_base, 0x10, "NCR53c406a");        if(irq_level > 0) {        if(request_irq(irq_level, NCR53c406a_intr, 0, "NCR53c406a", NULL)){            printk("NCR53c406a: unable to allocate IRQ %d\n", irq_level);            return 0;        }        tpnt->can_queue = 1;        DEB(printk("NCR53c406a: allocated IRQ %d\n", irq_level));    }    else if (irq_level == 0) {        tpnt->can_queue = 0;        DEB(printk("NCR53c406a: No interrupts detected\n"));#if USE_DMA        printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");        return 0;#endif USE_DMA    }    else {        DEB(printk("NCR53c406a: Shouldn't get here!\n"));        return 0;    }    #if USE_DMA    dma_chan = DMA_CHAN;    if(request_dma(dma_chan, "NCR53c406a") != 0){        printk("NCR53c406a: unable to allocate DMA channel %d\n", dma_chan);        return 0;    }        DEB(printk("Allocated DMA channel %d\n", dma_chan));#endif USE_DMA         tpnt->present = 1;    tpnt->proc_dir = &proc_scsi_NCR53c406a;        shpnt = scsi_register(tpnt, 0);    shpnt->irq = irq_level;    shpnt->io_port = port_base;    shpnt->n_io_port = 0x10;#if USE_DMA    shpnt->dma = dma_chan;#endif    #if USE_DMA    sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, DMA channel %d.",             port_base, irq_level, dma_chan);#else    sprintf(info_msg, "NCR53c406a at 0x%x, IRQ %d, %s PIO mode.",             port_base, irq_level, fast_pio ? "fast" : "slow");#endif        return (tpnt->present);}/* called from init/main.c */void NCR53c406a_setup(char *str, int *ints){    static size_t setup_idx = 0;    size_t i;        DEB(printk("NCR53c406a: Setup called\n"););        if (setup_idx >= PORT_COUNT - 1) {        printk("NCR53c406a: Setup called too many times.  Bad LILO params?\n");        return;    }    if (ints[0] < 1 || ints[0] > 3) {        printk("NCR53c406a: Malformed command line\n");        printk("NCR53c406a: Usage: ncr53c406a=<PORTBASE>[,<IRQ>[,<FASTPIO>]]\n");        return;    }    for (i = 0; i < PORT_COUNT && !port_base; i++)        if (ports[i] == ints[1]) {            port_base = ints[1];            DEB(printk("NCR53c406a: Specified port_base 0x%X\n", port_base);)        }    if (!port_base) {        printk("NCR53c406a: Invalid PORTBASE 0x%X specified\n", ints[1]);        return;    }        if (ints[0] > 1) {        if (ints[2] == 0) {            irq_level = 0;            DEB(printk("NCR53c406a: Specified irq %d\n", irq_level);)        }        else            for (i = 0; i < INTR_COUNT && irq_level < 0; i++)                if (intrs[i] == ints[2]) {                    irq_level = ints[2];                    DEB(printk("NCR53c406a: Specified irq %d\n", port_base);)                }        if (irq_level < 0)            printk("NCR53c406a: Invalid IRQ %d specified\n", ints[2]);    }        if (ints[0] > 2)        fast_pio = ints[3];        DEB(printk("NCR53c406a: port_base=0x%X, irq=%d, fast_pio=%d\n",                port_base, irq_level, fast_pio);)}const char* NCR53c406a_info(struct Scsi_Host *SChost){    DEB(printk("NCR53c406a_info called\n"));    return (info_msg);}static void internal_done(Scsi_Cmnd *SCpnt) {    internal_done_errcode = SCpnt->result;    ++internal_done_flag;}static void wait_intr() {    int i = jiffies + WATCHDOG;        while(i>jiffies && !(inb(STAT_REG)&0xe0)) /* wait for a pseudo-interrupt */        barrier();        if (i <= jiffies) {		/* Timed out */        rtrc(0);        current_SC->result = DID_TIME_OUT << 16;        current_SC->SCp.phase = idle;        current_SC->scsi_done(current_SC);        return;    }        NCR53c406a_intr(0, NULL, NULL);}int NCR53c406a_command(Scsi_Cmnd *SCpnt){    DEB(printk("NCR53c406a_command called\n"));    NCR53c406a_queue(SCpnt, internal_done);    if(irq_level)        while (!internal_done_flag);    else                        /* interrupts not supported */        while (!internal_done_flag)            wait_intr();        internal_done_flag = 0;    return internal_done_errcode;}int NCR53c406a_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)){    int i;    unsigned long flags = 0;    VDEB(printk("NCR53c406a_queue called\n"));    DEB(printk("cmd=%02x, cmd_len=%02x, target=%02x, lun=%02x, bufflen=%d\n",                SCpnt->cmnd[0],               SCpnt->cmd_len,               SCpnt->target,                SCpnt->lun,                 SCpnt->request_bufflen));    #if 0    VDEB(for(i=0; i<SCpnt->cmd_len; i++)         printk("cmd[%d]=%02x  ", i, SCpnt->cmnd[i]));    VDEB(printk("\n"));#endif        current_SC = SCpnt;    current_SC->scsi_done = done;    current_SC->SCp.phase = command_ph;    current_SC->SCp.Status = 0;    current_SC->SCp.Message = 0;        save_flags(flags);    cli();    REG0;    outb(SCpnt->target, DEST_ID); /* set destination */    outb(FLUSH_FIFO, CMD_REG);	/* reset the fifos */        for(i=0; i<SCpnt->cmd_len; i++){        outb(SCpnt->cmnd[i], SCSI_FIFO);    }    outb(SELECT_NO_ATN, CMD_REG);    restore_flags(flags);    

⌨️ 快捷键说明

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