Пример #1
0
int hsi_reconfigure_protocol(void)
{
	int ret = 0;

	/* ACWAKE ->LOW */
	ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_DOWN, NULL);
	if (ret == 0)
		printk(KERN_INFO "ACWAKE pulled low in %s()\n", __func__);
	else
		printk(KERN_INFO "ACWAKE down fail!! %d\n", ret);


	/*Clse channel 0 */
	ret = if_hsi_closechannel(&hsi_protocol_iface.channels[0]);
	if (ret < 0) {
		pr_err("Can not Close channel 0. Can not Stop HSI protocol for flashless\n");
		goto err;
	}


	printk(KERN_INFO "(%s)(%d) hsi_start_protocol Start.\n", __func__, __LINE__);
	hsi_start_protocol();
	printk(KERN_INFO "(%s)(%d) hsi_start_protocol Done.\n", __func__, __LINE__);

err:

	return ret;
}
static int if_hsi_set_wakeline(struct if_hsi_channel *channel,
			unsigned int state)
{
	int ret;

	spin_lock_bh(&channel->acwake_lock);
	if (channel->acwake == state) {
		spin_unlock_bh(&channel->acwake_lock);
		return 0;
	}

	ret = hsi_ioctl(channel->dev, state ?
		HSI_IOCTL_ACWAKE_UP : HSI_IOCTL_ACWAKE_DOWN, NULL);
	if (ret) {
		if (ret != -EPERM)
			pr_err("[MIPI-HSI] ACWAKE(%d) setting fail : %d\n",
						state, ret);
		/* duplicate operation */
		if (ret == -EPERM)
			channel->acwake = state;
		spin_unlock_bh(&channel->acwake_lock);
		return ret;
	}

	channel->acwake = state;
	spin_unlock_bh(&channel->acwake_lock);

	pr_debug("[MIPI-HSI] ACWAKE_%d(%d)\n", channel->channel_id, state);
	return 0;
}
Пример #3
0
void if_hsi_set_wakeline(int ch, unsigned int state)
{
	struct if_hsi_channel *channel;
	channel = &hsi_protocol_iface.channels[ch];
	hsi_ioctl(channel->dev,
		  state ? HSI_IOCTL_ACWAKE_UP : HSI_IOCTL_ACWAKE_DOWN, NULL);
}
Пример #4
0
//========================================================//
//                ++ Flashless Boot. ++                   //
//========================================================//
int hsi_start_protocol_single(void)
{
	int ret = 0;

	struct hst_ctx tx_config;
	struct hsr_ctx rx_config;

	/*Open channel 0 */
	ret = if_hsi_openchannel(&hsi_protocol_iface.channels[0]);
	if (ret < 0) {
		pr_err("Can not Open channel 0. Can not start HSI protocol\n");
		goto err;
	} else
		printk(KERN_INFO "if_hsi_openchannel() returned %d\n", ret);


	/*Set Tx Config*/
	hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_TX, &tx_config);
	tx_config.mode = 2;
	tx_config.channels = 1;
	tx_config.divisor = 0;
	ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_TX, &tx_config);
	if (ret < 0) {
		printk(KERN_INFO "write_hsi_direct : SET_TX Fail : %d\n", ret);
		return ret;
	}

	hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_RX, &rx_config);
	rx_config.mode = 2;
	rx_config.channels = 1;
	rx_config.divisor = 0;
	//rx_config.timeout = HZ / 2;
	ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_RX, &rx_config);
	if (ret < 0) {
		printk(KERN_INFO "write_hsi_direct : SET_RX Fail : %d\n", ret);
		return ret;
	}

	/* ACWAKE ->HIGH */
	ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL);
	if (ret == 0)
		printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__);

err:

	return ret;
}
Пример #5
0
int read_hsi_direct(u32 *data, int length)
{
	int retval = 0;
#if 0
	struct hsr_ctx rx_config;


	printk(KERN_INFO "read_hsi_direct : len : %d\n", length);
	hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_GET_RX, &rx_config);
	rx_config.mode = 2;
	rx_config.channels = 1;
	rx_config.divisor = 47;
	retval = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_SET_RX, &rx_config);
	if (retval < 0) {
		printk(KERN_INFO "read_hsi_direct : SET_RX Fail : %d\n", retval);
		return retval;
	}
	printk(KERN_INFO "read_hsi_direct : SET_RX Successful\n");

	retval = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL);
	if (retval < 0) {
		printk(KERN_INFO "read_hsi_direct : ACWAKE High Fail : %d\n", retval);
		return retval;
	}
	printk(KERN_INFO "read_hsi_direct : ACWAKE High\n");
#endif

#if 0
	if ((length > 16) && (length % 4))
		length += (4 - (length % 4));
	else if (length < 16)
		length = 16;
