static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
			   unsigned char op)
{
	if (scsi_is_rw(op))
		pvscsi_kick_rw_io(adapter);
	else
		pvscsi_process_request_ring(adapter);
}
示例#2
0
static void pvscsi_kick_io(const struct pvscsi_adapter *adapter,
			   unsigned char op)
{
	if (scsi_is_rw(op)) {
		struct PVSCSIRingsState *s = adapter->rings_state;

		if (!adapter->use_req_threshold ||
		    s->reqProdIdx - s->reqConsIdx >= s->reqCallThreshold)
			pvscsi_kick_rw_io(adapter);
	} else {
		pvscsi_process_request_ring(adapter);
	}
}
示例#3
0
int
pvscsi_process_op(struct disk_op_s *op)
{
    if (!CONFIG_PVSCSI)
        return DISK_RET_EBADTRACK;
    struct pvscsi_lun_s *plun =
        container_of(op->drive_gf, struct pvscsi_lun_s, drive);
    struct pvscsi_ring_dsc_s *ring_dsc = plun->ring_dsc;
    struct PVSCSIRingsState *s = ring_dsc->ring_state;
    u32 req_entries = s->reqNumEntriesLog2;
    u32 cmp_entries = s->cmpNumEntriesLog2;
    struct PVSCSIRingReqDesc *req;
    struct PVSCSIRingCmpDesc *rsp;
    u32 status;

    if (s->reqProdIdx - s->cmpConsIdx >= 1 << req_entries) {
        dprintf(1, "pvscsi: ring full: reqProdIdx=%d cmpConsIdx=%d\n",
                s->reqProdIdx, s->cmpConsIdx);
        return DISK_RET_EBADTRACK;
    }

    req = ring_dsc->ring_reqs + (s->reqProdIdx & MASK(req_entries));
    int blocksize = scsi_fill_cmd(op, req->cdb, 16);
    if (blocksize < 0)
        return default_process_op(op);
    req->bus = 0;
    req->target = plun->target;
    memset(req->lun, 0, sizeof(req->lun));
    req->lun[1] = plun->lun;
    req->senseLen = 0;
    req->senseAddr = 0;
    req->cdbLen = 16;
    req->vcpuHint = 0;
    req->tag = SIMPLE_QUEUE_TAG;
    req->flags = scsi_is_read(op) ?
        PVSCSI_FLAG_CMD_DIR_TOHOST : PVSCSI_FLAG_CMD_DIR_TODEVICE;
    req->dataLen = op->count * blocksize;
    req->dataAddr = (u32)op->buf_fl;
    s->reqProdIdx = s->reqProdIdx + 1;

    pvscsi_kick_rw_io(plun->iobase);
    pvscsi_wait_intr_cmpl(plun->iobase);

    rsp = ring_dsc->ring_cmps + (s->cmpConsIdx & MASK(cmp_entries));
    status = pvscsi_get_rsp(s, rsp);

    return status == 0 ? DISK_RET_SUCCESS : DISK_RET_EBADTRACK;
}