コード例 #1
0
bool link_pm_set_active(struct usb_link_device *usb_ld)
{
	int ret;
	struct link_pm_data *pm_data = usb_ld->link_pm_data;
	struct device *dev;

	if (has_hub(usb_ld)) {
		if (pm_data->hub_status != HUB_STATE_ACTIVE) {
			INIT_COMPLETION(pm_data->hub_active);
			SET_SLAVE_WAKEUP(usb_ld->pdata, 1);
			ret = wait_for_completion_timeout(&pm_data->hub_active,
				msecs_to_jiffies(2000));
			if (!ret) { /*timeout*/
				pr_err("%s: hub on timeout - retry\n",
						__func__);
				SET_SLAVE_WAKEUP(usb_ld->pdata, 0);
				queue_delayed_work(usb_ld->ld.tx_wq,
						&usb_ld->ld.tx_delayed_work, 0);
				return false;
			} else {
				pr_err("wait done\n");
				usb_make_resume(usb_ld);
				return true;
			}
		}
	} else {
		/* TODO do something */
	}
	return true;
}
コード例 #2
0
static int start_ipc(struct link_device *ld, struct io_device *iod)
{
	struct sk_buff *skb;
	char data[1] = {'a'};
	int err;
	struct usb_link_device *usb_ld = to_usb_link_device(ld);
	struct if_usb_devdata *pipe_data = &usb_ld->devdata[IF_USB_FMT_EP];

	if (has_hub(usb_ld) && usb_ld->link_pm_data->hub_handshake_done) {
		mif_err("Already send start ipc, skip start ipc\n");
		err = 0;
		goto exit;
	}

	if (!usb_ld->if_usb_connected) {
		mif_err("HSIC/USB not connected, skip start ipc\n");
		err = -ENODEV;
		goto exit;
	}

	if (has_hub(usb_ld) &&
		usb_ld->if_usb_initstates == INIT_IPC_START_DONE) {
		mif_debug("Already IPC started\n");
		err = 0;
		goto exit;
	}

	mif_info("send 'a'\n");

	skb = alloc_skb(16, GFP_ATOMIC);
	if (unlikely(!skb))
		return -ENOMEM;
	memcpy(skb_put(skb, 1), data, 1);

	skbpriv(skb)->iod = iod;
	skbpriv(skb)->ld = &usb_ld->ld;
	err = usb_tx_urb_with_skb(usb_ld, skb, pipe_data);
	if (err < 0) {
		mif_err("usb_tx_urb fail\n");
		goto exit;
	}
	usb_ld->link_pm_data->hub_handshake_done = true;
	usb_ld->if_usb_initstates = INIT_IPC_START_DONE;
exit:
	return err;
}
コード例 #3
0
/***********************************************************************//**
 * @brief Print VO client information
 *
 * @param[in] chatter Chattiness (defaults to NORMAL).
 * @return String containing VO client information
 ***************************************************************************/
std::string GVOClient::print(const GChatter& chatter) const
{
    // Initialise result string
    std::string result;

    // Continue only if chatter is not silent
    if (chatter != SILENT) {

        // Append header
        result.append("=== GVOClient ===");

        // Append client information
        result.append("\n"+gammalib::parformat("Name")+m_name);

        // Append Hub information
        if (has_hub()) {
            result.append("\n"+gammalib::parformat("Hub key")+m_secret);
            result.append("\n"+gammalib::parformat("Hub URL")+m_hub_url);
            result.append("\n"+gammalib::parformat("Hub host")+m_hub_host);
            result.append("\n"+gammalib::parformat("Hub port")+m_hub_port);
            result.append("\n"+gammalib::parformat("Hub path")+m_hub_path);
            result.append("\n"+gammalib::parformat("SAMP protocol version"));
            result.append(m_version);
            result.append("\n"+gammalib::parformat("Hub connection"));
            if (is_connected()) {
                if (!m_client_key.empty()) {
                    result.append("registered as \""+m_client_id);
                    result.append("\" on Hub \""+m_hub_id);
                    result.append("\".");
                }
                else {
                    result.append("established.");
                }
            }
            else {
                result.append("no");
            }
        }
        else {
            result.append("\n"+gammalib::parformat("Hub key"));
            result.append("No Hub has been found");
        }

    } // endif: chatter was not silent

    // Return result
    return result;
}
コード例 #4
0
/***********************************************************************//**
 * @brief Unregister client from VO Hub
 *
 * Disconnects the VO client from the VO Hub. The client is unregistered.
 ***************************************************************************/
