static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { syslogdrv_t* d = (syslogdrv_t*)handle; if (d->open) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } int index = 0, version, arity, type, size; if (command != SYSLOGDRV_OPEN) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_version(buf, &index, &version)) { return encode_error(*rbuf, "badver"); } if (ei_decode_tuple_header(buf, &index, &arity) || arity != 3) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_get_type(buf, &index, &type, &size)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (type == ERL_STRING_EXT) { long logopt, facility; if (d->ident) { driver_free(d->ident); } d->ident = driver_alloc(size+1); if (d->ident == NULL) { return encode_error(*rbuf, "enomem"); } if (ei_decode_string(buf, &index, d->ident)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_long(buf, &index, &logopt) || ei_decode_long(buf, &index, &facility)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } d->logopt = (int)logopt; d->facility = (int)facility; d->open = 1; return 0; } else { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } }
void encode_result(ei_x_buff* x, PGresult* res, PGconn* conn) { int row, n_rows, col, n_cols; switch (PQresultStatus(res)) { case PGRES_TUPLES_OK: n_rows = PQntuples(res); n_cols = PQnfields(res); ei_x_encode_tuple_header(x, 2); encode_ok(x); ei_x_encode_list_header(x, n_rows+1); ei_x_encode_list_header(x, n_cols); for (col = 0; col < n_cols; ++col) { ei_x_encode_string(x, PQfname(res, col)); } ei_x_encode_empty_list(x); for (row = 0; row < n_rows; ++row) { ei_x_encode_list_header(x, n_cols); for (col = 0; col < n_cols; ++col) { ei_x_encode_string(x, PQgetvalue(res, row, col)); } ei_x_encode_empty_list(x); } ei_x_encode_empty_list(x); break; case PGRES_COMMAND_OK: ei_x_encode_tuple_header(x, 2); encode_ok(x); ei_x_encode_string(x, PQcmdTuples(res)); break; default: encode_error(x, conn); break; } }
/* * register and unregister function to treat this device as char device */ int encode_driver_register(void) { struct device *encdev = NULL; /* encode char device node create */ encode_param.major = register_chrdev(ENCODE_DEFAULT_MAJOR, \ "imapx200-venc", &imapx200_encode_fops); if (encode_param.major < 0) { encode_error("Register char device for encode error\n"); goto register_error_1; } encode_param.major = ENCODE_DEFAULT_MAJOR; /* create a new char device class */ encode_class = class_create(THIS_MODULE, "imapx200-venc"); if (encode_class == NULL) { encode_error("Encode driver char device class create error\n"); goto register_error_2; } /* get major and minor number by MKDEV() */ encode_param.dev = MKDEV(encode_param.major, ENCODE_DEFAULT_MINOR); if (MAJOR(encode_param.dev) != encode_param.major) { encode_error("Encode driver MKDEV error\n"); goto register_error_3; } encode_param.minor = MINOR(encode_param.dev); /* mknod in filesystem using device_create() */ encdev = NULL; encdev = device_create(encode_class, NULL, encode_param.dev, NULL, "imapx200-venc"); /* this function mknod in filesystem */ if (encdev == NULL) { encode_error("Encode driver create node error\n"); goto register_error_3; } return ENCODE_RET_OK; register_error_3: class_destroy(encode_class); register_error_2: unregister_chrdev(encode_param.major, "imapx200-venc"); register_error_1: return ENCODE_RET_ERROR; }
/* * init and exit */ static int __init imapx200_encode_init(void) { if (platform_driver_register(&imapx200_encode_driver)) { encode_error("Fail to register platform driver for IMAPX200 Encoder Driver\n"); return -EPERM; } encode_debug("IMAPX200 Hantro 7280 Encode Driver init OK\n"); return ENCODE_RET_OK; }
static int do_select(const char* s, our_data_t* data) { PGconn* conn = data->conn; /* if there's an error return it now */ if (PQsendQueryParams(conn, s, 0, NULL, NULL, NULL, NULL, 1) == 0) { ei_x_buff x; ei_x_new_with_version(&x); encode_error(&x, conn); driver_output(data->port, x.buff, x.index); ei_x_free(&x); } /* else wait for ready_output to get results */ return 0; }
/* ioctl */ static int imapx200_encode_ioctl(struct inode *inode, struct file *file, \ unsigned int cmd, unsigned long arg) { int ret = -1; /* cmd check */ if (_IOC_TYPE(cmd) != HX280ENC_IOC_MAGIC) { return -ENOTTY; } if (_IOC_NR(cmd) > HX280ENC_IOC_MAXNR) { return -ENOTTY; } /* check command by command feature READ/WRITE */ if (_IOC_DIR(cmd) & _IOC_READ) { ret = !access_ok(VERIFY_WRITE, (void *)arg, _IOC_SIZE(cmd)); } else if (_IOC_DIR(cmd) & _IOC_WRITE) { ret = !access_ok(VERIFY_READ, (void *)arg, _IOC_SIZE(cmd)); } if (ret) { return -EFAULT; } switch (cmd) { case HX280ENC_IOCGHWOFFSET: __put_user(encode_param.reg_base_phys_addr, (unsigned int *)arg); break; case HX280ENC_IOCGHWIOSIZE: __put_user(IMAPX200_ENCODE_ACT_REG_SIZE, (unsigned int *)arg); break; case HX280ENC_IOC_CLI: case HX280ENC_IOC_STI: case HX280ENC_IOCHARDRESET: encode_debug("current ioctl command unsupported yet\n"); break; default: encode_error("encode driver unknow ioctl command\n"); break; } return ENCODE_RET_OK; }
static int do_connect(const char *s, our_data_t* data) { ei_x_buff x; PGconn* conn = PQconnectdb(s); ei_x_new_with_version(&x); if (PQstatus(conn) != CONNECTION_OK) { encode_error(&x, conn); PQfinish(conn); conn = NULL; } else { encode_ok(&x); data->socket = PQsocket(conn); driver_select(data->port, (ErlDrvEvent)data->socket, DO_READ, 1); } driver_output(data->port, x.buff, x.index); ei_x_free(&x); data->conn = conn; return 0; }
encoder& operator<<(encoder& e, const start& s) { switch (s.type) { case ARRAY: pn_data_put_array(pn_cast(&e), s.is_described, pn_type_t(s.element)); break; case MAP: pn_data_put_map(pn_cast(&e)); break; case LIST: pn_data_put_list(pn_cast(&e)); break; case DESCRIBED: pn_data_put_described(pn_cast(&e)); break; default: throw encode_error(MSG("" << s.type << " is not a container type")); } pn_data_enter(pn_cast(&e)); return e; }
encoder& operator<<(encoder& e, const data& v) { if (pn_cast(&e) == pn_cast(&v)) throw encode_error("cannot insert into self"); check(pn_data_append(pn_cast(&e), pn_cast(&v)), pn_cast(&e)); return e; }
/* probe */ static int imapx200_encode_probe(struct platform_device *pdev) { int ret = -1; unsigned int size = 0; struct resource *res = NULL; encode_debug("In imapx200_encode_probe\n"); /* get encode hardware clock and enable it */ imap_venc_clock = clk_get(&pdev->dev, "venc"); if (imap_venc_clock == NULL) { encode_error("Fail to get encode hardware source\n"); return -ENOENT; } clk_enable(imap_venc_clock); /* close 7280 ic if uboot has done something needs ic powered on */ encode_disable_hw_power(); /* initialize encode open count */ encode_open_count = 0; /* initialize global varaibles */ memset(&encode_param, 0x00, sizeof(encode_param_t)); /* initialize wait queue for poll system call */ init_waitqueue_head(&wait_encode); /* get register base resource */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { encode_error("Fail to get encode platform device resource\n"); return -ENOENT; } /* request memory region */ size = res->end - res->start + 1; encode_param.reg_reserved_size = size; encode_param.resource_mem = request_mem_region(res->start, size, pdev->name); if (encode_param.resource_mem == NULL) { encode_error("Fail to get IMAPX200 encode register memory region\n"); return -ENOENT; } encode_param.reg_base_phys_addr = res->start; /* remap register physics address nocache */ encode_param.reg_base_virt_addr = ioremap_nocache(res->start, size); if (encode_param.reg_base_virt_addr == NULL) { encode_error("Fail to ioremap IMAPX200 encode register base address\n"); return -EINVAL; } /* get and config irq */ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { encode_error("Fail to get IMAPX200 encode irq resource\n"); return -ENOENT; } if (res->start != IRQ_VENC) { encode_error("Get wrong irq number for IMAPX200 encode\n"); return -ENOENT; } /* request for irq */ ret = request_irq(res->start, imapx200_encode_irq_handle, IRQF_DISABLED, \ pdev->name, (void *)(&encode_param)); if (ret) { encode_error("Fail to request irq for IMAPX200 encode device\n"); return ret; } /* register driver device */ if (encode_driver_register() != ENCODE_RET_OK) { return ENCODE_RET_ERROR; } /* reset hardware registers */ reset_hw_reg_encode(); mutex_init(&encode_lock); encode_debug("IMAPX200 encode driver probe OK, major: %d minor: %d\n", \ encode_param.major, encode_param.minor); return ENCODE_RET_OK; }
static ErlDrvSSizeT syslogdrv_control(ErlDrvData handle, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { syslogdrv_t* d = (syslogdrv_t*)handle; int index = 0, version, arity, type, size; if (command != SYSLOGDRV_OPEN) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_version(buf, &index, &version)) { return encode_error(*rbuf, "badver"); } if (ei_decode_tuple_header(buf, &index, &arity) || arity != 4) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_get_type(buf, &index, &type, &size)) { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (type == ERL_STRING_EXT) { long logopt, facility, len; ErlDrvBinary* ref = 0; syslogdrv_t* nd = (syslogdrv_t*)driver_alloc(sizeof(syslogdrv_t)); if (nd == NULL) { return encode_error(*rbuf, "enomem"); } nd->ident = driver_alloc(size+1); if (nd->ident == NULL) { return encode_error(*rbuf, "enomem"); } if (ei_decode_string(buf, &index, nd->ident)) { driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_decode_long(buf, &index, &logopt) || ei_decode_long(buf, &index, &facility)) { driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (ei_get_type(buf, &index, &type, &size)) { driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } if (type != ERL_BINARY_EXT) { driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } ref = driver_alloc_binary(size); if (ref == NULL) { return encode_error(*rbuf, "enomem"); } if (ei_decode_binary(buf, &index, ref->orig_bytes, &len)) { driver_free_binary(ref); driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } nd->logopt = (int)logopt; nd->facility = (int)facility; nd->open = 1; { ErlDrvTermData refdata = TERM_DATA(ref->orig_bytes); ErlDrvPort port = d->port; ErlDrvTermData pid = driver_caller(port); ErlDrvData data = (ErlDrvData)nd; nd->port = driver_create_port(port, pid, DRV_NAME, data); if (nd->port == (ErlDrvPort)-1) { driver_free_binary(ref); driver_free(nd->ident); driver_free(nd); return (ErlDrvSSizeT)ERL_DRV_ERROR_GENERAL; } set_port_control_flags(nd->port, PORT_CONTROL_FLAG_BINARY); ErlDrvTermData term[] = { ERL_DRV_EXT2TERM, refdata, ref->orig_size, ERL_DRV_ATOM, driver_mk_atom("ok"), ERL_DRV_PORT, driver_mk_port(nd->port), ERL_DRV_TUPLE, 2, ERL_DRV_TUPLE, 2, }; erl_drv_output_term(driver_mk_port(port), term, sizeof term/sizeof *term); } driver_free_binary(ref); return 0; } else { return (ErlDrvSSizeT)ERL_DRV_ERROR_BADARG; } }