Exemple #1
0
static int
htif_enumerate(struct htif_softc *sc)
{
    char id[HTIF_ID_LEN] __aligned(HTIF_ALIGN);
    uint64_t paddr;
    uint64_t data;
    uint64_t cmd;
    int len;
    int i;

    device_printf(sc->dev, "Enumerating devices\n");

    for (i = 0; i < HTIF_NDEV; i++) {
        paddr = pmap_kextract((vm_offset_t)&id);
        data = (paddr << IDENTIFY_PADDR_SHIFT);
        data |= IDENTIFY_IDENT;

        sc->identify_id = i;
        sc->identify_done = 0;

        cmd = i;
        cmd <<= HTIF_DEV_ID_SHIFT;
        cmd |= (HTIF_CMD_IDENTIFY << HTIF_CMD_SHIFT);
        cmd |= data;

        htif_command(cmd);

        /* Do poll as interrupts are disabled yet */
        while (sc->identify_done == 0) {
            htif_handle_entry(sc);
        }

        len = strnlen(id, sizeof(id));
        if (len <= 0)
            break;

        if (bootverbose)
            printf(" %d %s\n", i, id);

        if (strncmp(id, "disk", 4) == 0)
            htif_add_device(sc, i, id, "htif_blk");
        else if (strncmp(id, "bcd", 3) == 0)
            htif_add_device(sc, i, id, "htif_console");
        else if (strncmp(id, "syscall_proxy", 13) == 0)
            htif_add_device(sc, i, id, "htif_syscall_proxy");
    }

    return (bus_generic_attach(sc->dev));
}
Exemple #2
0
static void
htif_blk_task(void *arg)
{
	struct htif_blk_request req __aligned(HTIF_ALIGN);
	struct htif_blk_softc *sc;
	uint64_t req_paddr;
	struct bio *bp;
	uint64_t paddr;
	uint64_t resp;
	uint64_t cmd;
	int i;

	sc = (struct htif_blk_softc *)arg;

	while (1) {
		HTIF_BLK_LOCK(sc);
		do {
			bp = bioq_takefirst(&sc->bio_queue);
			if (bp == NULL)
				msleep(sc, &sc->sc_mtx, PRIBIO, "jobqueue", 0);
		} while (bp == NULL);
		HTIF_BLK_UNLOCK(sc);

		if (bp->bio_cmd == BIO_READ || bp->bio_cmd == BIO_WRITE) {
			HTIF_BLK_LOCK(sc);

			rmb();
			req.offset = (bp->bio_pblkno * sc->disk->d_sectorsize);
			req.size = bp->bio_bcount;
			paddr = vtophys(bp->bio_data);
			KASSERT(paddr != 0, ("paddr is 0"));
			req.addr = paddr;
			sc->curtag++;
			req.tag = sc->curtag;

			cmd = sc->index;
			cmd <<= HTIF_DEV_ID_SHIFT;
			if (bp->bio_cmd == BIO_READ)
				cmd |= (HTIF_CMD_READ << HTIF_CMD_SHIFT);
			else
				cmd |= (HTIF_CMD_WRITE << HTIF_CMD_SHIFT);
			req_paddr = vtophys(&req);
			KASSERT(req_paddr != 0, ("req_paddr is 0"));
			cmd |= req_paddr;

			sc->cmd_done = 0;
			resp = htif_command(cmd);
			htif_blk_intr(sc, resp);

			/* Wait for interrupt */
			i = 0;
			while (sc->cmd_done == 0) {
				msleep(&sc->intr_chan, &sc->sc_mtx, PRIBIO, "intr", hz/2);

				if (i++ > 2) {
					/* TODO: try to re-issue operation on timeout ? */
					bp->bio_error = EIO;
					bp->bio_flags |= BIO_ERROR;
					disk_err(bp, "hard error", -1, 1);
					break;
				}
			}
			HTIF_BLK_UNLOCK(sc);

			biodone(bp);
		} else {
			printf("unknown op %d\n", bp->bio_cmd);
		}
	}
}