void GVOClient::disconnect(void)
{
    // Continue only if we have a Hub
    if (has_hub()) {

        // Unregister from Hub
        unregister_from_hub();

        // Close socket
        if (m_socket != -1) {
            close(m_socket);
            m_socket = -1;
        }

    } // endif: we had a Hub

    // Return
    return;
}
コード例 #5
0
/***********************************************************************//**
 * @brief Register client at VO Hub
 *
 * Registers a client at the VO Hub. The method will search for a VO Hub,
 * launch it's own VO Hub if no Hub was found, and the register the client
 * at the Hub, including sending of metadata.
 ***************************************************************************/
void GVOClient::connect(void)
{
    // Require a Hub
    require_hub();

    // Continue only if we have a Hub
    if (has_hub()) {
    
        // Register to Hub
        register_to_hub();

        // Send meta data
        send_metadata();

    } // endif: we had a Hub

    // Return
    return;
}
コード例 #6
0
bool link_pm_is_connected(struct usb_link_device *usb_ld)
{
	if (has_hub(usb_ld)) {
		if (usb_ld->link_pm_data->hub_init_lock)
			return false;

		if (usb_ld->link_pm_data->hub_status != HUB_STATE_ACTIVE) {
			schedule_delayed_work(
					&usb_ld->link_pm_data->link_pm_hub, 0);
			return false;
		}
	}

	if (!usb_ld->if_usb_connected) {
		mif_err("mif: if not connected\n");
		return false;
	}

	return true;
}
コード例 #7
0
static void if_usb_force_disconnect(struct work_struct *work)
{
	struct usb_link_device *usb_ld =
		container_of(work, struct usb_link_device, disconnect_work);
	struct usb_device *udev = usb_ld->usbdev;

	/* if already disconnected before run this workqueue */
	if (!udev || !(&udev->dev) || !usb_ld->if_usb_connected)
		return;

	/* disconnect udev's parent if usb hub used */
	if (has_hub(usb_ld))
		udev = udev->parent;

	pm_runtime_get_sync(&udev->dev);
	if (udev->state != USB_STATE_NOTATTACHED) {
		usb_force_disconnect(udev);
		mif_info("force disconnect\n");
	}
	pm_runtime_put_autosuspend(&udev->dev);
}
コード例 #8
0
bool link_pm_is_connected(struct usb_link_device *usb_ld)
{
	if (has_hub(usb_ld)) {
		struct link_pm_data *pm_data = usb_ld->link_pm_data;
		if (pm_data->hub_init_lock)
			return false;

		if (pm_data->hub_status == HUB_STATE_OFF) {
			if (pm_data->hub_work_running == false)
				start_hub_work(pm_data, 0);
			return false;
		}
	}

	if (!usb_ld->if_usb_connected) {
		mif_err("mif: if not connected\n");
		return false;
	}

	return true;
}
コード例 #9
0
static void if_usb_disconnect(struct usb_interface *intf)
{
	struct usb_link_device *usb_ld  = usb_get_intfdata(intf);
	struct usb_device *usbdev = usb_ld->usbdev;
	struct link_pm_data *pm_data = usb_ld->link_pm_data;
	int dev_id = intf->altsetting->desc.bInterfaceNumber;
	struct if_usb_devdata *pipe_data = &usb_ld->devdata[dev_id];


	usb_set_intfdata(intf, NULL);

	pipe_data->disconnected = 1;
	smp_wmb();

	wake_up(&usb_ld->l2_wait);

	usb_ld->if_usb_connected = 0;
	usb_ld->flow_suspend = 1;

	dev_dbg(&usbdev->dev, "%s\n", __func__);
	usb_ld->dev_count--;
	usb_driver_release_interface(&if_usb_driver, pipe_data->data_intf);

	usb_kill_anchored_urbs(&pipe_data->reading);
	usb_free_urbs(usb_ld, pipe_data);

	if (usb_ld->dev_count == 0) {
		cancel_delayed_work_sync(&usb_ld->runtime_pm_work);
		cancel_delayed_work_sync(&usb_ld->post_resume_work);
		cancel_delayed_work_sync(&usb_ld->ld.tx_delayed_work);
		usb_put_dev(usbdev);
		usb_ld->usbdev = NULL;
		if (!has_hub(usb_ld)) {
			if (pm_data->root_hub)
				pm_runtime_forbid(pm_data->root_hub);
			schedule_delayed_work(&usb_ld->wait_enumeration,
					WAIT_ENUMURATION_TIMEOUT_JIFFIES);
		}
	}
}
コード例 #10
0
/***********************************************************************//**
 * @brief Find VO Hub
 *
 * @return True if VO Hub has been found, false otherwise.
 *
 * Search a valid VO Hub and retrieve all mandatory token for this Hub.
 * The mandatory tokens are
 *
 *     samp.secret           Opaque text string required for Hub registration
 *     samp.hub.xmlrpc.url   XML-RPC endpoint for communication
 *     samp.profile.version  Version of SAMP profile
 *
 * Implements IVOA standard REC-SAMP-1.3-20120411.
 ***************************************************************************/
