예제 #1
0
파일: fjes_hw.c 프로젝트: Juan31/linux
enum ep_partner_status
fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
{
	enum ep_partner_status status;

	if (fjes_hw_epid_is_shared(hw->hw_info.share, epid)) {
		if (fjes_hw_epid_is_stop_requested(hw, epid)) {
			status = EP_PARTNER_WAITING;
		} else {
			if (fjes_hw_epid_is_stop_process_done(hw, epid))
				status = EP_PARTNER_COMPLETE;
			else
				status = EP_PARTNER_SHARED;
		}
	} else {
		status = EP_PARTNER_UNSHARE;
	}

	return status;
}
예제 #2
0
파일: fjes_hw.c 프로젝트: Juan31/linux
int fjes_hw_wait_epstop(struct fjes_hw *hw)
{
	enum ep_partner_status status;
	union ep_buffer_info *info;
	int wait_time = 0;
	int epidx;

	while (hw->hw_info.buffer_unshare_reserve_bit &&
	       (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)) {
		for (epidx = 0; epidx < hw->max_epid; epidx++) {
			if (epidx == hw->my_epid)
				continue;
			status = fjes_hw_epid_is_shared(hw->hw_info.share,
							epidx);
			info = hw->ep_shm_info[epidx].rx.info;
			if ((!status ||
			     (info->v1i.rx_status &
			      FJES_RX_STOP_REQ_DONE)) &&
			    test_bit(epidx,
				     &hw->hw_info.buffer_unshare_reserve_bit)) {
				clear_bit(epidx,
					  &hw->hw_info.buffer_unshare_reserve_bit);
			}
		}

		msleep(100);
		wait_time += 100;
	}

	for (epidx = 0; epidx < hw->max_epid; epidx++) {
		if (epidx == hw->my_epid)
			continue;
		if (test_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit))
			clear_bit(epidx,
				  &hw->hw_info.buffer_unshare_reserve_bit);
	}

	return (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)
			? 0 : -EBUSY;
}
예제 #3
0
static int fjes_dbg_status_show(struct seq_file *m, void *v)
{
	struct fjes_adapter *adapter = m->private;
	struct fjes_hw *hw = &adapter->hw;
	int max_epid = hw->max_epid;
	int my_epid = hw->my_epid;
	int epidx;

	seq_puts(m, "EPID\tSTATUS           SAME_ZONE        CONNECTED\n");
	for (epidx = 0; epidx < max_epid; epidx++) {
		if (epidx == my_epid) {
			seq_printf(m, "ep%d\t%-16c %-16c %-16c\n",
				   epidx, '-', '-', '-');
		} else {
			seq_printf(m, "ep%d\t%-16s %-16c %-16c\n",
				   epidx,
				   ep_status_string[fjes_hw_get_partner_ep_status(hw, epidx)],
				   fjes_hw_epid_is_same_zone(hw, epidx) ? 'Y' : 'N',
				   fjes_hw_epid_is_shared(hw->hw_info.share, epidx) ? 'Y' : 'N');
		}
	}

	return 0;
}
예제 #4
0
파일: fjes_main.c 프로젝트: asmalldev/linux
static void fjes_watch_unshare_task(struct work_struct *work)
{
	struct fjes_adapter *adapter =
	container_of(work, struct fjes_adapter, unshare_watch_task);

	struct net_device *netdev = adapter->netdev;
	struct fjes_hw *hw = &adapter->hw;

	int unshare_watch, unshare_reserve;
	int max_epid, my_epid, epidx;
	int stop_req, stop_req_done;
	ulong unshare_watch_bitmask;
	unsigned long flags;
	int wait_time = 0;
	int is_shared;
	int ret;

	my_epid = hw->my_epid;
	max_epid = hw->max_epid;

	unshare_watch_bitmask = adapter->unshare_watch_bitmask;
	adapter->unshare_watch_bitmask = 0;

	while ((unshare_watch_bitmask || hw->txrx_stop_req_bit) &&
	       (wait_time < 3000)) {
		for (epidx = 0; epidx < hw->max_epid; epidx++) {
			if (epidx == hw->my_epid)
				continue;

			is_shared = fjes_hw_epid_is_shared(hw->hw_info.share,
							   epidx);

			stop_req = test_bit(epidx, &hw->txrx_stop_req_bit);

			stop_req_done = hw->ep_shm_info[epidx].rx.info->v1i.rx_status &
					FJES_RX_STOP_REQ_DONE;

			unshare_watch = test_bit(epidx, &unshare_watch_bitmask);

			unshare_reserve = test_bit(epidx,
						   &hw->hw_info.buffer_unshare_reserve_bit);

			if ((!stop_req ||
			     (is_shared && (!is_shared || !stop_req_done))) &&
			    (is_shared || !unshare_watch || !unshare_reserve))
				continue;

			mutex_lock(&hw->hw_info.lock);
			ret = fjes_hw_unregister_buff_addr(hw, epidx);
			switch (ret) {
			case 0:
				break;
			case -ENOMSG:
			case -EBUSY:
			default:
				if (!work_pending(
					&adapter->force_close_task)) {
					adapter->force_reset = true;
					schedule_work(
						&adapter->force_close_task);
				}
				break;
			}
			mutex_unlock(&hw->hw_info.lock);
			hw->ep_shm_info[epidx].ep_stats
					.com_unregist_buf_exec += 1;

			spin_lock_irqsave(&hw->rx_status_lock, flags);
			fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
					    netdev->dev_addr, netdev->mtu);
			spin_unlock_irqrestore(&hw->rx_status_lock, flags);

			clear_bit(epidx, &hw->txrx_stop_req_bit);
			clear_bit(epidx, &unshare_watch_bitmask);
			clear_bit(epidx,
				  &hw->hw_info.buffer_unshare_reserve_bit);
		}

		msleep(100);
		wait_time += 100;
	}

	if (hw->hw_info.buffer_unshare_reserve_bit) {
		for (epidx = 0; epidx < hw->max_epid; epidx++) {
			if (epidx == hw->my_epid)
				continue;

			if (test_bit(epidx,
				     &hw->hw_info.buffer_unshare_reserve_bit)) {
				mutex_lock(&hw->hw_info.lock);

				ret = fjes_hw_unregister_buff_addr(hw, epidx);
				switch (ret) {
				case 0:
					break;
				case -ENOMSG:
				case -EBUSY:
				default:
					if (!work_pending(
						&adapter->force_close_task)) {
						adapter->force_reset = true;
						schedule_work(
							&adapter->force_close_task);
					}
					break;
				}
				mutex_unlock(&hw->hw_info.lock);

				hw->ep_shm_info[epidx].ep_stats
					.com_unregist_buf_exec += 1;

				spin_lock_irqsave(&hw->rx_status_lock, flags);
				fjes_hw_setup_epbuf(
					&hw->ep_shm_info[epidx].tx,
					netdev->dev_addr, netdev->mtu);
				spin_unlock_irqrestore(&hw->rx_status_lock,
						       flags);

				clear_bit(epidx, &hw->txrx_stop_req_bit);
				clear_bit(epidx, &unshare_watch_bitmask);
				clear_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
			}

			if (test_bit(epidx, &unshare_watch_bitmask)) {
				spin_lock_irqsave(&hw->rx_status_lock, flags);
				hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
						~FJES_RX_STOP_REQ_DONE;
				spin_unlock_irqrestore(&hw->rx_status_lock,
						       flags);
			}
		}
	}
}