/* 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); // addr = sun3_dvma_page((unsigned long)data, (unsigned long)dmabuf); addr = (void *)dvma_map_vme((unsigned long) data, count); sun3_dma_orig_addr = addr; sun3_dma_orig_count = count; #ifdef SUN3_SCSI_DEBUG printk("scsi: dma_setup addr %p count %x\n", addr, count); #endif // dregs->fifo_count = 0; #if 0 /* 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; /* reset fifo */ // dregs->csr &= ~CSR_FIFO; // dregs->csr |= CSR_FIFO; 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; #ifdef SUN3_SCSI_DEBUG printk("scsi: dma_setup done csr %x\n", dregs->csr); #endif 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; }