mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-04-21 15:08:03 +07:00
USB: UHCI: add native scatter-gather support(v1)
This patch adds native scatter-gather support to uhci-hcd. Reviewed-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Ming Lei <tom.leiming@gmail.com> Acked-by: Alan Stern <stern@rowland.harvard.edu> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
This commit is contained in:
parent
00be545e49
commit
689d6eacd1
@ -917,10 +917,13 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
|
|||||||
unsigned long destination, status;
|
unsigned long destination, status;
|
||||||
int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
|
int maxsze = le16_to_cpu(qh->hep->desc.wMaxPacketSize);
|
||||||
int len = urb->transfer_buffer_length;
|
int len = urb->transfer_buffer_length;
|
||||||
dma_addr_t data = urb->transfer_dma;
|
int this_sg_len;
|
||||||
|
dma_addr_t data;
|
||||||
__le32 *plink;
|
__le32 *plink;
|
||||||
struct urb_priv *urbp = urb->hcpriv;
|
struct urb_priv *urbp = urb->hcpriv;
|
||||||
unsigned int toggle;
|
unsigned int toggle;
|
||||||
|
struct scatterlist *sg;
|
||||||
|
int i;
|
||||||
|
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -937,12 +940,26 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
|
|||||||
if (usb_pipein(urb->pipe))
|
if (usb_pipein(urb->pipe))
|
||||||
status |= TD_CTRL_SPD;
|
status |= TD_CTRL_SPD;
|
||||||
|
|
||||||
|
i = urb->num_sgs;
|
||||||
|
if (len > 0 && i > 0) {
|
||||||
|
sg = urb->sg;
|
||||||
|
data = sg_dma_address(sg);
|
||||||
|
|
||||||
|
/* urb->transfer_buffer_length may be smaller than the
|
||||||
|
* size of the scatterlist (or vice versa)
|
||||||
|
*/
|
||||||
|
this_sg_len = min_t(int, sg_dma_len(sg), len);
|
||||||
|
} else {
|
||||||
|
sg = NULL;
|
||||||
|
data = urb->transfer_dma;
|
||||||
|
this_sg_len = len;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
* Build the DATA TDs
|
* Build the DATA TDs
|
||||||
*/
|
*/
|
||||||
plink = NULL;
|
plink = NULL;
|
||||||
td = qh->dummy_td;
|
td = qh->dummy_td;
|
||||||
do { /* Allow zero length packets */
|
for (;;) { /* Allow zero length packets */
|
||||||
int pktsze = maxsze;
|
int pktsze = maxsze;
|
||||||
|
|
||||||
if (len <= pktsze) { /* The last packet */
|
if (len <= pktsze) { /* The last packet */
|
||||||
@ -965,10 +982,18 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb,
|
|||||||
plink = &td->link;
|
plink = &td->link;
|
||||||
status |= TD_CTRL_ACTIVE;
|
status |= TD_CTRL_ACTIVE;
|
||||||
|
|
||||||
data += pktsze;
|
|
||||||
len -= maxsze;
|
|
||||||
toggle ^= 1;
|
toggle ^= 1;
|
||||||
} while (len > 0);
|
data += pktsze;
|
||||||
|
this_sg_len -= pktsze;
|
||||||
|
len -= maxsze;
|
||||||
|
if (this_sg_len <= 0) {
|
||||||
|
if (--i <= 0 || len <= 0)
|
||||||
|
break;
|
||||||
|
sg = sg_next(sg);
|
||||||
|
data = sg_dma_address(sg);
|
||||||
|
this_sg_len = min_t(int, sg_dma_len(sg), len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* URB_ZERO_PACKET means adding a 0-length packet, if direction
|
* URB_ZERO_PACKET means adding a 0-length packet, if direction
|
||||||
|
Loading…
Reference in New Issue
Block a user