Пример #1
0
static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
{
	struct opticon_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	int res;

	spin_lock_irqsave(&priv->lock, flags);
	priv->rts = false;
	spin_unlock_irqrestore(&priv->lock, flags);

	/* Clear RTS line */
	send_control_msg(port, CONTROL_RTS, 0);

	/* clear the halt status of the enpoint */
	usb_clear_halt(port->serial->dev, port->read_urb->pipe);

	res = usb_serial_generic_open(tty, port);
	if (!res)
		return res;

	/* Request CTS line state, sometimes during opening the current
	 * CTS state can be missed. */
	send_control_msg(port, RESEND_CTS_STATE, 1);

	return res;
}
Пример #2
0
int build_and_send_map_reply_msg(
        lispd_mapping_elt   *requested_mapping,
        lisp_addr_t         *src_rloc_addr,
        lisp_addr_t         *dst_rloc_addr,
        uint16_t            dport,
        uint64_t            nonce,
        map_reply_opts      opts)
{
    uint8_t         *map_reply_pkt      = NULL;
    int             map_reply_pkt_len   = 0;
    int             result              = 0;

    lispd_log_msg(LISP_LOG_DEBUG_2,"Build Map Reply Packet");

    /* Build the packet */
    if (opts.rloc_probe == TRUE){
        map_reply_pkt = build_map_reply_pkt(requested_mapping, src_rloc_addr, opts, nonce, &map_reply_pkt_len);
    }
    else{
        map_reply_pkt = build_map_reply_pkt(requested_mapping, NULL, opts, nonce, &map_reply_pkt_len);
    }
    if (map_reply_pkt == NULL){
        lispd_log_msg(LISP_LOG_DEBUG_1,"build_and_send_map_reply_msg: Couldn't send Map-Reply for requested EID %s/%d ",
                get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                requested_mapping->eid_prefix_length);
        return (BAD);
    }

    err = send_control_msg(map_reply_pkt,
            map_reply_pkt_len,
            src_rloc_addr,
            dst_rloc_addr,
            LISP_CONTROL_PORT,
            dport);
    free (map_reply_pkt);


    if (err == GOOD){
        if (opts.rloc_probe == TRUE){
            lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d probing local locator %s",
                    get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                    requested_mapping->eid_prefix_length,
                    get_char_from_lisp_addr_t(*src_rloc_addr));
        }else{
            lispd_log_msg(LISP_LOG_DEBUG_1, "Sent Map-Reply packet for %s/%d",
                    get_char_from_lisp_addr_t(requested_mapping->eid_prefix),
                    requested_mapping->eid_prefix_length);
        }
        result = GOOD;
    }else {
        if (opts.rloc_probe == TRUE){
            lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Probe Reply!");
        }else{
            lispd_log_msg(LISP_LOG_DEBUG_1, "Couldn't build/send Map-Reply!");
        }
        result = BAD;
    }

    return (result);
}
Пример #3
0
static int opticon_tiocmset(struct tty_struct *tty,
			   unsigned int set, unsigned int clear)
{
	struct usb_serial_port *port = tty->driver_data;
	struct opticon_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;
	bool rts;
	bool changed = false;
	int ret;

	/* We only support RTS so we only handle that */
	spin_lock_irqsave(&priv->lock, flags);

	rts = priv->rts;
	if (set & TIOCM_RTS)
		priv->rts = true;
	if (clear & TIOCM_RTS)
		priv->rts = false;
	changed = rts ^ priv->rts;
	spin_unlock_irqrestore(&priv->lock, flags);

	if (!changed)
		return 0;

	ret = send_control_msg(port, CONTROL_RTS, !rts);
	if (ret)
		return usb_translate_errors(ret);

	return 0;
}
Пример #4
0
static int opticon_tiocmset(struct tty_struct *tty,
			   unsigned int set, unsigned int clear)
{
	struct usb_serial_port *port = tty->driver_data;
	struct opticon_private *priv = usb_get_serial_data(port->serial);
	unsigned long flags;
	bool rts;
	bool changed = false;

	if (!usb_get_intfdata(port->serial->interface))
		return -ENODEV;
	/* We only support RTS so we only handle that */
	spin_lock_irqsave(&priv->lock, flags);

	rts = priv->rts;
	if (set & TIOCM_RTS)
		priv->rts = true;
	if (clear & TIOCM_RTS)
		priv->rts = false;
	changed = rts ^ priv->rts;
	spin_unlock_irqrestore(&priv->lock, flags);

	if (!changed)
		return 0;

	/* Send the new RTS state to the connected device */
	return send_control_msg(port, CONTROL_RTS, !rts);
}
Пример #5
0
int pwc_set_leds(struct pwc_device *pdev, int on_value, int off_value)
{
	int r;

	if (pdev->type < 730)
		return 0;
	on_value /= 100;
	off_value /= 100;
	if (on_value < 0)
		on_value = 0;
	if (on_value > 0xff)
		on_value = 0xff;
	if (off_value < 0)
		off_value = 0;
	if (off_value > 0xff)
		off_value = 0xff;

	pdev->ctrl_buf[0] = on_value;
	pdev->ctrl_buf[1] = off_value;

	r = send_control_msg(pdev,
		SET_STATUS_CTL, LED_FORMATTER, pdev->ctrl_buf, 2);
	if (r < 0)
		PWC_ERROR("Failed to set LED on/off time (%d)\n", r);

	return r;
}
Пример #6
0
int pwc_button_ctrl(struct pwc_device *pdev, u16 value)
{
	int ret;

	ret = send_control_msg(pdev, SET_STATUS_CTL, value, NULL, 0);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #7
0
int pwc_set_u8_ctrl(struct pwc_device *pdev, u8 request, u16 value, u8 data)
{
	int ret;

	pdev->ctrl_buf[0] = data;
	ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 1);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #8
0
int pwc_set_u16_ctrl(struct pwc_device *pdev, u8 request, u16 value, u16 data)
{
	int ret;

	pdev->ctrl_buf[0] = data & 0xff;
	pdev->ctrl_buf[1] = data >> 8;
	ret = send_control_msg(pdev, request, value, pdev->ctrl_buf, 2);
	if (ret < 0)
		return ret;

	return 0;
}
Пример #9
0
/* open the camera */
static int zr364xx_open(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct zr364xx_camera *cam = video_get_drvdata(vdev);
	struct usb_device *udev = cam->udev;
	int i, err;

	DBG("zr364xx_open");

	mutex_lock(&cam->lock);

	if (cam->users) {
		err = -EBUSY;
		goto out;
	}

	if (!cam->framebuf) {
		cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
		if (!cam->framebuf) {
			dev_err(&cam->udev->dev, "vmalloc_32 failed!\n");
			err = -ENOMEM;
			goto out;
		}
	}

	for (i = 0; init[cam->method][i].size != -1; i++) {
		err =
		    send_control_msg(udev, 1, init[cam->method][i].value,
				     0, init[cam->method][i].bytes,
				     init[cam->method][i].size);
		if (err < 0) {
			dev_err(&cam->udev->dev,
				"error during open sequence: %d\n", i);
			goto out;
		}
	}

	cam->skip = 2;
	cam->users++;
	file->private_data = vdev;

	/* Added some delay here, since opening/closing the camera quickly,
	 * like Ekiga does during its startup, can crash the webcam
	 */
	mdelay(100);
	err = 0;

out:
	mutex_unlock(&cam->lock);
	return err;
}
Пример #10
0
static int opticon_open(struct tty_struct *tty, struct usb_serial_port *port)
{
	struct opticon_private *priv = usb_get_serial_data(port->serial);
	unsigned long flags;
	int result = 0;

	dbg("%s - port %d", __func__, port->number);

	spin_lock_irqsave(&priv->lock, flags);
	priv->throttled = false;
	priv->actually_throttled = false;
	priv->port = port;
	priv->rts = false;
	spin_unlock_irqrestore(&priv->lock, flags);

	/* Clear RTS line */
	send_control_msg(port, CONTROL_RTS, 0);

	/* Setup the read URB and start reading from the device */
	usb_fill_bulk_urb(priv->bulk_read_urb, priv->udev,
			  usb_rcvbulkpipe(priv->udev,
					  priv->bulk_address),
			  priv->bulk_in_buffer, priv->buffer_size,
			  opticon_read_bulk_callback, priv);

	/* clear the halt status of the enpoint */
	usb_clear_halt(priv->udev, priv->bulk_read_urb->pipe);

	result = usb_submit_urb(priv->bulk_read_urb, GFP_KERNEL);
	if (result)
		dev_err(&port->dev,
			"%s - failed resubmitting read urb, error %d\n",
			__func__, result);
	/* Request CTS line state, sometimes during opening the current
	 * CTS state can be missed. */
	send_control_msg(port, RESEND_CTS_STATE, 1);
	return result;
}
Пример #11
0
/* open the camera */
static int zr364xx_open(struct inode *inode, struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct zr364xx_camera *cam = video_get_drvdata(vdev);
	struct usb_device *udev = cam->udev;
	int i, err;

	DBG("zr364xx_open");

	cam->skip = 2;

	err = video_exclusive_open(inode, file);
	if (err < 0)
		return err;

	if (!cam->framebuf) {
		cam->framebuf = vmalloc_32(MAX_FRAME_SIZE * FRAMES);
		if (!cam->framebuf) {
			info("vmalloc_32 failed!");
			return -ENOMEM;
		}
	}

	mutex_lock(&cam->lock);
	for (i = 0; init[cam->method][i].size != -1; i++) {
		err =
		    send_control_msg(udev, 1, init[cam->method][i].value,
				     0, init[cam->method][i].bytes,
				     init[cam->method][i].size);
		if (err < 0) {
			info("error during open sequence: %d", i);
			mutex_unlock(&cam->lock);
			return err;
		}
	}

	file->private_data = vdev;

	/* Added some delay here, since opening/closing the camera quickly,
	 * like Ekiga does during its startup, can crash the webcam
	 */
	mdelay(100);

	mutex_unlock(&cam->lock);
	return 0;
}
Пример #12
0
/* POWER */
void pwc_camera_power(struct pwc_device *pdev, int power)
{
	int r;

	if (!pdev->power_save)
		return;

	if (pdev->type < 675 || (pdev->type < 730 && pdev->release < 6))
		return;	/* Not supported by Nala or Timon < release 6 */

	if (power)
		pdev->ctrl_buf[0] = 0x00; /* active */
	else
		pdev->ctrl_buf[0] = 0xFF; /* power save */
	r = send_control_msg(pdev, SET_STATUS_CTL,
		SET_POWER_SAVE_MODE_FORMATTER, pdev->ctrl_buf, 1);
	if (r < 0)
		PWC_ERROR("Failed to power %s camera (%d)\n",
			  power ? "on" : "off", r);
}
Пример #13
0
/* release the camera */
static int zr364xx_release(struct file *file)
{
	struct video_device *vdev = video_devdata(file);
	struct zr364xx_camera *cam;
	struct usb_device *udev;
	int i, err;

	DBG("zr364xx_release");

	if (vdev == NULL)
		return -ENODEV;
	cam = video_get_drvdata(vdev);

	udev = cam->udev;

	mutex_lock(&cam->lock);

	cam->users--;
	file->private_data = NULL;

	for (i = 0; i < 2; i++) {
		err =
		    send_control_msg(udev, 1, init[cam->method][i].value,
				     0, init[cam->method][i].bytes,
				     init[cam->method][i].size);
		if (err < 0) {
			dev_err(&udev->dev, "error during release sequence\n");
			goto out;
		}
	}

	/* Added some delay here, since opening/closing the camera quickly,
	 * like Ekiga does during its startup, can crash the webcam
	 */
	mdelay(100);
	err = 0;

out:
	mutex_unlock(&cam->lock);
	return err;
}
Пример #14
0
static int pwc_set_motor(struct pwc_device *pdev)
{
	int ret;

	pdev->ctrl_buf[0] = 0;
	if (pdev->motor_pan_reset->is_new)
		pdev->ctrl_buf[0] |= 0x01;
	if (pdev->motor_tilt_reset->is_new)
		pdev->ctrl_buf[0] |= 0x02;
	if (pdev->motor_pan_reset->is_new || pdev->motor_tilt_reset->is_new) {
		ret = send_control_msg(pdev, SET_MPT_CTL,
				       PT_RESET_CONTROL_FORMATTER,
				       pdev->ctrl_buf, 1);
		if (ret < 0)
			return ret;
	}

	memset(pdev->ctrl_buf, 0, 4);
	if (pdev->motor_pan->is_new) {
		pdev->ctrl_buf[0] = pdev->motor_pan->val & 0xFF;
		pdev->ctrl_buf[1] = (pdev->motor_pan->val >> 8);
	}
Пример #15
0
/* this function reads a full JPEG picture synchronously
 * TODO: do it asynchronously... */
static int read_frame(struct zr364xx_camera *cam, int framenum)
{
	int i, n, temp, head, size, actual_length;
	unsigned char *ptr = NULL, *jpeg;

      redo:
	/* hardware brightness */
	n = send_control_msg(cam->udev, 1, 0x2001, 0, NULL, 0);
	temp = (0x60 << 8) + 127 - cam->brightness;
	n = send_control_msg(cam->udev, 1, temp, 0, NULL, 0);

	/* during the first loop we are going to insert JPEG header */
	head = 0;
	/* this is the place in memory where we are going to build
	 * the JPEG image */
	jpeg = cam->framebuf + framenum * MAX_FRAME_SIZE;
	/* read data... */
	do {
		n = usb_bulk_msg(cam->udev,
				 usb_rcvbulkpipe(cam->udev, 0x81),
				 cam->buffer, BUFFER_SIZE, &actual_length,
				 CTRL_TIMEOUT);
		DBG("buffer : %d %d", cam->buffer[0], cam->buffer[1]);
		DBG("bulk : n=%d size=%d", n, actual_length);
		if (n < 0) {
			dev_err(&cam->udev->dev, "error reading bulk msg\n");
			return 0;
		}
		if (actual_length < 0 || actual_length > BUFFER_SIZE) {
			dev_err(&cam->udev->dev, "wrong number of bytes\n");
			return 0;
		}

		/* swap bytes if camera needs it */
		if (cam->method == METHOD0) {
			u16 *buf = (u16*)cam->buffer;
			for (i = 0; i < BUFFER_SIZE/2; i++)
				swab16s(buf + i);
		}

		/* write the JPEG header */
		if (!head) {
			DBG("jpeg header");
			ptr = jpeg;
			memcpy(ptr, header1, sizeof(header1));
			ptr += sizeof(header1);
			header3 = 0;
			memcpy(ptr, &header3, 1);
			ptr++;
			memcpy(ptr, cam->buffer, 64);
			ptr += 64;
			header3 = 1;
			memcpy(ptr, &header3, 1);
			ptr++;
			memcpy(ptr, cam->buffer + 64, 64);
			ptr += 64;
			memcpy(ptr, header2, sizeof(header2));
			ptr += sizeof(header2);
			memcpy(ptr, cam->buffer + 128,
			       actual_length - 128);
			ptr += actual_length - 128;
			head = 1;
			DBG("header : %d %d %d %d %d %d %d %d %d",
			    cam->buffer[0], cam->buffer[1], cam->buffer[2],
			    cam->buffer[3], cam->buffer[4], cam->buffer[5],
			    cam->buffer[6], cam->buffer[7], cam->buffer[8]);
		} else {
			memcpy(ptr, cam->buffer, actual_length);
			ptr += actual_length;
		}
	}
	/* ... until there is no more */
	while (actual_length == BUFFER_SIZE);

	/* we skip the 2 first frames which are usually buggy */
	if (cam->skip) {
		cam->skip--;
		goto redo;
	}

	/* go back to find the JPEG EOI marker */
	size = ptr - jpeg;
	ptr -= 2;
	while (ptr > jpeg) {
		if (*ptr == 0xFF && *(ptr + 1) == 0xD9
		    && *(ptr + 2) == 0xFF)
			break;
		ptr--;
	}
	if (ptr == jpeg)
		DBG("No EOI marker");

	/* Sometimes there is junk data in the middle of the picture,
	 * we want to skip this bogus frames */
	while (ptr > jpeg) {
		if (*ptr == 0xFF && *(ptr + 1) == 0xFF
		    && *(ptr + 2) == 0xFF)
			break;
		ptr--;
	}
	if (ptr != jpeg) {
		DBG("Bogus frame ? %d", cam->nb);
		goto redo;
	}

	DBG("jpeg : %d %d %d %d %d %d %d %d",
	    jpeg[0], jpeg[1], jpeg[2], jpeg[3],
	    jpeg[4], jpeg[5], jpeg[6], jpeg[7]);

	return size;
}
Пример #16
0
u32 au0828_writereg(struct au0828_dev *dev, u16 reg, u32 val)
{
	dprintk(8, "%s(0x%04x, 0x%02x)\n", __func__, reg, val);
	return send_control_msg(dev, CMD_REQUEST_OUT, val, reg);
}
Пример #17
0
//static void* poll_cq(struct RDMA_communicator* comm)
static void* poll_cq(struct poll_cq_args* args)
{
  struct ibv_cq *cq;
  struct ibv_wc wc;
  struct connection *conn;
  struct RDMA_communicator *comm;
  //  struct RDMA_message *msg;
  struct control_msg cmsg;
  void* ctx;
  char* buff; 
  uint64_t buff_size;
  int tag;

  uint64_t mr_size=0;
  uint64_t sent_size=0;
  char* send_base_addr;

  int* flag = args->flag;

  comm= args->comm;
  buff= args->msg->buff;
  send_base_addr = args->msg->buff;;
  buff_size= args->msg->size;
  tag= args->msg->tag;

  cmsg.type=MR_INIT;
  cmsg.data1.buff_size=buff_size;
  send_control_msg(comm->cm_id->context, &cmsg);
  post_receives(comm->cm_id->context);
  
  while (1) {
    TEST_NZ(ibv_get_cq_event(s_ctx->comp_channel, &cq, &ctx));
    ibv_ack_cq_events(cq, 1);
    TEST_NZ(ibv_req_notify_cq(cq, 0));

    while (ibv_poll_cq(cq, 1, &wc)){
      conn = (struct connection *)(uintptr_t)wc.wr_id;

      if (wc.status != IBV_WC_SUCCESS) {
        die("on_completion: status is not IBV_WC_SUCCESS.");
      }

      if (wc.opcode == IBV_WC_RECV) {
        switch (conn->recv_msg->type)
          {
          case MR_INIT_ACK:
          case MR_CHUNK_ACK:
            debug(printf("Recived: Type=%d\n",  conn->recv_msg->type), 1);
	    if (sent_size == buff_size) {
              /*sent all data*/
	      cmsg.type=MR_FIN;
	      cmsg.data1.tag=tag;
	    } else {
              /*not sent all data yet*/
	      if (sent_size + RDMA_BUF_SIZE_C > buff_size) {
		mr_size = buff_size - sent_size;
	      } else {
		mr_size = RDMA_BUF_SIZE_C;
	      }
	      debug(printf("mr_size=%lu\n", mr_size),1);
	      //	      printf("%s\n", send_base_addr);
	      register_rdma_region(conn, send_base_addr, mr_size);
	      send_base_addr += mr_size;
	      sent_size += mr_size;

	      cmsg.type=MR_CHUNK;
	      cmsg.data1.mr_size=mr_size;
	      memcpy(&cmsg.data.mr, conn->rdma_msg_mr, sizeof(struct ibv_mr));
	      //	      cmsg.data.mr = conn->rdma_msg_mr;
	    }
            break;
          case MR_FIN_ACK:
            debug(printf("Recived: Type=%d\n",  conn->recv_msg->type),1);
	    *flag = 1;
	    // rdma_disconnect(comm->cm_id);
	    // rdma_disconnect(conn->id);
	    //exit(0);
	    return NULL;
          default:
            debug(printf("Unknown TYPE"), 1);
	    return NULL;
          }
	send_control_msg(conn, &cmsg);
        post_receives(conn);
      } else if (wc.opcode == IBV_WC_SEND) {
	  debug(printf("Sent: TYPE=%d\n", conn->send_msg->type),1);
      } else {
	  die("unknow opecode.");
      }
    }
  }
  return NULL;
}
Пример #18
0
//static void* poll_cq(struct RDMA_communicator* comm)
static void* poll_cq(struct poll_cq_args* args)
{
  struct ibv_cq *cq;
  struct ibv_wc wc;
  struct connection *conn;
  struct RDMA_communicator *comm;
  //  struct RDMA_message *msg;
  double s, e;
  char* ip;

  struct control_msg cmsg;
  void* ctx;
  char* buff; 
  uint64_t buff_size;
  int tag;

  uint64_t mr_size=0;
  uint64_t sent_size=0;
  char* send_base_addr;

  int* flag = args->flag;
  int mr_index;

  //for (i = 0; i < RDMA_BUF_NUM_C; i++){ rdma_msg_mr[i] = NULL;}
  
  comm = args->comm;
  buff = args->msg->buff;
  send_base_addr = args->msg->buff;
  buff_size= args->msg->size;
  tag= args->msg->tag;

  cmsg.type=MR_INIT;
  cmsg.data1.buff_size=buff_size;
  send_control_msg(comm->cm_id->context, &cmsg);
  //  fprintf(stderr, "RDMA lib: SEND: INIT: tag=%d\n", tag);
  post_receives(comm->cm_id->context);
  s = get_dtime();
  while (1) {
    if (ibv_get_cq_event(s_ctx->comp_channel, &cq, &ctx)) {
      fprintf(stderr, "RDMA lib: SEND: ERROR: get cq event  failed @ %s:%d", __FILE__, __LINE__);
      exit(1);
    }
    ibv_ack_cq_events(cq, 1);
    if (ibv_req_notify_cq(cq, 0)) {
      fprintf(stderr, "RDMA lib: SEND: ERROR: request notification failed @ %s:%d", __FILE__, __LINE__);
      exit(1);
    }

    while (ibv_poll_cq(cq, 1, &wc)){
      conn = (struct connection *)(uintptr_t)wc.wr_id;
      debug(printf("Control MSG from: %lu\n", (uintptr_t)conn->id), 1);
      if (wc.status != IBV_WC_SUCCESS) {
        die("RDMA lib: SEND: ERROR: on_completion: status is not IBV_WC_SUCCESS.");
      }

      if (wc.opcode == IBV_WC_RECV) {
        switch (conn->recv_msg->type)
          {
          case MR_INIT_ACK:
	    debug(printf("Recived: Type=%d\n",  conn->recv_msg->type), 1);
	    for (mr_index = 0; mr_index < RDMA_BUF_NUM_C; mr_index++) {
	      debug(printf("Recived: Type=%d\n",  conn->recv_msg->type), 1);
	      if (sent_size == buff_size) {
		/*sent all data*/
		cmsg.type=MR_FIN;
		cmsg.data1.tag=tag;
		send_control_msg(conn, &cmsg);
		//		fprintf(stderr,"Yahoooooooooo !!\n");
		post_receives(conn);
		debug(printf("RDMA lib: SEND: Recieved MR_INIT_ACK: for tag=%d\n",  tag), 1);
	      } else {
		debug(printf("RDMA lib: SEND: Recieved MR_INIT_ACK: for tag=%d\n",  tag), 1);
		/*not sent all data yet*/
		if (sent_size + rdma_buf_size > buff_size) {
		  mr_size = buff_size - sent_size;
		} else {
		  mr_size = rdma_buf_size;
		}
		debug(printf("mr_size=%lu\n", mr_size),1);
		//	      printf("%s\n", send_base_addr);
		//	      register_rdma_region(conn, send_base_addr, mr_size);
		
		register_rdma_msg_mr(mr_index, send_base_addr, mr_size);
		send_base_addr += mr_size;
		sent_size += mr_size;
		
		cmsg.type=MR_CHUNK;
		cmsg.data1.mr_size=mr_size;
		memcpy(&cmsg.data.mr, rdma_msg_mr[mr_index], sizeof(struct ibv_mr));
		//	      cmsg.data.mr = conn->rdma_msg_mr;
		send_control_msg(conn, &cmsg);
		//		fprintf(stderr, "RDMA lib: SEND: CHUNK: tag=%d\n", tag);
		post_receives(conn);
	      }
	    }
            break;
          case MR_CHUNK_ACK:

	    if (sent_size == buff_size) {
              /*sent all data*/
	      cmsg.type=MR_FIN;
	      cmsg.data1.tag=tag;
	      debug(printf("RDMA lib: SEND: Recieved MR_CHUNK_ACK => FIN: for tag=%d\n",  tag), 1);
	    } else {
              /*not sent all data yet*/
	      debug(printf("RDMA lib: SEND: Recieved MR_CHUNK_ACK: for tag=%d\n",  tag), 1);
	      if (sent_size + rdma_buf_size > buff_size) {
		mr_size = buff_size - sent_size;
	      } else {
		mr_size = rdma_buf_size;
	      }
	      debug(printf("mr_size=%lu\n", mr_size),1);
	      //	      printf("%s\n", send_base_addr);
	      //	      register_rdma_region(conn, send_base_addr, mr_size);
	      //	      mr_index = (mr_index+ 1) % RDMA_BUF_NUM_C;
	      mr_index = (mr_index+ 1) % RDMA_BUF_NUM_C;
	      debug(printf("mr_index=%d\n", mr_index),1);
	      register_rdma_msg_mr(mr_index, send_base_addr, mr_size);
	      send_base_addr += mr_size;

	      sent_size += mr_size;
	      cmsg.type=MR_CHUNK;
	      cmsg.data1.mr_size=mr_size;
	      memcpy(&cmsg.data.mr, rdma_msg_mr[mr_index], sizeof(struct ibv_mr));
	      //	      cmsg.data.mr = conn->rdma_msg_mr;
	    }
	    send_control_msg(conn, &cmsg);
	    //	    fprintf(stderr, "RDMA lib: SEND: CHUNK2: tag=%d, slid=%lu\n", tag, (uintptr_t)wc.slid);
	    post_receives(conn);
            break;
          case MR_FIN_ACK:
            debug(printf("Recived: Type=%d\n",  conn->recv_msg->type),1);
	    *flag = 1;
	    // rdma_disconnect(comm->cm_id);
	    // rdma_disconnect(conn->id);
	    //exit(0);
	    e = get_dtime();
	    free(args->msg);
	    free(args);
	    //	    fprintf(stderr, "RDMA lib: SEND: FIN_ACK: tag=%d\n", tag);
	    //ip = get_ip_addr("ib0");
	    //	    printf("RDMA lib: SEND: %s: send time= %f secs, send size= %lu MB, throughput = %f MB/s\n", ip, e - s, buff_size/1000000, buff_size/(e - s)/1000000.0);
	    return NULL;
          default:
            debug(printf("Unknown TYPE"), 1);
	    return NULL;
          }
      } else if (wc.opcode == IBV_WC_SEND) {
	//	fprintf(stderr, "RDMA lib: SENT: DONE: tag=%d\n", tag);
	debug(printf("RDMA lib: SEND: Sent: TYPE=%d, tag=%d\n", conn->send_msg->type, tag),1);
      } else {
	  die("unknow opecode.");
      }
    }
  }
  return NULL;
}