bool GVOClient::find_hub(void)
{
    // Allocate line buffer
    const int n = 1000; 
    char      line[n];

    // Initialise find flag to false
    bool found = false;

    // Get lockfile URL
    std::string lockurl = get_hub_lockfile();

    // Continue only if a URL has been found
    if (!lockurl.empty()) {

        // If we have a file:// prefix then strip it now. This is a kluge
        // and should be remplaced by a method that allows opening any kind
        // of URL
        if (lockurl.compare(0, 7, "file://") == 0) {
            lockurl = lockurl.substr(7, std::string::npos);
        }
    
        // Open SAMP lockfile. Continue only if opening was successful
        FILE* fptr = fopen(lockurl.c_str(), "r");
        if (fptr != NULL) {

            // Parse lockfile and search for mandatory tokens
            while (fgets(line, n, fptr) != NULL) {

                // Convert line to C++ string
                std::string cline = std::string(line);

                // Check for secret key
                if (cline.compare(0, 12, "samp.secret=") == 0) {
                    m_secret = gammalib::strip_chars(cline.substr(12, std::string::npos), "\r\n");
                }

                // Check for Hub URL
                else if (cline.compare(0, 20, "samp.hub.xmlrpc.url=") == 0) {
                    m_hub_url = gammalib::strip_chars(cline.substr(20, std::string::npos), "\r\n");
                }

                // Check for profile version
                else if (cline.compare(0, 21, "samp.profile.version=") == 0) {
                    m_version = gammalib::strip_chars(cline.substr(21, std::string::npos), "\r\n");
                }

            }

            // Close SAMP lockfile
            fclose(fptr);

            // Extract host, port and path from Hub URL
            if (m_hub_url.compare(0, 7, "http://") == 0) {
                size_t length;
                size_t start = 7;
                size_t stop  = m_hub_url.find(":", start);
                size_t end   = std::string::npos;
                if (stop != std::string::npos) {
                    length = stop - start;
                }
                else {
                    length = std::string::npos;
                }
                m_hub_host = m_hub_url.substr(start, length);
                if (stop != std::string::npos) {
                    stop++;
                    end  = m_hub_url.find("/", stop);
                    if (end != std::string::npos) {
                        length = end - stop;
                    }
                    else {
                        length = std::string::npos;
                    }
                    m_hub_port = m_hub_url.substr(stop, length);
                }
                if (end != std::string::npos) {
                    end++;
                    length     = m_hub_url.length() - end;
                    m_hub_path = m_hub_url.substr(end, length);
                }
            }

            // Check for existence of mandatory tokens
            found = has_hub();

        } // endif: SAMP lockfile opened

    } // endif: URL has been found

    // Return find flag
    return found;
}
コード例 #11
0
static int __devinit if_usb_probe(struct usb_interface *intf,
					const struct usb_device_id *id)
{
	struct usb_host_interface *data_desc;
	struct usb_link_device *usb_ld =
			(struct usb_link_device *)id->driver_info;
	struct link_device *ld = &usb_ld->ld;
	struct usb_interface *data_intf;
	struct usb_device *usbdev = interface_to_usbdev(intf);
	struct device *dev, *ehci_dev, *root_hub;
	struct if_usb_devdata *pipe;
	struct urb *urb;
	int i;
	int j;
	int dev_id;
	int err;

	/* To detect usb device order probed */
	dev_id = intf->cur_altsetting->desc.bInterfaceNumber;

	if (dev_id >= IF_USB_DEVNUM_MAX) {
		dev_err(&intf->dev, "Device id %d cannot support\n",
								dev_id);
		return -EINVAL;
	}

	if (!usb_ld) {
		dev_err(&intf->dev,
		"if_usb device doesn't be allocated\n");
		err = ENOMEM;
		goto out;
	}

	mif_info("probe dev_id=%d usb_device_id(0x%p), usb_ld (0x%p)\n",
				dev_id, id, usb_ld);

	usb_ld->usbdev = usbdev;
	usb_get_dev(usbdev);

	for (i = 0; i < IF_USB_DEVNUM_MAX; i++) {
		data_intf = usb_ifnum_to_if(usbdev, i);

		/* remap endpoint of RAW to no.1 for LTE modem */
		if (i == 0)
			pipe = &usb_ld->devdata[1];
		else if (i == 1)
			pipe = &usb_ld->devdata[0];
		else
			pipe = &usb_ld->devdata[i];

		pipe->disconnected = 0;
		pipe->data_intf = data_intf;
		data_desc = data_intf->cur_altsetting;

		/* Endpoints */
		if (usb_pipein(data_desc->endpoint[0].desc.bEndpointAddress)) {
			pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
				data_desc->endpoint[0].desc.bEndpointAddress);
			pipe->tx_pipe = usb_sndbulkpipe(usbdev,
				data_desc->endpoint[1].desc.bEndpointAddress);
			pipe->rx_buf_size = 1024*4;
		} else {
			pipe->rx_pipe = usb_rcvbulkpipe(usbdev,
				data_desc->endpoint[1].desc.bEndpointAddress);
			pipe->tx_pipe = usb_sndbulkpipe(usbdev,
				data_desc->endpoint[0].desc.bEndpointAddress);
			pipe->rx_buf_size = 1024*4;
		}

		if (i == 0) {
			dev_info(&usbdev->dev, "USB IF USB device found\n");
		} else {
			err = usb_driver_claim_interface(&if_usb_driver,
					data_intf, usb_ld);
			if (err < 0) {
				mif_err("failed to cliam usb interface\n");
				goto out;
			}
		}

		usb_set_intfdata(data_intf, usb_ld);
		usb_ld->dev_count++;
		pm_suspend_ignore_children(&data_intf->dev, true);

		for (j = 0; j < URB_COUNT; j++) {
			urb = usb_alloc_urb(0, GFP_KERNEL);
			if (!urb) {
				mif_err("alloc urb fail\n");
				err = -ENOMEM;
				goto out2;
			}

			urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
			urb->transfer_buffer = usb_alloc_coherent(usbdev,
				pipe->rx_buf_size, GFP_KERNEL,
				&urb->transfer_dma);
			if (!urb->transfer_buffer) {
				mif_err(
				"Failed to allocate transfer buffer\n");
				usb_free_urb(urb);
				err = -ENOMEM;
				goto out2;
			}

			usb_fill_bulk_urb(urb, usbdev, pipe->rx_pipe,
				urb->transfer_buffer, pipe->rx_buf_size,
				usb_rx_complete, pipe);
			usb_anchor_urb(urb, &pipe->urbs);
		}
	}

	/* temporary call reset_resume */
	atomic_set(&usb_ld->suspend_count, 1);
	if_usb_reset_resume(data_intf);
	atomic_set(&usb_ld->suspend_count, 0);

	SET_HOST_ACTIVE(usb_ld->pdata, 1);
	usb_ld->host_wake_timeout_flag = 0;

	if (gpio_get_value(usb_ld->pdata->gpio_phone_active)) {
		struct link_pm_data *pm_data = usb_ld->link_pm_data;
		int delay = pm_data->autosuspend_delay_ms ?:
				DEFAULT_AUTOSUSPEND_DELAY_MS;
		pm_runtime_set_autosuspend_delay(&usbdev->dev, delay);
		dev = &usbdev->dev;
		if (dev->parent) {
			dev_dbg(&usbdev->dev, "if_usb Runtime PM Start!!\n");
			usb_enable_autosuspend(usb_ld->usbdev);
			/* s5p-ehci runtime pm allow - usb phy suspend mode */
			root_hub = &usbdev->bus->root_hub->dev;
			ehci_dev = root_hub->parent;
			mif_debug("ehci device = %s, %s\n",
					dev_driver_string(ehci_dev),
					dev_name(ehci_dev));
			pm_runtime_allow(ehci_dev);

			if (!pm_data->autosuspend)
				pm_runtime_forbid(dev);

			if (has_hub(usb_ld))
				link_pm_preactive(pm_data);

			pm_data->root_hub = root_hub;
		}

		usb_ld->flow_suspend = 0;
		/* Queue work if skbs were pending before a disconnect/probe */
		if (ld->sk_fmt_tx_q.qlen || ld->sk_raw_tx_q.qlen)
			queue_delayed_work(ld->tx_wq, &ld->tx_delayed_work, 0);

		usb_ld->if_usb_connected = 1;
		/*USB3503*/
		mif_debug("hub active complete\n");

		usb_change_modem_state(usb_ld, STATE_ONLINE);
	} else {