* @param udev pointer to the Device Data Structure
* @return returns negative value on failure else 0 on success
*/
-void xhci_setup_addressable_virt_dev(struct usb_device *udev)
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+ int speed, int hop_portnr)
{
- struct usb_device *hop = udev;
struct xhci_virt_device *virt_dev;
struct xhci_ep_ctx *ep0_ctx;
struct xhci_slot_ctx *slot_ctx;
u32 port_num = 0;
u64 trb_64 = 0;
- struct xhci_ctrl *ctrl = udev->controller;
- virt_dev = ctrl->devs[udev->slot_id];
+ virt_dev = ctrl->devs[slot_id];
BUG_ON(!virt_dev);
/* Only the control endpoint is valid - one endpoint context */
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0);
- switch (udev->speed) {
+ switch (speed) {
case USB_SPEED_SUPER:
slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
break;
BUG();
}
- /* Extract the root hub port number */
- if (hop->parent)
- while (hop->parent->parent)
- hop = hop->parent;
- port_num = hop->portnr;
+ port_num = hop_portnr;
debug("port_num = %d\n", port_num);
slot_ctx->dev_info2 |=
/* Step 4 - ring already allocated */
/* Step 5 */
ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT);
- debug("SPEED = %d\n", udev->speed);
+ debug("SPEED = %d\n", speed);
- switch (udev->speed) {
+ switch (speed) {
case USB_SPEED_SUPER:
ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) <<
MAX_PACKET_SHIFT));
* @param udev pointer to the Device Data Structure
* @return 0 if successful else error code on failure
*/
-static int xhci_address_device(struct usb_device *udev)
+static int xhci_address_device(struct usb_device *udev, int root_portnr)
{
int ret = 0;
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
* This is the first Set Address since device plug-in
* so setting up the slot context.
*/
- debug("Setting up addressable devices\n");
- xhci_setup_addressable_virt_dev(udev);
+ debug("Setting up addressable devices %p\n", ctrl->dcbaa);
+ xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed,
+ root_portnr);
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
* @param buffer buffer to be read/written based on the request
* @param length length of the buffer
* @param setup Request type
+ * @param root_portnr Root port number that this device is on
* @return returns 0 if successful else -1 on failure
*/
-int
-submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
- int length, struct devrequest *setup)
+static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup, int root_portnr)
{
struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
int ret = 0;
return xhci_submit_root(udev, pipe, buffer, setup);
if (setup->request == USB_REQ_SET_ADDRESS)
- return xhci_address_device(udev);
+ return xhci_address_device(udev, root_portnr);
if (setup->request == USB_REQ_SET_CONFIGURATION) {
ret = xhci_set_configuration(udev);
return 0;
}
+int submit_control_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length, struct devrequest *setup)
+{
+ struct usb_device *hop = udev;
+
+ if (hop->parent)
+ while (hop->parent->parent)
+ hop = hop->parent;
+
+ return _xhci_submit_control_msg(udev, pipe, buffer, length, setup,
+ hop->portnr);
+}
+
/**
* Stops the XHCI host controller
* and cleans up all the related data structures
void xhci_slot_copy(struct xhci_ctrl *ctrl,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx);
-void xhci_setup_addressable_virt_dev(struct usb_device *udev);
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+ int speed, int hop_portnr);
void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr,
u32 slot_id, u32 ep_index, trb_type cmd);
void xhci_acknowledge_event(struct xhci_ctrl *ctrl);