static int macscsi_pwrite(struct Scsi_Host *instance, unsigned char *src, int len) { struct NCR5380_hostdata *hostdata = shost_priv(instance); unsigned char *s; unsigned char *d; NCR5380_local_declare(); NCR5380_setup(instance); s = src; d = hostdata->pdma_base + (OUTPUT_DATA_REG << 4); /* These conditions are derived from MacOS */ while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (!(NCR5380_read(STATUS_REG) & SR_REQ) || (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))) ; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) { pr_err("Error in macscsi_pwrite\n"); return -1; } CP_MEM_TO_IO(s, d, len); if (len != 0) { pr_notice("Bus error in macscsi_pwrite\n"); return -1; } return 0; }
static void mac_scsi_reset_boot(struct Scsi_Host *instance) { unsigned long end; NCR5380_local_declare(); NCR5380_setup(instance); /* * Do a SCSI reset to clean up the bus during initialization. No messing * with the queues, interrupts, or locks necessary here. */ printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); /* get in phase */ NCR5380_write( TARGET_COMMAND_REG, PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); /* assert RST */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); /* The min. reset hold time is 25us, so 40us should be enough */ udelay( 50 ); /* reset RST and interrupt */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) barrier(); printk(KERN_INFO " done\n" ); }
/* clean up after our dma is done */ static int sun3scsi_dma_finish(int write_flag) { unsigned short count; unsigned short fifo; int ret = 0; sun3_dma_active = 0; // check to empty the fifo on a read if(!write_flag) { int tmo = 200000; /* 2 sec */ while(1) { if(dregs->csr & CSR_FIFO_EMPTY) break; if(--tmo <= 0) return 1; udelay(10); } } count = sun3scsi_dma_count(default_instance); #ifdef OLDDMA /* if we've finished a read, copy out the data we read */ if(sun3_dma_orig_addr) { /* check for residual bytes after dma end */ if(count && (NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK))) { printk("scsi%d: sun3_scsi_finish: read overrun baby... ", default_instance->host_no); printk("basr now %02x\n", NCR5380_read(BUS_AND_STATUS_REG)); ret = count; } /* copy in what we dma'd no matter what */ memcpy(sun3_dma_orig_addr, dmabuf, sun3_dma_orig_count); sun3_dma_orig_addr = NULL; } #else fifo = dregs->fifo_count; last_residual = fifo; /* empty bytes from the fifo which didn't make it */ if((!write_flag) && (count - fifo) == 2) { unsigned short data; unsigned char *vaddr; data = dregs->fifo_data; vaddr = (unsigned char *)dvma_btov(sun3_dma_orig_addr); vaddr += (sun3_dma_orig_count - fifo); vaddr[-2] = (data & 0xff00) >> 8; vaddr[-1] = (data & 0xff); }
static void __init atari_scsi_reset_boot(void) { unsigned long end; /* * Do a SCSI reset to clean up the bus during initialization. No messing * with the queues, interrupts, or locks necessary here. */ printk( "Atari SCSI: resetting the SCSI bus..." ); /* get in phase */ NCR5380_write( TARGET_COMMAND_REG, PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); /* assert RST */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); /* The min. reset hold time is 25us, so 40us should be enough */ udelay( 50 ); /* reset RST and interrupt */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); end = jiffies + AFTER_RESET_DELAY; while (time_before(jiffies, end)) barrier(); printk( " done\n" ); }
static int macscsi_pwrite (struct Scsi_Host *instance, unsigned char *src, int len) { unsigned char *s; volatile unsigned char *d; NCR5380_local_declare(); NCR5380_setup(instance); s = src; d = mac_scsi_drq; /* These conditions are derived from MacOS */ while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (!(NCR5380_read(STATUS_REG) & SR_REQ) || (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH))) ; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ)) { printk(KERN_ERR "Error in macscsi_pwrite\n"); return -1; } CP_MEM_TO_IO(s, d, len); if (len != 0) { printk(KERN_NOTICE "Bus error in macscsi_pwrite\n"); return -1; } return 0; }
static void mac_scsi_reset_boot(struct Scsi_Host *instance) { unsigned long end; NCR5380_local_declare(); NCR5380_setup(instance); printk(KERN_INFO "Macintosh SCSI: resetting the SCSI bus..." ); disable_irq(IRQ_MAC_SCSI); NCR5380_write( TARGET_COMMAND_REG, PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); udelay( 50 ); NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) barrier(); enable_irq(IRQ_MAC_SCSI); printk(KERN_INFO " done\n" ); }
static int macscsi_pread (struct Scsi_Host *instance, unsigned char *dst, int len) { unsigned char *d; volatile unsigned char *s; NCR5380_local_declare(); NCR5380_setup(instance); s = mac_scsi_drq+0x60; d = dst; while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && !(NCR5380_read(STATUS_REG) & SR_REQ)) ; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) { printk(KERN_ERR "Error in macscsi_pread\n"); return -1; } CP_IO_TO_MEM(s, d, len); if (len != 0) { printk(KERN_NOTICE "Bus error in macscsi_pread\n"); return -1; } return 0; }
static int g_NCR5380_probe_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); int irq_mask, irq; NCR5380_read(RESET_PARITY_INTERRUPT_REG); irq_mask = probe_irq_on(); g_NCR5380_trigger_irq(instance); irq = probe_irq_off(irq_mask); NCR5380_read(RESET_PARITY_INTERRUPT_REG); if (irq <= 0) return NO_IRQ; return irq; }
static void g_NCR5380_trigger_irq(struct Scsi_Host *instance) { struct NCR5380_hostdata *hostdata = shost_priv(instance); /* * An interrupt is triggered whenever BSY = false, SEL = true * and a bit set in the SELECT_ENABLE_REG is asserted on the * SCSI bus. * * Note that the bus is only driven when the phase control signals * (I/O, C/D, and MSG) match those in the TCR. */ NCR5380_write(TARGET_COMMAND_REG, PHASE_SR_TO_TCR(NCR5380_read(STATUS_REG) & PHASE_MASK)); NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask); NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | ICR_ASSERT_SEL); msleep(1); NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE); NCR5380_write(SELECT_ENABLE_REG, 0); NCR5380_write(TARGET_COMMAND_REG, 0); }
static void sun3_scsi_reset_boot(struct Scsi_Host *instance) { unsigned long end; NCR5380_local_declare(); NCR5380_setup(instance); /* * Do a SCSI reset to clean up the bus during initialization. No * messing with the queues, interrupts, or locks necessary here. */ printk( "Sun3 SCSI: resetting the SCSI bus..." ); /* switch off SCSI IRQ - catch an interrupt without IRQ bit set else */ // sun3_disable_irq( IRQ_SUN3_SCSI ); /* get in phase */ NCR5380_write( TARGET_COMMAND_REG, PHASE_SR_TO_TCR( NCR5380_read(STATUS_REG) )); /* assert RST */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_RST ); /* The min. reset hold time is 25us, so 40us should be enough */ udelay( 50 ); /* reset RST and interrupt */ NCR5380_write( INITIATOR_COMMAND_REG, ICR_BASE ); NCR5380_read( RESET_PARITY_INTERRUPT_REG ); for( end = jiffies + AFTER_RESET_DELAY; time_before(jiffies, end); ) barrier(); /* switch on SCSI IRQ again */ // sun3_enable_irq( IRQ_SUN3_SCSI ); printk( " done\n" ); }
/* clean up after our dma is done */ static int sun3scsi_dma_finish(void) { unsigned short count; int ret = 0; count = sun3scsi_dma_residual(default_instance); sun3_dma_active = 0; /* if we've finished a read, copy out the data we read */ if(sun3_dma_orig_addr) { /* check for residual bytes after dma end */ if(count && (NCR5380_read(BUS_AND_STATUS_REG) & (BASR_PHASE_MATCH | BASR_ACK))) { printk("scsi%d: sun3_scsi_finish: read overrun baby... ", default_instance->host_no); printk("basr now %02x\n", NCR5380_read(BUS_AND_STATUS_REG)); ret = count; } /* copy in what we dma'd no matter what */ memcpy(sun3_dma_orig_addr, dmabuf, sun3_dma_orig_count); sun3_dma_orig_addr = NULL; } sun3_udc_write(UDC_RESET, UDC_CSR); dregs->csr &= ~CSR_SEND; /* reset fifo */ dregs->csr &= ~CSR_FIFO; dregs->csr |= CSR_FIFO; sun3_dma_setup_done = NULL; return ret; }
static inline int macscsi_pwrite(struct NCR5380_hostdata *hostdata, unsigned char *src, int len) { unsigned char *s = src; unsigned char *d = hostdata->pdma_io + (OUTPUT_DATA_REG << 4); int n = len; int transferred; while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_DRQ | BASR_PHASE_MATCH, BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { CP_MEM_TO_IO(s, d, n); transferred = s - src - n; hostdata->pdma_residual = len - transferred; /* Target changed phase early? */ if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ, BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0) scmd_printk(KERN_ERR, hostdata->connected, "%s: !REQ and !ACK\n", __func__); if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) return 0; /* No bus error. */ if (n == 0) { if (NCR5380_poll_politely(hostdata, TARGET_COMMAND_REG, TCR_LAST_BYTE_SENT, TCR_LAST_BYTE_SENT, HZ / 64) < 0) scmd_printk(KERN_ERR, hostdata->connected, "%s: Last Byte Sent timeout\n", __func__); return 0; } dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host, "%s: bus error (%d/%d)\n", __func__, transferred, len); NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); s = src + transferred; n = len - transferred; } scmd_printk(KERN_ERR, hostdata->connected, "%s: phase mismatch or !DRQ\n", __func__); NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); return -1; }
static inline int macscsi_pread(struct NCR5380_hostdata *hostdata, unsigned char *dst, int len) { unsigned char *s = hostdata->pdma_io + (INPUT_DATA_REG << 4); unsigned char *d = dst; int n = len; int transferred; while (!NCR5380_poll_politely(hostdata, BUS_AND_STATUS_REG, BASR_DRQ | BASR_PHASE_MATCH, BASR_DRQ | BASR_PHASE_MATCH, HZ / 64)) { CP_IO_TO_MEM(s, d, n); transferred = d - dst - n; hostdata->pdma_residual = len - transferred; /* No bus error. */ if (n == 0) return 0; /* Target changed phase early? */ if (NCR5380_poll_politely2(hostdata, STATUS_REG, SR_REQ, SR_REQ, BUS_AND_STATUS_REG, BASR_ACK, BASR_ACK, HZ / 64) < 0) scmd_printk(KERN_ERR, hostdata->connected, "%s: !REQ and !ACK\n", __func__); if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) return 0; dsprintk(NDEBUG_PSEUDO_DMA, hostdata->host, "%s: bus error (%d/%d)\n", __func__, transferred, len); NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); d = dst + transferred; n = len - transferred; } scmd_printk(KERN_ERR, hostdata->connected, "%s: phase mismatch or !DRQ\n", __func__); NCR5380_dprint(NDEBUG_PSEUDO_DMA, hostdata->host); return -1; }
static inline int generic_NCR5380_pread(struct NCR5380_hostdata *hostdata, unsigned char *dst, int len) { int blocks = len / 128; int start = 0; NCR5380_write(hostdata->c400_ctl_status, CSR_BASE | CSR_TRANS_DIR); NCR5380_write(hostdata->c400_blk_cnt, blocks); while (1) { if (NCR5380_read(hostdata->c400_blk_cnt) == 0) break; if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { printk(KERN_ERR "53C400r: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); return -1; } while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; /* FIXME - no timeout */ if (hostdata->io_port && hostdata->io_width == 2) insw(hostdata->io_port + hostdata->c400_host_buf, dst + start, 64); else if (hostdata->io_port) insb(hostdata->io_port + hostdata->c400_host_buf, dst + start, 128); else memcpy_fromio(dst + start, hostdata->io + NCR53C400_host_buffer, 128); start += 128; blocks--; } if (blocks) { while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; /* FIXME - no timeout */ if (hostdata->io_port && hostdata->io_width == 2) insw(hostdata->io_port + hostdata->c400_host_buf, dst + start, 64); else if (hostdata->io_port) insb(hostdata->io_port + hostdata->c400_host_buf, dst + start, 128); else memcpy_fromio(dst + start, hostdata->io + NCR53C400_host_buffer, 128); start += 128; blocks--; } if (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ)) printk("53C400r: no 53C80 gated irq after transfer"); /* wait for 53C80 registers to be available */ while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) ; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) printk(KERN_ERR "53C400r: no end dma signal\n"); return 0; }
static inline int generic_NCR5380_pwrite(struct NCR5380_hostdata *hostdata, unsigned char *src, int len) { int blocks = len / 128; int start = 0; NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); NCR5380_write(hostdata->c400_blk_cnt, blocks); while (1) { if (NCR5380_read(hostdata->c400_ctl_status) & CSR_GATED_53C80_IRQ) { printk(KERN_ERR "53C400w: Got 53C80_IRQ start=%d, blocks=%d\n", start, blocks); return -1; } if (NCR5380_read(hostdata->c400_blk_cnt) == 0) break; while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; // FIXME - timeout if (hostdata->io_port && hostdata->io_width == 2) outsw(hostdata->io_port + hostdata->c400_host_buf, src + start, 64); else if (hostdata->io_port) outsb(hostdata->io_port + hostdata->c400_host_buf, src + start, 128); else memcpy_toio(hostdata->io + NCR53C400_host_buffer, src + start, 128); start += 128; blocks--; } if (blocks) { while (NCR5380_read(hostdata->c400_ctl_status) & CSR_HOST_BUF_NOT_RDY) ; // FIXME - no timeout if (hostdata->io_port && hostdata->io_width == 2) outsw(hostdata->io_port + hostdata->c400_host_buf, src + start, 64); else if (hostdata->io_port) outsb(hostdata->io_port + hostdata->c400_host_buf, src + start, 128); else memcpy_toio(hostdata->io + NCR53C400_host_buffer, src + start, 128); start += 128; blocks--; } /* wait for 53C80 registers to be available */ while (!(NCR5380_read(hostdata->c400_ctl_status) & CSR_53C80_REG)) { udelay(4); /* DTC436 chip hangs without this */ /* FIXME - no timeout */ } if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_END_DMA_TRANSFER)) { printk(KERN_ERR "53C400w: no end dma signal\n"); } while (!(NCR5380_read(TARGET_COMMAND_REG) & TCR_LAST_BYTE_SENT)) ; // TIMEOUT return 0; }
static __inline__ int macscsi_pread(struct Scsi_Host *instance, unsigned char *addr, int len) { volatile unsigned char *dma_io = mac_scsi_drq + 0x60; NCR5380_local_declare(); NCR5380_setup(instance); len = pdma_read_count; dprintk(NDEBUG_PSEUDO_DMA, ("scsi%d : about to pread %d bytes...", instance->host_no, len)); if(!len) return 0; counter = 0; while (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && !(NCR5380_read(STATUS_REG) & SR_REQ)) { counter++; } if (counter) printk("_%d_", (unsigned int)counter); counter = 0; if (!(NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ) && (NCR5380_read(BUS_AND_STATUS_REG) & BASR_PHASE_MATCH)) { printk(KERN_ERR "Error in macscsi_pread\n"); pdma_read_count = 0; return -1; } // m2_poll_start(); // pmu_suspend(); pdma_read_residue = len; dprintk(NDEBUG_PSEUDO_DMA, ("preading: ")); cycle_counter = 0; while(pdma_read_residue >= 1) { int status; #ifdef DRQ_INTERRUPT spin_lock_irq(&io_request_lock); #endif if(pdma_read_residue == 0) { #ifdef DRQ_INTERRUPT spin_unlock_irq(&io_request_lock); #endif break; } cycle_counter++; counter = 0; while (!((status = NCR5380_read(BUS_AND_STATUS_REG)) & BASR_DRQ)) { // pmu_poll(); counter++; if (!(status & BASR_PHASE_MATCH)) { (void) NCR5380_read(RESET_PARITY_INTERRUPT_REG); len = pdma_read_residue; pdma_read_residue = 0; #ifdef DRQ_INTERRUPT spin_unlock_irq(&io_request_lock); #endif // m2_poll_stop(); // pmu_resume(); return len; } if (!(NCR5380_read(MODE_REG) & MR_DMA_MODE)) { len = pdma_read_residue; pdma_read_residue = 0; #ifdef DRQ_INTERRUPT spin_unlock_irq(&io_request_lock); #endif // m2_poll_stop(); // pmu_resume(); return len; } // udelay(1); } *pdma_dst++ = in_8((void *)dma_io); pdma_read_residue -= 1; average += counter; #ifdef DRQ_INTERRUPT spin_unlock_irq(&io_request_lock); #endif // while (NCR5380_read(BUS_AND_STATUS_REG) & BASR_DRQ); } average /= cycle_counter; // printk(".%d.\n", average); average = 0; len = pdma_read_residue; pdma_read_residue = 0; // m2_poll_stop(); // pmu_resume(); return len; }
static int generic_NCR5380_init_one(struct scsi_host_template *tpnt, struct device *pdev, int base, int irq, int board) { bool is_pmio = base <= 0xffff; int ret; int flags = 0; unsigned int *ports = NULL; u8 *magic = NULL; int i; int port_idx = -1; unsigned long region_size; struct Scsi_Host *instance; struct NCR5380_hostdata *hostdata; u8 __iomem *iomem; switch (board) { case BOARD_NCR5380: flags = FLAG_NO_PSEUDO_DMA | FLAG_DMA_FIXUP; break; case BOARD_NCR53C400A: ports = ncr_53c400a_ports; magic = ncr_53c400a_magic; break; case BOARD_HP_C2502: ports = ncr_53c400a_ports; magic = hp_c2502_magic; break; case BOARD_DTC3181E: ports = dtc_3181e_ports; magic = ncr_53c400a_magic; break; } if (is_pmio && ports && magic) { /* wakeup sequence for the NCR53C400A and DTC3181E */ /* Disable the adapter and look for a free io port */ magic_configure(-1, 0, magic); region_size = 16; if (base) for (i = 0; ports[i]; i++) { if (base == ports[i]) { /* index found */ if (!request_region(ports[i], region_size, "ncr53c80")) return -EBUSY; break; } } else for (i = 0; ports[i]; i++) { if (!request_region(ports[i], region_size, "ncr53c80")) continue; if (inb(ports[i]) == 0xff) break; release_region(ports[i], region_size); } if (ports[i]) { /* At this point we have our region reserved */ magic_configure(i, 0, magic); /* no IRQ yet */ base = ports[i]; outb(0xc0, base + 9); if (inb(base + 9) != 0x80) { ret = -ENODEV; goto out_release; } port_idx = i; } else return -EINVAL; } else if (is_pmio) { /* NCR5380 - no configuration, just grab */ region_size = 8; if (!base || !request_region(base, region_size, "ncr5380")) return -EBUSY; } else { /* MMIO */ region_size = NCR53C400_region_size; if (!request_mem_region(base, region_size, "ncr5380")) return -EBUSY; } if (is_pmio) iomem = ioport_map(base, region_size); else iomem = ioremap(base, region_size); if (!iomem) { ret = -ENOMEM; goto out_release; } instance = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata)); if (instance == NULL) { ret = -ENOMEM; goto out_unmap; } hostdata = shost_priv(instance); hostdata->io = iomem; hostdata->region_size = region_size; if (is_pmio) { hostdata->io_port = base; hostdata->io_width = 1; /* 8-bit PDMA by default */ hostdata->offset = 0; /* * On NCR53C400 boards, NCR5380 registers are mapped 8 past * the base address. */ switch (board) { case BOARD_NCR53C400: hostdata->io_port += 8; hostdata->c400_ctl_status = 0; hostdata->c400_blk_cnt = 1; hostdata->c400_host_buf = 4; break; case BOARD_DTC3181E: hostdata->io_width = 2; /* 16-bit PDMA */ /* fall through */ case BOARD_NCR53C400A: case BOARD_HP_C2502: hostdata->c400_ctl_status = 9; hostdata->c400_blk_cnt = 10; hostdata->c400_host_buf = 8; break; } } else { hostdata->base = base; hostdata->offset = NCR53C400_mem_base; switch (board) { case BOARD_NCR53C400: hostdata->c400_ctl_status = 0x100; hostdata->c400_blk_cnt = 0x101; hostdata->c400_host_buf = 0x104; break; case BOARD_DTC3181E: case BOARD_NCR53C400A: case BOARD_HP_C2502: pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); ret = -EINVAL; goto out_unregister; } } /* Check for vacant slot */ NCR5380_write(MODE_REG, 0); if (NCR5380_read(MODE_REG) != 0) { ret = -ENODEV; goto out_unregister; } ret = NCR5380_init(instance, flags | FLAG_LATE_DMA_SETUP); if (ret) goto out_unregister; switch (board) { case BOARD_NCR53C400: case BOARD_DTC3181E: case BOARD_NCR53C400A: case BOARD_HP_C2502: NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); } NCR5380_maybe_reset_bus(instance); /* Compatibility with documented NCR5380 kernel parameters */ if (irq == 255 || irq == 0) irq = NO_IRQ; else if (irq == -1) irq = IRQ_AUTO; if (board == BOARD_HP_C2502) { int *irq_table = hp_c2502_irqs; int board_irq = -1; switch (irq) { case NO_IRQ: board_irq = 0; break; case IRQ_AUTO: board_irq = legacy_find_free_irq(irq_table); break; default: while (*irq_table != -1) if (*irq_table++ == irq) board_irq = irq; } if (board_irq <= 0) { board_irq = 0; irq = NO_IRQ; } magic_configure(port_idx, board_irq, magic); } if (irq == IRQ_AUTO) { instance->irq = g_NCR5380_probe_irq(instance); if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq detected\n"); } else { instance->irq = irq; if (instance->irq == NO_IRQ) shost_printk(KERN_INFO, instance, "no irq provided\n"); } if (instance->irq != NO_IRQ) { if (request_irq(instance->irq, generic_NCR5380_intr, 0, "NCR5380", instance)) { instance->irq = NO_IRQ; shost_printk(KERN_INFO, instance, "irq %d denied\n", instance->irq); } else { shost_printk(KERN_INFO, instance, "irq %d acquired\n", instance->irq); } } ret = scsi_add_host(instance, pdev); if (ret) goto out_free_irq; scsi_scan_host(instance); dev_set_drvdata(pdev, instance); return 0; out_free_irq: if (instance->irq != NO_IRQ) free_irq(instance->irq, instance); NCR5380_exit(instance); out_unregister: scsi_host_put(instance); out_unmap: iounmap(iomem); out_release: if (is_pmio) release_region(base, region_size); else release_mem_region(base, region_size); return ret; }