static ssize_t stm_write(struct file *file, const char __user *data, size_t size, loff_t *ppos) { struct stm_drvdata *drvdata = container_of(file->private_data, struct stm_drvdata, miscdev); char *buf; uint8_t entity_id, proto_id; uint32_t options; if (!drvdata->enable || !size) return -EINVAL; if (size > STM_TRACE_BUF_SIZE) size = STM_TRACE_BUF_SIZE; buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; if (copy_from_user(buf, data, size)) { kfree(buf); dev_dbg(drvdata->dev, "%s: copy_from_user failed\n", __func__); return -EFAULT; } if (size >= STM_USERSPACE_HEADER_SIZE && buf[0] == STM_USERSPACE_MAGIC1_VAL && buf[1] == STM_USERSPACE_MAGIC2_VAL) { entity_id = buf[2]; proto_id = buf[3]; options = *(uint32_t *)(buf + 4); if (!test_bit(entity_id, drvdata->entities) || !(size - STM_USERSPACE_HEADER_SIZE)) { kfree(buf); return size; } __stm_trace(options, entity_id, proto_id, buf + STM_USERSPACE_HEADER_SIZE, size - STM_USERSPACE_HEADER_SIZE); } else { if (!test_bit(OST_ENTITY_DEV_NODE, drvdata->entities)) { kfree(buf); return size; } __stm_trace(STM_OPTION_TIMESTAMPED, OST_ENTITY_DEV_NODE, 0, buf, size); } kfree(buf); return size; }
static ssize_t stm_write(struct file *file, const char __user *data, size_t size, loff_t *ppos) { struct stm_drvdata *drvdata = container_of(file->private_data, struct stm_drvdata, miscdev); char *buf; if (!drvdata->enable) { return -EINVAL; } if (!(drvdata->entity & OST_ENTITY_DEV_NODE)) { return size; } if (size > STM_TRACE_BUF_SIZE) size = STM_TRACE_BUF_SIZE; buf = kmalloc(size, GFP_KERNEL); if (!buf) { return -ENOMEM; } if (copy_from_user(buf, data, size)) { kfree(buf); dev_err(drvdata->dev, "scopy_from_user failed\n"); return -EFAULT; } __stm_trace(STM_OPTION_TIMESTAMPED, OST_ENTITY_DEV_NODE, 0, buf, size); kfree(buf); return size; }
/** * stm_trace - trace the binary or string data through STM * @options: tracing options - guaranteed, timestamped, etc * @entity_id: entity representing the trace data * @proto_id: protocol id to distinguish between different binary formats * @data: pointer to binary or string data buffer * @size: size of data to send * * Packetizes the data as the payload to an OST packet and sends it over STM * * CONTEXT: * Can be called from any context. * * RETURNS: * number of bytes transfered over STM */ int stm_virt_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id, const void *data, uint32_t size) { struct stm_drvdata *drvdata = virt_stmdrvdata; /* we don't support sizes more than 24bits (0 to 23) */ if (!(drvdata && drvdata->enable && (drvdata->entity & entity_id) && (size < 0x1000000))) return 0; return __stm_trace(options, entity_id, proto_id, data, size); }
int stm_trace(uint32_t options, uint8_t entity_id, uint8_t proto_id, const void *data, uint32_t size) { struct stm_drvdata *drvdata = stmdrvdata; /* */ if (!(drvdata && drvdata->enable && test_bit(entity_id, drvdata->entities) && size && (size < 0x1000000))) return 0; return __stm_trace(options, entity_id, proto_id, data, size); }