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 = dvma_alloc(virt_to_phys(sg[sz].addr), sg[sz].len); sz--; } sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dvma_address); }
/* * Open the PROM device. * Return netif ptr on success. */ struct devdata * netif_init(void *aux) { struct devdata *dd = &netif_devdata; struct saioreq *si; struct bootparam *bp; int error; /* * Setup our part of the saioreq. * (determines what gets opened) */ si = &dd->dd_si; memset(si, 0, sizeof(*si)); bp = *romVectorPtr->bootParam; si->si_boottab = bp->bootDevice; si->si_ctlr = bp->ctlrNum; si->si_unit = bp->unitNum; si->si_boff = bp->partNum; #ifdef NETIF_DEBUG if (debug) printf("netif_init: calling prom_iopen\n"); #endif /* * Note: Sun PROMs will do RARP on open, but does not tell * you the IP address it gets, so it is just noise to us... */ if ((error = prom_iopen(si)) != 0) { printf("netif_init: prom_iopen, error=%d\n", error); return (NULL); } if (si->si_sif == NULL) { printf("netif_init: not a network device\n"); prom_iclose(si); return (NULL); } /* Allocate the transmit/receive buffers. */ if (dd->rbuf == NULL) { dd->rbuf_len = PKT_BUF_SIZE; dd->rbuf = dvma_alloc(dd->rbuf_len); } if (dd->tbuf == NULL) { dd->tbuf_len = PKT_BUF_SIZE; dd->tbuf = dvma_alloc(dd->tbuf_len); } if ((dd->rbuf == NULL) || (dd->tbuf == NULL)) panic("netif_init: malloc failed"); #ifdef NETIF_DEBUG if (debug) printf("netif_init: rbuf=0x%x, tbuf=0x%x\n", dd->rbuf, dd->tbuf); #endif /* Record our ethernet address. */ netif_getether(si->si_sif, dd->dd_myea); dd->dd_opens = 0; return(dd); }
/* Detecting ESP chips on the machine. This is the simple and easy * version. */ int sun3x_esp_detect(Scsi_Host_Template *tpnt) { struct NCR_ESP *esp; struct ConfigDev *esp_dev; esp_dev = 0; esp = esp_allocate(tpnt, (void *) esp_dev); /* Do command transfer with DMA */ esp->do_pio_cmds = 0; /* 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 = &dma_barrier; esp->dma_drain = &dma_drain; esp->dma_irq_entry = &dma_ints_off; esp->dma_irq_exit = &dma_ints_on; esp->dma_led_on = 0; esp->dma_led_off = 0; esp->dma_poll = &dma_poll; esp->dma_reset = &dma_reset; /* 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 = 20000000; esp->eregs = (struct ESP_regs *)(SUN3X_ESP_BASE); esp->dregs = (void *)SUN3X_ESP_DMA; esp->esp_command = (volatile unsigned char *)cmd_buffer; esp->esp_command_dvma = dvma_alloc(virt_to_phys(cmd_buffer), sizeof (cmd_buffer)); esp->irq = 2; request_irq(esp->irq, esp_intr, SA_INTERRUPT, "SUN3X SCSI", NULL); esp->scsi_id = 7; 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; }
static void dma_mmu_get_scsi_one (struct NCR_ESP *esp, Scsi_Cmnd *sp) { sp->SCp.have_data_in = dvma_alloc(virt_to_phys(sp->SCp.buffer), sp->SCp.this_residual); sp->SCp.ptr = (char *)((unsigned long)sp->SCp.have_data_in); }
int ob_esp_init(unsigned int slot, uint64_t base, unsigned long espoffset, unsigned long dmaoffset) { int id, diskcount = 0, cdcount = 0, *counter_ptr; char nodebuff[256], aliasbuff[256]; esp_private_t *esp; unsigned int i; DPRINTF("Initializing SCSI..."); esp = malloc(sizeof(esp_private_t)); if (!esp) { DPRINTF("Can't allocate ESP private structure\n"); return -1; } global_esp = esp; if (espdma_init(slot, base, dmaoffset, &esp->espdma) != 0) { return -1; } /* Get the IO region */ esp->ll = (void *)ofmem_map_io(base + (uint64_t)espoffset, sizeof(struct esp_regs)); if (esp->ll == NULL) { DPRINTF("Can't map ESP registers\n"); return -1; } esp->buffer = (void *)dvma_alloc(BUFSIZE, &esp->buffer_dvma); if (!esp->buffer || !esp->buffer_dvma) { DPRINTF("Can't get a DVMA buffer\n"); return -1; } // Chip reset esp->ll->regs[ESP_CMD] = ESP_CMD_RC; DPRINTF("ESP at 0x%lx, buffer va 0x%lx dva 0x%lx\n", (unsigned long)esp, (unsigned long)esp->buffer, (unsigned long)esp->buffer_dvma); DPRINTF("done\n"); DPRINTF("Initializing SCSI devices..."); for (id = 0; id < 8; id++) { esp->sd[id].id = id; if (!inquiry(esp, &esp->sd[id])) { DPRINTF("Unit %d not present\n", id); continue; } /* Clear Unit Attention condition from reset */ for (i = 0; i < 5; i++) { if (test_unit_ready(esp, &esp->sd[id])) { break; } } if (i == 5) { DPRINTF("Unit %d present but won't become ready\n", id); continue; } DPRINTF("Unit %d present\n", id); read_capacity(esp, &esp->sd[id]); #ifdef CONFIG_DEBUG_ESP dump_drive(&esp->sd[id]); #endif } REGISTER_NAMED_NODE(ob_esp, "/iommu/sbus/espdma/esp"); device_end(); /* set reg */ push_str("/iommu/sbus/espdma/esp"); fword("find-device"); PUSH(slot); fword("encode-int"); PUSH(espoffset); fword("encode-int"); fword("encode+"); PUSH(0x00000010); fword("encode-int"); fword("encode+"); push_str("reg"); fword("property"); PUSH(0x02625a00); fword("encode-int"); push_str("clock-frequency"); fword("property"); for (id = 0; id < 8; id++) { if (!esp->sd[id].present) continue; push_str("/iommu/sbus/espdma/esp"); fword("find-device"); fword("new-device"); push_str("sd"); fword("device-name"); push_str("block"); fword("device-type"); fword("is-deblocker"); PUSH(id); fword("encode-int"); PUSH(0); fword("encode-int"); fword("encode+"); push_str("reg"); fword("property"); fword("finish-device"); snprintf(nodebuff, sizeof(nodebuff), "/iommu/sbus/espdma/esp/sd@%d,0", id); REGISTER_NODE_METHODS(ob_sd, nodebuff); if (esp->sd[id].media == TYPE_ROM) { counter_ptr = &cdcount; } else { counter_ptr = &diskcount; } if (*counter_ptr == 0) { add_alias(nodebuff, esp->sd[id].media_str[0]); add_alias(nodebuff, esp->sd[id].media_str[1]); } snprintf(aliasbuff, sizeof(aliasbuff), "%s%d", esp->sd[id].media_str[0], *counter_ptr); add_alias(nodebuff, aliasbuff); snprintf(aliasbuff, sizeof(aliasbuff), "%s%d", esp->sd[id].media_str[1], *counter_ptr); add_alias(nodebuff, aliasbuff); snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)", id); add_alias(nodebuff, aliasbuff); snprintf(aliasbuff, sizeof(aliasbuff), "sd(0,%d,0)@0,0", id); add_alias(nodebuff, aliasbuff); (*counter_ptr)++; } DPRINTF("done\n"); return 0; }