#endif
	//printk(KERN_INFO "read_hsi_direct : new len : %d\n", length);

	retval = hsi_proto_read(0, data, length);
	if (retval < 0) {
		printk(KERN_INFO "read_hsi_direct : hsi_proto_read Fail : %d\n", retval);
		return retval;
	}
	//printk(KERN_INFO "read_hsi_direct : Read returned %d\n", retval);

	return retval;
}
static void hsi_conn_err_recovery(struct mipi_link_device *mipi_ld)
{
	int i;
	int ret;
	struct hst_ctx tx_config;
	struct hsr_ctx rx_config;

	if (mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].opened) {
		hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
				HSI_IOCTL_SW_RESET, NULL);
		for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++)
			mipi_ld->hsi_channles[i].opened = 0;
	}

	for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) {
		if (!mipi_ld->hsi_channles[i].opened)
			if_hsi_open_channel(&mipi_ld->hsi_channles[i]);

		hsi_ioctl(mipi_ld->hsi_channles[i].dev,
					HSI_IOCTL_GET_TX, &tx_config);
		tx_config.mode = 2;
		tx_config.divisor = 0; /* Speed : 96MHz */
		tx_config.channels = HSI_MAX_CHANNELS;
		hsi_ioctl(mipi_ld->hsi_channles[i].dev,
					HSI_IOCTL_SET_TX, &tx_config);

		hsi_ioctl(mipi_ld->hsi_channles[i].dev,
					HSI_IOCTL_GET_RX, &rx_config);
		rx_config.mode = 2;
		rx_config.divisor = 0; /* Speed : 96MHz */
		rx_config.channels = HSI_MAX_CHANNELS;
		hsi_ioctl(mipi_ld->hsi_channles[i].dev,
					HSI_IOCTL_SET_RX, &rx_config);
		pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");
	}

	hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
			HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL);
	pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n");

	ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
		mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data, 1);
	if (ret)
		pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);

	for (i = 1; i < HSI_NUM_OF_USE_CHANNELS; i++) {
		if ((mipi_ld->hsi_channles[i].recv_step == STEP_RX) &&
				(mipi_ld->hsi_channles[i].rx_count)) {
			pr_err("[MIPI-HSI] there was rx pending. ch:%d, len:%d",
					i, mipi_ld->hsi_channles[i].rx_count);
			ret = hsi_read(mipi_ld->hsi_channles[i].dev,
					mipi_ld->hsi_channles[i].rx_data,
					mipi_ld->hsi_channles[i].rx_count / 4);
			if (ret)
				pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);
		}
	}

	pr_debug("[MIPI-HSI] hsi_conn_err_recovery Done\n");
}
Пример #7
0
int hsi_start_protocol(void)
{
	struct hst_ctx tx_config;
	struct hsr_ctx rx_config;
	int i, ret = 0;

	printk(KERN_INFO "In function  %s()\n", __func__);
	/*Open All channels */
	for (i = 0; i <= 5; i++) {
		ret = if_hsi_openchannel(&hsi_protocol_iface.channels[i]);
		if (ret < 0)
			pr_err("Can not Open channel->%d . Can not start HSI protocol\n", i);
		else
			printk(KERN_INFO "Channel->%d Open Successful\n", i);

		/*Set Rx Config*/
		hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_GET_RX, &rx_config);
		rx_config.mode = 2;
		rx_config.divisor = 1;
		rx_config.channels = HSI_MAX_CHANNELS;
		ret = hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_SET_RX, &rx_config);
		if (ret == 0)
			printk(KERN_INFO "SET_RX Successful for ch->%d\n", i);

		/*Set Tx Config*/
		hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_GET_TX, &tx_config);
		tx_config.mode = 2;
		tx_config.divisor = 1;
		tx_config.channels = HSI_MAX_CHANNELS;
		ret = hsi_ioctl(hsi_protocol_iface.channels[i].dev, HSI_IOCTL_SET_TX, &tx_config);
		if (ret == 0)
			printk(KERN_INFO "SET_TX Successful for ch->%d\n", i);
	}
	/*Make channel-0 tx_state to IDLE*/
	hsi_protocol_iface.channels[0].tx_state = HSI_LL_TX_STATE_IDLE;
	return ret;
}
static int hsi_init_handshake(struct mipi_link_device *mipi_ld, int mode)
{
	int ret;
	int i;
	struct hst_ctx tx_config;
	struct hsr_ctx rx_config;

	switch (mode) {
	case HSI_INIT_MODE_NORMAL:
		if (timer_pending(&mipi_ld->hsi_acwake_down_timer))
			del_timer(&mipi_ld->hsi_acwake_down_timer);

		for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++) {
			if (mipi_ld->hsi_channles[i].opened) {
				hsi_write_cancel(mipi_ld->hsi_channles[i].dev);
				hsi_read_cancel(mipi_ld->hsi_channles[i].dev);
			} else {
				ret = if_hsi_open_channel(
						&mipi_ld->hsi_channles[i]);
				if (ret)
					return ret;
			}
			mipi_ld->hsi_channles[i].send_step = STEP_IDLE;
			mipi_ld->hsi_channles[i].recv_step = STEP_IDLE;

			hsi_ioctl(mipi_ld->hsi_channles[i].dev,
						HSI_IOCTL_GET_TX, &tx_config);
			tx_config.mode = 2;
			tx_config.divisor = 0; /* Speed : 96MHz */
			tx_config.channels = HSI_MAX_CHANNELS;
			hsi_ioctl(mipi_ld->hsi_channles[i].dev,
						HSI_IOCTL_SET_TX, &tx_config);

			hsi_ioctl(mipi_ld->hsi_channles[i].dev,
						HSI_IOCTL_GET_RX, &rx_config);
			rx_config.mode = 2;
			rx_config.divisor = 0; /* Speed : 96MHz */
			rx_config.channels = HSI_MAX_CHANNELS;
			hsi_ioctl(mipi_ld->hsi_channles[i].dev,
						HSI_IOCTL_SET_RX, &rx_config);
			pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");
		}

		hsi_ioctl(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
			HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL);
		pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n");

		if (mipi_ld->ld.com_state != COM_ONLINE)
			mipi_ld->ld.com_state = COM_HANDSHAKE;

		ret = hsi_read(mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].dev,
			mipi_ld->hsi_channles[HSI_CONTROL_CHANNEL].rx_data,
					1);
		if (ret)
			pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);

		if (mipi_ld->ld.com_state != COM_ONLINE)
			schedule_delayed_work(&mipi_ld->start_work, 3 * HZ);

		pr_debug("[MIPI-HSI] hsi_init_handshake Done : MODE_NORMAL\n");
		return 0;

	case HSI_INIT_MODE_FLASHLESS_BOOT:
		mipi_ld->ld.com_state = COM_BOOT;

		if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) {
			hsi_ioctl(mipi_ld->hsi_channles[
			HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET,
						NULL);
			for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++)
				mipi_ld->hsi_channles[i].opened = 0;
		}

		if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened)
			if_hsi_open_channel(
				&mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]);
		mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].send_step
					= STEP_IDLE;
		mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].recv_step
					= STEP_IDLE;

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_GET_TX, &tx_config);
		tx_config.mode = 2;
		tx_config.divisor = 3; /* Speed : 24MHz */
		tx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_SET_TX, &tx_config);

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_GET_RX, &rx_config);
		rx_config.mode = 2;
		rx_config.divisor = 3; /* Speed : 24MHz */
		rx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_SET_RX, &rx_config);
		pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
				HSI_IOCTL_SET_WAKE_RX_3WIRES_MODE, NULL);
		pr_debug("[MIPI-HSI] Set 3 WIRE MODE\n");

		if (!wake_lock_active(&mipi_ld->wlock)) {
			wake_lock(&mipi_ld->wlock);
			pr_debug("[MIPI-HSI] wake_lock\n");
		}

		ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
		mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1);
		if (ret)
			pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);

		pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT\n");
		return 0;

	case HSI_INIT_MODE_FLASHLESS_BOOT_EBL:
		mipi_ld->ld.com_state = COM_BOOT_EBL;

		if (mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened) {
			hsi_ioctl(mipi_ld->hsi_channles[
			HSI_FLASHLESS_CHANNEL].dev, HSI_IOCTL_SW_RESET,
						NULL);
			for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++)
				mipi_ld->hsi_channles[i].opened = 0;
		}

		if (!mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].opened)
			if_hsi_open_channel(
				&mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL]);

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_GET_TX, &tx_config);
		tx_config.mode = 2;
		tx_config.divisor = 0; /* Speed : 96MHz */
		tx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_SET_TX, &tx_config);

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_GET_RX, &rx_config);
		rx_config.mode = 2;
		rx_config.divisor = 0; /* Speed : 96MHz */
		rx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
					HSI_IOCTL_SET_RX, &rx_config);
		pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");

		hsi_ioctl(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
				HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL);
		pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n");

		if (!wake_lock_active(&mipi_ld->wlock)) {
			wake_lock(&mipi_ld->wlock);
			pr_debug("[MIPI-HSI] wake_lock\n");
		}

		if_hsi_set_wakeline(
			&mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL], 1);

		ret = hsi_read(mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].dev,
		mipi_ld->hsi_channles[HSI_FLASHLESS_CHANNEL].rx_data, 1);
		if (ret)
			pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);

		pr_debug("[MIPI-HSI] hsi_init_handshake Done : FLASHLESS_BOOT_EBL\n");
		return 0;

	case HSI_INIT_MODE_CP_RAMDUMP:
		mipi_ld->ld.com_state = COM_CRASH;

		if (mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened) {
			hsi_ioctl(mipi_ld->hsi_channles[
			HSI_CP_RAMDUMP_CHANNEL].dev, HSI_IOCTL_SW_RESET,
						NULL);
			for (i = 0; i < HSI_NUM_OF_USE_CHANNELS; i++)
				mipi_ld->hsi_channles[i].opened = 0;
		}

		if (!mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].opened)
			if_hsi_open_channel(
				&mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL]);
		mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].send_step
					= STEP_IDLE;
		mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].recv_step
					= STEP_IDLE;

		hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
					HSI_IOCTL_GET_TX, &tx_config);
		tx_config.mode = 2;
		tx_config.divisor = 0; /* Speed : 96MHz */
		tx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
					HSI_IOCTL_SET_TX, &tx_config);

		hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
					HSI_IOCTL_GET_RX, &rx_config);
		rx_config.mode = 2;
		rx_config.divisor = 0; /* Speed : 96MHz */
		rx_config.channels = 1;
		hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
					HSI_IOCTL_SET_RX, &rx_config);
		pr_debug("[MIPI-HSI] Set TX/RX MIPI-HSI\n");

		hsi_ioctl(mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
				HSI_IOCTL_SET_WAKE_RX_4WIRES_MODE, NULL);
		pr_debug("[MIPI-HSI] Set 4 WIRE MODE\n");

		if (!wake_lock_active(&mipi_ld->wlock)) {
			wake_lock(&mipi_ld->wlock);
			pr_debug("[MIPI-HSI] wake_lock\n");
		}

		if_hsi_set_wakeline(
			&mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL], 1);

		ret = hsi_read(
			mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].dev,
			mipi_ld->hsi_channles[HSI_CP_RAMDUMP_CHANNEL].rx_data,
					DUMP_ERR_INFO_SIZE);
		if (ret)
			pr_err("[MIPI-HSI] hsi_read fail : %d\n", ret);

		pr_debug("[MIPI-HSI] hsi_init_handshake Done : RAMDUMP\n");
		return 0;

	default:
		return -EINVAL;
	}
}
Пример #9
0
/*Write data to channel*/
int write_hsi(u32 ch, u32 *data, int length)
{
	int ret;
	//u32 cmd[4] = {0x00000000, 0xAAAAAAAA, 0xBBBBBBBB, 0xCCCCCCCC};
	struct if_hsi_channel *channel;
	struct task_struct *read_thread;

	channel = &hsi_protocol_iface.channels[ch];
	channel->tx_buf = data;
	channel->tx_count = 0;

	//cmd[0] = protocol_create_cmd(HSI_LL_MSG_OPEN_CONN_OCTET, ch, (void *)&length);
	//printk(KERN_INFO "data ptr is %x\n", data);

	if (initialization == 0) {

#if 0
		/* ACWAKE ->HIGH */
		ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL);
		if (ret == 0)
			printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__);
		else
			printk(KERN_INFO "ACWAKE pulled high in %s() ERROR : %d\n", __func__, ret);
