static ssize_t bcm2079x_dev_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct bcm2079x_dev *bcm2079x_dev = filp->private_data; char tmp[MAX_BUFFER_SIZE]; int ret; if (count > MAX_BUFFER_SIZE) { dev_err(&bcm2079x_dev->client->dev, "out of memory\n"); return -ENOMEM; } if (copy_from_user(tmp, buf, count)) { dev_err(&bcm2079x_dev->client->dev, "failed to copy from user space\n"); return -EFAULT; } mutex_lock(&bcm2079x_dev->read_mutex); /* Write data */ ret = i2c_master_send(bcm2079x_dev->client, tmp, count); if (ret != count) { #if 0 if ((bcm2079x_dev->client->flags & I2C_CLIENT_TEN) != I2C_CLIENT_TEN && bcm2079x_dev->error_write == 0) { set_client_addr(bcm2079x_dev, 0x1FA); ret = i2c_master_send(bcm2079x_dev->client, tmp, count); if (ret != count) { bcm2079x_dev->error_write++; set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address); } } else #endif { dev_err(&bcm2079x_dev->client->dev, "failed to write %d\n", ret); ret = -EIO; bcm2079x_dev->error_write++; } } mutex_unlock(&bcm2079x_dev->read_mutex); //printk("[dsc]write data ,length =%d \n",ret); //print_hex_dump(KERN_DEBUG, " write: ", DUMP_PREFIX_NONE, 16, 1, tmp, ret, false); return ret; }
static long bcm2079x_dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct bcm2079x_dev *bcm2079x_dev = filp->private_data; switch (cmd) { case BCMNFC_READ_FULL_PACKET: break; case BCMNFC_READ_MULTI_PACKETS: break; case BCMNFC_CHANGE_ADDR: dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_CHANGE_ADDR (%x, %lx):\n", __func__, cmd, arg); return change_client_addr(bcm2079x_dev, arg); case BCMNFC_POWER_CTL: gpio_set_value(bcm2079x_dev->en_gpio, arg); break; case BCMNFC_WAKE_CTL: gpio_set_value(bcm2079x_dev->wake_gpio, arg); break; case BCMNFC_SET_ADDR: set_client_addr(bcm2079x_dev, arg); break; default: dev_err(&bcm2079x_dev->client->dev, "%s, unknown cmd (%x, %lx)\n", __func__, cmd, arg); return 0; } return 0; }
static ssize_t bcm2079x_dev_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset) { struct bcm2079x_dev *bcm2079x_dev = filp->private_data; char tmp[MAX_BUFFER_SIZE]; int ret; DBG2(dev_info(&bcm2079x_dev->client->dev, "bcm2079x_dev_write enter %llu\n", get_jiffies_64())); if (count > MAX_BUFFER_SIZE) { dev_err(&bcm2079x_dev->client->dev, "out of memory\n"); return -ENOMEM; } if (copy_from_user(tmp, buf, count)) { dev_err(&bcm2079x_dev->client->dev, "failed to copy from user space\n"); return -EFAULT; } mutex_lock(&bcm2079x_dev->read_mutex); /* Write data */ ret = i2c_master_send(bcm2079x_dev->client, tmp, count); if (ret != count) { if ((bcm2079x_dev->client->flags & I2C_CLIENT_TEN) != I2C_CLIENT_TEN && bcm2079x_dev->error_write == 0) { set_client_addr(bcm2079x_dev, 0x1FA); ret = i2c_master_send(bcm2079x_dev->client, tmp, count); if (ret != count) { bcm2079x_dev->error_write++; set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address); } } else { dev_err(&bcm2079x_dev->client->dev, "failed to write %d\n", ret); ret = -EIO; bcm2079x_dev->error_write++; } } mutex_unlock(&bcm2079x_dev->read_mutex); DBG2(dev_info(&bcm2079x_dev->client->dev, "bcm2079x_dev_write leave\n")); return ret; }
void redis_command::set_client(redis_client* conn) { if (conn != NULL) { conn_ = conn; cluster_ = NULL; set_client_addr(*conn); } }
static long bcm2079x_dev_compat_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct bcm2079x_dev *bcm2079x_dev = filp->private_data; printk("[dsc-test]bcm2079x_dev_compat_unlocked_ioctl\n"); arg = (compat_u64)arg; switch (cmd) { case BCMNFC_READ_FULL_PACKET: break; case BCMNFC_READ_MULTI_PACKETS: break; case BCMNFC_CHANGE_ADDR: dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_CHANGE_ADDR (%x, %lx):\n", __func__, cmd, arg); change_client_addr(bcm2079x_dev, arg); break; case BCMNFC_POWER_CTL: dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_POWER_CTL (%x, %lx):\n", __func__, cmd, arg); if (arg != 1) set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address); gpio_set_value(bcm2079x_dev->en_gpio, arg); break; case BCMNFC_WAKE_CTL: dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_WAKE_CTL (%x, %lx):\n", __func__, cmd, arg); //printk("zhanglongbo:arg is %lx\n",arg); #ifdef USE_WAKE_LOCK if(arg != 0) { while(wake_lock_active(&bcm2079x_dev->wake_lock )) { printk("release wake lock!!!\n"); wake_unlock(&bcm2079x_dev->wake_lock); } wake_lock_timeout(&bcm2079x_dev->wake_lock, HZ*2); } #endif gpio_set_value(bcm2079x_dev->wake_gpio, arg); break; default: dev_err(&bcm2079x_dev->client->dev, "%s, unknown cmd (%x, %lx)\n", __func__, cmd, arg); return 0; } return 0; }
redis_command::redis_command(redis_client* conn) : check_addr_(false) , conn_(conn) , cluster_(NULL) , max_conns_(0) , used_(0) , slot_(-1) , redirect_max_(15) , redirect_sleep_(1) , slice_req_(false) , request_buf_(NULL) , request_obj_(NULL) , argv_size_(0) , argv_(NULL) , argv_lens_(NULL) , slice_res_(false) , result_(NULL) { dbuf_ = new dbuf_pool(); if (conn != NULL) set_client_addr(*conn); else addr_[0] = 0; }
const redis_result* redis_command::run(redis_client_cluster* cluster, size_t nchild, int* timeout /* = NULL */) { redis_client* conn = peek_conn(cluster, slot_); // 如果没有找到可用的连接对象,则直接返回 NULL 表示出错 if (conn == NULL) { logger_error("peek_conn NULL, slot_: %d", slot_); return NULL; } set_client_addr(*conn); conn->set_check_addr(check_addr_); redis_result_t type; bool last_moved = false; int n = 0; while (n++ < redirect_max_) { // 根据请求过程是否采用内存分片方式调用不同的请求过程 if (slice_req_) result_ = conn->run(dbuf_, *request_obj_, nchild, timeout); else result_ = conn->run(dbuf_, *request_buf_, nchild, timeout); // 如果连接异常断开,则需要进行重试 if (conn->eof()) { // 删除哈希槽中的地址映射关系以便下次操作时重新获取 cluster->clear_slot(slot_); // 将连接对象归还给连接池对象 conn->get_pool()->put(conn, false); // 如果连接断开且请求数据为空时,则无须重试 if (request_obj_->get_size() == 0 && request_buf_->empty()) { logger_error("not retry when no request!"); return NULL; } // 将连接池对象置为不可用状态 conn->get_pool()->set_alive(false); // 从连接池集群中顺序取得一个连接对象 conn = peek_conn(cluster, slot_); if (conn == NULL) { logger_error("peek_conn NULL"); return result_; } last_moved = true; clear(true); set_client_addr(*conn); continue; } if (result_ == NULL) { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); logger_error("result NULL"); return NULL; } // 取得服务器的响应结果的类型,并进行分别处理 type = result_->get_type(); if (type == REDIS_RESULT_UNKOWN) { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); logger_error("unknown result type: %d", type); return NULL; } if (type != REDIS_RESULT_ERROR) { // 如果发生重定向过程,则设置哈希槽对应 redis 服务地址 if (slot_ < 0 || !last_moved) { // 将连接对象归还给连接池对象 conn->get_pool()->put(conn, true); return result_; } // XXX: 因为此处还要引用一次 conn 对象,所以将 conn // 归还给连接池的过程须放在此段代码之后 const char* addr = conn->get_pool()->get_addr(); cluster->set_slot(slot_, addr); // 将连接对象归还给连接池对象 conn->get_pool()->put(conn, true); return result_; } #define EQ(x, y) !strncasecmp((x), (y), sizeof(y) -1) // 对于结果类型为错误类型,则需要进一步判断是否是重定向指令 const char* ptr = result_->get_error(); if (ptr == NULL || *ptr == 0) { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); logger_error("result error: null"); return result_; } // 如果出错信息为重定向指令,则执行重定向过程 if (EQ(ptr, "MOVED")) { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); const char* addr = get_addr(ptr); if (addr == NULL) { logger_warn("MOVED invalid, ptr: %s", ptr); return result_; } conn = redirect(cluster, addr); if (conn == NULL) { logger_error("redirect NULL, addr: %s", addr); return result_; } ptr = conn->get_pool()->get_addr(); set_client_addr(ptr); if (n >= 2 && redirect_sleep_ > 0 && strcmp(ptr, addr) != 0) { logger("redirect %d, curr %s, waiting %s ...", n, ptr, addr); acl_doze(redirect_sleep_); } last_moved = true; // 需要保存哈希槽值 clear(true); } else if (EQ(ptr, "ASK")) { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); const char* addr = get_addr(ptr); if (addr == NULL) { logger_warn("ASK invalid, ptr: %s", ptr); return result_; } conn = redirect(cluster, addr); if (conn == NULL) { logger_error("redirect NULL, addr: %s", addr); return result_; } ptr = conn->get_pool()->get_addr(); set_client_addr(ptr); if (n >= 2 && redirect_sleep_ > 0 && strcmp(ptr, addr) != 0) { logger("redirect %d, curr %s, waiting %s ...", n, ptr, addr); acl_doze(redirect_sleep_); } result_ = conn->run(dbuf_, "ASKING\r\n", 0); if (result_ == NULL) { logger_error("ASKING's reply null"); return NULL; } const char* status = result_->get_status(); if (status == NULL || strcasecmp(status, "OK") != 0) { logger_error("ASKING's reply error: %s", status ? status : "null"); return NULL; } last_moved = false; clear(true); } // 处理一个主结点失效的情形 else if (EQ(ptr, "CLUSTERDOWN")) { cluster->clear_slot(slot_); if (redirect_sleep_ > 0) { logger("%s: redirect %d, slot %d, waiting %s ...", conn->get_pool()->get_addr(), n, slot_, ptr); acl_doze(redirect_sleep_); } // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); conn = peek_conn(cluster, -1); if (conn == NULL) { logger_error("peek_conn NULL"); return result_; } clear(true); set_client_addr(*conn); } // 对于其它错误类型,则直接返回本次得到的响应结果对象 else { // 将旧连接对象归还给连接池对象 conn->get_pool()->put(conn, true); logger_error("server error: %s", ptr); if (!slice_req_) logger_error("request: %s", request_buf_->c_str()); return result_; } } if (conn != NULL) conn->get_pool()->put(conn, true); logger_warn("too many redirect: %d, max: %d", n, redirect_max_); return NULL; }
static long bcm2079x_dev_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct bcm2079x_dev *bcm2079x_dev = filp->private_data; switch (cmd) { case BCMNFC_READ_FULL_PACKET: DBG(dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_READ_FULL_PACKET (%x, %lx):\n", __func__, cmd, arg)); break; case BCMNFC_READ_MULTI_PACKETS: DBG(dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_READ_MULTI_PACKETS (%x, %lx):\n", __func__, cmd, arg)); break; case BCMNFC_CHANGE_ADDR: DBG(dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_CHANGE_ADDR (%x, %lx):\n", __func__, cmd, arg)); change_client_addr(bcm2079x_dev, arg); break; case BCMNFC_POWER_CTL: DBG(dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_POWER_CTL (%x, %lx):\n", __func__, cmd, arg)); if (arg == 1) { /* Power On */ gpio_set_value(bcm2079x_dev->en_gpio, 1); if (bcm2079x_dev->irq_enabled == FALSE) { bcm2079x_dev->count_irq = 0; enable_irq(bcm2079x_dev->client->irq); bcm2079x_dev->irq_enabled = true; } } else { if (bcm2079x_dev->irq_enabled == true) { bcm2079x_dev->irq_enabled = FALSE; disable_irq_nosync(bcm2079x_dev->client->irq); if (bcm2079x_dev->count_irq > 0) wake_unlock(&nfc_wake_lock); } gpio_set_value(bcm2079x_dev->en_gpio, 0); set_client_addr(bcm2079x_dev, bcm2079x_dev->original_address); } break; case BCMNFC_WAKE_CTL: DBG(dev_info(&bcm2079x_dev->client->dev, "%s, BCMNFC_WAKE_CTL (%x, %lx):\n", __func__, cmd, arg)); #ifdef CONFIG_HAS_WAKELOCK if (arg == 0) { wake_lock(&nfc_wake_lock); DBG(dev_info(&bcm2079x_dev->client->dev, "%s: got wake lock", __func__)); } #endif gpio_set_value(bcm2079x_dev->wake_gpio, arg); #ifdef CONFIG_HAS_WAKELOCK if (arg == 1) { wake_unlock(&nfc_wake_lock); DBG(dev_info(&bcm2079x_dev->client->dev, "%s: release wake lock, count_irq = %d", __func__, bcm2079x_dev->count_irq)); } #endif break; default: dev_err(&bcm2079x_dev->client->dev, "%s, unknown cmd (%x, %lx)\n", __func__, cmd, arg); return 0; } return 0; }