This patch (as1300) adds native scatter-gather support to ehci-hcd. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> --- Index: usb-2.6/drivers/usb/host/ehci-q.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-q.c +++ usb-2.6/drivers/usb/host/ehci-q.c @@ -604,9 +604,11 @@ qh_urb_transaction ( ) { struct ehci_qtd *qtd, *qtd_prev; dma_addr_t buf; - int len, maxpacket; + int len, this_sg_len, maxpacket; int is_input; u32 token; + int i; + struct scatterlist *sg; /* * URBs map to sequences of QTDs: one logical transaction @@ -647,7 +649,20 @@ qh_urb_transaction ( /* * data transfer stage: buffer setup */ - buf = urb->transfer_dma; + i = urb->num_sgs; + if (len > 0 && i > 0) { + sg = urb->sg->sg; + buf = 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; + buf = urb->transfer_dma; + this_sg_len = len; + } if (is_input) token |= (1 /* "in" */ << 8); @@ -663,7 +678,9 @@ qh_urb_transaction ( for (;;) { int this_qtd_len; - this_qtd_len = qtd_fill(ehci, qtd, buf, len, token, maxpacket); + this_qtd_len = qtd_fill(ehci, qtd, buf, this_sg_len, token, + maxpacket); + this_sg_len -= this_qtd_len; len -= this_qtd_len; buf += this_qtd_len; @@ -679,8 +696,13 @@ qh_urb_transaction ( if ((maxpacket & (this_qtd_len + (maxpacket - 1))) == 0) token ^= QTD_TOGGLE; - if (likely (len <= 0)) - break; + if (likely(this_sg_len <= 0)) { + if (--i <= 0 || len <= 0) + break; + sg = sg_next(sg); + buf = sg_dma_address(sg); + this_sg_len = min_t(int, sg_dma_len(sg), len); + } qtd_prev = qtd; qtd = ehci_qtd_alloc (ehci, flags); Index: usb-2.6/drivers/usb/host/ehci-hcd.c =================================================================== --- usb-2.6.orig/drivers/usb/host/ehci-hcd.c +++ usb-2.6/drivers/usb/host/ehci-hcd.c @@ -604,6 +604,8 @@ static int ehci_init(struct usb_hcd *hcd } ehci->command = temp; + /* Accept arbitrarily long scatter-gather lists */ + hcd->self.sg_tablesize = ~0; return 0; } -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html