#endif

		/*Creating read thread*/
		read_thread = kthread_run(hsi_read_thrd, NULL, "hsi_read_thread");

		initialization++;
	}
	/*Wait till previous data transfer is over*/
	while (channel->tx_state != HSI_LL_TX_STATE_IDLE) {
		//printk(KERN_INFO "Wait 5ms previous data transfer isn't over %s()\n", __func__);

		//msleep(5);

		return -EAGAIN;
	}

#if 1
	/* ACWAKE ->HIGH */
	ret = hsi_ioctl(hsi_protocol_iface.channels[0].dev, HSI_IOCTL_ACWAKE_UP, NULL);
	if (ret == 0)
		printk(KERN_INFO "ACWAKE pulled high in %s()\n", __func__);
	else
		printk(KERN_INFO "ACWAKE pulled high in %s() ERROR : %d\n", __func__, ret);
#endif

	channel->tx_state = HSI_LL_TX_STATE_WAIT_FOR_ACK;

	//send_cmd(cmd, channel, data)
	//ret = hsi_proto_write(0, &cmd, 4*4);
	//printk(KERN_INFO "Write returned %d\n", ret);
	hsi_protocol_send_command(HSI_LL_MSG_OPEN_CONN_OCTET, ch, length);

	wait_event_interruptible(ipc_write_wait, channel->tx_count != 0);

	return	channel->tx_count;


}