static int dax_preprocess_usr_ccbs()

in char/oradax.c [777:848]


static int dax_preprocess_usr_ccbs(struct dax_ctx *ctx, int idx, int nelem)
{
	int i;

	/*
	 * The user is not allowed to specify real address types in
	 * the CCB header.  This must be enforced by the kernel before
	 * submitting the CCBs to HV.  The only allowed values for all
	 * address fields are VA or IMM
	 */
	for (i = 0; i < nelem; i++) {
		struct dax_ccb *ccbp = &ctx->ccb_buf[i];
		unsigned long ca_offset;

		if (ccbp->hdr.ccb_version > max_ccb_version)
			return DAX_SUBMIT_ERR_CCB_INVAL;

		switch (ccbp->hdr.opcode) {
		case DAX_OP_SYNC_NOP:
		case DAX_OP_EXTRACT:
		case DAX_OP_SCAN_VALUE:
		case DAX_OP_SCAN_RANGE:
		case DAX_OP_TRANSLATE:
		case DAX_OP_SCAN_VALUE | DAX_OP_INVERT:
		case DAX_OP_SCAN_RANGE | DAX_OP_INVERT:
		case DAX_OP_TRANSLATE | DAX_OP_INVERT:
		case DAX_OP_SELECT:
			break;
		default:
			return DAX_SUBMIT_ERR_CCB_INVAL;
		}

		if (ccbp->hdr.out_addr_type != DAX_ADDR_TYPE_VA &&
		    ccbp->hdr.out_addr_type != DAX_ADDR_TYPE_NONE) {
			dax_dbg("invalid out_addr_type in user CCB[%d]", i);
			return DAX_SUBMIT_ERR_CCB_INVAL;
		}

		if (ccbp->hdr.pri_addr_type != DAX_ADDR_TYPE_VA &&
		    ccbp->hdr.pri_addr_type != DAX_ADDR_TYPE_NONE) {
			dax_dbg("invalid pri_addr_type in user CCB[%d]", i);
			return DAX_SUBMIT_ERR_CCB_INVAL;
		}

		if (ccbp->hdr.sec_addr_type != DAX_ADDR_TYPE_VA &&
		    ccbp->hdr.sec_addr_type != DAX_ADDR_TYPE_NONE) {
			dax_dbg("invalid sec_addr_type in user CCB[%d]", i);
			return DAX_SUBMIT_ERR_CCB_INVAL;
		}

		if (ccbp->hdr.table_addr_type != DAX_ADDR_TYPE_VA &&
		    ccbp->hdr.table_addr_type != DAX_ADDR_TYPE_NONE) {
			dax_dbg("invalid table_addr_type in user CCB[%d]", i);
			return DAX_SUBMIT_ERR_CCB_INVAL;
		}

		/* set completion (real) address and address type */
		ccbp->hdr.cca_addr_type = DAX_ADDR_TYPE_RA;
		ca_offset = (idx + i) * sizeof(struct dax_cca);
		ccbp->ca = (void *)ctx->ca_buf_ra + ca_offset;
		memset(&ctx->ca_buf[idx + i], 0, sizeof(struct dax_cca));

		dax_dbg("ccb[%d]=%p, ca_offset=0x%lx, compl RA=0x%llx",
			i, ccbp, ca_offset, ctx->ca_buf_ra + ca_offset);

		/* skip over 2nd 64 bytes of long CCB */
		if (ccbp->hdr.longccb)
			i++;
	}

	return DAX_SUBMIT_OK;
}