On Fri, 4 Dec 2009, David Vrabel wrote: > Andrew Morton wrote: > > On Mon, 24 Aug 2009 15:54:17 +0000 David Vrabel <david.vrabel@xxxxxxx> wrote: > > > >> + if (std->len + dma_len > QTD_MAX_XFER_SIZE) { > >> + dma_len = QTD_MAX_XFER_SIZE - std->len; > >> + ep = ((dma_addr + dma_len) / qset->max_packet) * qset->max_packet; > >> + dma_len = ep - dma_addr; > >> + } > > > > Generates a call to __udivdi3 on i386, which doesn't exist. > > This only happens if CONFIG_HIGHMEM_64G is enabled which isn't a very > interesting configuration so fixing this is low priority. > > I do have a patch but it needs more testing. > > > I'm reluctant to convert it to do_div() because I can't conceive of any > > situation in which it makes sense to perform division on a physical bus > > address :( > > I don't understand this comment. Can you think of a way to implement > this in another way? The computation itself looks a little strange. Exactly what is it trying to accomplish? Apparently it truncates a transfer length if the value is too large, and arranges that the truncated DMA buffer ends at an address which is evenly divisible by maxpacket. The second part is rather odd. Who cares where the buffer ends? Isn't the buffer length more important than the ending address? In other words, wouldn't it be more appropriate to do something like this? if (std->len + dma_len > QTD_MAX_XFER_SIZE) { dma_len = ((QTD_MAX_XFER_SIZE - std->len) / qset->max_packet) * qset->max_packet; ep = dma_addr + dma_len; } (The assignment to ep can be omitted if it isn't needed later.) Alan Stern -- 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