提交 81bf46f3 编写于 作者: P Pete Zaitcev 提交者: Greg Kroah-Hartman

USB: Let usb_sg_init to set transfer_buffer more often

This fix permits the "new" usbmon to access usb-storage's data buffer
without DMA remapping tricks. It should be compatible with PIO controllers
and not add any new crashes. Note that from now on PIO controllers and
usbmon are uniform in their access pattern and if one crashes then
the other will too. Hopefuly neither does.

As a side effect, we get rid for #ifdefs, which were a little ugly.
Signed-off-by: NPete Zaitcev <zaitcev@redhat.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 4e9e9200
......@@ -459,35 +459,23 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
io->urbs[i]->context = io;
/*
* Some systems need to revert to PIO when DMA is
* temporarily unavailable. For their sakes, both
* transfer_buffer and transfer_dma are set when
* possible. However this can only work on systems
* without:
* Some systems need to revert to PIO when DMA is temporarily
* unavailable. For their sakes, both transfer_buffer and
* transfer_dma are set when possible.
*
* - HIGHMEM, since DMA buffers located in high memory
* are not directly addressable by the CPU for PIO;
*
* - IOMMU, since dma_map_sg() is allowed to use an
* IOMMU to make virtually discontiguous buffers be
* "dma-contiguous" so that PIO and DMA need diferent
* numbers of URBs.
*
* So when HIGHMEM or IOMMU are in use, transfer_buffer
* is NULL to prevent stale pointers and to help spot
* bugs.
* Note that if IOMMU coalescing occurred, we cannot
* trust sg_page anymore, so check if S/G list shrunk.
*/
if (io->nents == io->entries && !PageHighMem(sg_page(sg)))
io->urbs[i]->transfer_buffer = sg_virt(sg);
else
io->urbs[i]->transfer_buffer = NULL;
if (dma) {
io->urbs[i]->transfer_dma = sg_dma_address(sg);
len = sg_dma_len(sg);
#if defined(CONFIG_HIGHMEM) || defined(CONFIG_GART_IOMMU)
io->urbs[i]->transfer_buffer = NULL;
#else
io->urbs[i]->transfer_buffer = sg_virt(sg);
#endif
} else {
/* hc may use _only_ transfer_buffer */
io->urbs[i]->transfer_buffer = sg_virt(sg);
len = sg->length;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册