/* Return the maximum endpoint service interval time (ESIT) payload. * Basically, this is the maxpacket size, multiplied by the burst size * and mult size. */ static inline u32 xhci_get_max_esit_payload(struct xhci_hcd *xhci, struct usb_device *udev, struct usb_host_endpoint *ep) { int max_burst; int max_packet; /* Only applies for interrupt or isochronous endpoints */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) return 0; if (udev->speed == USB_SPEED_SUPER) { if (ep->ss_ep_comp) return ep->ss_ep_comp->desc.wBytesPerInterval; xhci_warn(xhci, "WARN no SS endpoint companion descriptor.\n"); /* Assume no bursts, no multiple opportunities to send. */ return ep->desc.wMaxPacketSize; } max_packet = ep->desc.wMaxPacketSize & 0x3ff; max_burst = (ep->desc.wMaxPacketSize & 0x1800) >> 11; /* A 0 in max burst means 1 transfer per ESIT */ return max_packet * (max_burst + 1); }
static inline u32 xhci_get_endpoint_type(struct usb_device *udev, struct usb_host_endpoint *ep) { int in; u32 type; in = usb_endpoint_dir_in(&ep->desc); if (usb_endpoint_xfer_control(&ep->desc)) { type = EP_TYPE(CTRL_EP); } else if (usb_endpoint_xfer_bulk(&ep->desc)) { if (in) type = EP_TYPE(BULK_IN_EP); else type = EP_TYPE(BULK_OUT_EP); } else if (usb_endpoint_xfer_isoc(&ep->desc)) { if (in) type = EP_TYPE(ISOC_IN_EP); else type = EP_TYPE(ISOC_OUT_EP); } else if (usb_endpoint_xfer_int(&ep->desc)) { if (in) type = EP_TYPE(INT_IN_EP); else type = EP_TYPE(INT_OUT_EP); } else { BUG(); } return type; }
static int get_pipe(struct stub_device *sdev, int epnum, int dir) { struct usb_device *udev = interface_to_usbdev(sdev->interface); struct usb_host_endpoint *ep; struct usb_endpoint_descriptor *epd = NULL; ep = get_ep_from_epnum(udev, epnum); if (!ep) { uerr("no such endpoint?, %d", epnum); BUG(); } epd = &ep->desc; #if 0 /* epnum 0 is always control */ if (epnum == 0) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, 0); else return usb_rcvctrlpipe(udev, 0); } #endif if (usb_endpoint_xfer_control(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndctrlpipe(udev, epnum); else return usb_rcvctrlpipe(udev, epnum); } if (usb_endpoint_xfer_bulk(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndbulkpipe(udev, epnum); else return usb_rcvbulkpipe(udev, epnum); } if (usb_endpoint_xfer_int(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndintpipe(udev, epnum); else return usb_rcvintpipe(udev, epnum); } if (usb_endpoint_xfer_isoc(epd)) { if (dir == USBIP_DIR_OUT) return usb_sndisocpipe(udev, epnum); else return usb_rcvisocpipe(udev, epnum); } /* NOT REACHED */ uerr("get pipe, epnum %d\n", epnum); return 0; }
int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); unsigned long flags; int ret = 0; unsigned int slot_id, ep_index; if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, __func__) <= 0) return -EINVAL; slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); if (!xhci->devs || !xhci->devs[slot_id]) { if (!in_interrupt()) dev_warn(&urb->dev->dev, "WARN: urb submitted for dev with no Slot ID\n"); ret = -EINVAL; goto exit; } if (!test_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags)) { if (!in_interrupt()) xhci_dbg(xhci, "urb submitted during PCI suspend\n"); ret = -ESHUTDOWN; goto exit; } if (usb_endpoint_xfer_control(&urb->ep->desc)) { if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); if (ret < 0) return ret; } spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); spin_unlock_irqrestore(&xhci->lock, flags); } else { ret = -EINVAL; } exit: return ret; }
/** * xhci_get_endpoint_index - Used for passing endpoint bitmasks between the core and * HCDs. Find the index for an endpoint given its descriptor. Use the return * value to right shift 1 for the bitmask. * * Index = (epnum * 2) + direction - 1, * where direction = 0 for OUT, 1 for IN. * For control endpoints, the IN index is used (OUT index is unused), so * index = (epnum * 2) + direction - 1 = (epnum * 2) + 1 - 1 = (epnum * 2) */ unsigned int xhci_get_endpoint_index(struct usb_endpoint_descriptor *desc) { unsigned int index; if (usb_endpoint_xfer_control(desc)) index = (unsigned int) (usb_endpoint_num(desc)*2); else index = (unsigned int) (usb_endpoint_num(desc)*2) + (usb_endpoint_dir_in(desc) ? 1 : 0) - 1; return index; }
/* Return the polling or NAK interval. * * The polling interval is expressed in "microframes". If xHCI's Interval field * is set to N, it will service the endpoint every 2^(Interval)*125us. * * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval * is set to 0. */ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, struct usb_host_endpoint *ep) { unsigned int interval = 0; switch (udev->speed) { case USB_SPEED_HIGH: /* Max NAK rate */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) interval = ep->desc.bInterval; /* Fall through - SS and HS isoc/int have same decoding */ case USB_SPEED_SUPER: if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { if (ep->desc.bInterval == 0) interval = 0; else interval = ep->desc.bInterval - 1; if (interval > 15) interval = 15; if (interval != ep->desc.bInterval + 1) dev_warn(&udev->dev, "ep %#x - rounding interval to %d microframes\n", ep->desc.bEndpointAddress, 1 << interval); } break; /* Convert bInterval (in 1-255 frames) to microframes and round down to * nearest power of 2. */ case USB_SPEED_FULL: case USB_SPEED_LOW: if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { interval = fls(8*ep->desc.bInterval) - 1; if (interval > 10) interval = 10; if (interval < 3) interval = 3; if ((1 << interval) != 8*ep->desc.bInterval) dev_warn(&udev->dev, "ep %#x - rounding interval" " to %d microframes, " "ep desc says %d microframes\n", ep->desc.bEndpointAddress, 1 << interval, 8*ep->desc.bInterval); } break; default: BUG(); } return EP_INTERVAL(interval); }
/* * Wait for all URBs to the endpoint to be completed, then delete the * qset. */ static void whc_endpoint_disable(struct usb_hcd *usb_hcd, struct usb_host_endpoint *ep) { struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); struct whc *whc = wusbhc_to_whc(wusbhc); struct whc_qset *qset; qset = ep->hcpriv; if (qset) { ep->hcpriv = NULL; if (usb_endpoint_xfer_bulk(&ep->desc) || usb_endpoint_xfer_control(&ep->desc)) asl_qset_delete(whc, qset); else pzl_qset_delete(whc, qset); } }
/* Return the polling or NAK interval. * * The polling interval is expressed in "microframes". If xHCI's Interval field * is set to N, it will service the endpoint every 2^(Interval)*125us. * * The NAK interval is one NAK per 1 to 255 microframes, or no NAKs if interval * is set to 0. */ static inline unsigned int xhci_get_endpoint_interval(struct usb_device *udev, struct usb_host_endpoint *ep) { unsigned int interval = 0; switch (udev->speed) { case USB_SPEED_HIGH: /* Max NAK rate */ if (usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_bulk(&ep->desc)) { interval = xhci_parse_microframe_interval(udev, ep); break; } /* Fall through - SS and HS isoc/int have same decoding */ case USB_SPEED_SUPER: if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { interval = xhci_parse_exponent_interval(udev, ep); } break; case USB_SPEED_FULL: if (usb_endpoint_xfer_isoc(&ep->desc)) { interval = xhci_parse_exponent_interval(udev, ep); break; } /* * Fall through for interrupt endpoint interval decoding * since it uses the same rules as low speed interrupt * endpoints. */ case USB_SPEED_LOW: if (usb_endpoint_xfer_int(&ep->desc) || usb_endpoint_xfer_isoc(&ep->desc)) { interval = xhci_parse_frame_interval(udev, ep); } break; default: BUG(); } return EP_INTERVAL(interval); }
void xhci_endpoint_reset(struct usb_hcd *hcd, struct usb_host_endpoint *ep) { struct xhci_hcd *xhci; struct usb_device *udev; unsigned int ep_index; unsigned long flags; int ret; struct xhci_virt_ep *virt_ep; xhci = hcd_to_xhci(hcd); udev = (struct usb_device *) ep->hcpriv; if (!ep->hcpriv) return; ep_index = xhci_get_endpoint_index(&ep->desc); virt_ep = &xhci->devs[udev->slot_id]->eps[ep_index]; if (!virt_ep->stopped_td) { xhci_dbg(xhci, "Endpoint 0x%x not halted, refusing to reset.\n", ep->desc.bEndpointAddress); return; } if (usb_endpoint_xfer_control(&ep->desc)) { xhci_dbg(xhci, "Control endpoint stall already handled.\n"); return; } xhci_dbg(xhci, "Queueing reset endpoint command\n"); spin_lock_irqsave(&xhci->lock, flags); ret = xhci_queue_reset_ep(xhci, udev->slot_id, ep_index); if (!ret) { xhci_cleanup_stalled_ring(xhci, udev, ep_index); kfree(virt_ep->stopped_td); xhci_ring_cmd_db(xhci); } spin_unlock_irqrestore(&xhci->lock, flags); if (ret) xhci_warn(xhci, "FIXME allocate a new ring segment\n"); }
static void whc_endpoint_reset(struct usb_hcd *usb_hcd, struct usb_host_endpoint *ep) { struct wusbhc *wusbhc = usb_hcd_to_wusbhc(usb_hcd); struct whc *whc = wusbhc_to_whc(wusbhc); struct whc_qset *qset; unsigned long flags; spin_lock_irqsave(&whc->lock, flags); qset = ep->hcpriv; if (qset) { qset->remove = 1; qset->reset = 1; if (usb_endpoint_xfer_bulk(&ep->desc) || usb_endpoint_xfer_control(&ep->desc)) queue_work(whc->workqueue, &whc->async_work); else queue_work(whc->workqueue, &whc->periodic_work); } spin_unlock_irqrestore(&whc->lock, flags); }
static int sunxi_hcd_alloc_temp_setup(struct urb *urb, gfp_t mem_flags) { struct temp_buffer *temp; if (!usb_endpoint_xfer_control(&urb->ep->desc)) return 0; /* sunxi hardware requires setup packet to be DMA aligned */ if (!((uintptr_t)urb->setup_packet & (SUNXI_USB_DMA_ALIGN - 1))) return 0; /* Allocate a buffer with enough padding for alignment */ temp = alloc_temp_buffer(sizeof(struct usb_ctrlrequest), mem_flags); if (!temp) return -ENOMEM; temp->old_buffer = urb->setup_packet; memcpy(temp->data, urb->setup_packet, sizeof(struct usb_ctrlrequest)); urb->setup_packet = temp->data; urb->transfer_flags |= URB_ALIGNED_TEMP_SETUP; return 0; }
static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_endpoint *ep, unsigned char *buffer, int size) { struct usb_ss_ep_comp_descriptor *desc; int max_tx; /* The SuperSpeed endpoint companion descriptor is supposed to * be the first thing immediately following the endpoint descriptor. */ desc = (struct usb_ss_ep_comp_descriptor *) buffer; if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || size < USB_DT_SS_EP_COMP_SIZE) { dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); /* Fill in some default values. * Leave bmAttributes as zero, which will mean no streams for * bulk, and isoc won't support multiple bursts of packets. * With bursts of only one packet, and a Mult of 1, the max * amount of data moved per endpoint service interval is one * packet. */ ep->ss_ep_comp.bLength = USB_DT_SS_EP_COMP_SIZE; ep->ss_ep_comp.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; if (usb_endpoint_xfer_isoc(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) ep->ss_ep_comp.wBytesPerInterval = ep->desc.wMaxPacketSize; return; } memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE); /* Check the various values */ if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) { dev_warn(ddev, "Control endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bMaxBurst = 0; } else if (desc->bMaxBurst > 15) { dev_warn(ddev, "Endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to 15\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bMaxBurst = 15; } if ((usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) && desc->bmAttributes != 0) { dev_warn(ddev, "%s endpoint with bmAttributes = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", desc->bmAttributes, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 0; } else if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) { dev_warn(ddev, "Bulk endpoint with more than 65536 streams in " "config %d interface %d altsetting %d ep %d: " "setting to max\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 16; } else if (usb_endpoint_xfer_isoc(&ep->desc) && desc->bmAttributes > 2) { dev_warn(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", desc->bmAttributes + 1, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 2; } if (usb_endpoint_xfer_isoc(&ep->desc)) max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * usb_endpoint_maxp(&ep->desc); else if (usb_endpoint_xfer_int(&ep->desc)) max_tx = usb_endpoint_maxp(&ep->desc) * (desc->bMaxBurst + 1); else max_tx = 999999; if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", le16_to_cpu(desc->wBytesPerInterval), cfgno, inum, asnum, ep->desc.bEndpointAddress, max_tx); ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); } }
static int usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_endpoint *ep, int num_ep, unsigned char *buffer, int size) { unsigned char *buffer_start = buffer; struct usb_ss_ep_comp_descriptor *desc; int retval; int num_skipped; int max_tx; int i; desc = (struct usb_ss_ep_comp_descriptor *) buffer; if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP) { dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); /* * The next descriptor is for an Endpoint or Interface, * no extra descriptors to copy into the companion structure, * and we didn't eat up any of the buffer. */ return 0; } memcpy(&ep->ss_ep_comp->desc, desc, USB_DT_SS_EP_COMP_SIZE); desc = &ep->ss_ep_comp->desc; buffer += desc->bLength; size -= desc->bLength; /* Eat up the other descriptors we don't care about */ ep->ss_ep_comp->extra = buffer; i = find_next_descriptor(buffer, size, USB_DT_ENDPOINT, USB_DT_INTERFACE, &num_skipped); ep->ss_ep_comp->extralen = i; buffer += i; size -= i; retval = buffer - buffer_start; if (num_skipped > 0) dev_dbg(ddev, "skipped %d descriptor%s after %s\n", num_skipped, plural(num_skipped), "SuperSpeed endpoint companion"); /* Check the various values */ if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) { dev_warn(ddev, "Control endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); desc->bMaxBurst = 0; } if (desc->bMaxBurst > 15) { dev_warn(ddev, "Endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to 15\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); desc->bMaxBurst = 15; } if ((usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) && desc->bmAttributes != 0) { dev_warn(ddev, "%s endpoint with bmAttributes = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", desc->bmAttributes, cfgno, inum, asnum, ep->desc.bEndpointAddress); desc->bmAttributes = 0; } if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) { dev_warn(ddev, "Bulk endpoint with more than 65536 streams in " "config %d interface %d altsetting %d ep %d: " "setting to max\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); desc->bmAttributes = 16; } if (usb_endpoint_xfer_isoc(&ep->desc) && desc->bmAttributes > 2) { dev_warn(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", desc->bmAttributes + 1, cfgno, inum, asnum, ep->desc.bEndpointAddress); desc->bmAttributes = 2; } if (usb_endpoint_xfer_isoc(&ep->desc)) { max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * le16_to_cpu(ep->desc.wMaxPacketSize); } else if (usb_endpoint_xfer_int(&ep->desc)) { max_tx = le16_to_cpu(ep->desc.wMaxPacketSize) * (desc->bMaxBurst + 1); } else { goto valid; } if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", le16_to_cpu(desc->wBytesPerInterval), cfgno, inum, asnum, ep->desc.bEndpointAddress, max_tx); desc->wBytesPerInterval = cpu_to_le16(max_tx); } valid: return retval; }
static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, struct urb *urb) { struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); struct usbhs_pipe *pipe; struct usb_endpoint_descriptor *desc = &urb->ep->desc; struct device *dev = usbhs_priv_to_dev(priv); unsigned long flags; int dir_in_req = !!usb_pipein(urb->pipe); int is_dcp = usb_endpoint_xfer_control(desc); int i, dir_in; int ret = -EBUSY; /******************** spin lock ********************/ usbhs_lock(priv, flags); /* * if uep has been attached to pipe, * reuse it */ if (usbhsh_uep_to_pipe(uep)) { ret = 0; goto usbhsh_pipe_attach_done; } usbhs_for_each_pipe_with_dcp(pipe, priv, i) { /* check pipe type */ if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) continue; /* check pipe direction if normal pipe */ if (!is_dcp) { dir_in = !!usbhs_pipe_is_dir_in(pipe); if (0 != (dir_in - dir_in_req)) continue; } /* check pipe is free */ if (usbhsh_pipe_to_uep(pipe)) continue; /* * attach pipe to uep * * usbhs_pipe_config_update() should be called after * usbhs_set_device_config() * see * DCPMAXP/PIPEMAXP */ usbhsh_uep_to_pipe(uep) = pipe; usbhsh_pipe_to_uep(pipe) = uep; usbhs_pipe_config_update(pipe, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc), usb_endpoint_maxp(desc)); dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, usbhsh_device_number(hpriv, udev), usb_endpoint_num(desc), usbhs_pipe_name(pipe), dir_in_req ? "in" : "out"); ret = 0; break; } usbhsh_pipe_attach_done: if (0 == ret) uep->counter++; usbhs_unlock(priv, flags); /******************** spin unlock ******************/ return ret; }
static void usb_parse_ss_endpoint_companion(struct device *ddev, int cfgno, int inum, int asnum, struct usb_host_endpoint *ep, unsigned char *buffer, int size) { struct usb_ss_ep_comp_descriptor *desc; int max_tx; desc = (struct usb_ss_ep_comp_descriptor *) buffer; if (desc->bDescriptorType != USB_DT_SS_ENDPOINT_COMP || size < USB_DT_SS_EP_COMP_SIZE) { dev_warn(ddev, "No SuperSpeed endpoint companion for config %d " " interface %d altsetting %d ep %d: " "using minimum values\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bLength = USB_DT_SS_EP_COMP_SIZE; ep->ss_ep_comp.bDescriptorType = USB_DT_SS_ENDPOINT_COMP; if (usb_endpoint_xfer_isoc(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) ep->ss_ep_comp.wBytesPerInterval = ep->desc.wMaxPacketSize; return; } memcpy(&ep->ss_ep_comp, desc, USB_DT_SS_EP_COMP_SIZE); if (usb_endpoint_xfer_control(&ep->desc) && desc->bMaxBurst != 0) { dev_warn(ddev, "Control endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bMaxBurst = 0; } else if (desc->bMaxBurst > 15) { dev_warn(ddev, "Endpoint with bMaxBurst = %d in " "config %d interface %d altsetting %d ep %d: " "setting to 15\n", desc->bMaxBurst, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bMaxBurst = 15; } if ((usb_endpoint_xfer_control(&ep->desc) || usb_endpoint_xfer_int(&ep->desc)) && desc->bmAttributes != 0) { dev_warn(ddev, "%s endpoint with bmAttributes = %d in " "config %d interface %d altsetting %d ep %d: " "setting to zero\n", usb_endpoint_xfer_control(&ep->desc) ? "Control" : "Bulk", desc->bmAttributes, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 0; } else if (usb_endpoint_xfer_bulk(&ep->desc) && desc->bmAttributes > 16) { dev_warn(ddev, "Bulk endpoint with more than 65536 streams in " "config %d interface %d altsetting %d ep %d: " "setting to max\n", cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 16; } else if (usb_endpoint_xfer_isoc(&ep->desc) && desc->bmAttributes > 2) { dev_warn(ddev, "Isoc endpoint has Mult of %d in " "config %d interface %d altsetting %d ep %d: " "setting to 3\n", desc->bmAttributes + 1, cfgno, inum, asnum, ep->desc.bEndpointAddress); ep->ss_ep_comp.bmAttributes = 2; } if (usb_endpoint_xfer_isoc(&ep->desc)) max_tx = (desc->bMaxBurst + 1) * (desc->bmAttributes + 1) * usb_endpoint_maxp(&ep->desc); else if (usb_endpoint_xfer_int(&ep->desc)) max_tx = usb_endpoint_maxp(&ep->desc) * (desc->bMaxBurst + 1); else max_tx = 999999; if (le16_to_cpu(desc->wBytesPerInterval) > max_tx) { dev_warn(ddev, "%s endpoint with wBytesPerInterval of %d in " "config %d interface %d altsetting %d ep %d: " "setting to %d\n", usb_endpoint_xfer_isoc(&ep->desc) ? "Isoc" : "Int", le16_to_cpu(desc->wBytesPerInterval), cfgno, inum, asnum, ep->desc.bEndpointAddress, max_tx); ep->ss_ep_comp.wBytesPerInterval = cpu_to_le16(max_tx); } }
/* * non-error returns are a promise to giveback() the urb later * we drop ownership so next owner (or urb unlink) can get it */ int xhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, gfp_t mem_flags) { struct xhci_hcd *xhci = hcd_to_xhci(hcd); struct xhci_td *buffer; unsigned long flags; int ret = 0; unsigned int slot_id, ep_index; struct urb_priv *urb_priv; int size, i; if (!urb || xhci_check_args(hcd, urb->dev, urb->ep, true, true, __func__) <= 0) return -EINVAL; slot_id = urb->dev->slot_id; ep_index = xhci_get_endpoint_index(&urb->ep->desc); if (!HCD_HW_ACCESSIBLE(hcd)) { if (!in_interrupt()) xhci_dbg(xhci, "urb submitted during PCI suspend\n"); ret = -ESHUTDOWN; goto exit; } if (usb_endpoint_xfer_isoc(&urb->ep->desc)) size = urb->number_of_packets; else size = 1; urb_priv = kzalloc(sizeof(struct urb_priv) + size * sizeof(struct xhci_td *), mem_flags); if (!urb_priv) return -ENOMEM; buffer = kzalloc(size * sizeof(struct xhci_td), mem_flags); if (!buffer) { kfree(urb_priv); return -ENOMEM; } for (i = 0; i < size; i++) { urb_priv->td[i] = buffer; buffer++; } urb_priv->length = size; urb_priv->td_cnt = 0; urb->hcpriv = urb_priv; if (usb_endpoint_xfer_control(&urb->ep->desc)) { /* Check to see if the max packet size for the default control * endpoint changed during FS device enumeration */ if (urb->dev->speed == USB_SPEED_FULL) { ret = xhci_check_maxpacket(xhci, slot_id, ep_index, urb); if (ret < 0) { xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; return ret; } } /* We have a spinlock and interrupts disabled, so we must pass * atomic context to this function, which may allocate memory. */ spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_ctrl_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_bulk(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_GETTING_STREAMS) { xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep " "is transitioning to using streams.\n"); ret = -EINVAL; } else if (xhci->devs[slot_id]->eps[ep_index].ep_state & EP_GETTING_NO_STREAMS) { xhci_warn(xhci, "WARN: Can't enqueue URB while bulk ep " "is transitioning to " "not having streams.\n"); ret = -EINVAL; } else { ret = xhci_queue_bulk_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); } if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else if (usb_endpoint_xfer_int(&urb->ep->desc)) { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_intr_tx(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } else { spin_lock_irqsave(&xhci->lock, flags); if (xhci->xhc_state & XHCI_STATE_DYING) goto dying; ret = xhci_queue_isoc_tx_prepare(xhci, GFP_ATOMIC, urb, slot_id, ep_index); if (ret) goto free_priv; spin_unlock_irqrestore(&xhci->lock, flags); } exit: return ret; dying: xhci_dbg(xhci, "Ep 0x%x: URB %p submitted for " "non-responsive xHCI host.\n", urb->ep->desc.bEndpointAddress, urb); ret = -ESHUTDOWN; free_priv: xhci_urb_free_priv(urb_priv); urb->hcpriv = NULL; spin_unlock_irqrestore(&xhci->lock, flags); return ret; }
static int igorplugusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *udev; struct usb_host_interface *idesc; struct usb_endpoint_descriptor *ep; struct igorplugusb *ir; struct rc_dev *rc; int ret = -ENOMEM; udev = interface_to_usbdev(intf); idesc = intf->cur_altsetting; if (idesc->desc.bNumEndpoints != 1) { dev_err(&intf->dev, "incorrect number of endpoints"); return -ENODEV; } ep = &idesc->endpoint[0].desc; if (!usb_endpoint_dir_in(ep) || !usb_endpoint_xfer_control(ep)) { dev_err(&intf->dev, "endpoint incorrect"); return -ENODEV; } ir = devm_kzalloc(&intf->dev, sizeof(*ir), GFP_KERNEL); if (!ir) return -ENOMEM; ir->dev = &intf->dev; setup_timer(&ir->timer, igorplugusb_timer, (unsigned long)ir); ir->request.bRequest = GET_INFRACODE; ir->request.bRequestType = USB_TYPE_VENDOR | USB_DIR_IN; ir->request.wLength = cpu_to_le16(sizeof(ir->buf_in)); ir->urb = usb_alloc_urb(0, GFP_KERNEL); if (!ir->urb) goto fail; usb_fill_control_urb(ir->urb, udev, usb_rcvctrlpipe(udev, 0), (uint8_t *)&ir->request, ir->buf_in, sizeof(ir->buf_in), igorplugusb_callback, ir); usb_make_path(udev, ir->phys, sizeof(ir->phys)); rc = rc_allocate_device(RC_DRIVER_IR_RAW); if (!rc) goto fail; rc->device_name = DRIVER_DESC; rc->input_phys = ir->phys; usb_to_input_id(udev, &rc->input_id); rc->dev.parent = &intf->dev; /* * This device can only store 36 pulses + spaces, which is not enough * for the NEC protocol and many others. */ rc->allowed_protocols = RC_PROTO_BIT_ALL_IR_DECODER & ~(RC_PROTO_BIT_NEC | RC_PROTO_BIT_NECX | RC_PROTO_BIT_NEC32 | RC_PROTO_BIT_RC6_6A_20 | RC_PROTO_BIT_RC6_6A_24 | RC_PROTO_BIT_RC6_6A_32 | RC_PROTO_BIT_RC6_MCE | RC_PROTO_BIT_SONY20 | RC_PROTO_BIT_SANYO); rc->priv = ir; rc->driver_name = DRIVER_NAME; rc->map_name = RC_MAP_HAUPPAUGE; rc->timeout = MS_TO_NS(100); rc->rx_resolution = 85333; ir->rc = rc; ret = rc_register_device(rc); if (ret) { dev_err(&intf->dev, "failed to register rc device: %d", ret); goto fail; } usb_set_intfdata(intf, ir); igorplugusb_cmd(ir, SET_INFRABUFFER_EMPTY); return 0; fail: rc_free_device(ir->rc); usb_free_urb(ir->urb); del_timer(&ir->timer); return ret; }