static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) { sun3_udc_write(UDC_CHN_START, UDC_CSR); return 0; }
static inline int sun3scsi_dma_start(unsigned long count, unsigned char *data) { #ifdef SUN3_SCSI_VME unsigned short csr; csr = dregs->csr; dregs->dma_count_hi = (sun3_dma_orig_count >> 16); dregs->dma_count_lo = (sun3_dma_orig_count & 0xffff); dregs->fifo_count_hi = (sun3_dma_orig_count >> 16); dregs->fifo_count = (sun3_dma_orig_count & 0xffff); /* if(!(csr & CSR_DMA_ENABLE)) * dregs->csr |= CSR_DMA_ENABLE; */ #else sun3_udc_write(UDC_CHN_START, UDC_CSR); #endif return 0; }
/* 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; }
/* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) { if(write_flag) memcpy(dmabuf, data, count); else { sun3_dma_orig_addr = data; sun3_dma_orig_count = count; } dregs->fifo_count = 0; sun3_udc_write(UDC_RESET, UDC_CSR); /* reset fifo */ dregs->csr &= ~CSR_FIFO; dregs->csr |= CSR_FIFO; /* set direction */ if(write_flag) dregs->csr |= CSR_SEND; else dregs->csr &= ~CSR_SEND; /* byte count for fifo */ dregs->fifo_count = count; sun3_udc_write(UDC_RESET, UDC_CSR); /* reset fifo */ dregs->csr &= ~CSR_FIFO; dregs->csr |= CSR_FIFO; if(dregs->fifo_count != count) { printk("scsi%d: fifo_mismatch %04x not %04x\n", default_instance->host_no, dregs->fifo_count, (unsigned int) count); NCR5380_print(default_instance); } /* setup udc */ udc_regs->addr_hi = ((sun3_dvma_vtop(dmabuf) & 0xff0000) >> 8); udc_regs->addr_lo = (sun3_dvma_vtop(dmabuf) & 0xffff); udc_regs->count = count/2; /* count in words */ udc_regs->mode_hi = UDC_MODE_HIWORD; if(write_flag) { if(count & 1) udc_regs->count++; udc_regs->mode_lo = UDC_MODE_LSEND; udc_regs->rsel = UDC_RSEL_SEND; } else { udc_regs->mode_lo = UDC_MODE_LRECV; udc_regs->rsel = UDC_RSEL_RECV; } /* announce location of regs block */ sun3_udc_write(((sun3_dvma_vtop(udc_regs) & 0xff0000) >> 8), UDC_CHN_HI); sun3_udc_write((sun3_dvma_vtop(udc_regs) & 0xffff), UDC_CHN_LO); /* set dma master on */ sun3_udc_write(0xd, UDC_MODE); /* interrupt enable */ sun3_udc_write(UDC_INT_ENABLE, UDC_CSR); return count; }
/* sun3scsi_dma_setup() -- initialize the dma controller for a read/write */ static unsigned long sun3scsi_dma_setup(void *data, unsigned long count, int write_flag) { void *addr; if(sun3_dma_orig_addr != NULL) dvma_unmap(sun3_dma_orig_addr); #ifdef SUN3_SCSI_VME addr = (void *)dvma_map_vme((unsigned long) data, count); #else addr = (void *)dvma_map((unsigned long) data, count); #endif sun3_dma_orig_addr = addr; sun3_dma_orig_count = count; #ifndef SUN3_SCSI_VME dregs->fifo_count = 0; sun3_udc_write(UDC_RESET, UDC_CSR); /* reset fifo */ dregs->csr &= ~CSR_FIFO; dregs->csr |= CSR_FIFO; #endif /* set direction */ if(write_flag) dregs->csr |= CSR_SEND; else dregs->csr &= ~CSR_SEND; #ifdef SUN3_SCSI_VME dregs->csr |= CSR_PACK_ENABLE; dregs->dma_addr_hi = ((unsigned long)addr >> 16); dregs->dma_addr_lo = ((unsigned long)addr & 0xffff); dregs->dma_count_hi = 0; dregs->dma_count_lo = 0; dregs->fifo_count_hi = 0; dregs->fifo_count = 0; #else /* byte count for fifo */ dregs->fifo_count = count; sun3_udc_write(UDC_RESET, UDC_CSR); /* reset fifo */ dregs->csr &= ~CSR_FIFO; dregs->csr |= CSR_FIFO; if(dregs->fifo_count != count) { printk("scsi%d: fifo_mismatch %04x not %04x\n", default_instance->host_no, dregs->fifo_count, (unsigned int) count); NCR5380_dprint(NDEBUG_DMA, default_instance); } /* setup udc */ udc_regs->addr_hi = (((unsigned long)(addr) & 0xff0000) >> 8); udc_regs->addr_lo = ((unsigned long)(addr) & 0xffff); udc_regs->count = count/2; /* count in words */ udc_regs->mode_hi = UDC_MODE_HIWORD; if(write_flag) { if(count & 1) udc_regs->count++; udc_regs->mode_lo = UDC_MODE_LSEND; udc_regs->rsel = UDC_RSEL_SEND; } else { udc_regs->mode_lo = UDC_MODE_LRECV; udc_regs->rsel = UDC_RSEL_RECV; } /* announce location of regs block */ sun3_udc_write(((dvma_vtob(udc_regs) & 0xff0000) >> 8), UDC_CHN_HI); sun3_udc_write((dvma_vtob(udc_regs) & 0xffff), UDC_CHN_LO); /* set dma master on */ sun3_udc_write(0xd, UDC_MODE); /* interrupt enable */ sun3_udc_write(UDC_INT_ENABLE, UDC_CSR); #endif return count; }