static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp) { int sz = sp->SCp.buffers_residual; struct mmu_sglist *sg = (struct mmu_sglist *) sp->SCp.buffer; while (sz >= 0) { sg[sz].dvma_addr = vdma_alloc(PHYSADDR(sg[sz].addr), sg[sz].len); sz--; } sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address); }
static unsigned long jazz_fd_dma_mem_alloc(unsigned long size) { unsigned long mem; mem = __get_dma_pages(GFP_KERNEL, get_order(size)); if(!mem) return 0; vdma_alloc(PHYSADDR(mem), size); /* XXX error checking */ return mem; }
static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, struct scsi_cmnd *sp) { int sz = sp->SCp.buffers_residual; struct scatterlist *sg = (struct scatterlist *) sp->SCp.buffer; while (sz >= 0) { sg[sz].dma_address = vdma_alloc(CPHYSADDR(page_address(sg[sz].page) + sg[sz].offset), sg[sz].length); sz--; } sp->SCp.ptr=(char *)(sp->SCp.buffer->dma_address); }
/* * transmit packet */ static int sonic_send_packet(struct sk_buff *skb, struct net_device *dev) { struct sonic_local *lp = (struct sonic_local *)dev->priv; unsigned int base_addr = dev->base_addr; unsigned int laddr; int entry,length; if (sonic_debug > 2) printk("sonic_send_packet: skb=%p, dev=%p\n",skb,dev); if (dev->tbusy) { int tickssofar = jiffies - dev->trans_start; /* If we get here, some higher level has decided we are broken. There should really be a "kick me" function call instead. */ if (sonic_debug > 1) printk("sonic_send_packet: called with dev->tbusy = 1 !\n"); if (tickssofar < 5) return 1; printk("%s: transmit timed out.\n", dev->name); /* Try to restart the adaptor. */ sonic_init(dev); dev->tbusy=0; dev->trans_start = jiffies; } /* * Block a timer-based transmit from overlapping. This could better be * done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) { printk("%s: Transmitter access conflict.\n", dev->name); return 1; } /* * Map the packet data into the logical DMA address space */ if ((laddr = vdma_alloc(PHYSADDR(skb->data),skb->len)) == ~0UL) { printk("%s: no VDMA entry for transmit available.\n",dev->name); dev_kfree_skb(skb); dev->tbusy = 0; return 1; } entry = lp->cur_tx & SONIC_TDS_MASK; lp->tx_laddr[entry] = laddr; lp->tx_skb[entry] = skb; length = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; flush_cache_all(); /* * Setup the transmit descriptor and issue the transmit command. */ lp->tda[entry].tx_status = 0; /* clear status */ lp->tda[entry].tx_frag_count = 1; /* single fragment */ lp->tda[entry].tx_pktsize = length; /* length of packet */ lp->tda[entry].tx_frag_ptr_l = laddr & 0xffff; lp->tda[entry].tx_frag_ptr_h = laddr >> 16; lp->tda[entry].tx_frag_size = length; lp->cur_tx++; lp->stats.tx_bytes += length; if (sonic_debug > 2) printk("sonic_send_packet: issueing Tx command\n"); SONIC_WRITE(SONIC_CMD,SONIC_CR_TXP); dev->trans_start = jiffies; if (lp->cur_tx < lp->dirty_tx + SONIC_NUM_TDS) dev->tbusy = 0; else lp->tx_full = 1; return 0; }
/***************************************************************** Detection */ int jazz_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; struct ConfigDev *esp_dev; /* * first assumption it is there:-) */ if (1) { esp_dev = 0; esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with programmed I/O */ esp->do_pio_cmds = 1; /* Required functions */ esp->dma_bytes_sent = &dma_bytes_sent; esp->dma_can_transfer = &dma_can_transfer; esp->dma_dump_state = &dma_dump_state; esp->dma_init_read = &dma_init_read; esp->dma_init_write = &dma_init_write; esp->dma_ints_off = &dma_ints_off; esp->dma_ints_on = &dma_ints_on; esp->dma_irq_p = &dma_irq_p; esp->dma_ports_p = &dma_ports_p; esp->dma_setup = &dma_setup; /* Optional functions */ esp->dma_barrier = 0; esp->dma_drain = 0; esp->dma_invalidate = 0; esp->dma_irq_entry = 0; esp->dma_irq_exit = 0; esp->dma_poll = 0; esp->dma_reset = 0; esp->dma_led_off = &dma_led_off; esp->dma_led_on = &dma_led_on; /* virtual DMA functions */ esp->dma_mmu_get_scsi_one = &dma_mmu_get_scsi_one; esp->dma_mmu_get_scsi_sgl = &dma_mmu_get_scsi_sgl; esp->dma_mmu_release_scsi_one = &dma_mmu_release_scsi_one; esp->dma_mmu_release_scsi_sgl = &dma_mmu_release_scsi_sgl; esp->dma_advance_sg = &dma_advance_sg; /* SCSI chip speed */ esp->cfreq = 40000000; /* * we don't give the address of DMA channel, but the number * of DMA channel, so we can use the jazz DMA functions * */ esp->dregs = JAZZ_SCSI_DMA; /* ESP register base */ esp->eregs = (struct ESP_regs *)(JAZZ_SCSI_BASE); /* Set the command buffer */ esp->esp_command = (volatile unsigned char *)cmd_buffer; /* get virtual dma address for command buffer */ esp->esp_command_dvma = vdma_alloc(PHYSADDR(cmd_buffer), sizeof (cmd_buffer)); esp->irq = JAZZ_SCSI_IRQ; request_irq(JAZZ_SCSI_IRQ, esp_intr, SA_INTERRUPT, "JAZZ SCSI", esp->ehost); /* * FIXME, look if the scsi id is available from NVRAM */ esp->scsi_id = 7; /* Check for differential SCSI-bus */ /* What is this stuff? */ esp->diff = 0; esp_initialize(esp); printk("ESP: Total of %d ESP hosts found, %d actually in use.\n", nesps,esps_in_use); esps_running = esps_in_use; return esps_in_use; } return 0; }
static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) { sp->SCp.have_data_in = vdma_alloc(PHYSADDR(sp->SCp.buffer), sp->SCp.this_residual); sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); }