예제 #1
0
파일: sun3x_esp.c 프로젝트: davidbau/davej
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);
}
예제 #2
0
/*
 * 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);
}
예제 #3
0
파일: sun3x_esp.c 프로젝트: davidbau/davej
/* 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;
}
예제 #4
0
파일: sun3x_esp.c 프로젝트: davidbau/davej
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);
}
예제 #5
0
파일: esp.c 프로젝트: xHypervisor/WinQEMU
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;
}