• L
    dma: Remove comment about embedding dma_slave_config into custom structs · 7cbccb55
    Lars-Peter Clausen 提交于
    The documentation for the dma_slave_config struct recommends that if a DMA
    controller has special configuration options, which can not be configured
    through the dma_slave_config struct, the driver should create its own custom
    config struct and embed the dma_slave_config struct in it and pass the custom
    config struct to dmaengine_slave_config(). This overloads the generic
    dmaengine_slave_config() API with custom semantics and any caller of the
    dmaengine_slave_config() that is not aware of these special semantics will cause
    undefined behavior. This means that it is impossible for generic code to make
    use of dmaengine_slave_config(). Such a restriction contradicts the very idea of
    having a generic API.
    
    E.g. consider the following case of a DMA controller that has an option to
    reverse the field polarity of the DMA transfer with the following implementation
    for setting the configuration:
    
    	struct my_slave_config {
    		struct dma_slave_config config;
    		unsigned int field_polarity;
    	};
    
    	static int my_dma_controller_slave_config(struct dma_chan *chan,
    		struct dma_slave_config *config)
    	{
    		struct my_slave_config *my_cfg = container_of(config,
    				struct my_slave_config, config);
    
    		...
    		my_dma_set_field_polarity(chan, my_cfg->field_polarity);
    		...
    	}
    
    Now a generic user of the dmaengine API might want to configure a DMA channel
    for this DMA controller that it obtained using the following code:
    
    	struct dma_slave_config config;
    
    	config.src_addr = ...;
    	...
    	dmaengine_slave_config(chan, &config);
    
    The call to dmaengine_slave_config() will eventually call into
    my_dma_controller_slave_config() which will cast from dma_slave_config to
    my_slave_config and then tries to access the field_polarity member. Since the
    dma_slave_config struct that was passed in was never embedded into a
    my_slave_config struct this attempt will just read random stack garbage and use
    that to configure the DMA controller. This is bad. Instead, if a DMA controller
    really needs to have custom configuration options, the driver should create a
    custom API for it. This makes it very clear that there is a direct dependency
    of a user of such an API and the implementer. E.g.:
    
    	int my_dma_set_field_polarity(struct dma_chan *chan,
    		unsigned int field_polarity) {
    		if (chan->device->dev->driver != &my_dma_controller_driver.driver)
    			return -EINVAL;
    		...
    	}
    	EXPORT_SYMBOL_GPL(my_dma_set_field_polarity);
    Signed-off-by: NLars-Peter Clausen <lars@metafoo.de>
    Signed-off-by: NVinod Koul <vinod.koul@intel.com>
    7cbccb55
dmaengine.h 36.9 KB