Re: Drop #ifdef from usb_sg_init

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 10 Jun 2009, Pete Zaitcev wrote:

> Hi, Alan:
> 
> Please look at the attached patch. It allows the "new" usbmon to show
> the storage data in kernels that could possibly be running on systems
> with GART-based IOMMUs, but aren't actually. These #ifdefs always
> bothered me.

The basic idea is sound and the code is cleaner.

> Greetings,
> -- Pete
> 
> diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
> index b626283..e2ecf36 100644
> --- a/drivers/usb/core/message.c
> +++ b/drivers/usb/core/message.c
> @@ -421,30 +421,21 @@ int usb_sg_init(struct usb_sg_request *io, struct usb_device *dev,
>  		/*
>  		 * 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:
> +		 * 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 the IOMMU coalescing occured, we cannot

s/if the/if/
s/occured/occurred/

> +		 * 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;

There needs to be a test here for transfer_buffer != NULL.  It would
not be good for an HCD using PIO to crash the system because it tried
to access invalid memory.

>  		}

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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux