int rump_shmif_create(const char *path, int *ifnum) { struct shmif_sc *sc; vmem_addr_t t; int unit, error; int memfd = -1; /* XXXgcc */ if (path) { error = rumpuser_open(path, RUMPUSER_OPEN_RDWR | RUMPUSER_OPEN_CREATE, &memfd); if (error) return error; } error = vmem_xalloc(shmif_units, 1, 0, 0, 0, VMEM_ADDR_MIN, VMEM_ADDR_MAX, VM_INSTANTFIT | VM_SLEEP, &t); if (error != 0) { if (path) rumpuser_close(memfd); return error; } unit = t - 1; if ((error = allocif(unit, &sc)) != 0) { if (path) rumpuser_close(memfd); return error; } if (!path) goto out; error = initbackend(sc, memfd); if (error) { shmif_unclone(&sc->sc_ec.ec_if); return error; } sc->sc_backfilelen = strlen(path)+1; sc->sc_backfile = kmem_alloc(sc->sc_backfilelen, KM_SLEEP); strcpy(sc->sc_backfile, path); out: if (ifnum) *ifnum = unit; return 0; }
static void finibackend(struct shmif_sc *sc) { if (sc->sc_backfile == NULL) return; if (sc->sc_backfile) { kmem_free(sc->sc_backfile, sc->sc_backfilelen); sc->sc_backfile = NULL; sc->sc_backfilelen = 0; } rumpuser_unmap(sc->sc_busmem, BUSMEM_SIZE); rumpuser_close(sc->sc_memfd); rumpuser_close(sc->sc_kq); sc->sc_memfd = -1; }
int rumpuser_getfileinfo(const char *name, uint64_t *size, int *type) { int rv, num; if ((num = devname2num(name)) == -1) return ENXIO; if ((rv = devopen(num)) != 0) return rv; *size = blkinfos[num].sectors * blkinfos[num].sector_size; *type = RUMPUSER_FT_BLK; rumpuser_close(num + BLKFDOFF); return 0; }
static int shmif_ioctl(struct ifnet *ifp, u_long cmd, void *data) { struct shmif_sc *sc = ifp->if_softc; struct ifdrv *ifd; char *path; int s, rv, memfd; s = splnet(); switch (cmd) { case SIOCGLINKSTR: ifd = data; if (sc->sc_backfilelen == 0) { rv = ENOENT; break; } ifd->ifd_len = sc->sc_backfilelen; if (ifd->ifd_cmd == IFLINKSTR_QUERYLEN) { rv = 0; break; } if (ifd->ifd_cmd != 0) { rv = EINVAL; break; } rv = copyoutstr(sc->sc_backfile, ifd->ifd_data, MIN(sc->sc_backfilelen, ifd->ifd_len), NULL); break; case SIOCSLINKSTR: if (ifp->if_flags & IFF_UP) { rv = EBUSY; break; } ifd = data; if (ifd->ifd_cmd == IFLINKSTR_UNSET) { finibackend(sc); rv = 0; break; } else if (ifd->ifd_cmd != 0) { rv = EINVAL; break; } else if (sc->sc_backfile) { rv = EBUSY; break; } if (ifd->ifd_len > MAXPATHLEN) { rv = E2BIG; break; } else if (ifd->ifd_len < 1) { rv = EINVAL; break; } path = kmem_alloc(ifd->ifd_len, KM_SLEEP); rv = copyinstr(ifd->ifd_data, path, ifd->ifd_len, NULL); if (rv) { kmem_free(path, ifd->ifd_len); break; } rv = rumpuser_open(path, RUMPUSER_OPEN_RDWR | RUMPUSER_OPEN_CREATE, &memfd); if (rv) { kmem_free(path, ifd->ifd_len); break; } rv = initbackend(sc, memfd); if (rv) { kmem_free(path, ifd->ifd_len); rumpuser_close(memfd); break; } sc->sc_backfile = path; sc->sc_backfilelen = ifd->ifd_len; break; default: rv = ether_ioctl(ifp, cmd, data); if (rv == ENETRESET) rv = 0; break; } splx(s); return rv; }
/* * This is pretty much a CD target for now */ static void scsitest_request(struct scsipi_channel *chan, scsipi_adapter_req_t req, void *arg) { struct scsipi_xfer *xs = arg; struct scsipi_generic *cmd = xs->cmd; #ifdef USE_TOSI_ISO int error; #endif if (req != ADAPTER_REQ_RUN_XFER) return; //show_scsipi_xs(xs); switch (cmd->opcode) { case SCSI_TEST_UNIT_READY: if (isofd == -1) sense_notready(xs); break; case INQUIRY: { struct scsipi_inquiry_data *inqbuf = (void *)xs->data; memset(inqbuf, 0, sizeof(*inqbuf)); inqbuf->device = T_CDROM; inqbuf->dev_qual2 = SID_REMOVABLE; strcpy(inqbuf->vendor, "RUMPHOBO"); strcpy(inqbuf->product, "It's a LIE"); strcpy(inqbuf->revision, "0.00"); break; } case READ_CD_CAPACITY: { struct scsipi_read_cd_cap_data *ret = (void *)xs->data; _lto4b(CDBLOCKSIZE, ret->length); _lto4b(mycdsize, ret->addr); break; } case READ_DISCINFO: { struct scsipi_read_discinfo_data *ret = (void *)xs->data; memset(ret, 0, sizeof(*ret)); break; } case READ_TRACKINFO: { struct scsipi_read_trackinfo_data *ret = (void *)xs->data; _lto4b(mycdsize, ret->track_size); break; } case READ_TOC: { struct scsipi_toc_header *ret = (void *)xs->data; memset(ret, 0, sizeof(*ret)); break; } case START_STOP: { struct scsipi_start_stop *param = (void *)cmd; if (param->how & SSS_LOEJ) { #ifdef USE_TOSI_ISO rumpuser_close(isofd, &error); #endif isofd = -1; } break; } case SCSI_SYNCHRONIZE_CACHE_10: { if (isofd == -1) { if ((xs->xs_control & XS_CTL_SILENT) == 0) atomic_inc_uint(&rump_scsitest_err [RUMP_SCSITEST_NOISYSYNC]); sense_notready(xs); } break; } case GET_CONFIGURATION: { memset(xs->data, 0, sizeof(struct scsipi_get_conf_data)); break; } case SCSI_READ_6_COMMAND: { #ifdef USE_TOSI_ISO struct scsi_rw_6 *param = (void *)cmd; printf("reading %d bytes from %d\n", param->length * CDBLOCKSIZE, _3btol(param->addr) * CDBLOCKSIZE); rumpuser_pread(isofd, xs->data, param->length * CDBLOCKSIZE, _3btol(param->addr) * CDBLOCKSIZE, &error); #endif break; } case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL: /* hardcoded for now */ break; default: printf("unhandled opcode 0x%x\n", cmd->opcode); break; } scsipi_done(xs); }