This patch (as1377) simplifies the code in usb_sg_init(), without changing its functionality. It also removes a couple of unused fields from the usb_sg_request structure. Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> --- Index: usb-2.6/include/linux/usb.h =================================================================== --- usb-2.6.orig/include/linux/usb.h +++ usb-2.6/include/linux/usb.h @@ -1454,8 +1454,6 @@ struct usb_sg_request { struct usb_device *dev; int pipe; - struct scatterlist *sg; - int nents; int entries; struct urb **urbs; Index: usb-2.6/drivers/usb/core/message.c =================================================================== --- usb-2.6.orig/drivers/usb/core/message.c +++ usb-2.6/drivers/usb/core/message.c @@ -372,79 +372,64 @@ int usb_sg_init(struct usb_sg_request *i spin_lock_init(&io->lock); io->dev = dev; io->pipe = pipe; - io->sg = sg; - io->nents = nents; - io->entries = nents; - /* initialize all the urbs we'll use */ if (dev->bus->sg_tablesize > 0) { - io->urbs = kmalloc(sizeof *io->urbs, mem_flags); use_sg = true; + io->entries = 1; } else { - io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); use_sg = false; + io->entries = nents; } + + /* initialize all the urbs we'll use */ + io->urbs = kmalloc(io->entries * sizeof *io->urbs, mem_flags); if (!io->urbs) goto nomem; - urb_flags = 0; + urb_flags = URB_NO_INTERRUPT; if (usb_pipein(pipe)) urb_flags |= URB_SHORT_NOT_OK; - if (use_sg) { - io->urbs[0] = usb_alloc_urb(0, mem_flags); - if (!io->urbs[0]) { - io->entries = 0; + for_each_sg(sg, sg, io->entries, i) { + struct urb *urb; + unsigned len; + + urb = usb_alloc_urb(0, mem_flags); + if (!urb) { + io->entries = i; goto nomem; } + io->urbs[i] = urb; - io->urbs[0]->dev = NULL; - io->urbs[0]->pipe = pipe; - io->urbs[0]->interval = period; - io->urbs[0]->transfer_flags = urb_flags; - - io->urbs[0]->complete = sg_complete; - io->urbs[0]->context = io; - - /* A length of zero means transfer the whole sg list */ - io->urbs[0]->transfer_buffer_length = length; - if (length == 0) { - for_each_sg(sg, sg, io->entries, i) { - io->urbs[0]->transfer_buffer_length += - sg->length; + urb->dev = NULL; + urb->pipe = pipe; + urb->interval = period; + urb->transfer_flags = urb_flags; + urb->complete = sg_complete; + urb->context = io; + urb->sg = sg; + + if (use_sg) { + /* There is no single transfer buffer */ + urb->transfer_buffer = NULL; + urb->num_sgs = nents; + + /* A length of zero means transfer the whole sg list */ + len = length; + if (len == 0) { + for_each_sg(sg, sg, nents, i) + len += sg->length; } - } - io->urbs[0]->sg = sg; - io->urbs[0]->num_sgs = io->entries; - io->entries = 1; - } else { - urb_flags |= URB_NO_INTERRUPT; - for_each_sg(sg, sg, io->entries, i) { - unsigned len; - - io->urbs[i] = usb_alloc_urb(0, mem_flags); - if (!io->urbs[i]) { - io->entries = i; - goto nomem; - } - - io->urbs[i]->dev = NULL; - io->urbs[i]->pipe = pipe; - io->urbs[i]->interval = period; - io->urbs[i]->transfer_flags = urb_flags; - - io->urbs[i]->complete = sg_complete; - io->urbs[i]->context = io; - + } else { /* * Some systems can't use DMA; they use PIO instead. * For their sakes, transfer_buffer is set whenever * possible. */ if (!PageHighMem(sg_page(sg))) - io->urbs[i]->transfer_buffer = sg_virt(sg); + urb->transfer_buffer = sg_virt(sg); else - io->urbs[i]->transfer_buffer = NULL; + urb->transfer_buffer = NULL; len = sg->length; if (length) { @@ -453,12 +438,10 @@ int usb_sg_init(struct usb_sg_request *i if (length == 0) io->entries = i + 1; } - io->urbs[i]->transfer_buffer_length = len; - - io->urbs[i]->sg = sg; } - io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; + urb->transfer_buffer_length = len; } + io->urbs[--i]->transfer_flags &= ~URB_NO_INTERRUPT; /* transaction state */ io->count = io->entries; -- 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