static ssize_t show_diag_xfer_count(struct device *dev, struct device_attribute *attr, char *buf) { int length = 0; length = sprintf(buf, "tx_count: %llu, rx_count: %llu\n", smd_xfer_count_func(0, data_get_tx), smd_xfer_count_func(0, data_get_rx)); return length; }
static ssize_t diag2arm9_write(struct file *fp, const char __user *buf, size_t count, loff_t *pos) { struct diag_context *ctxt = &_context; int r = count; int writed = 0; DBG("diag2arm9_write(%d)\n", count); if (_lock(&ctxt->write_arm9_excl)) return -EBUSY; while(count > 0) { writed = count > ARM9_MAX ? ARM9_MAX : count; if (copy_from_user(ctxt->toARM9_buf, buf, writed)) { r = -EFAULT; break; } smd_write(ctxt->ch, ctxt->toARM9_buf, writed); smd_xfer_count_func(writed, data_set_tx); buf += writed; count -= writed; } _unlock(&ctxt->write_arm9_excl); return r; }
static void smd_try_to_send(struct diag_context *ctxt) { if (ctxt->ch) { int r = smd_read_avail(ctxt->ch); if (r > RXN_MAX) { printk(KERN_ERR "The SMD data is too large to send (%d) !!\n", r); // return; r = RXN_MAX; } if (r > 0) { struct diag_request *req = get_req(ctxt, &ctxt->rx_arm9_idle); if (!req) { printk(KERN_ERR "There is no enough request to ARM11!!\n"); return; } smd_read(ctxt->ch, req->buf, r); smd_xfer_count_func(r, data_set_rx); //req->length = r; //printk(KERN_ERR "ARM9 data to ARM11 %s\n", (char *)req->buf); req->actual = r; put_req(ctxt, &ctxt->rx_arm9_done, req); wake_up(&ctxt->read_arm9_wq); } } }
static void diag_unbind(void *_ctxt) { struct diag_context *ctxt = _ctxt; struct diag_request *req; printk(KERN_DEBUG "diag_unbind()\n"); smd_xfer_count_func(0,data_set_clear); while ((req = get_req(ctxt, &ctxt->rx_arm9_idle))) { kfree(req->buf); kfree(req); } ctxt->online = 0; ctxt->error = 1; /* readers may be blocked waiting for us to go online */ wake_up(&ctxt->read_arm9_wq); }
static void diag_bind(void *_ctxt) { struct diag_context *ctxt = _ctxt; struct diag_request *req; int n; printk(KERN_DEBUG "diag_bind()\n"); for (n = 0; n < RX_REQ_MAX; n++) { req = kmalloc(sizeof(struct diag_request), GFP_KERNEL); if (req == 0) { pr_err("%s: kmalloc out of memory\n", __func__); goto fail; } req->buf = kmalloc(RXN_MAX, GFP_KERNEL); if (!req->buf) { pr_err("%s: kmalloc out of memory\n", __func__); kfree(req); goto fail; } req->context = ctxt; put_req(ctxt, &ctxt->rx_arm9_idle, req); } printk(KERN_DEBUG "diag_bind() allocated %d rx requests\n", RX_REQ_MAX); smd_xfer_count_func(0,data_set_clear); return; fail: printk(KERN_WARNING "diag_bind() could not allocate requests\n"); diag_unbind(ctxt); }
static void diag_process_hdlc(struct diag_context *ctxt, void *_data, unsigned len) { unsigned char *data = _data; unsigned count = ctxt->hdlc_count; unsigned escape = ctxt->hdlc_escape; unsigned char *hdlc = ctxt->hdlc_buf; while (len-- > 0) { unsigned char x = *data++; if (x == 0x7E) { if (count > 2) { /* we're just ignoring the crc here */ //TRACE("PC>", hdlc, count - 2, 0); if (ctxt->ch) { smd_write(ctxt->ch, hdlc, count - 2); smd_xfer_count_func(count - 2, data_set_tx); } } count = 0; escape = 0; } else if (x == 0x7D) { escape = 1; } else { if (escape) { x = x ^ 0x20; escape = 0; } hdlc[count++] = x; /* discard frame if we overflow */ if (count == HDLC_MAX) count = 0; } } ctxt->hdlc_count = count; ctxt->hdlc_escape = escape; }