Re: [PATCH] staging: gasket: formatting fixes
On Mon, Nov 12, 2018 at 1:27 PM Robert Deal wrote: > > Reformat arguments in a few functions in gasket_page_table.c to better > follow linux kernel formatting standards. > > Signed-off-by: Robert Deal > --- > drivers/staging/gasket/gasket_page_table.c | 24 ++ > 1 file changed, 11 insertions(+), 13 deletions(-) > > diff --git a/drivers/staging/gasket/gasket_page_table.c > b/drivers/staging/gasket/gasket_page_table.c > index f5253ba9a430..26755d9ca41d 100644 > --- a/drivers/staging/gasket/gasket_page_table.c > +++ b/drivers/staging/gasket/gasket_page_table.c > @@ -1088,9 +1088,9 @@ void gasket_page_table_reset(struct gasket_page_table > *pg_tbl) > } > > /* See gasket_page_table.h for description. */ > -int gasket_page_table_lookup_page( > - struct gasket_page_table *pg_tbl, ulong dev_addr, struct page **ppage, > - ulong *poffset) > +int gasket_page_table_lookup_page(struct gasket_page_table *pg_tbl, > + ulong dev_addr, struct page **ppage, > + ulong *poffset) > { > uint page_num; > struct gasket_page_table_entry *pte; > @@ -1134,9 +1134,9 @@ int gasket_page_table_lookup_page( > } > > /* See gasket_page_table.h for description. */ > -bool gasket_page_table_are_addrs_bad( > - struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr, > - ulong bytes) > +bool gasket_page_table_are_addrs_bad(struct gasket_page_table *pg_tbl, > +ulong host_addr, ulong dev_addr, > +ulong bytes) > { > if (host_addr & (PAGE_SIZE - 1)) { > dev_err(pg_tbl->device, > @@ -1150,8 +1150,8 @@ bool gasket_page_table_are_addrs_bad( > EXPORT_SYMBOL(gasket_page_table_are_addrs_bad); > > /* See gasket_page_table.h for description. */ > -bool gasket_page_table_is_dev_addr_bad( > - struct gasket_page_table *pg_tbl, ulong dev_addr, ulong bytes) > +bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *pg_tbl, > + ulong dev_addr, ulong bytes) > { > uint num_pages = bytes / PAGE_SIZE; > > @@ -1226,9 +1226,8 @@ int gasket_page_table_system_status(struct > gasket_page_table *page_table) > } > > /* Record the host_addr to coherent dma memory mapping. */ > -int gasket_set_user_virt( > - struct gasket_dev *gasket_dev, u64 size, dma_addr_t dma_address, > - ulong vma) > +int gasket_set_user_virt(struct gasket_dev *gasket_dev, u64 size, > +dma_addr_t dma_address, ulong vma) > { > int j; > struct gasket_page_table *pg_tbl; > @@ -1346,8 +1345,7 @@ int gasket_free_coherent_memory(struct gasket_dev > *gasket_dev, u64 size, > } > > /* Release all coherent memory. */ > -void gasket_free_coherent_memory_all( > - struct gasket_dev *gasket_dev, u64 index) > +void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev, u64 > index) > { > if (!gasket_dev->page_table[index]) > return; > -- > 2.17.1 > Acked-by: Todd Poynor Thanks!
Re: [PATCH] staging: gasket: formatting fixes
On Mon, Nov 12, 2018 at 1:27 PM Robert Deal wrote: > > Reformat arguments in a few functions in gasket_page_table.c to better > follow linux kernel formatting standards. > > Signed-off-by: Robert Deal > --- > drivers/staging/gasket/gasket_page_table.c | 24 ++ > 1 file changed, 11 insertions(+), 13 deletions(-) > > diff --git a/drivers/staging/gasket/gasket_page_table.c > b/drivers/staging/gasket/gasket_page_table.c > index f5253ba9a430..26755d9ca41d 100644 > --- a/drivers/staging/gasket/gasket_page_table.c > +++ b/drivers/staging/gasket/gasket_page_table.c > @@ -1088,9 +1088,9 @@ void gasket_page_table_reset(struct gasket_page_table > *pg_tbl) > } > > /* See gasket_page_table.h for description. */ > -int gasket_page_table_lookup_page( > - struct gasket_page_table *pg_tbl, ulong dev_addr, struct page **ppage, > - ulong *poffset) > +int gasket_page_table_lookup_page(struct gasket_page_table *pg_tbl, > + ulong dev_addr, struct page **ppage, > + ulong *poffset) > { > uint page_num; > struct gasket_page_table_entry *pte; > @@ -1134,9 +1134,9 @@ int gasket_page_table_lookup_page( > } > > /* See gasket_page_table.h for description. */ > -bool gasket_page_table_are_addrs_bad( > - struct gasket_page_table *pg_tbl, ulong host_addr, ulong dev_addr, > - ulong bytes) > +bool gasket_page_table_are_addrs_bad(struct gasket_page_table *pg_tbl, > +ulong host_addr, ulong dev_addr, > +ulong bytes) > { > if (host_addr & (PAGE_SIZE - 1)) { > dev_err(pg_tbl->device, > @@ -1150,8 +1150,8 @@ bool gasket_page_table_are_addrs_bad( > EXPORT_SYMBOL(gasket_page_table_are_addrs_bad); > > /* See gasket_page_table.h for description. */ > -bool gasket_page_table_is_dev_addr_bad( > - struct gasket_page_table *pg_tbl, ulong dev_addr, ulong bytes) > +bool gasket_page_table_is_dev_addr_bad(struct gasket_page_table *pg_tbl, > + ulong dev_addr, ulong bytes) > { > uint num_pages = bytes / PAGE_SIZE; > > @@ -1226,9 +1226,8 @@ int gasket_page_table_system_status(struct > gasket_page_table *page_table) > } > > /* Record the host_addr to coherent dma memory mapping. */ > -int gasket_set_user_virt( > - struct gasket_dev *gasket_dev, u64 size, dma_addr_t dma_address, > - ulong vma) > +int gasket_set_user_virt(struct gasket_dev *gasket_dev, u64 size, > +dma_addr_t dma_address, ulong vma) > { > int j; > struct gasket_page_table *pg_tbl; > @@ -1346,8 +1345,7 @@ int gasket_free_coherent_memory(struct gasket_dev > *gasket_dev, u64 size, > } > > /* Release all coherent memory. */ > -void gasket_free_coherent_memory_all( > - struct gasket_dev *gasket_dev, u64 index) > +void gasket_free_coherent_memory_all(struct gasket_dev *gasket_dev, u64 > index) > { > if (!gasket_dev->page_table[index]) > return; > -- > 2.17.1 > Acked-by: Todd Poynor Thanks!
RFC: staging: gasket: re-implement using UIO
On Mon, Sep 10, 2018 at 8:28 AM Ahmed S. Darwish wrote: > > The gasket in-kernel framework, recently introduced under staging, > re-implements what is already long-time provided by the UIO > subsystem, with extra PCI BAR remapping and MSI conveniences. > > Before moving it out of staging, make sure we add the new bits to > the UIO framework instead, then transform its signle client, the > Apex driver, to a proper UIO driver (uio_driver.h). > > Link: https://lkml.kernel.org/r/20180828103817.GB1397@do-kernel So I'm looking at this for reals now. The BAR mapping stuff is straightforward with the existing framework. Everything else could be done outside of UIO via the existing device interface, but figured I'd collect any opinions about adding the new bits to UIO. The Apex device has 13 MSIX interrupts. UIO does one IRQ per device. The PRUSS driver registers 8 instances of the UIO device with identical memory mappings but individual IRQs for its 8 interrupts. Currently gasket has userspace pass down an eventfd (via ioctl) for each interrupt it wants to watch. Is there interest in modifying UIO to handle multiple IRQs in some perhaps similar fashion? Speaking of ioctls, are those allowed here, or is sysfs or something else always required? The aforementioned multiple IRQ stuff probably maps nicely to sysfs (there's a small number of them easily represented as attributes), while DMA buffer mappings seem more problematic, but maybe somebody's thought of a good way to represent these already. And then we need to map buffers to our device. We could probably implement this via an IOMMU driver API for our custom MMU and hook that up to generic IOMMU support for UIO, which sounds like something a lot of drivers could use. There's a few other tidbits the driver does, including allocating coherent memory for userspace to share with the device, but that's probably enough for now. If anybody wants to squash any of the above as a non-starter for UIO or point things in a different direction, it's appreciated. Thanks, Todd
RFC: staging: gasket: re-implement using UIO
On Mon, Sep 10, 2018 at 8:28 AM Ahmed S. Darwish wrote: > > The gasket in-kernel framework, recently introduced under staging, > re-implements what is already long-time provided by the UIO > subsystem, with extra PCI BAR remapping and MSI conveniences. > > Before moving it out of staging, make sure we add the new bits to > the UIO framework instead, then transform its signle client, the > Apex driver, to a proper UIO driver (uio_driver.h). > > Link: https://lkml.kernel.org/r/20180828103817.GB1397@do-kernel So I'm looking at this for reals now. The BAR mapping stuff is straightforward with the existing framework. Everything else could be done outside of UIO via the existing device interface, but figured I'd collect any opinions about adding the new bits to UIO. The Apex device has 13 MSIX interrupts. UIO does one IRQ per device. The PRUSS driver registers 8 instances of the UIO device with identical memory mappings but individual IRQs for its 8 interrupts. Currently gasket has userspace pass down an eventfd (via ioctl) for each interrupt it wants to watch. Is there interest in modifying UIO to handle multiple IRQs in some perhaps similar fashion? Speaking of ioctls, are those allowed here, or is sysfs or something else always required? The aforementioned multiple IRQ stuff probably maps nicely to sysfs (there's a small number of them easily represented as attributes), while DMA buffer mappings seem more problematic, but maybe somebody's thought of a good way to represent these already. And then we need to map buffers to our device. We could probably implement this via an IOMMU driver API for our custom MMU and hook that up to generic IOMMU support for UIO, which sounds like something a lot of drivers could use. There's a few other tidbits the driver does, including allocating coherent memory for userspace to share with the device, but that's probably enough for now. If anybody wants to squash any of the above as a non-starter for UIO or point things in a different direction, it's appreciated. Thanks, Todd
[PATCH 2/3] staging: gasket: remove debug logs in page table mapping calls
From: Todd Poynor Remove very noisy debug logs that also contain typos and incorrect output formats. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 24 -- 1 file changed, 24 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 5b398b7ba81d3..b7d460cf15fbc 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -477,7 +477,6 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, for (i = 0; i < num_pages; i++) { page_addr = host_addr + i * PAGE_SIZE; offset = page_addr & (PAGE_SIZE - 1); - dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i); if (is_coherent(pg_tbl, host_addr)) { u64 off = (u64)host_addr - @@ -506,22 +505,9 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, ptes[i].dma_addr = dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - dev_dbg(pg_tbl->device, - "%s i %d pte %p pfn %p -> mapped %llx\n", - __func__, i, [i], - (void *)page_to_pfn(page), - (unsigned long long)ptes[i].dma_addr); if (dma_mapping_error(pg_tbl->device, ptes[i].dma_addr)) { - dev_dbg(pg_tbl->device, - "%s i %d -> fail to map page %llx " - "[pfn %p ohys %p]\n", - __func__, i, - (unsigned long long)ptes[i].dma_addr, - (void *)page_to_pfn(page), - (void *)page_to_phys(page)); - if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; @@ -892,11 +878,6 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, DMA_TO_DEVICE); if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) { - dev_dbg(pg_tbl->device, - "%s: fail to map page [pfn %lx phys %llx]\n", - __func__, page_to_pfn(pte->page), - page_to_phys(pte->page)); - free_page(page_addr); vfree(pte->sublevel); memset(pte, 0, sizeof(struct gasket_page_table_entry)); @@ -1050,11 +1031,6 @@ int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr, } mutex_unlock(_tbl->mutex); - - dev_dbg(pg_tbl->device, - "%s done: ha %llx daddr %llx num %d, ret %d\n", - __func__, (unsigned long long)host_addr, - (unsigned long long)dev_addr, num_pages, ret); return ret; } EXPORT_SYMBOL(gasket_page_table_map); -- 2.19.1.331.ge82ca0e54c-goog
[PATCH 3/3] staging: gasket: page_table: add mapping flags
From: Nick Ewalt This allows for more precise dma_direction in the dma_map_page requests. Also leaves room for adding more flags later. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket.h| 33 drivers/staging/gasket/gasket_ioctl.c | 62 +++ drivers/staging/gasket/gasket_page_table.c | 87 ++ drivers/staging/gasket/gasket_page_table.h | 4 +- 4 files changed, 141 insertions(+), 45 deletions(-) diff --git a/drivers/staging/gasket/gasket.h b/drivers/staging/gasket/gasket.h index a0f065c517a52..93e7af1551975 100644 --- a/drivers/staging/gasket/gasket.h +++ b/drivers/staging/gasket/gasket.h @@ -37,6 +37,31 @@ struct gasket_page_table_ioctl { u64 device_address; }; +/* + * Structure for ioctl mapping buffers with flags when using the Gasket + * page_table module. + */ +struct gasket_page_table_ioctl_flags { + struct gasket_page_table_ioctl base; + /* +* Flags indicating status and attribute requests from the host. +* NOTE: STATUS bit does not need to be set in this request. +* Set RESERVED bits to 0 to ensure backwards compatibility. +* +* Bitfields: +* [0] - STATUS: indicates if this entry/slot is free +*0 = PTE_FREE +*1 = PTE_INUSE +* [2:1] - DMA_DIRECTION: dma_data_direction requested by host +* 00 = DMA_BIDIRECTIONAL +* 01 = DMA_TO_DEVICE +* 10 = DMA_FROM_DEVICE +* 11 = DMA_NONE +* [31:3] - RESERVED +*/ + u32 flags; +}; + /* * Common structure for ioctls mapping and unmapping buffers when using the * Gasket page_table module. @@ -119,4 +144,12 @@ struct gasket_coherent_alloc_config_ioctl { #define GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR \ _IOWR(GASKET_IOCTL_BASE, 11, struct gasket_coherent_alloc_config_ioctl) +/* + * Tells the kernel to map size bytes at host_address to device_address in + * page_table_index page table. Passes flags to indicate additional attribute + * requests for the mapped memory. + */ +#define GASKET_IOCTL_MAP_BUFFER_FLAGS \ + _IOW(GASKET_IOCTL_BASE, 12, struct gasket_page_table_ioctl_flags) + #endif /* __GASKET_H__ */ diff --git a/drivers/staging/gasket/gasket_ioctl.c b/drivers/staging/gasket/gasket_ioctl.c index 0ca48e688818f..e80f38509f47c 100644 --- a/drivers/staging/gasket/gasket_ioctl.c +++ b/drivers/staging/gasket/gasket_ioctl.c @@ -20,6 +20,7 @@ #define trace_gasket_ioctl_integer_data(x) #define trace_gasket_ioctl_eventfd_data(x, ...) #define trace_gasket_ioctl_page_table_data(x, ...) +#define trace_gasket_ioctl_page_table_flags_data(x, ...) #define trace_gasket_ioctl_config_coherent_allocator(x, ...) #endif @@ -130,29 +131,59 @@ static int gasket_partition_page_table( } /* Map a userspace buffer to a device virtual address. */ +static int gasket_map_buffers_common( + struct gasket_dev *gasket_dev, + struct gasket_page_table_ioctl_flags *pibuf) +{ + if (pibuf->base.page_table_index >= gasket_dev->num_page_tables) + return -EFAULT; + + if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[pibuf->base.page_table_index], + pibuf->base.host_address, + pibuf->base.device_address, + pibuf->base.size)) + return -EINVAL; + + return gasket_page_table_map(gasket_dev->page_table[pibuf->base.page_table_index], +pibuf->base.host_address, +pibuf->base.device_address, +pibuf->base.size / PAGE_SIZE, +pibuf->flags); +} + static int gasket_map_buffers(struct gasket_dev *gasket_dev, struct gasket_page_table_ioctl __user *argp) { - struct gasket_page_table_ioctl ibuf; + struct gasket_page_table_ioctl_flags ibuf; - if (copy_from_user(, argp, sizeof(struct gasket_page_table_ioctl))) + if (copy_from_user(, argp, sizeof(struct gasket_page_table_ioctl))) return -EFAULT; - trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size, - ibuf.host_address, - ibuf.device_address); + ibuf.flags = 0; - if (ibuf.page_table_index >= gasket_dev->num_page_tables) + trace_gasket_ioctl_page_table_data(ibuf.base.page_table_index, + ibuf.base.size, + ibuf.base.host_address, +
[PATCH 0/3] staging: gasket: add DMA direction flags a.o.
From: Todd Poynor Add flags to page mapping ioctls that specify DMA directions other than bi-directional, avoiding unnecessary cache maintenance for read-only or write-only buffers. Remove some spammy / unhelpful / inaccurately formatted debug logs. Nick Ewalt (1): staging: gasket: page_table: add mapping flags Todd Poynor (2): staging: gasket: remove debug logs for callback invocation staging: gasket: remove debug logs in page table mapping calls drivers/staging/gasket/gasket.h| 33 ++ drivers/staging/gasket/gasket_core.c | 7 +- drivers/staging/gasket/gasket_ioctl.c | 62 +--- drivers/staging/gasket/gasket_page_table.c | 111 +++-- drivers/staging/gasket/gasket_page_table.h | 4 +- 5 files changed, 142 insertions(+), 75 deletions(-) -- 2.19.1.331.ge82ca0e54c-goog
[PATCH 2/3] staging: gasket: remove debug logs in page table mapping calls
From: Todd Poynor Remove very noisy debug logs that also contain typos and incorrect output formats. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 24 -- 1 file changed, 24 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 5b398b7ba81d3..b7d460cf15fbc 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -477,7 +477,6 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, for (i = 0; i < num_pages; i++) { page_addr = host_addr + i * PAGE_SIZE; offset = page_addr & (PAGE_SIZE - 1); - dev_dbg(pg_tbl->device, "%s i %d\n", __func__, i); if (is_coherent(pg_tbl, host_addr)) { u64 off = (u64)host_addr - @@ -506,22 +505,9 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, ptes[i].dma_addr = dma_map_page(pg_tbl->device, page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - dev_dbg(pg_tbl->device, - "%s i %d pte %p pfn %p -> mapped %llx\n", - __func__, i, [i], - (void *)page_to_pfn(page), - (unsigned long long)ptes[i].dma_addr); if (dma_mapping_error(pg_tbl->device, ptes[i].dma_addr)) { - dev_dbg(pg_tbl->device, - "%s i %d -> fail to map page %llx " - "[pfn %p ohys %p]\n", - __func__, i, - (unsigned long long)ptes[i].dma_addr, - (void *)page_to_pfn(page), - (void *)page_to_phys(page)); - if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; @@ -892,11 +878,6 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, DMA_TO_DEVICE); if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) { - dev_dbg(pg_tbl->device, - "%s: fail to map page [pfn %lx phys %llx]\n", - __func__, page_to_pfn(pte->page), - page_to_phys(pte->page)); - free_page(page_addr); vfree(pte->sublevel); memset(pte, 0, sizeof(struct gasket_page_table_entry)); @@ -1050,11 +1031,6 @@ int gasket_page_table_map(struct gasket_page_table *pg_tbl, ulong host_addr, } mutex_unlock(_tbl->mutex); - - dev_dbg(pg_tbl->device, - "%s done: ha %llx daddr %llx num %d, ret %d\n", - __func__, (unsigned long long)host_addr, - (unsigned long long)dev_addr, num_pages, ret); return ret; } EXPORT_SYMBOL(gasket_page_table_map); -- 2.19.1.331.ge82ca0e54c-goog
[PATCH 3/3] staging: gasket: page_table: add mapping flags
From: Nick Ewalt This allows for more precise dma_direction in the dma_map_page requests. Also leaves room for adding more flags later. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket.h| 33 drivers/staging/gasket/gasket_ioctl.c | 62 +++ drivers/staging/gasket/gasket_page_table.c | 87 ++ drivers/staging/gasket/gasket_page_table.h | 4 +- 4 files changed, 141 insertions(+), 45 deletions(-) diff --git a/drivers/staging/gasket/gasket.h b/drivers/staging/gasket/gasket.h index a0f065c517a52..93e7af1551975 100644 --- a/drivers/staging/gasket/gasket.h +++ b/drivers/staging/gasket/gasket.h @@ -37,6 +37,31 @@ struct gasket_page_table_ioctl { u64 device_address; }; +/* + * Structure for ioctl mapping buffers with flags when using the Gasket + * page_table module. + */ +struct gasket_page_table_ioctl_flags { + struct gasket_page_table_ioctl base; + /* +* Flags indicating status and attribute requests from the host. +* NOTE: STATUS bit does not need to be set in this request. +* Set RESERVED bits to 0 to ensure backwards compatibility. +* +* Bitfields: +* [0] - STATUS: indicates if this entry/slot is free +*0 = PTE_FREE +*1 = PTE_INUSE +* [2:1] - DMA_DIRECTION: dma_data_direction requested by host +* 00 = DMA_BIDIRECTIONAL +* 01 = DMA_TO_DEVICE +* 10 = DMA_FROM_DEVICE +* 11 = DMA_NONE +* [31:3] - RESERVED +*/ + u32 flags; +}; + /* * Common structure for ioctls mapping and unmapping buffers when using the * Gasket page_table module. @@ -119,4 +144,12 @@ struct gasket_coherent_alloc_config_ioctl { #define GASKET_IOCTL_CONFIG_COHERENT_ALLOCATOR \ _IOWR(GASKET_IOCTL_BASE, 11, struct gasket_coherent_alloc_config_ioctl) +/* + * Tells the kernel to map size bytes at host_address to device_address in + * page_table_index page table. Passes flags to indicate additional attribute + * requests for the mapped memory. + */ +#define GASKET_IOCTL_MAP_BUFFER_FLAGS \ + _IOW(GASKET_IOCTL_BASE, 12, struct gasket_page_table_ioctl_flags) + #endif /* __GASKET_H__ */ diff --git a/drivers/staging/gasket/gasket_ioctl.c b/drivers/staging/gasket/gasket_ioctl.c index 0ca48e688818f..e80f38509f47c 100644 --- a/drivers/staging/gasket/gasket_ioctl.c +++ b/drivers/staging/gasket/gasket_ioctl.c @@ -20,6 +20,7 @@ #define trace_gasket_ioctl_integer_data(x) #define trace_gasket_ioctl_eventfd_data(x, ...) #define trace_gasket_ioctl_page_table_data(x, ...) +#define trace_gasket_ioctl_page_table_flags_data(x, ...) #define trace_gasket_ioctl_config_coherent_allocator(x, ...) #endif @@ -130,29 +131,59 @@ static int gasket_partition_page_table( } /* Map a userspace buffer to a device virtual address. */ +static int gasket_map_buffers_common( + struct gasket_dev *gasket_dev, + struct gasket_page_table_ioctl_flags *pibuf) +{ + if (pibuf->base.page_table_index >= gasket_dev->num_page_tables) + return -EFAULT; + + if (gasket_page_table_are_addrs_bad(gasket_dev->page_table[pibuf->base.page_table_index], + pibuf->base.host_address, + pibuf->base.device_address, + pibuf->base.size)) + return -EINVAL; + + return gasket_page_table_map(gasket_dev->page_table[pibuf->base.page_table_index], +pibuf->base.host_address, +pibuf->base.device_address, +pibuf->base.size / PAGE_SIZE, +pibuf->flags); +} + static int gasket_map_buffers(struct gasket_dev *gasket_dev, struct gasket_page_table_ioctl __user *argp) { - struct gasket_page_table_ioctl ibuf; + struct gasket_page_table_ioctl_flags ibuf; - if (copy_from_user(, argp, sizeof(struct gasket_page_table_ioctl))) + if (copy_from_user(, argp, sizeof(struct gasket_page_table_ioctl))) return -EFAULT; - trace_gasket_ioctl_page_table_data(ibuf.page_table_index, ibuf.size, - ibuf.host_address, - ibuf.device_address); + ibuf.flags = 0; - if (ibuf.page_table_index >= gasket_dev->num_page_tables) + trace_gasket_ioctl_page_table_data(ibuf.base.page_table_index, + ibuf.base.size, + ibuf.base.host_address, +
[PATCH 0/3] staging: gasket: add DMA direction flags a.o.
From: Todd Poynor Add flags to page mapping ioctls that specify DMA directions other than bi-directional, avoiding unnecessary cache maintenance for read-only or write-only buffers. Remove some spammy / unhelpful / inaccurately formatted debug logs. Nick Ewalt (1): staging: gasket: page_table: add mapping flags Todd Poynor (2): staging: gasket: remove debug logs for callback invocation staging: gasket: remove debug logs in page table mapping calls drivers/staging/gasket/gasket.h| 33 ++ drivers/staging/gasket/gasket_core.c | 7 +- drivers/staging/gasket/gasket_ioctl.c | 62 +--- drivers/staging/gasket/gasket_page_table.c | 111 +++-- drivers/staging/gasket/gasket_page_table.h | 4 +- 5 files changed, 142 insertions(+), 75 deletions(-) -- 2.19.1.331.ge82ca0e54c-goog
[PATCH 1/3] staging: gasket: remove debug logs for callback invocation
From: Todd Poynor Debug logs for device-specific callback invocation aren't very useful, remove. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index f230bec76ae4e..a445d58fb3999 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -109,8 +109,6 @@ check_and_invoke_callback(struct gasket_dev *gasket_dev, { int ret = 0; - dev_dbg(gasket_dev->dev, "check_and_invoke_callback %p\n", - cb_function); if (cb_function) { mutex_lock(_dev->mutex); ret = cb_function(gasket_dev); @@ -126,11 +124,8 @@ gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev, { int ret = 0; - if (cb_function) { - dev_dbg(gasket_dev->dev, - "Invoking device-specific callback.\n"); + if (cb_function) ret = cb_function(gasket_dev); - } return ret; } -- 2.19.1.331.ge82ca0e54c-goog
[PATCH 1/3] staging: gasket: remove debug logs for callback invocation
From: Todd Poynor Debug logs for device-specific callback invocation aren't very useful, remove. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 7 +-- 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index f230bec76ae4e..a445d58fb3999 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -109,8 +109,6 @@ check_and_invoke_callback(struct gasket_dev *gasket_dev, { int ret = 0; - dev_dbg(gasket_dev->dev, "check_and_invoke_callback %p\n", - cb_function); if (cb_function) { mutex_lock(_dev->mutex); ret = cb_function(gasket_dev); @@ -126,11 +124,8 @@ gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev, { int ret = 0; - if (cb_function) { - dev_dbg(gasket_dev->dev, - "Invoking device-specific callback.\n"); + if (cb_function) ret = cb_function(gasket_dev); - } return ret; } -- 2.19.1.331.ge82ca0e54c-goog
Re: [PATCH 01/11] staging: gasket: core: debug log updates
On Mon, Oct 15, 2018 at 12:34 AM Greg Kroah-Hartman wrote: > > On Sun, Oct 14, 2018 at 09:59:17PM -0700, Todd Poynor wrote: > > From: Todd Poynor > > > > Add debug logs for device enable/disable events, > > Why? > > What is going to need this? As one of the few people actually developing for Apex chips (but this may be more soon), I ran into a situation where I cared about this. But I usually cobble together custom debugging for development situations, and generally don't get debug logs for released-in-the-wild drivers, so I'm fine not including these or any other debug logs. It sounds like debug logs face a pretty high bar for acceptance. I'm happy to send a patch removing all of 'em from gasket/apex if that's preferred. > > remove logs for > > callbacks (the called functions can generate their own logs if needed). > > That's a different thing than "adding" them, so shouldn't this really be > 2 patches? If it was, I could have accepted this patch already, and > ignored the "add new logs" one :) Sure, the callbacks most frequently occur during disable/enable events and were linked in my brain, but will send a new patch to just remove the useless callback logs. > > thanks, > > greg k-h
Re: [PATCH 01/11] staging: gasket: core: debug log updates
On Mon, Oct 15, 2018 at 12:34 AM Greg Kroah-Hartman wrote: > > On Sun, Oct 14, 2018 at 09:59:17PM -0700, Todd Poynor wrote: > > From: Todd Poynor > > > > Add debug logs for device enable/disable events, > > Why? > > What is going to need this? As one of the few people actually developing for Apex chips (but this may be more soon), I ran into a situation where I cared about this. But I usually cobble together custom debugging for development situations, and generally don't get debug logs for released-in-the-wild drivers, so I'm fine not including these or any other debug logs. It sounds like debug logs face a pretty high bar for acceptance. I'm happy to send a patch removing all of 'em from gasket/apex if that's preferred. > > remove logs for > > callbacks (the called functions can generate their own logs if needed). > > That's a different thing than "adding" them, so shouldn't this really be > 2 patches? If it was, I could have accepted this patch already, and > ignored the "add new logs" one :) Sure, the callbacks most frequently occur during disable/enable events and were linked in my brain, but will send a new patch to just remove the useless callback logs. > > thanks, > > greg k-h
Re: [PATCH v3] staging: gasket: Fix sparse "incorrect type in assignment" warnings.
On Wed, Oct 10, 2018 at 2:14 PM Laurence Rochfort wrote: > > Remove the coherent buffer __iomem cookie because the buffer is > allocated from dma_alloc_coherent(). > > warning: incorrect type in assignment (different address spaces) >expected unsigned char [noderef] [usertype] *virt_base >got void *[assigned] mem > warning: incorrect type in argument 3 (different address spaces) >expected void *cpu_addr >got unsigned char [noderef] [usertype] *virt_base > > Signed-off-by: Laurence Rochfort > --- > Changes in v3: > - Just remove the __iommem cookie, don't alter type. > > drivers/staging/gasket/gasket_core.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/gasket/gasket_core.h > b/drivers/staging/gasket/gasket_core.h > index 275fd0b..e62adcd 100644 > --- a/drivers/staging/gasket/gasket_core.h > +++ b/drivers/staging/gasket/gasket_core.h > @@ -231,7 +231,7 @@ struct gasket_coherent_buffer_desc { > /* Coherent buffer structure. */ > struct gasket_coherent_buffer { > /* Virtual base address. */ > - u8 __iomem *virt_base; > + u8 *virt_base; > > /* Physical base address. */ > ulong phys_base; > -- > 2.9.5 Reviewed-by: Todd Poynor Thanks!
Re: [PATCH v3] staging: gasket: Fix sparse "incorrect type in assignment" warnings.
On Wed, Oct 10, 2018 at 2:14 PM Laurence Rochfort wrote: > > Remove the coherent buffer __iomem cookie because the buffer is > allocated from dma_alloc_coherent(). > > warning: incorrect type in assignment (different address spaces) >expected unsigned char [noderef] [usertype] *virt_base >got void *[assigned] mem > warning: incorrect type in argument 3 (different address spaces) >expected void *cpu_addr >got unsigned char [noderef] [usertype] *virt_base > > Signed-off-by: Laurence Rochfort > --- > Changes in v3: > - Just remove the __iommem cookie, don't alter type. > > drivers/staging/gasket/gasket_core.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/staging/gasket/gasket_core.h > b/drivers/staging/gasket/gasket_core.h > index 275fd0b..e62adcd 100644 > --- a/drivers/staging/gasket/gasket_core.h > +++ b/drivers/staging/gasket/gasket_core.h > @@ -231,7 +231,7 @@ struct gasket_coherent_buffer_desc { > /* Coherent buffer structure. */ > struct gasket_coherent_buffer { > /* Virtual base address. */ > - u8 __iomem *virt_base; > + u8 *virt_base; > > /* Physical base address. */ > ulong phys_base; > -- > 2.9.5 Reviewed-by: Todd Poynor Thanks!
Re: [PATCH 00/11] staging: gasket: fixes
On Mon, Oct 15, 2018 at 12:33 AM Greg Kroah-Hartman wrote: > > On Sun, Oct 14, 2018 at 09:59:16PM -0700, Todd Poynor wrote: > > From: Todd Poynor > > > > Various fixes for gasket/apex drivers. > > For some reason you seem to have ignored/missed this patch: > Subject: [PATCH v3] staging: gasket: Fix sparse "incorrect type in > assignment" warnings. > that was sent last week. > > Any specific reason? Coming off a 2 week vacation, I'm behind on everything. I saw you had commented already, but I'll take a look as well, sure. > > thanks, > > greg k-h -- Todd
Re: [PATCH 00/11] staging: gasket: fixes
On Mon, Oct 15, 2018 at 12:33 AM Greg Kroah-Hartman wrote: > > On Sun, Oct 14, 2018 at 09:59:16PM -0700, Todd Poynor wrote: > > From: Todd Poynor > > > > Various fixes for gasket/apex drivers. > > For some reason you seem to have ignored/missed this patch: > Subject: [PATCH v3] staging: gasket: Fix sparse "incorrect type in > assignment" warnings. > that was sent last week. > > Any specific reason? Coming off a 2 week vacation, I'm behind on everything. I saw you had commented already, but I'll take a look as well, sure. > > thanks, > > greg k-h -- Todd
[PATCH 07/11] staging: gasket: page_table: fix comment in components_to_dev_address
From: Nick Ewalt Comments in components_to_dev_address() describing examples are inconsistent, fix these to be accurate. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index a88f2ae0cee8b..ec9359576ea7c 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -687,13 +687,13 @@ static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl, * Convert (simple, page, offset) into a device address. * Examples: * Simple page 0, offset 32: - * Input (0, 0, 32), Output 0x20 + * Input (1, 0, 32), Output 0x20 * Simple page 1000, offset 511: - * Input (0, 1000, 512), Output 0x3E81FF + * Input (1, 1000, 511), Output 0x3E81FF * Extended page 0, offset 32: * Input (0, 0, 32), Output 0x800020 * Extended page 1000, offset 511: - * Input (1, 1000, 512), Output 0x8003E81FF + * Input (0, 1000, 511), Output 0x8003E81FF */ static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl, int is_simple, uint page_index, -- 2.19.0.605.g01d371f741-goog
[PATCH 07/11] staging: gasket: page_table: fix comment in components_to_dev_address
From: Nick Ewalt Comments in components_to_dev_address() describing examples are inconsistent, fix these to be accurate. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index a88f2ae0cee8b..ec9359576ea7c 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -687,13 +687,13 @@ static inline bool gasket_addr_is_simple(struct gasket_page_table *pg_tbl, * Convert (simple, page, offset) into a device address. * Examples: * Simple page 0, offset 32: - * Input (0, 0, 32), Output 0x20 + * Input (1, 0, 32), Output 0x20 * Simple page 1000, offset 511: - * Input (0, 1000, 512), Output 0x3E81FF + * Input (1, 1000, 511), Output 0x3E81FF * Extended page 0, offset 32: * Input (0, 0, 32), Output 0x800020 * Extended page 1000, offset 511: - * Input (1, 1000, 512), Output 0x8003E81FF + * Input (0, 1000, 511), Output 0x8003E81FF */ static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl, int is_simple, uint page_index, -- 2.19.0.605.g01d371f741-goog
[PATCH 04/11] staging: gasket: page_table: remove unnecessary PTE status set to free
From: Nick Ewalt Remove unnecessary ptes[i].status update in gasket_perform_unmapping. The vaaue will be cleared in the following memset. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 985a3a93499d5..d2e115d2dba30 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -623,7 +623,6 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; } - ptes[i].status = PTE_FREE; /* and clear the PTE. */ memset([i], 0, sizeof(struct gasket_page_table_entry)); -- 2.19.0.605.g01d371f741-goog
[PATCH 11/11] staging: gasket: Update device virtual address comment
From: Nick Ewalt Add that number of page table entries and extended address bit offset are configurable. Update example virtual address format to be more consistent with typical usage. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index c2fbab74194f8..5b398b7ba81d3 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -10,10 +10,18 @@ * * This file assumes 4kB pages throughout; can be factored out when necessary. * - * Address format is as follows: + * There is a configurable number of page table entries, as well as a + * configurable bit index for the extended address flag. Both of these are + * specified in gasket_page_table_init through the page_table_config parameter. + * + * The following example assumes: + * page_table_config->total_entries = 8192 + * page_table_config->extended_bit = 63 + * + * Address format: * Simple addresses - those whose containing pages are directly placed in the * device's address translation registers - are laid out as: - * [ 63 - 40: Unused | 39 - 28: 0 | 27 - 12: page index | 11 - 0: page offset ] + * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page offset ] * page index: The index of the containing page in the device's address * translation registers. * page offset: The index of the address into the containing page. @@ -21,7 +29,7 @@ * Extended address - those whose containing pages are contained in a second- * level page table whose address is present in the device's address translation * registers - are laid out as: - * [ 63 - 40: Unused | 39: flag | 38 - 37: 0 | 36 - 21: dev/level 0 index | + * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index | * 20 - 12: host/level 1 index | 11 - 0: page offset ] * flag:Marker indicating that this is an extended address. Always 1. * dev index: The index of the first-level page in the device's extended -- 2.19.0.605.g01d371f741-goog
[PATCH 02/11] staging: gasket: page table: return valid error code on map fail
From: Todd Poynor Return -EINVAL on mapping failures, instead of -1, which triggers a checkpatch error. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 964146f0df526..2e1de8ad4a2c6 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -514,13 +514,12 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (void *)page_to_pfn(page), (void *)page_to_phys(page)); - /* clean up */ if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; memset([i], 0, sizeof(struct gasket_page_table_entry)); - return -1; + return -EINVAL; } } @@ -1165,7 +1164,7 @@ int gasket_page_table_lookup_page( *ppage = NULL; *poffset = 0; mutex_unlock(_tbl->mutex); - return -1; + return -EINVAL; } /* See gasket_page_table.h for description. */ -- 2.19.0.605.g01d371f741-goog
[PATCH 08/11] staging: gasket: page_table: simplify gasket_components_to_dev_address
From: Nick Ewalt Refactor gasket_components_to_dev_address to be faster and easier to understand. The old implementation was unnecessarily complex and masked the page_index for simple addresses but not extended ones. It makes the most sense for this function to perform no such masking. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 21 ++--- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index ec9359576ea7c..c2fbab74194f8 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -699,26 +699,9 @@ static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl, int is_simple, uint page_index, uint offset) { - ulong lvl0_index, lvl1_index; + ulong dev_addr = (page_index << GASKET_SIMPLE_PAGE_SHIFT) | offset; - if (is_simple) { - /* Return simple addresses directly. */ - lvl0_index = page_index & (pg_tbl->config.total_entries - 1); - return (lvl0_index << GASKET_SIMPLE_PAGE_SHIFT) | offset; - } - - /* -* This could be compressed into fewer statements, but -* A) the compiler should optimize it -* B) this is not slow -* C) this is an uncommon operation -* D) this is actually readable this way. -*/ - lvl0_index = page_index / GASKET_PAGES_PER_SUBTABLE; - lvl1_index = page_index & (GASKET_PAGES_PER_SUBTABLE - 1); - return (pg_tbl)->extended_flag | - (lvl0_index << GASKET_EXTENDED_LVL0_SHIFT) | - (lvl1_index << GASKET_EXTENDED_LVL1_SHIFT) | offset; + return is_simple ? dev_addr : (pg_tbl->extended_flag | dev_addr); } /* -- 2.19.0.605.g01d371f741-goog
[PATCH 04/11] staging: gasket: page_table: remove unnecessary PTE status set to free
From: Nick Ewalt Remove unnecessary ptes[i].status update in gasket_perform_unmapping. The vaaue will be cleared in the following memset. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 985a3a93499d5..d2e115d2dba30 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -623,7 +623,6 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; } - ptes[i].status = PTE_FREE; /* and clear the PTE. */ memset([i], 0, sizeof(struct gasket_page_table_entry)); -- 2.19.0.605.g01d371f741-goog
[PATCH 11/11] staging: gasket: Update device virtual address comment
From: Nick Ewalt Add that number of page table entries and extended address bit offset are configurable. Update example virtual address format to be more consistent with typical usage. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index c2fbab74194f8..5b398b7ba81d3 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -10,10 +10,18 @@ * * This file assumes 4kB pages throughout; can be factored out when necessary. * - * Address format is as follows: + * There is a configurable number of page table entries, as well as a + * configurable bit index for the extended address flag. Both of these are + * specified in gasket_page_table_init through the page_table_config parameter. + * + * The following example assumes: + * page_table_config->total_entries = 8192 + * page_table_config->extended_bit = 63 + * + * Address format: * Simple addresses - those whose containing pages are directly placed in the * device's address translation registers - are laid out as: - * [ 63 - 40: Unused | 39 - 28: 0 | 27 - 12: page index | 11 - 0: page offset ] + * [ 63 - 25: 0 | 24 - 12: page index | 11 - 0: page offset ] * page index: The index of the containing page in the device's address * translation registers. * page offset: The index of the address into the containing page. @@ -21,7 +29,7 @@ * Extended address - those whose containing pages are contained in a second- * level page table whose address is present in the device's address translation * registers - are laid out as: - * [ 63 - 40: Unused | 39: flag | 38 - 37: 0 | 36 - 21: dev/level 0 index | + * [ 63: flag | 62 - 34: 0 | 33 - 21: dev/level 0 index | * 20 - 12: host/level 1 index | 11 - 0: page offset ] * flag:Marker indicating that this is an extended address. Always 1. * dev index: The index of the first-level page in the device's extended -- 2.19.0.605.g01d371f741-goog
[PATCH 02/11] staging: gasket: page table: return valid error code on map fail
From: Todd Poynor Return -EINVAL on mapping failures, instead of -1, which triggers a checkpatch error. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 964146f0df526..2e1de8ad4a2c6 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -514,13 +514,12 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (void *)page_to_pfn(page), (void *)page_to_phys(page)); - /* clean up */ if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; memset([i], 0, sizeof(struct gasket_page_table_entry)); - return -1; + return -EINVAL; } } @@ -1165,7 +1164,7 @@ int gasket_page_table_lookup_page( *ppage = NULL; *poffset = 0; mutex_unlock(_tbl->mutex); - return -1; + return -EINVAL; } /* See gasket_page_table.h for description. */ -- 2.19.0.605.g01d371f741-goog
[PATCH 08/11] staging: gasket: page_table: simplify gasket_components_to_dev_address
From: Nick Ewalt Refactor gasket_components_to_dev_address to be faster and easier to understand. The old implementation was unnecessarily complex and masked the page_index for simple addresses but not extended ones. It makes the most sense for this function to perform no such masking. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 21 ++--- 1 file changed, 2 insertions(+), 19 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index ec9359576ea7c..c2fbab74194f8 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -699,26 +699,9 @@ static ulong gasket_components_to_dev_address(struct gasket_page_table *pg_tbl, int is_simple, uint page_index, uint offset) { - ulong lvl0_index, lvl1_index; + ulong dev_addr = (page_index << GASKET_SIMPLE_PAGE_SHIFT) | offset; - if (is_simple) { - /* Return simple addresses directly. */ - lvl0_index = page_index & (pg_tbl->config.total_entries - 1); - return (lvl0_index << GASKET_SIMPLE_PAGE_SHIFT) | offset; - } - - /* -* This could be compressed into fewer statements, but -* A) the compiler should optimize it -* B) this is not slow -* C) this is an uncommon operation -* D) this is actually readable this way. -*/ - lvl0_index = page_index / GASKET_PAGES_PER_SUBTABLE; - lvl1_index = page_index & (GASKET_PAGES_PER_SUBTABLE - 1); - return (pg_tbl)->extended_flag | - (lvl0_index << GASKET_EXTENDED_LVL0_SHIFT) | - (lvl1_index << GASKET_EXTENDED_LVL1_SHIFT) | offset; + return is_simple ? dev_addr : (pg_tbl->extended_flag | dev_addr); } /* -- 2.19.0.605.g01d371f741-goog
[PATCH 01/11] staging: gasket: core: debug log updates
From: Todd Poynor Add debug logs for device enable/disable events, remove logs for callbacks (the called functions can generate their own logs if needed). Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index f230bec76ae4e..62a7515915e59 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -109,8 +109,6 @@ check_and_invoke_callback(struct gasket_dev *gasket_dev, { int ret = 0; - dev_dbg(gasket_dev->dev, "check_and_invoke_callback %p\n", - cb_function); if (cb_function) { mutex_lock(_dev->mutex); ret = cb_function(gasket_dev); @@ -126,11 +124,8 @@ gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev, { int ret = 0; - if (cb_function) { - dev_dbg(gasket_dev->dev, - "Invoking device-specific callback.\n"); + if (cb_function) ret = cb_function(gasket_dev); - } return ret; } @@ -633,6 +628,7 @@ void gasket_disable_device(struct gasket_dev *gasket_dev) gasket_dev->internal_desc->driver_desc; int i; + dev_dbg(gasket_dev->dev, "disabling device\n"); /* Only delete the device if it has been successfully added. */ if (gasket_dev->dev_info.cdev_added) cdev_del(_dev->dev_info.cdev); @@ -1357,6 +1353,7 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) const struct gasket_driver_desc *driver_desc = gasket_dev->internal_desc->driver_desc; + dev_dbg(gasket_dev->dev, "enabling device\n"); ret = gasket_interrupt_init(gasket_dev); if (ret) { dev_err(gasket_dev->dev, -- 2.19.0.605.g01d371f741-goog
[PATCH 09/11] staging: gasket: apex: fix sysfs_show
From: Nick Ewalt sysfs_show was incorrectly extracting the sysfs_attribute_type from the gasket_sysfs_attribute. This prevented dispatch from working properly. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/apex_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/apex_driver.c b/drivers/staging/gasket/apex_driver.c index 6dca3b177863c..3c7a13a4798ef 100644 --- a/drivers/staging/gasket/apex_driver.c +++ b/drivers/staging/gasket/apex_driver.c @@ -526,7 +526,7 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr, return -ENODEV; } - type = (enum sysfs_attribute_type)gasket_sysfs_get_attr(device, attr); + type = (enum sysfs_attribute_type)gasket_attr->data.attr_type; switch (type) { case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE: ret = scnprintf(buf, PAGE_SIZE, "%u\n", -- 2.19.0.605.g01d371f741-goog
[PATCH 03/11] staging: gasket: page table: remove dead code in coherent mem alloc
From: Todd Poynor gasket_alloc_coherent_memory() has some unnecessary code related to out of memory checking that will never hit the condition checked, remove. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 2e1de8ad4a2c6..985a3a93499d5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1316,7 +1316,6 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, GFP_KERNEL); if (!gasket_dev->page_table[index]->coherent_pages) goto nomem; - *dma_address = 0; gasket_dev->coherent_buffer.length_bytes = PAGE_SIZE * (num_pages); @@ -1331,15 +1330,12 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, (u64)mem + j * PAGE_SIZE; } - if (*dma_address == 0) - goto nomem; return 0; nomem: - if (mem) { + if (mem) dma_free_coherent(gasket_get_device(gasket_dev), num_pages * PAGE_SIZE, mem, handle); - } kfree(gasket_dev->page_table[index]->coherent_pages); gasket_dev->page_table[index]->coherent_pages = NULL; -- 2.19.0.605.g01d371f741-goog
[PATCH 06/11] staging: gasket: page table: fixup error path allocating coherent mem
From: Nick Ewalt Correctly clean up data structure state in gasket_alloc_coherent_memory error path, to ensure no double free on the stale pointer value. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 9c2f8671216b5..a88f2ae0cee8b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1332,9 +1332,13 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, return 0; nomem: - if (mem) + if (mem) { dma_free_coherent(gasket_get_device(gasket_dev), num_pages * PAGE_SIZE, mem, handle); + gasket_dev->coherent_buffer.length_bytes = 0; + gasket_dev->coherent_buffer.virt_base = NULL; + gasket_dev->coherent_buffer.phys_base = 0; + } kfree(gasket_dev->page_table[index]->coherent_pages); gasket_dev->page_table[index]->coherent_pages = NULL; -- 2.19.0.605.g01d371f741-goog
[PATCH 00/11] staging: gasket: fixes
From: Todd Poynor Various fixes for gasket/apex drivers. Nick Ewalt (8): staging: gasket: page_table: remove unnecessary PTE status set to free staging: gasket: page_table: rearrange gasket_page_table_entry staging: gasket: page table: fixup error path allocating coherent mem staging: gasket: page_table: fix comment in components_to_dev_address staging: gasket: page_table: simplify gasket_components_to_dev_address staging: gasket: apex: fix sysfs_show staging: gasket: sysfs: fix attribute release comment staging: gasket: Update device virtual address comment Todd Poynor (3): staging: gasket: core: debug log updates staging: gasket: page table: return valid error code on map fail staging: gasket: page table: remove dead code in coherent mem alloc drivers/staging/gasket/apex_driver.c | 2 +- drivers/staging/gasket/gasket_core.c | 9 +-- drivers/staging/gasket/gasket_page_table.c | 65 +- drivers/staging/gasket/gasket_sysfs.h | 4 +- 4 files changed, 33 insertions(+), 47 deletions(-) -- 2.19.0.605.g01d371f741-goog
[PATCH 01/11] staging: gasket: core: debug log updates
From: Todd Poynor Add debug logs for device enable/disable events, remove logs for callbacks (the called functions can generate their own logs if needed). Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 9 +++-- 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index f230bec76ae4e..62a7515915e59 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -109,8 +109,6 @@ check_and_invoke_callback(struct gasket_dev *gasket_dev, { int ret = 0; - dev_dbg(gasket_dev->dev, "check_and_invoke_callback %p\n", - cb_function); if (cb_function) { mutex_lock(_dev->mutex); ret = cb_function(gasket_dev); @@ -126,11 +124,8 @@ gasket_check_and_invoke_callback_nolock(struct gasket_dev *gasket_dev, { int ret = 0; - if (cb_function) { - dev_dbg(gasket_dev->dev, - "Invoking device-specific callback.\n"); + if (cb_function) ret = cb_function(gasket_dev); - } return ret; } @@ -633,6 +628,7 @@ void gasket_disable_device(struct gasket_dev *gasket_dev) gasket_dev->internal_desc->driver_desc; int i; + dev_dbg(gasket_dev->dev, "disabling device\n"); /* Only delete the device if it has been successfully added. */ if (gasket_dev->dev_info.cdev_added) cdev_del(_dev->dev_info.cdev); @@ -1357,6 +1353,7 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) const struct gasket_driver_desc *driver_desc = gasket_dev->internal_desc->driver_desc; + dev_dbg(gasket_dev->dev, "enabling device\n"); ret = gasket_interrupt_init(gasket_dev); if (ret) { dev_err(gasket_dev->dev, -- 2.19.0.605.g01d371f741-goog
[PATCH 09/11] staging: gasket: apex: fix sysfs_show
From: Nick Ewalt sysfs_show was incorrectly extracting the sysfs_attribute_type from the gasket_sysfs_attribute. This prevented dispatch from working properly. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/apex_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/apex_driver.c b/drivers/staging/gasket/apex_driver.c index 6dca3b177863c..3c7a13a4798ef 100644 --- a/drivers/staging/gasket/apex_driver.c +++ b/drivers/staging/gasket/apex_driver.c @@ -526,7 +526,7 @@ static ssize_t sysfs_show(struct device *device, struct device_attribute *attr, return -ENODEV; } - type = (enum sysfs_attribute_type)gasket_sysfs_get_attr(device, attr); + type = (enum sysfs_attribute_type)gasket_attr->data.attr_type; switch (type) { case ATTR_KERNEL_HIB_PAGE_TABLE_SIZE: ret = scnprintf(buf, PAGE_SIZE, "%u\n", -- 2.19.0.605.g01d371f741-goog
[PATCH 03/11] staging: gasket: page table: remove dead code in coherent mem alloc
From: Todd Poynor gasket_alloc_coherent_memory() has some unnecessary code related to out of memory checking that will never hit the condition checked, remove. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 2e1de8ad4a2c6..985a3a93499d5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1316,7 +1316,6 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, GFP_KERNEL); if (!gasket_dev->page_table[index]->coherent_pages) goto nomem; - *dma_address = 0; gasket_dev->coherent_buffer.length_bytes = PAGE_SIZE * (num_pages); @@ -1331,15 +1330,12 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, (u64)mem + j * PAGE_SIZE; } - if (*dma_address == 0) - goto nomem; return 0; nomem: - if (mem) { + if (mem) dma_free_coherent(gasket_get_device(gasket_dev), num_pages * PAGE_SIZE, mem, handle); - } kfree(gasket_dev->page_table[index]->coherent_pages); gasket_dev->page_table[index]->coherent_pages = NULL; -- 2.19.0.605.g01d371f741-goog
[PATCH 06/11] staging: gasket: page table: fixup error path allocating coherent mem
From: Nick Ewalt Correctly clean up data structure state in gasket_alloc_coherent_memory error path, to ensure no double free on the stale pointer value. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 9c2f8671216b5..a88f2ae0cee8b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1332,9 +1332,13 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, return 0; nomem: - if (mem) + if (mem) { dma_free_coherent(gasket_get_device(gasket_dev), num_pages * PAGE_SIZE, mem, handle); + gasket_dev->coherent_buffer.length_bytes = 0; + gasket_dev->coherent_buffer.virt_base = NULL; + gasket_dev->coherent_buffer.phys_base = 0; + } kfree(gasket_dev->page_table[index]->coherent_pages); gasket_dev->page_table[index]->coherent_pages = NULL; -- 2.19.0.605.g01d371f741-goog
[PATCH 00/11] staging: gasket: fixes
From: Todd Poynor Various fixes for gasket/apex drivers. Nick Ewalt (8): staging: gasket: page_table: remove unnecessary PTE status set to free staging: gasket: page_table: rearrange gasket_page_table_entry staging: gasket: page table: fixup error path allocating coherent mem staging: gasket: page_table: fix comment in components_to_dev_address staging: gasket: page_table: simplify gasket_components_to_dev_address staging: gasket: apex: fix sysfs_show staging: gasket: sysfs: fix attribute release comment staging: gasket: Update device virtual address comment Todd Poynor (3): staging: gasket: core: debug log updates staging: gasket: page table: return valid error code on map fail staging: gasket: page table: remove dead code in coherent mem alloc drivers/staging/gasket/apex_driver.c | 2 +- drivers/staging/gasket/gasket_core.c | 9 +-- drivers/staging/gasket/gasket_page_table.c | 65 +- drivers/staging/gasket/gasket_sysfs.h | 4 +- 4 files changed, 33 insertions(+), 47 deletions(-) -- 2.19.0.605.g01d371f741-goog
[PATCH 10/11] staging: gasket: sysfs: fix attribute release comment
From: Nick Ewalt Comments for gasket_sysfs_get_attr() incorrectly describe reference release procedure. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_sysfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_sysfs.h b/drivers/staging/gasket/gasket_sysfs.h index f32eaf89e056b..151e8edd28ea6 100644 --- a/drivers/staging/gasket/gasket_sysfs.h +++ b/drivers/staging/gasket/gasket_sysfs.h @@ -152,8 +152,8 @@ void gasket_sysfs_put_device_data(struct device *device, * Returns the Gasket sysfs attribute associated with the kernel device * attribute and device structure itself. Upon success, this call will take a * reference to internal sysfs data that must be released with a call to - * gasket_sysfs_get_device_data. While this reference is held, the underlying - * device sysfs information/structure will remain valid/will not be deleted. + * gasket_sysfs_put_attr. While this reference is held, the underlying device + * sysfs information/structure will remain valid/will not be deleted. */ struct gasket_sysfs_attribute * gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr); -- 2.19.0.605.g01d371f741-goog
[PATCH 05/11] staging: gasket: page_table: rearrange gasket_page_table_entry
From: Nick Ewalt Rearrange gasket_page_table entry to reduce padding slop. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index d2e115d2dba30..9c2f8671216b5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -103,12 +103,6 @@ struct gasket_page_table_entry { /* The status of this entry/slot: free or in use. */ enum pte_status status; - /* Address of the page in DMA space. */ - dma_addr_t dma_addr; - - /* Linux page descriptor for the page described by this structure. */ - struct page *page; - /* * Index for alignment into host vaddrs. * When a user specifies a host address for a mapping, that address may @@ -119,6 +113,12 @@ struct gasket_page_table_entry { */ int offset; + /* Address of the page in DMA space. */ + dma_addr_t dma_addr; + + /* Linux page descriptor for the page described by this structure. */ + struct page *page; + /* * If this is an extended and first-level entry, sublevel points * to the second-level entries underneath this entry. -- 2.19.0.605.g01d371f741-goog
[PATCH 10/11] staging: gasket: sysfs: fix attribute release comment
From: Nick Ewalt Comments for gasket_sysfs_get_attr() incorrectly describe reference release procedure. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_sysfs.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_sysfs.h b/drivers/staging/gasket/gasket_sysfs.h index f32eaf89e056b..151e8edd28ea6 100644 --- a/drivers/staging/gasket/gasket_sysfs.h +++ b/drivers/staging/gasket/gasket_sysfs.h @@ -152,8 +152,8 @@ void gasket_sysfs_put_device_data(struct device *device, * Returns the Gasket sysfs attribute associated with the kernel device * attribute and device structure itself. Upon success, this call will take a * reference to internal sysfs data that must be released with a call to - * gasket_sysfs_get_device_data. While this reference is held, the underlying - * device sysfs information/structure will remain valid/will not be deleted. + * gasket_sysfs_put_attr. While this reference is held, the underlying device + * sysfs information/structure will remain valid/will not be deleted. */ struct gasket_sysfs_attribute * gasket_sysfs_get_attr(struct device *device, struct device_attribute *attr); -- 2.19.0.605.g01d371f741-goog
[PATCH 05/11] staging: gasket: page_table: rearrange gasket_page_table_entry
From: Nick Ewalt Rearrange gasket_page_table entry to reduce padding slop. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index d2e115d2dba30..9c2f8671216b5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -103,12 +103,6 @@ struct gasket_page_table_entry { /* The status of this entry/slot: free or in use. */ enum pte_status status; - /* Address of the page in DMA space. */ - dma_addr_t dma_addr; - - /* Linux page descriptor for the page described by this structure. */ - struct page *page; - /* * Index for alignment into host vaddrs. * When a user specifies a host address for a mapping, that address may @@ -119,6 +113,12 @@ struct gasket_page_table_entry { */ int offset; + /* Address of the page in DMA space. */ + dma_addr_t dma_addr; + + /* Linux page descriptor for the page described by this structure. */ + struct page *page; + /* * If this is an extended and first-level entry, sublevel points * to the second-level entries underneath this entry. -- 2.19.0.605.g01d371f741-goog
[PATCH 00/10] staging: gasket: Apex uncloaks, plus fixes
From: Todd Poynor Add a description of the Gasket framework device Apex (it's a Google Edge TPU machine learning accelerator soon to be released), plus a handful of fixes. Nick Ewalt (7): staging: gasket: fix DMA direction for extended page tables staging: gasket: fix data page unmap DMA direction staging: gasket: page_table: don't unmap coherent pages staging: gasket: fix gasket_free_coherent_memory metadata frees staging: gasket: cleanup if dma_map_page fails in gasket_perform_mapping staging: gasket: page_table: use total_entries for max ext lvl0 page idx staging: gasket: page_table: handle failed dma_map_page Todd Poynor (3): staging: gasket: Kconfig: describe Apex as an Edge TPU device staging: gasket: interrupt: remove PCI-MSIX-specific status check staging: gasket: page table: use GFP_KERNEL for dma_alloc_coherent drivers/staging/gasket/Kconfig | 5 +- drivers/staging/gasket/gasket_interrupt.c | 5 -- drivers/staging/gasket/gasket_page_table.c | 61 +++--- 3 files changed, 45 insertions(+), 26 deletions(-) -- 2.19.0.397.gdd90340f6a-goog
[PATCH 00/10] staging: gasket: Apex uncloaks, plus fixes
From: Todd Poynor Add a description of the Gasket framework device Apex (it's a Google Edge TPU machine learning accelerator soon to be released), plus a handful of fixes. Nick Ewalt (7): staging: gasket: fix DMA direction for extended page tables staging: gasket: fix data page unmap DMA direction staging: gasket: page_table: don't unmap coherent pages staging: gasket: fix gasket_free_coherent_memory metadata frees staging: gasket: cleanup if dma_map_page fails in gasket_perform_mapping staging: gasket: page_table: use total_entries for max ext lvl0 page idx staging: gasket: page_table: handle failed dma_map_page Todd Poynor (3): staging: gasket: Kconfig: describe Apex as an Edge TPU device staging: gasket: interrupt: remove PCI-MSIX-specific status check staging: gasket: page table: use GFP_KERNEL for dma_alloc_coherent drivers/staging/gasket/Kconfig | 5 +- drivers/staging/gasket/gasket_interrupt.c | 5 -- drivers/staging/gasket/gasket_page_table.c | 61 +++--- 3 files changed, 45 insertions(+), 26 deletions(-) -- 2.19.0.397.gdd90340f6a-goog
[PATCH 01/10] staging: gasket: Kconfig: describe Apex as an Edge TPU device
From: Todd Poynor Add a brief description and URL for more information on the Apex device, an Edge TPU (Tensorflow Processing Unit) machine learning accelerator. Signed-off-by: Todd Poynor --- drivers/staging/gasket/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/Kconfig b/drivers/staging/gasket/Kconfig index 970e299046c37..e82b85541f7ef 100644 --- a/drivers/staging/gasket/Kconfig +++ b/drivers/staging/gasket/Kconfig @@ -14,8 +14,9 @@ config STAGING_APEX_DRIVER tristate "Apex Driver" depends on STAGING_GASKET_FRAMEWORK help - This driver supports the Apex device. Say Y if you want to - include this driver in the kernel. + This driver supports the Apex Edge TPU device. See + https://cloud.google.com/edge-tpu/ for more information. + Say Y if you want to include this driver in the kernel. To compile this driver as a module, choose M here. The module will be called "apex". -- 2.19.0.397.gdd90340f6a-goog
[PATCH 01/10] staging: gasket: Kconfig: describe Apex as an Edge TPU device
From: Todd Poynor Add a brief description and URL for more information on the Apex device, an Edge TPU (Tensorflow Processing Unit) machine learning accelerator. Signed-off-by: Todd Poynor --- drivers/staging/gasket/Kconfig | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/Kconfig b/drivers/staging/gasket/Kconfig index 970e299046c37..e82b85541f7ef 100644 --- a/drivers/staging/gasket/Kconfig +++ b/drivers/staging/gasket/Kconfig @@ -14,8 +14,9 @@ config STAGING_APEX_DRIVER tristate "Apex Driver" depends on STAGING_GASKET_FRAMEWORK help - This driver supports the Apex device. Say Y if you want to - include this driver in the kernel. + This driver supports the Apex Edge TPU device. See + https://cloud.google.com/edge-tpu/ for more information. + Say Y if you want to include this driver in the kernel. To compile this driver as a module, choose M here. The module will be called "apex". -- 2.19.0.397.gdd90340f6a-goog
[PATCH 07/10] staging: gasket: fix gasket_free_coherent_memory metadata frees
From: Nick Ewalt Free gasket_coherent_page_entries metadata memory, update data structures accordingly. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 33d98043953a5..c1ce8f984f8e0 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1353,6 +1353,11 @@ int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, u64 size, gasket_dev->coherent_buffer.virt_base = NULL; gasket_dev->coherent_buffer.phys_base = 0; } + + kfree(gasket_dev->page_table[index]->coherent_pages); + gasket_dev->page_table[index]->coherent_pages = NULL; + gasket_dev->page_table[index]->num_coherent_pages = 0; + return 0; } -- 2.19.0.397.gdd90340f6a-goog
[PATCH 10/10] staging: gasket: page_table: handle failed dma_map_page
From: Nick Ewalt Handle dma_map_page failing in gasket_alloc_extended_subtable: free memory, don't add invalid page table entry. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 8364b49f147c2..964146f0df526 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -902,6 +902,17 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, /* Map the page into DMA space. */ pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, DMA_TO_DEVICE); + if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) { + dev_dbg(pg_tbl->device, + "%s: fail to map page [pfn %lx phys %llx]\n", + __func__, page_to_pfn(pte->page), + page_to_phys(pte->page)); + + free_page(page_addr); + vfree(pte->sublevel); + memset(pte, 0, sizeof(struct gasket_page_table_entry)); + return -ENOMEM; + } /* make the addresses available to the device */ dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 06/10] staging: gasket: page_table: don't unmap coherent pages
From: Nick Ewalt Only call dma_unmap_page if there was an associated dma_map_page call. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 8fe27e7d1b53c..33d98043953a5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -610,7 +610,7 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, /* release the address from the driver, */ if (ptes[i].status == PTE_INUSE) { - if (ptes[i].dma_addr) { + if (ptes[i].page && ptes[i].dma_addr) { dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL); } -- 2.19.0.397.gdd90340f6a-goog
[PATCH 07/10] staging: gasket: fix gasket_free_coherent_memory metadata frees
From: Nick Ewalt Free gasket_coherent_page_entries metadata memory, update data structures accordingly. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 5 + 1 file changed, 5 insertions(+) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 33d98043953a5..c1ce8f984f8e0 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1353,6 +1353,11 @@ int gasket_free_coherent_memory(struct gasket_dev *gasket_dev, u64 size, gasket_dev->coherent_buffer.virt_base = NULL; gasket_dev->coherent_buffer.phys_base = 0; } + + kfree(gasket_dev->page_table[index]->coherent_pages); + gasket_dev->page_table[index]->coherent_pages = NULL; + gasket_dev->page_table[index]->num_coherent_pages = 0; + return 0; } -- 2.19.0.397.gdd90340f6a-goog
[PATCH 10/10] staging: gasket: page_table: handle failed dma_map_page
From: Nick Ewalt Handle dma_map_page failing in gasket_alloc_extended_subtable: free memory, don't add invalid page table entry. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 11 +++ 1 file changed, 11 insertions(+) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 8364b49f147c2..964146f0df526 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -902,6 +902,17 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, /* Map the page into DMA space. */ pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, DMA_TO_DEVICE); + if (dma_mapping_error(pg_tbl->device, pte->dma_addr)) { + dev_dbg(pg_tbl->device, + "%s: fail to map page [pfn %lx phys %llx]\n", + __func__, page_to_pfn(pte->page), + page_to_phys(pte->page)); + + free_page(page_addr); + vfree(pte->sublevel); + memset(pte, 0, sizeof(struct gasket_page_table_entry)); + return -ENOMEM; + } /* make the addresses available to the device */ dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 06/10] staging: gasket: page_table: don't unmap coherent pages
From: Nick Ewalt Only call dma_unmap_page if there was an associated dma_map_page call. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 8fe27e7d1b53c..33d98043953a5 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -610,7 +610,7 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, /* release the address from the driver, */ if (ptes[i].status == PTE_INUSE) { - if (ptes[i].dma_addr) { + if (ptes[i].page && ptes[i].dma_addr) { dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, PAGE_SIZE, DMA_BIDIRECTIONAL); } -- 2.19.0.397.gdd90340f6a-goog
[PATCH 08/10] staging: gasket: cleanup if dma_map_page fails in gasket_perform_mapping
From: Nick Ewalt Previously pages would have never been unmapped in this case. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 33 +- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index c1ce8f984f8e0..779ad2f23ef9b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -433,6 +433,19 @@ static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr) return min <= host_addr && host_addr < max; } +/* Safely return a page to the OS. */ +static bool gasket_release_page(struct page *page) +{ + if (!page) + return false; + + if (!PageReserved(page)) + SetPageDirty(page); + put_page(page); + + return true; +} + /* * Get and map last level page table buffers. * @@ -500,6 +513,13 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (unsigned long long)ptes[i].dma_addr, (void *)page_to_pfn(page), (void *)page_to_phys(page)); + + /* clean up */ + if (gasket_release_page(ptes[i].page)) + --pg_tbl->num_active_pages; + + memset([i], 0, + sizeof(struct gasket_page_table_entry)); return -1; } } @@ -571,19 +591,6 @@ static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl, return 0; } -/* Safely return a page to the OS. */ -static bool gasket_release_page(struct page *page) -{ - if (!page) - return false; - - if (!PageReserved(page)) - SetPageDirty(page); - put_page(page); - - return true; -} - /* * Unmap and release mapped pages. * The page table mutex must be held by the caller. -- 2.19.0.397.gdd90340f6a-goog
[PATCH 08/10] staging: gasket: cleanup if dma_map_page fails in gasket_perform_mapping
From: Nick Ewalt Previously pages would have never been unmapped in this case. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 33 +- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index c1ce8f984f8e0..779ad2f23ef9b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -433,6 +433,19 @@ static int is_coherent(struct gasket_page_table *pg_tbl, ulong host_addr) return min <= host_addr && host_addr < max; } +/* Safely return a page to the OS. */ +static bool gasket_release_page(struct page *page) +{ + if (!page) + return false; + + if (!PageReserved(page)) + SetPageDirty(page); + put_page(page); + + return true; +} + /* * Get and map last level page table buffers. * @@ -500,6 +513,13 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (unsigned long long)ptes[i].dma_addr, (void *)page_to_pfn(page), (void *)page_to_phys(page)); + + /* clean up */ + if (gasket_release_page(ptes[i].page)) + --pg_tbl->num_active_pages; + + memset([i], 0, + sizeof(struct gasket_page_table_entry)); return -1; } } @@ -571,19 +591,6 @@ static int gasket_alloc_simple_entries(struct gasket_page_table *pg_tbl, return 0; } -/* Safely return a page to the OS. */ -static bool gasket_release_page(struct page *page) -{ - if (!page) - return false; - - if (!PageReserved(page)) - SetPageDirty(page); - put_page(page); - - return true; -} - /* * Unmap and release mapped pages. * The page table mutex must be held by the caller. -- 2.19.0.397.gdd90340f6a-goog
[PATCH 04/10] staging: gasket: fix DMA direction for extended page tables
From: Nick Ewalt Extended page tables should be mapped as DMA_TO_DEVICE, not bi-directional. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 71b77da2e18ca..e86bdc5fc79d2 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -320,7 +320,7 @@ static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl, if (pte->dma_addr) dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE, - DMA_BIDIRECTIONAL); + DMA_TO_DEVICE); vfree(pte->sublevel); @@ -894,7 +894,7 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, /* Map the page into DMA space. */ pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, -DMA_BIDIRECTIONAL); +DMA_TO_DEVICE); /* make the addresses available to the device */ dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 02/10] staging: gasket: interrupt: remove PCI-MSIX-specific status check
From: Todd Poynor Devices not using MSIX don't use the msix_initialized field, so don't require it to be set in the interrupt system status check. The general check for interrupts configured that follows can cover both MSIX and device-managed interrupts. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_interrupt.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index 2cd262be65ca0..49d47afad64fa 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -478,11 +478,6 @@ int gasket_interrupt_system_status(struct gasket_dev *gasket_dev) return GASKET_STATUS_DEAD; } - if (!gasket_dev->interrupt_data->msix_configured) { - dev_dbg(gasket_dev->dev, "Interrupt not initialized\n"); - return GASKET_STATUS_LAMED; - } - if (gasket_dev->interrupt_data->num_configured != gasket_dev->interrupt_data->num_interrupts) { dev_dbg(gasket_dev->dev, -- 2.19.0.397.gdd90340f6a-goog
[PATCH 03/10] staging: gasket: page table: use GFP_KERNEL for dma_alloc_coherent
From: Todd Poynor Flags should be specified for dma_alloc_coherent() call. Use GFP_KERNEL, it's fine to sleep here. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 53492f4fad6aa..71b77da2e18ca 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1287,7 +1287,7 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, return -EINVAL; mem = dma_alloc_coherent(gasket_get_device(gasket_dev), -num_pages * PAGE_SIZE, , 0); +num_pages * PAGE_SIZE, , GFP_KERNEL); if (!mem) goto nomem; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 05/10] staging: gasket: fix data page unmap DMA direction
From: Nick Ewalt The DMA direction supplied to dma_unmap_page should match the corresponding dma_map_page call, which is mapped bi-directional. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index e86bdc5fc79d2..8fe27e7d1b53c 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -612,7 +612,7 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, if (ptes[i].status == PTE_INUSE) { if (ptes[i].dma_addr) { dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, - PAGE_SIZE, DMA_FROM_DEVICE); + PAGE_SIZE, DMA_BIDIRECTIONAL); } if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 04/10] staging: gasket: fix DMA direction for extended page tables
From: Nick Ewalt Extended page tables should be mapped as DMA_TO_DEVICE, not bi-directional. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 71b77da2e18ca..e86bdc5fc79d2 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -320,7 +320,7 @@ static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl, if (pte->dma_addr) dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE, - DMA_BIDIRECTIONAL); + DMA_TO_DEVICE); vfree(pte->sublevel); @@ -894,7 +894,7 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, /* Map the page into DMA space. */ pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, -DMA_BIDIRECTIONAL); +DMA_TO_DEVICE); /* make the addresses available to the device */ dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 02/10] staging: gasket: interrupt: remove PCI-MSIX-specific status check
From: Todd Poynor Devices not using MSIX don't use the msix_initialized field, so don't require it to be set in the interrupt system status check. The general check for interrupts configured that follows can cover both MSIX and device-managed interrupts. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_interrupt.c | 5 - 1 file changed, 5 deletions(-) diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index 2cd262be65ca0..49d47afad64fa 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -478,11 +478,6 @@ int gasket_interrupt_system_status(struct gasket_dev *gasket_dev) return GASKET_STATUS_DEAD; } - if (!gasket_dev->interrupt_data->msix_configured) { - dev_dbg(gasket_dev->dev, "Interrupt not initialized\n"); - return GASKET_STATUS_LAMED; - } - if (gasket_dev->interrupt_data->num_configured != gasket_dev->interrupt_data->num_interrupts) { dev_dbg(gasket_dev->dev, -- 2.19.0.397.gdd90340f6a-goog
[PATCH 03/10] staging: gasket: page table: use GFP_KERNEL for dma_alloc_coherent
From: Todd Poynor Flags should be specified for dma_alloc_coherent() call. Use GFP_KERNEL, it's fine to sleep here. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 53492f4fad6aa..71b77da2e18ca 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1287,7 +1287,7 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, return -EINVAL; mem = dma_alloc_coherent(gasket_get_device(gasket_dev), -num_pages * PAGE_SIZE, , 0); +num_pages * PAGE_SIZE, , GFP_KERNEL); if (!mem) goto nomem; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 05/10] staging: gasket: fix data page unmap DMA direction
From: Nick Ewalt The DMA direction supplied to dma_unmap_page should match the corresponding dma_map_page call, which is mapped bi-directional. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index e86bdc5fc79d2..8fe27e7d1b53c 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -612,7 +612,7 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, if (ptes[i].status == PTE_INUSE) { if (ptes[i].dma_addr) { dma_unmap_page(pg_tbl->device, ptes[i].dma_addr, - PAGE_SIZE, DMA_FROM_DEVICE); + PAGE_SIZE, DMA_BIDIRECTIONAL); } if (gasket_release_page(ptes[i].page)) --pg_tbl->num_active_pages; -- 2.19.0.397.gdd90340f6a-goog
[PATCH 09/10] staging: gasket: page_table: use total_entries for max ext lvl0 page idx
From: Nick Ewalt The maximum number of entries in the page table is configurable at initialization time and should be used in gasket_extended_lvl0_page_idx. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 779ad2f23ef9b..8364b49f147c2 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -562,7 +562,7 @@ static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl, ulong dev_addr) { return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) & - ((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1); + (pg_tbl->config.total_entries - 1); } /* -- 2.19.0.397.gdd90340f6a-goog
[PATCH 09/10] staging: gasket: page_table: use total_entries for max ext lvl0 page idx
From: Nick Ewalt The maximum number of entries in the page table is configurable at initialization time and should be used in gasket_extended_lvl0_page_idx. Signed-off-by: Nick Ewalt Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 779ad2f23ef9b..8364b49f147c2 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -562,7 +562,7 @@ static ulong gasket_extended_lvl0_page_idx(struct gasket_page_table *pg_tbl, ulong dev_addr) { return (dev_addr >> GASKET_EXTENDED_LVL0_SHIFT) & - ((1 << GASKET_EXTENDED_LVL0_WIDTH) - 1); + (pg_tbl->config.total_entries - 1); } /* -- 2.19.0.397.gdd90340f6a-goog
Re: [GIT PULL] Staging/IIO driver patches for 4.19-rc1
On Tue, Aug 28, 2018 at 3:38 AM Ahmed S. Darwish wrote: >[...] > On Sat, 18 Aug 2018 17:57:24 +0200, Greg KH wrote: > [...] > > addition of some new IIO drivers. Also added was a "gasket" driver from > > Google that needs loads of work and the erofs filesystem. > > > > Why are we adding __a whole new in-kernel framework__ for > developing basic user-space drivers? > > We already have a frameowrk for that, and it's UIO. [1] The UIO > code is a very stable and simple subsystem; it's also heavily used > in the embedded industry.. Yeah, it's clear all the userspace I/O framework code needs to move to UIO with some patches to add agreed-upon new pieces. I think everyone agrees this code shouldn't move out of staging until that happens. A whole lot of work is needed on these drivers, and UIO conversion is on my list to address soon. > > I've looked at the gasket documentation [2], and the first user > of this new in-kernel API [3], and this is almost replicating UIO > it's not funny. [4] True, the gasket APIs adds some extra new > conveniences (PCI BAR re-mapping, MSI, ..), but there's no > technical reason this cannot be added to the UIO code instead. > > More-over, the exposed user-space API is just some ioctls. So if > google hase some shipped user-space code that is using this, > hopefully the driver can still be re-implemented through UIO > without changing these bits.. > > Thanks, > > [1] https://www.kernel.org/doc/html/v4.18/driver-api/uio-howto.html > [2] drivers/staging/gasket/gasket_core.h :: struct gasket_driver_desc > [3] drivers/staging/gasket/apex_driver.c > [4] include/linux/uio_driver.h > > -- > Darwi > http://darwish.chasingpointers.com Thanks -- Todd
Re: [GIT PULL] Staging/IIO driver patches for 4.19-rc1
On Tue, Aug 28, 2018 at 3:38 AM Ahmed S. Darwish wrote: >[...] > On Sat, 18 Aug 2018 17:57:24 +0200, Greg KH wrote: > [...] > > addition of some new IIO drivers. Also added was a "gasket" driver from > > Google that needs loads of work and the erofs filesystem. > > > > Why are we adding __a whole new in-kernel framework__ for > developing basic user-space drivers? > > We already have a frameowrk for that, and it's UIO. [1] The UIO > code is a very stable and simple subsystem; it's also heavily used > in the embedded industry.. Yeah, it's clear all the userspace I/O framework code needs to move to UIO with some patches to add agreed-upon new pieces. I think everyone agrees this code shouldn't move out of staging until that happens. A whole lot of work is needed on these drivers, and UIO conversion is on my list to address soon. > > I've looked at the gasket documentation [2], and the first user > of this new in-kernel API [3], and this is almost replicating UIO > it's not funny. [4] True, the gasket APIs adds some extra new > conveniences (PCI BAR re-mapping, MSI, ..), but there's no > technical reason this cannot be added to the UIO code instead. > > More-over, the exposed user-space API is just some ioctls. So if > google hase some shipped user-space code that is using this, > hopefully the driver can still be re-implemented through UIO > without changing these bits.. > > Thanks, > > [1] https://www.kernel.org/doc/html/v4.18/driver-api/uio-howto.html > [2] drivers/staging/gasket/gasket_core.h :: struct gasket_driver_desc > [3] drivers/staging/gasket/apex_driver.c > [4] include/linux/uio_driver.h > > -- > Darwi > http://darwish.chasingpointers.com Thanks -- Todd
Re: [PATCH 01/16] MAINTAINERS: Switch a maintainer for drivers/staging/gasket
On Thu, Aug 9, 2018 at 11:14 PM Greg Kroah-Hartman wrote: > > On Thu, Aug 09, 2018 at 08:40:06PM -0700, John Joseph wrote: > > Acked-by: John Joseph > > Why are you acking something you supposidly already signed-off on? Sorry, my fault, wasn't sure what the protocol was for these so I suggested he send an Acked-by as well, can drop that. > > > On Thu, Aug 9, 2018 at 8:20 PM, Todd Poynor wrote: > > > From: Todd Poynor > > > > > > Todd Poynor takes over for John Joseph. > > > > > > Signed-off-by: John Joseph > > > Signed-off-by: Todd Poynor > > Did you not really provide your signed-off-by here? We generated this together, the S-o-b is valid, > > totally confused, > > greg k-h
Re: [PATCH 01/16] MAINTAINERS: Switch a maintainer for drivers/staging/gasket
On Thu, Aug 9, 2018 at 11:14 PM Greg Kroah-Hartman wrote: > > On Thu, Aug 09, 2018 at 08:40:06PM -0700, John Joseph wrote: > > Acked-by: John Joseph > > Why are you acking something you supposidly already signed-off on? Sorry, my fault, wasn't sure what the protocol was for these so I suggested he send an Acked-by as well, can drop that. > > > On Thu, Aug 9, 2018 at 8:20 PM, Todd Poynor wrote: > > > From: Todd Poynor > > > > > > Todd Poynor takes over for John Joseph. > > > > > > Signed-off-by: John Joseph > > > Signed-off-by: Todd Poynor > > Did you not really provide your signed-off-by here? We generated this together, the S-o-b is valid, > > totally confused, > > greg k-h
[PATCH 05/16] staging: gasket: core: remove ftrace-style debug logs
From: Todd Poynor Remove debug logs that only indicate the name of the entered function, in favor of using ftrace for function tracing style logs. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 5f54b3615f67c..0fe5b86b294c8 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1789,7 +1789,6 @@ static int __init gasket_init(void) { int i; - pr_debug("%s\n", __func__); mutex_lock(_mutex); for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) { g_descs[i].driver_desc = NULL; @@ -1804,7 +1803,6 @@ static int __init gasket_init(void) static void __exit gasket_exit(void) { - pr_debug("%s\n", __func__); } MODULE_DESCRIPTION("Google Gasket driver framework"); MODULE_VERSION(GASKET_FRAMEWORK_VERSION); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 02/16] staging: gasket: core: remove debug log that could crash
From: Todd Poynor A debug log in gasket_alloc_dev() is issued regardless of whether the device pointer used returned success or error. The log isn't that useful anyway, remove it. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index d12ab560411f7..37d14e30ffa21 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -234,8 +234,6 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, dev_info->device = device_create(internal_desc->class, parent, dev_info->devt, gasket_dev, dev_info->name); - dev_dbg(dev_info->device, "Gasket device allocated.\n"); - /* cdev has not yet been added; cdev_added is 0 */ dev_info->gasket_dev_ptr = gasket_dev; /* ownership is all 0, indicating no owner or opens. */ -- 2.18.0.597.ga71716f1ad-goog
[PATCH 00/16] staging: gasket: return of the son of cleanups
From: Todd Poynor Remove extraneous memory barriers, refactor PCI-specific code in prep for platform devices in the near future, general cleanups, and make de facto maintainership official. Todd Poynor (16): MAINTAINERS: Switch a maintainer for drivers/staging/gasket staging: gasket: core: remove debug log that could crash staging: gasket: core: fix line continuation indent in gasket_alloc_dev staging: gasket: core: remove kobj_name param from gasket_alloc_dev staging: gasket: core: remove ftrace-style debug logs staging: gasket: remove gasket_exit() staging: gasket: page table: remove unnecessary NULL check staging: gasket: page table: use dma_mapping_error for error detection staging: gasket: core: switch to relaxed memory-mapped I/O staging: gasket: page table: remove extraneous memory barriers staging: gasket: core: factor out generic device add code from PCI code staging: gasket: core: factor out generic device remove code from PCI staging: gasket: core: rename lookup_internal_desc to be PCI-specific staging: gasket: interrupt: refactor PCI MSIX-specific handler code staging: gasket: interrupt: simplify interrupt init parameters staging: gasket: interrupt: remove unimplemented interrupt types MAINTAINERS| 2 +- drivers/staging/gasket/gasket_core.c | 138 +++-- drivers/staging/gasket/gasket_core.h | 19 +-- drivers/staging/gasket/gasket_interrupt.c | 105 ++-- drivers/staging/gasket/gasket_interrupt.h | 24 +--- drivers/staging/gasket/gasket_page_table.c | 24 ++-- 6 files changed, 124 insertions(+), 188 deletions(-) -- 2.18.0.597.ga71716f1ad-goog
[PATCH 07/16] staging: gasket: page table: remove unnecessary NULL check
From: Todd Poynor gasket_alloc_coherent_memory remove unnecessary NULL check for coherent_pages. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index d4c5f8aa7dd34..bd921dc6094de 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1328,10 +1328,8 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, num_pages * PAGE_SIZE, mem, handle); } - if (gasket_dev->page_table[index]->coherent_pages) { - kfree(gasket_dev->page_table[index]->coherent_pages); - gasket_dev->page_table[index]->coherent_pages = NULL; - } + kfree(gasket_dev->page_table[index]->coherent_pages); + gasket_dev->page_table[index]->coherent_pages = NULL; gasket_dev->page_table[index]->num_coherent_pages = 0; return -ENOMEM; } -- 2.18.0.597.ga71716f1ad-goog
[PATCH 03/16] staging: gasket: core: fix line continuation indent in gasket_alloc_dev
From: Todd Poynor Previous cleanups missed a case of multi-line function call with line continuation parameters not aligned per kernel style. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 37d14e30ffa21..3fb805204d700 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -231,8 +231,9 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, dev_info->devt = MKDEV(driver_desc->major, driver_desc->minor + gasket_dev->dev_idx); - dev_info->device = device_create(internal_desc->class, parent, - dev_info->devt, gasket_dev, dev_info->name); + dev_info->device = + device_create(internal_desc->class, parent, dev_info->devt, + gasket_dev, dev_info->name); /* cdev has not yet been added; cdev_added is 0 */ dev_info->gasket_dev_ptr = gasket_dev; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 00/16] staging: gasket: return of the son of cleanups
From: Todd Poynor Remove extraneous memory barriers, refactor PCI-specific code in prep for platform devices in the near future, general cleanups, and make de facto maintainership official. Todd Poynor (16): MAINTAINERS: Switch a maintainer for drivers/staging/gasket staging: gasket: core: remove debug log that could crash staging: gasket: core: fix line continuation indent in gasket_alloc_dev staging: gasket: core: remove kobj_name param from gasket_alloc_dev staging: gasket: core: remove ftrace-style debug logs staging: gasket: remove gasket_exit() staging: gasket: page table: remove unnecessary NULL check staging: gasket: page table: use dma_mapping_error for error detection staging: gasket: core: switch to relaxed memory-mapped I/O staging: gasket: page table: remove extraneous memory barriers staging: gasket: core: factor out generic device add code from PCI code staging: gasket: core: factor out generic device remove code from PCI staging: gasket: core: rename lookup_internal_desc to be PCI-specific staging: gasket: interrupt: refactor PCI MSIX-specific handler code staging: gasket: interrupt: simplify interrupt init parameters staging: gasket: interrupt: remove unimplemented interrupt types MAINTAINERS| 2 +- drivers/staging/gasket/gasket_core.c | 138 +++-- drivers/staging/gasket/gasket_core.h | 19 +-- drivers/staging/gasket/gasket_interrupt.c | 105 ++-- drivers/staging/gasket/gasket_interrupt.h | 24 +--- drivers/staging/gasket/gasket_page_table.c | 24 ++-- 6 files changed, 124 insertions(+), 188 deletions(-) -- 2.18.0.597.ga71716f1ad-goog
[PATCH 07/16] staging: gasket: page table: remove unnecessary NULL check
From: Todd Poynor gasket_alloc_coherent_memory remove unnecessary NULL check for coherent_pages. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 6 ++ 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index d4c5f8aa7dd34..bd921dc6094de 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -1328,10 +1328,8 @@ int gasket_alloc_coherent_memory(struct gasket_dev *gasket_dev, u64 size, num_pages * PAGE_SIZE, mem, handle); } - if (gasket_dev->page_table[index]->coherent_pages) { - kfree(gasket_dev->page_table[index]->coherent_pages); - gasket_dev->page_table[index]->coherent_pages = NULL; - } + kfree(gasket_dev->page_table[index]->coherent_pages); + gasket_dev->page_table[index]->coherent_pages = NULL; gasket_dev->page_table[index]->num_coherent_pages = 0; return -ENOMEM; } -- 2.18.0.597.ga71716f1ad-goog
[PATCH 03/16] staging: gasket: core: fix line continuation indent in gasket_alloc_dev
From: Todd Poynor Previous cleanups missed a case of multi-line function call with line continuation parameters not aligned per kernel style. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 37d14e30ffa21..3fb805204d700 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -231,8 +231,9 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, dev_info->devt = MKDEV(driver_desc->major, driver_desc->minor + gasket_dev->dev_idx); - dev_info->device = device_create(internal_desc->class, parent, - dev_info->devt, gasket_dev, dev_info->name); + dev_info->device = + device_create(internal_desc->class, parent, dev_info->devt, + gasket_dev, dev_info->name); /* cdev has not yet been added; cdev_added is 0 */ dev_info->gasket_dev_ptr = gasket_dev; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 05/16] staging: gasket: core: remove ftrace-style debug logs
From: Todd Poynor Remove debug logs that only indicate the name of the entered function, in favor of using ftrace for function tracing style logs. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 5f54b3615f67c..0fe5b86b294c8 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1789,7 +1789,6 @@ static int __init gasket_init(void) { int i; - pr_debug("%s\n", __func__); mutex_lock(_mutex); for (i = 0; i < GASKET_FRAMEWORK_DESC_MAX; i++) { g_descs[i].driver_desc = NULL; @@ -1804,7 +1803,6 @@ static int __init gasket_init(void) static void __exit gasket_exit(void) { - pr_debug("%s\n", __func__); } MODULE_DESCRIPTION("Google Gasket driver framework"); MODULE_VERSION(GASKET_FRAMEWORK_VERSION); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 02/16] staging: gasket: core: remove debug log that could crash
From: Todd Poynor A debug log in gasket_alloc_dev() is issued regardless of whether the device pointer used returned success or error. The log isn't that useful anyway, remove it. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index d12ab560411f7..37d14e30ffa21 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -234,8 +234,6 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, dev_info->device = device_create(internal_desc->class, parent, dev_info->devt, gasket_dev, dev_info->name); - dev_dbg(dev_info->device, "Gasket device allocated.\n"); - /* cdev has not yet been added; cdev_added is 0 */ dev_info->gasket_dev_ptr = gasket_dev; /* ownership is all 0, indicating no owner or opens. */ -- 2.18.0.597.ga71716f1ad-goog
[PATCH 13/16] staging: gasket: core: rename lookup_internal_desc to be PCI-specific
From: Todd Poynor Rename lookup_internal_desc() to lookup_pci_internal_desc() to reflect use for PCI devices only, in prep for non-PCI devices in the future. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 5e048f6e16e12..99f3f11d75ce2 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -651,13 +651,13 @@ void gasket_disable_device(struct gasket_dev *gasket_dev) EXPORT_SYMBOL(gasket_disable_device); /* - * Registered descriptor lookup. + * Registered driver descriptor lookup for PCI devices. * * Precondition: Called with g_mutex held (to avoid a race on return). * Returns NULL if no matching device was found. */ static struct gasket_internal_desc * -lookup_internal_desc(struct pci_dev *pci_dev) +lookup_pci_internal_desc(struct pci_dev *pci_dev) { int i; @@ -1488,7 +1488,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, dev_dbg(_dev->dev, "add PCI gasket device\n"); mutex_lock(_mutex); - internal_desc = lookup_internal_desc(pci_dev); + internal_desc = lookup_pci_internal_desc(pci_dev); mutex_unlock(_mutex); if (!internal_desc) { dev_err(_dev->dev, @@ -1536,7 +1536,7 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) struct gasket_dev *gasket_dev = NULL; /* Find the device desc. */ mutex_lock(_mutex); - internal_desc = lookup_internal_desc(pci_dev); + internal_desc = lookup_pci_internal_desc(pci_dev); if (!internal_desc) { mutex_unlock(_mutex); return; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 11/16] staging: gasket: core: factor out generic device add code from PCI code
From: Todd Poynor Split out generic gasket device add code from the code for adding a PCI gasket device, in prep for other gasket device types in the future. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 76 ++-- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index aee819f379e9a..ce8ae226f82d9 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1419,6 +1419,48 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) } EXPORT_SYMBOL(gasket_enable_device); +static int __gasket_add_device(struct device *parent_dev, + struct gasket_internal_desc *internal_desc, + struct gasket_dev **gasket_devp) +{ + int ret; + struct gasket_dev *gasket_dev; + const struct gasket_driver_desc *driver_desc = + internal_desc->driver_desc; + + ret = gasket_alloc_dev(internal_desc, parent_dev, _dev); + if (ret) + return ret; + if (IS_ERR(gasket_dev->dev_info.device)) { + dev_err(parent_dev, "Cannot create %s device %s [ret = %ld]\n", + driver_desc->name, gasket_dev->dev_info.name, + PTR_ERR(gasket_dev->dev_info.device)); + ret = -ENODEV; + goto free_gasket_dev; + } + + ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device, + gasket_dev); + if (ret) + goto remove_device; + + ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device, + gasket_sysfs_generic_attrs); + if (ret) + goto remove_sysfs_mapping; + + *gasket_devp = gasket_dev; + return 0; + +remove_sysfs_mapping: + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); +remove_device: + device_destroy(internal_desc->class, gasket_dev->dev_info.devt); +free_gasket_dev: + gasket_free_dev(gasket_dev); + return ret; +} + /* * Add PCI gasket device. * @@ -1433,7 +1475,6 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, int ret; struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev; - const struct gasket_driver_desc *driver_desc; struct device *parent; dev_dbg(_dev->dev, "add PCI gasket device\n"); @@ -1447,29 +1488,15 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, return -ENODEV; } - driver_desc = internal_desc->driver_desc; - parent = _dev->dev; - ret = gasket_alloc_dev(internal_desc, parent, _dev); + ret = __gasket_add_device(parent, internal_desc, _dev); if (ret) return ret; - gasket_dev->pci_dev = pci_dev; - if (IS_ERR_OR_NULL(gasket_dev->dev_info.device)) { - pr_err("Cannot create %s device %s [ret = %ld]\n", - driver_desc->name, gasket_dev->dev_info.name, - PTR_ERR(gasket_dev->dev_info.device)); - ret = -ENODEV; - goto fail1; - } + gasket_dev->pci_dev = pci_dev; ret = gasket_setup_pci(pci_dev, gasket_dev); if (ret) - goto fail2; - - ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device, - gasket_dev); - if (ret) - goto fail3; + goto cleanup_pci; /* * Once we've created the mapping structures successfully, attempt to @@ -1480,23 +1507,16 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, if (ret) { dev_err(gasket_dev->dev, "Cannot create sysfs pci link: %d\n", ret); - goto fail3; + goto cleanup_pci; } - ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device, - gasket_sysfs_generic_attrs); - if (ret) - goto fail4; *gasket_devp = gasket_dev; return 0; -fail4: -fail3: - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); -fail2: +cleanup_pci: gasket_cleanup_pci(gasket_dev); + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); device_destroy(internal_desc->class, gasket_dev->dev_info.devt); -fail1: gasket_free_dev(gasket_dev); return ret; } -- 2.18.0.597.ga71716f1ad-goog
[PATCH 12/16] staging: gasket: core: factor out generic device remove code from PCI
From: Todd Poynor Separate code for generic parts of gasket device removal sequence from the PCI device removal code, in prep for non-PCI devices later. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index ce8ae226f82d9..5e048f6e16e12 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1461,6 +1461,14 @@ static int __gasket_add_device(struct device *parent_dev, return ret; } +static void __gasket_remove_device(struct gasket_internal_desc *internal_desc, + struct gasket_dev *gasket_dev) +{ + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); + device_destroy(internal_desc->class, gasket_dev->dev_info.devt); + gasket_free_dev(gasket_dev); +} + /* * Add PCI gasket device. * @@ -1515,9 +1523,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, cleanup_pci: gasket_cleanup_pci(gasket_dev); - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); - device_destroy(internal_desc->class, gasket_dev->dev_info.devt); - gasket_free_dev(gasket_dev); + __gasket_remove_device(internal_desc, gasket_dev); return ret; } EXPORT_SYMBOL(gasket_pci_add_device); @@ -1528,7 +1534,6 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) int i; struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev = NULL; - const struct gasket_driver_desc *driver_desc; /* Find the device desc. */ mutex_lock(_mutex); internal_desc = lookup_internal_desc(pci_dev); @@ -1538,8 +1543,6 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) } mutex_unlock(_mutex); - driver_desc = internal_desc->driver_desc; - /* Now find the specific device */ mutex_lock(_desc->mutex); for (i = 0; i < GASKET_DEV_MAX; i++) { @@ -1558,10 +1561,7 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) internal_desc->driver_desc->name); gasket_cleanup_pci(gasket_dev); - - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); - device_destroy(internal_desc->class, gasket_dev->dev_info.devt); - gasket_free_dev(gasket_dev); + __gasket_remove_device(internal_desc, gasket_dev); } EXPORT_SYMBOL(gasket_pci_remove_device); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 06/16] staging: gasket: remove gasket_exit()
From: Todd Poynor Remove now-empty gasket_exit() function. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 0fe5b86b294c8..aee819f379e9a 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1801,12 +1801,8 @@ static int __init gasket_init(void) return 0; } -static void __exit gasket_exit(void) -{ -} MODULE_DESCRIPTION("Google Gasket driver framework"); MODULE_VERSION(GASKET_FRAMEWORK_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Rob Springer "); module_init(gasket_init); -module_exit(gasket_exit); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 13/16] staging: gasket: core: rename lookup_internal_desc to be PCI-specific
From: Todd Poynor Rename lookup_internal_desc() to lookup_pci_internal_desc() to reflect use for PCI devices only, in prep for non-PCI devices in the future. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 5e048f6e16e12..99f3f11d75ce2 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -651,13 +651,13 @@ void gasket_disable_device(struct gasket_dev *gasket_dev) EXPORT_SYMBOL(gasket_disable_device); /* - * Registered descriptor lookup. + * Registered driver descriptor lookup for PCI devices. * * Precondition: Called with g_mutex held (to avoid a race on return). * Returns NULL if no matching device was found. */ static struct gasket_internal_desc * -lookup_internal_desc(struct pci_dev *pci_dev) +lookup_pci_internal_desc(struct pci_dev *pci_dev) { int i; @@ -1488,7 +1488,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, dev_dbg(_dev->dev, "add PCI gasket device\n"); mutex_lock(_mutex); - internal_desc = lookup_internal_desc(pci_dev); + internal_desc = lookup_pci_internal_desc(pci_dev); mutex_unlock(_mutex); if (!internal_desc) { dev_err(_dev->dev, @@ -1536,7 +1536,7 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) struct gasket_dev *gasket_dev = NULL; /* Find the device desc. */ mutex_lock(_mutex); - internal_desc = lookup_internal_desc(pci_dev); + internal_desc = lookup_pci_internal_desc(pci_dev); if (!internal_desc) { mutex_unlock(_mutex); return; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 11/16] staging: gasket: core: factor out generic device add code from PCI code
From: Todd Poynor Split out generic gasket device add code from the code for adding a PCI gasket device, in prep for other gasket device types in the future. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 76 ++-- 1 file changed, 48 insertions(+), 28 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index aee819f379e9a..ce8ae226f82d9 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1419,6 +1419,48 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) } EXPORT_SYMBOL(gasket_enable_device); +static int __gasket_add_device(struct device *parent_dev, + struct gasket_internal_desc *internal_desc, + struct gasket_dev **gasket_devp) +{ + int ret; + struct gasket_dev *gasket_dev; + const struct gasket_driver_desc *driver_desc = + internal_desc->driver_desc; + + ret = gasket_alloc_dev(internal_desc, parent_dev, _dev); + if (ret) + return ret; + if (IS_ERR(gasket_dev->dev_info.device)) { + dev_err(parent_dev, "Cannot create %s device %s [ret = %ld]\n", + driver_desc->name, gasket_dev->dev_info.name, + PTR_ERR(gasket_dev->dev_info.device)); + ret = -ENODEV; + goto free_gasket_dev; + } + + ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device, + gasket_dev); + if (ret) + goto remove_device; + + ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device, + gasket_sysfs_generic_attrs); + if (ret) + goto remove_sysfs_mapping; + + *gasket_devp = gasket_dev; + return 0; + +remove_sysfs_mapping: + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); +remove_device: + device_destroy(internal_desc->class, gasket_dev->dev_info.devt); +free_gasket_dev: + gasket_free_dev(gasket_dev); + return ret; +} + /* * Add PCI gasket device. * @@ -1433,7 +1475,6 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, int ret; struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev; - const struct gasket_driver_desc *driver_desc; struct device *parent; dev_dbg(_dev->dev, "add PCI gasket device\n"); @@ -1447,29 +1488,15 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, return -ENODEV; } - driver_desc = internal_desc->driver_desc; - parent = _dev->dev; - ret = gasket_alloc_dev(internal_desc, parent, _dev); + ret = __gasket_add_device(parent, internal_desc, _dev); if (ret) return ret; - gasket_dev->pci_dev = pci_dev; - if (IS_ERR_OR_NULL(gasket_dev->dev_info.device)) { - pr_err("Cannot create %s device %s [ret = %ld]\n", - driver_desc->name, gasket_dev->dev_info.name, - PTR_ERR(gasket_dev->dev_info.device)); - ret = -ENODEV; - goto fail1; - } + gasket_dev->pci_dev = pci_dev; ret = gasket_setup_pci(pci_dev, gasket_dev); if (ret) - goto fail2; - - ret = gasket_sysfs_create_mapping(gasket_dev->dev_info.device, - gasket_dev); - if (ret) - goto fail3; + goto cleanup_pci; /* * Once we've created the mapping structures successfully, attempt to @@ -1480,23 +1507,16 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, if (ret) { dev_err(gasket_dev->dev, "Cannot create sysfs pci link: %d\n", ret); - goto fail3; + goto cleanup_pci; } - ret = gasket_sysfs_create_entries(gasket_dev->dev_info.device, - gasket_sysfs_generic_attrs); - if (ret) - goto fail4; *gasket_devp = gasket_dev; return 0; -fail4: -fail3: - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); -fail2: +cleanup_pci: gasket_cleanup_pci(gasket_dev); + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); device_destroy(internal_desc->class, gasket_dev->dev_info.devt); -fail1: gasket_free_dev(gasket_dev); return ret; } -- 2.18.0.597.ga71716f1ad-goog
[PATCH 12/16] staging: gasket: core: factor out generic device remove code from PCI
From: Todd Poynor Separate code for generic parts of gasket device removal sequence from the PCI device removal code, in prep for non-PCI devices later. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 20 ++-- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index ce8ae226f82d9..5e048f6e16e12 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1461,6 +1461,14 @@ static int __gasket_add_device(struct device *parent_dev, return ret; } +static void __gasket_remove_device(struct gasket_internal_desc *internal_desc, + struct gasket_dev *gasket_dev) +{ + gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); + device_destroy(internal_desc->class, gasket_dev->dev_info.devt); + gasket_free_dev(gasket_dev); +} + /* * Add PCI gasket device. * @@ -1515,9 +1523,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, cleanup_pci: gasket_cleanup_pci(gasket_dev); - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); - device_destroy(internal_desc->class, gasket_dev->dev_info.devt); - gasket_free_dev(gasket_dev); + __gasket_remove_device(internal_desc, gasket_dev); return ret; } EXPORT_SYMBOL(gasket_pci_add_device); @@ -1528,7 +1534,6 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) int i; struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev = NULL; - const struct gasket_driver_desc *driver_desc; /* Find the device desc. */ mutex_lock(_mutex); internal_desc = lookup_internal_desc(pci_dev); @@ -1538,8 +1543,6 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) } mutex_unlock(_mutex); - driver_desc = internal_desc->driver_desc; - /* Now find the specific device */ mutex_lock(_desc->mutex); for (i = 0; i < GASKET_DEV_MAX; i++) { @@ -1558,10 +1561,7 @@ void gasket_pci_remove_device(struct pci_dev *pci_dev) internal_desc->driver_desc->name); gasket_cleanup_pci(gasket_dev); - - gasket_sysfs_remove_mapping(gasket_dev->dev_info.device); - device_destroy(internal_desc->class, gasket_dev->dev_info.devt); - gasket_free_dev(gasket_dev); + __gasket_remove_device(internal_desc, gasket_dev); } EXPORT_SYMBOL(gasket_pci_remove_device); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 06/16] staging: gasket: remove gasket_exit()
From: Todd Poynor Remove now-empty gasket_exit() function. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 4 1 file changed, 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 0fe5b86b294c8..aee819f379e9a 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1801,12 +1801,8 @@ static int __init gasket_init(void) return 0; } -static void __exit gasket_exit(void) -{ -} MODULE_DESCRIPTION("Google Gasket driver framework"); MODULE_VERSION(GASKET_FRAMEWORK_VERSION); MODULE_LICENSE("GPL v2"); MODULE_AUTHOR("Rob Springer "); module_init(gasket_init); -module_exit(gasket_exit); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 08/16] staging: gasket: page table: use dma_mapping_error for error detection
From: Todd Poynor gasket_perform_mapping() call dma_mapping_error() to determine if mapping failed. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index bd921dc6094de..4d2499269499b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -493,7 +493,8 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (void *)page_to_pfn(page), (unsigned long long)ptes[i].dma_addr); - if (ptes[i].dma_addr == -1) { + if (dma_mapping_error(pg_tbl->device, + ptes[i].dma_addr)) { dev_dbg(pg_tbl->device, "%s i %d -> fail to map page %llx " "[pfn %p ohys %p]\n", -- 2.18.0.597.ga71716f1ad-goog
[PATCH 14/16] staging: gasket: interrupt: refactor PCI MSIX-specific handler code
From: Todd Poynor Split interrupt handler into PCI MSIX-specific and generic functions, for adding non-MSIX handlers in the future. Move MSIX init code together,, out of generic init path. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_interrupt.c | 48 --- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index 1cfbc120f2284..f94e4ea9a7ded 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -157,9 +157,22 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) } } -static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) +static void +gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data, + int interrupt_index) { struct eventfd_ctx *ctx; + + trace_gasket_interrupt_event(interrupt_data->name, interrupt_index); + ctx = interrupt_data->eventfd_ctxs[interrupt_index]; + if (ctx) + eventfd_signal(ctx, 1); + + ++(interrupt_data->interrupt_counts[interrupt_index]); +} + +static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) +{ struct gasket_interrupt_data *interrupt_data = dev_id; int interrupt = -1; int i; @@ -175,14 +188,7 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) pr_err("Received unknown irq %d\n", irq); return IRQ_HANDLED; } - trace_gasket_interrupt_event(interrupt_data->name, interrupt); - - ctx = interrupt_data->eventfd_ctxs[interrupt]; - if (ctx) - eventfd_signal(ctx, 1); - - ++(interrupt_data->interrupt_counts[interrupt]); - + gasket_handle_interrupt(interrupt_data, interrupt); return IRQ_HANDLED; } @@ -192,6 +198,12 @@ gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data) int ret = 1; int i; + interrupt_data->msix_entries = + kcalloc(interrupt_data->num_interrupts, + sizeof(struct msix_entry), GFP_KERNEL); + if (!interrupt_data->msix_entries) + return -ENOMEM; + for (i = 0; i < interrupt_data->num_interrupts; i++) { interrupt_data->msix_entries[i].entry = i; interrupt_data->msix_entries[i].vector = 0; @@ -343,20 +355,10 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, interrupt_data->num_configured = 0; interrupt_data->wire_interrupt_offsets = wire_int_offsets; - /* Allocate all dynamic structures. */ - interrupt_data->msix_entries = kcalloc(num_interrupts, - sizeof(struct msix_entry), - GFP_KERNEL); - if (!interrupt_data->msix_entries) { - kfree(interrupt_data); - return -ENOMEM; - } - interrupt_data->eventfd_ctxs = kcalloc(num_interrupts, sizeof(struct eventfd_ctx *), GFP_KERNEL); if (!interrupt_data->eventfd_ctxs) { - kfree(interrupt_data->msix_entries); kfree(interrupt_data); return -ENOMEM; } @@ -366,7 +368,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, GFP_KERNEL); if (!interrupt_data->interrupt_counts) { kfree(interrupt_data->eventfd_ctxs); - kfree(interrupt_data->msix_entries); kfree(interrupt_data); return -ENOMEM; } @@ -417,6 +418,7 @@ gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data) if (interrupt_data->msix_configured) pci_disable_msix(interrupt_data->pci_dev); interrupt_data->msix_configured = 0; + kfree(interrupt_data->msix_entries); } int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) @@ -448,10 +450,11 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) } if (ret) { - /* Failing to setup MSIx will cause the device + /* Failing to setup interrupts will cause the device * to report GASKET_STATUS_LAMED, but is not fatal. */ - dev_warn(gasket_dev->dev, "Couldn't init msix: %d\n", ret); + dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n", +ret); return 0; } @@ -497,7 +500,6 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) kfree(interrupt_data->interrupt_counts)
[PATCH 08/16] staging: gasket: page table: use dma_mapping_error for error detection
From: Todd Poynor gasket_perform_mapping() call dma_mapping_error() to determine if mapping failed. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index bd921dc6094de..4d2499269499b 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -493,7 +493,8 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (void *)page_to_pfn(page), (unsigned long long)ptes[i].dma_addr); - if (ptes[i].dma_addr == -1) { + if (dma_mapping_error(pg_tbl->device, + ptes[i].dma_addr)) { dev_dbg(pg_tbl->device, "%s i %d -> fail to map page %llx " "[pfn %p ohys %p]\n", -- 2.18.0.597.ga71716f1ad-goog
[PATCH 14/16] staging: gasket: interrupt: refactor PCI MSIX-specific handler code
From: Todd Poynor Split interrupt handler into PCI MSIX-specific and generic functions, for adding non-MSIX handlers in the future. Move MSIX init code together,, out of generic init path. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_interrupt.c | 48 --- 1 file changed, 25 insertions(+), 23 deletions(-) diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index 1cfbc120f2284..f94e4ea9a7ded 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -157,9 +157,22 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) } } -static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) +static void +gasket_handle_interrupt(struct gasket_interrupt_data *interrupt_data, + int interrupt_index) { struct eventfd_ctx *ctx; + + trace_gasket_interrupt_event(interrupt_data->name, interrupt_index); + ctx = interrupt_data->eventfd_ctxs[interrupt_index]; + if (ctx) + eventfd_signal(ctx, 1); + + ++(interrupt_data->interrupt_counts[interrupt_index]); +} + +static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) +{ struct gasket_interrupt_data *interrupt_data = dev_id; int interrupt = -1; int i; @@ -175,14 +188,7 @@ static irqreturn_t gasket_msix_interrupt_handler(int irq, void *dev_id) pr_err("Received unknown irq %d\n", irq); return IRQ_HANDLED; } - trace_gasket_interrupt_event(interrupt_data->name, interrupt); - - ctx = interrupt_data->eventfd_ctxs[interrupt]; - if (ctx) - eventfd_signal(ctx, 1); - - ++(interrupt_data->interrupt_counts[interrupt]); - + gasket_handle_interrupt(interrupt_data, interrupt); return IRQ_HANDLED; } @@ -192,6 +198,12 @@ gasket_interrupt_msix_init(struct gasket_interrupt_data *interrupt_data) int ret = 1; int i; + interrupt_data->msix_entries = + kcalloc(interrupt_data->num_interrupts, + sizeof(struct msix_entry), GFP_KERNEL); + if (!interrupt_data->msix_entries) + return -ENOMEM; + for (i = 0; i < interrupt_data->num_interrupts; i++) { interrupt_data->msix_entries[i].entry = i; interrupt_data->msix_entries[i].vector = 0; @@ -343,20 +355,10 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, interrupt_data->num_configured = 0; interrupt_data->wire_interrupt_offsets = wire_int_offsets; - /* Allocate all dynamic structures. */ - interrupt_data->msix_entries = kcalloc(num_interrupts, - sizeof(struct msix_entry), - GFP_KERNEL); - if (!interrupt_data->msix_entries) { - kfree(interrupt_data); - return -ENOMEM; - } - interrupt_data->eventfd_ctxs = kcalloc(num_interrupts, sizeof(struct eventfd_ctx *), GFP_KERNEL); if (!interrupt_data->eventfd_ctxs) { - kfree(interrupt_data->msix_entries); kfree(interrupt_data); return -ENOMEM; } @@ -366,7 +368,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, GFP_KERNEL); if (!interrupt_data->interrupt_counts) { kfree(interrupt_data->eventfd_ctxs); - kfree(interrupt_data->msix_entries); kfree(interrupt_data); return -ENOMEM; } @@ -417,6 +418,7 @@ gasket_interrupt_msix_cleanup(struct gasket_interrupt_data *interrupt_data) if (interrupt_data->msix_configured) pci_disable_msix(interrupt_data->pci_dev); interrupt_data->msix_configured = 0; + kfree(interrupt_data->msix_entries); } int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) @@ -448,10 +450,11 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) } if (ret) { - /* Failing to setup MSIx will cause the device + /* Failing to setup interrupts will cause the device * to report GASKET_STATUS_LAMED, but is not fatal. */ - dev_warn(gasket_dev->dev, "Couldn't init msix: %d\n", ret); + dev_warn(gasket_dev->dev, "Couldn't reinit interrupts: %d\n", +ret); return 0; } @@ -497,7 +500,6 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) kfree(interrupt_data->interrupt_counts)
[PATCH 16/16] staging: gasket: interrupt: remove unimplemented interrupt types
From: Todd Poynor Interrupt types PCI_MSI and PLATFORM_WIRE are unused and unimplemented. Remove these. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.h | 11 drivers/staging/gasket/gasket_interrupt.c | 34 +-- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h index fd7e75b765a6d..0203460f48957 100644 --- a/drivers/staging/gasket/gasket_core.h +++ b/drivers/staging/gasket/gasket_core.h @@ -50,8 +50,6 @@ enum gasket_interrupt_packing { /* Type of the interrupt supported by the device. */ enum gasket_interrupt_type { PCI_MSIX = 0, - PCI_MSI = 1, - PLATFORM_WIRE = 2, }; /* @@ -69,12 +67,6 @@ struct gasket_interrupt_desc { int packing; }; -/* Offsets to the wire interrupt handling registers */ -struct gasket_wire_interrupt_offsets { - u64 pending_bit_array; - u64 mask_array; -}; - /* * This enum is used to identify memory regions being part of the physical * memory that belongs to a device. @@ -384,9 +376,6 @@ struct gasket_driver_desc { */ struct gasket_coherent_buffer_desc coherent_buffer_description; - /* Offset of wire interrupt registers. */ - const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets; - /* Interrupt type. (One of gasket_interrupt_type). */ int interrupt_type; diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index eb5dfbe08e214..2cd262be65ca0 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -45,9 +45,6 @@ struct gasket_interrupt_data { /* The width of a single interrupt in a packed interrupt register. */ int pack_width; - /* offset of wire interrupt registers */ - const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets; - /* * Design-wise, these elements should be bundled together, but * pci_enable_msix's interface requires that they be managed @@ -92,19 +89,6 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) dev_dbg(gasket_dev->dev, "Running interrupt setup\n"); - if (interrupt_data->type == PLATFORM_WIRE || - interrupt_data->type == PCI_MSI) { - /* Nothing needs to be done for platform or PCI devices. */ - return; - } - - if (interrupt_data->type != PCI_MSIX) { - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); - return; - } - /* Setup the MSIX table. */ for (i = 0; i < interrupt_data->num_interrupts; i++) { @@ -351,8 +335,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index; interrupt_data->pack_width = driver_desc->interrupt_pack_width; interrupt_data->num_configured = 0; - interrupt_data->wire_interrupt_offsets = - driver_desc->wire_interrupt_offsets; interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts, sizeof(struct eventfd_ctx *), @@ -379,12 +361,7 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) force_msix_interrupt_unmasking(gasket_dev); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_err(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); ret = -EINVAL; } @@ -439,12 +416,7 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) force_msix_interrupt_unmasking(gasket_dev); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - gasket_dev->interrupt_data->type); ret = -EINVAL; } @@ -489,12 +461,8 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) gasket_interrupt_msix_cleanup(interrupt_data); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); + break; } kfree(interrupt_data->interrupt_counts); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 16/16] staging: gasket: interrupt: remove unimplemented interrupt types
From: Todd Poynor Interrupt types PCI_MSI and PLATFORM_WIRE are unused and unimplemented. Remove these. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.h | 11 drivers/staging/gasket/gasket_interrupt.c | 34 +-- 2 files changed, 1 insertion(+), 44 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h index fd7e75b765a6d..0203460f48957 100644 --- a/drivers/staging/gasket/gasket_core.h +++ b/drivers/staging/gasket/gasket_core.h @@ -50,8 +50,6 @@ enum gasket_interrupt_packing { /* Type of the interrupt supported by the device. */ enum gasket_interrupt_type { PCI_MSIX = 0, - PCI_MSI = 1, - PLATFORM_WIRE = 2, }; /* @@ -69,12 +67,6 @@ struct gasket_interrupt_desc { int packing; }; -/* Offsets to the wire interrupt handling registers */ -struct gasket_wire_interrupt_offsets { - u64 pending_bit_array; - u64 mask_array; -}; - /* * This enum is used to identify memory regions being part of the physical * memory that belongs to a device. @@ -384,9 +376,6 @@ struct gasket_driver_desc { */ struct gasket_coherent_buffer_desc coherent_buffer_description; - /* Offset of wire interrupt registers. */ - const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets; - /* Interrupt type. (One of gasket_interrupt_type). */ int interrupt_type; diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index eb5dfbe08e214..2cd262be65ca0 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -45,9 +45,6 @@ struct gasket_interrupt_data { /* The width of a single interrupt in a packed interrupt register. */ int pack_width; - /* offset of wire interrupt registers */ - const struct gasket_wire_interrupt_offsets *wire_interrupt_offsets; - /* * Design-wise, these elements should be bundled together, but * pci_enable_msix's interface requires that they be managed @@ -92,19 +89,6 @@ static void gasket_interrupt_setup(struct gasket_dev *gasket_dev) dev_dbg(gasket_dev->dev, "Running interrupt setup\n"); - if (interrupt_data->type == PLATFORM_WIRE || - interrupt_data->type == PCI_MSI) { - /* Nothing needs to be done for platform or PCI devices. */ - return; - } - - if (interrupt_data->type != PCI_MSIX) { - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); - return; - } - /* Setup the MSIX table. */ for (i = 0; i < interrupt_data->num_interrupts; i++) { @@ -351,8 +335,6 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index; interrupt_data->pack_width = driver_desc->interrupt_pack_width; interrupt_data->num_configured = 0; - interrupt_data->wire_interrupt_offsets = - driver_desc->wire_interrupt_offsets; interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts, sizeof(struct eventfd_ctx *), @@ -379,12 +361,7 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev) force_msix_interrupt_unmasking(gasket_dev); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_err(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); ret = -EINVAL; } @@ -439,12 +416,7 @@ int gasket_interrupt_reinit(struct gasket_dev *gasket_dev) force_msix_interrupt_unmasking(gasket_dev); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - gasket_dev->interrupt_data->type); ret = -EINVAL; } @@ -489,12 +461,8 @@ void gasket_interrupt_cleanup(struct gasket_dev *gasket_dev) gasket_interrupt_msix_cleanup(interrupt_data); break; - case PCI_MSI: - case PLATFORM_WIRE: default: - dev_dbg(gasket_dev->dev, - "Cannot handle unsupported interrupt type %d\n", - interrupt_data->type); + break; } kfree(interrupt_data->interrupt_counts); -- 2.18.0.597.ga71716f1ad-goog
[PATCH 04/16] staging: gasket: core: remove kobj_name param from gasket_alloc_dev
From: Todd Poynor gasket_alloc_dev can retrieve the device name from the parent parameter, a separate parameter isn't needed for this. Rename the variable to better reflect its meaning, as the name of the parent device for which a gasket device is being allocated. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 3fb805204d700..5f54b3615f67c 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -189,26 +189,26 @@ static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc, * Returns 0 if successful, a negative error code otherwise. */ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, - struct device *parent, struct gasket_dev **pdev, - const char *kobj_name) + struct device *parent, struct gasket_dev **pdev) { int dev_idx; const struct gasket_driver_desc *driver_desc = internal_desc->driver_desc; struct gasket_dev *gasket_dev; struct gasket_cdev_info *dev_info; + const char *parent_name = dev_name(parent); - pr_debug("Allocating a Gasket device %s.\n", kobj_name); + pr_debug("Allocating a Gasket device, parent %s.\n", parent_name); *pdev = NULL; - dev_idx = gasket_find_dev_slot(internal_desc, kobj_name); + dev_idx = gasket_find_dev_slot(internal_desc, parent_name); if (dev_idx < 0) return dev_idx; gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL); if (!gasket_dev) { - pr_err("no memory for device %s\n", kobj_name); + pr_err("no memory for device, parent %s\n", parent_name); return -ENOMEM; } internal_desc->devs[dev_idx] = gasket_dev; @@ -217,7 +217,7 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, gasket_dev->internal_desc = internal_desc; gasket_dev->dev_idx = dev_idx; - snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", kobj_name); + snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name); gasket_dev->dev = get_device(parent); /* gasket_bar_data is uninitialized. */ gasket_dev->num_page_tables = driver_desc->num_page_tables; @@ -1431,13 +1431,12 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, struct gasket_dev **gasket_devp) { int ret; - const char *kobj_name = dev_name(_dev->dev); struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev; const struct gasket_driver_desc *driver_desc; struct device *parent; - pr_debug("add PCI device %s\n", kobj_name); + dev_dbg(_dev->dev, "add PCI gasket device\n"); mutex_lock(_mutex); internal_desc = lookup_internal_desc(pci_dev); @@ -1451,7 +1450,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, driver_desc = internal_desc->driver_desc; parent = _dev->dev; - ret = gasket_alloc_dev(internal_desc, parent, _dev, kobj_name); + ret = gasket_alloc_dev(internal_desc, parent, _dev); if (ret) return ret; gasket_dev->pci_dev = pci_dev; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 01/16] MAINTAINERS: Switch a maintainer for drivers/staging/gasket
From: Todd Poynor Todd Poynor takes over for John Joseph. Signed-off-by: John Joseph Signed-off-by: Todd Poynor --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index af64fe0f0b41f..f3466b5c50482 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5939,7 +5939,7 @@ F:Documentation/gcc-plugins.txt GASKET DRIVER FRAMEWORK M: Rob Springer -M: John Joseph +M: Todd Poynor M: Ben Chan S: Maintained F: drivers/staging/gasket/ -- 2.18.0.597.ga71716f1ad-goog
[PATCH 15/16] staging: gasket: interrupt: simplify interrupt init parameters
From: Todd Poynor Pass the gasket driver descriptor to the interrupt init function, rather than exploding out separate parameters from various fields of that structure. This allows us to make more localized changes to the types of interrupts supported (MSIX vs. wire, etc.) without affecting the calling sequence, and seems nicer for simplification purposes. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 8 +-- drivers/staging/gasket/gasket_interrupt.c | 27 +++ drivers/staging/gasket/gasket_interrupt.h | 24 +--- 3 files changed, 15 insertions(+), 44 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 99f3f11d75ce2..f230bec76ae4e 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1357,13 +1357,7 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) const struct gasket_driver_desc *driver_desc = gasket_dev->internal_desc->driver_desc; - ret = gasket_interrupt_init(gasket_dev, driver_desc->name, - driver_desc->interrupt_type, - driver_desc->interrupts, - driver_desc->num_interrupts, - driver_desc->interrupt_pack_width, - driver_desc->interrupt_bar_index, - driver_desc->wire_interrupt_offsets); + ret = gasket_interrupt_init(gasket_dev); if (ret) { dev_err(gasket_dev->dev, "Critical failure to allocate interrupts: %d\n", ret); diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index f94e4ea9a7ded..eb5dfbe08e214 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -331,31 +331,30 @@ static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = { GASKET_END_OF_ATTR_ARRAY, }; -int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, - int type, - const struct gasket_interrupt_desc *interrupts, - int num_interrupts, int pack_width, int bar_index, - const struct gasket_wire_interrupt_offsets *wire_int_offsets) +int gasket_interrupt_init(struct gasket_dev *gasket_dev) { int ret; struct gasket_interrupt_data *interrupt_data; + const struct gasket_driver_desc *driver_desc = + gasket_get_driver_desc(gasket_dev); interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data), GFP_KERNEL); if (!interrupt_data) return -ENOMEM; gasket_dev->interrupt_data = interrupt_data; - interrupt_data->name = name; - interrupt_data->type = type; + interrupt_data->name = driver_desc->name; + interrupt_data->type = driver_desc->interrupt_type; interrupt_data->pci_dev = gasket_dev->pci_dev; - interrupt_data->num_interrupts = num_interrupts; - interrupt_data->interrupts = interrupts; - interrupt_data->interrupt_bar_index = bar_index; - interrupt_data->pack_width = pack_width; + interrupt_data->num_interrupts = driver_desc->num_interrupts; + interrupt_data->interrupts = driver_desc->interrupts; + interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index; + interrupt_data->pack_width = driver_desc->interrupt_pack_width; interrupt_data->num_configured = 0; - interrupt_data->wire_interrupt_offsets = wire_int_offsets; + interrupt_data->wire_interrupt_offsets = + driver_desc->wire_interrupt_offsets; - interrupt_data->eventfd_ctxs = kcalloc(num_interrupts, + interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts, sizeof(struct eventfd_ctx *), GFP_KERNEL); if (!interrupt_data->eventfd_ctxs) { @@ -363,7 +362,7 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, return -ENOMEM; } - interrupt_data->interrupt_counts = kcalloc(num_interrupts, + interrupt_data->interrupt_counts = kcalloc(driver_desc->num_interrupts, sizeof(ulong), GFP_KERNEL); if (!interrupt_data->interrupt_counts) { diff --git a/drivers/staging/gasket/gasket_interrupt.h b/drivers/staging/gasket/gasket_interrupt.h index 835af439e96a9..85526a1374a1a 100644 --- a/drivers/staging/gasket/gasket_interrupt.h +++ b/drivers/staging/gask
[PATCH 09/16] staging: gasket: core: switch to relaxed memory-mapped I/O
From: Todd Poynor Use of readl() is deprecated; readl_relaxed() with appropriate memory barriers is preferred. Switch to relaxed reads and writes for better performance as well. Memory barriers required for I/O vs. normal memory access on Apex devices have already been explicitly coded in the page table routines. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.h | 8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.h b/drivers/staging/gasket/gasket_core.h index 275fd0b345b6e..fd7e75b765a6d 100644 --- a/drivers/staging/gasket/gasket_core.h +++ b/drivers/staging/gasket/gasket_core.h @@ -590,25 +590,25 @@ const char *gasket_num_name_lookup(uint num, static inline ulong gasket_dev_read_64(struct gasket_dev *gasket_dev, int bar, ulong location) { - return readq(_dev->bar_data[bar].virt_base[location]); + return readq_relaxed(_dev->bar_data[bar].virt_base[location]); } static inline void gasket_dev_write_64(struct gasket_dev *dev, u64 value, int bar, ulong location) { - writeq(value, >bar_data[bar].virt_base[location]); + writeq_relaxed(value, >bar_data[bar].virt_base[location]); } static inline void gasket_dev_write_32(struct gasket_dev *dev, u32 value, int bar, ulong location) { - writel(value, >bar_data[bar].virt_base[location]); + writel_relaxed(value, >bar_data[bar].virt_base[location]); } static inline u32 gasket_dev_read_32(struct gasket_dev *dev, int bar, ulong location) { - return readl(>bar_data[bar].virt_base[location]); + return readl_relaxed(>bar_data[bar].virt_base[location]); } static inline void gasket_read_modify_write_64(struct gasket_dev *dev, int bar, -- 2.18.0.597.ga71716f1ad-goog
[PATCH 10/16] staging: gasket: page table: remove extraneous memory barriers
From: Todd Poynor Some explicit memory barriers in the page table code are not necessary, either because: (a) The barrier follows a non-relaxed MMIO access that already performs a read or write memory barrier. (b) The barrier follows DMA API calls for which the device-visible effects of IOMMU programming are guaranteed to be flushed to the IOMMU prior to the call returning, and doesn't need to sync with normal memory access. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_page_table.c | 15 +-- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/gasket/gasket_page_table.c b/drivers/staging/gasket/gasket_page_table.c index 4d2499269499b..53492f4fad6aa 100644 --- a/drivers/staging/gasket/gasket_page_table.c +++ b/drivers/staging/gasket/gasket_page_table.c @@ -317,8 +317,6 @@ static void gasket_free_extended_subtable(struct gasket_page_table *pg_tbl, /* Release the page table from the device */ writeq(0, slot); - /* Force sync around the address release. */ - mb(); if (pte->dma_addr) dma_unmap_page(pg_tbl->device, pte->dma_addr, PAGE_SIZE, @@ -504,8 +502,6 @@ static int gasket_perform_mapping(struct gasket_page_table *pg_tbl, (void *)page_to_phys(page)); return -1; } - /* Wait until the page is mapped. */ - mb(); } /* Make the DMA-space address available to the device. */ @@ -604,12 +600,13 @@ static void gasket_perform_unmapping(struct gasket_page_table *pg_tbl, */ for (i = 0; i < num_pages; i++) { /* release the address from the device, */ - if (is_simple_mapping || ptes[i].status == PTE_INUSE) + if (is_simple_mapping || ptes[i].status == PTE_INUSE) { writeq(0, [i]); - else + } else { ((u64 __force *)slots)[i] = 0; - /* Force sync around the address release. */ - mb(); + /* sync above PTE update before updating mappings */ + wmb(); + } /* release the address from the driver, */ if (ptes[i].status == PTE_INUSE) { @@ -898,8 +895,6 @@ static int gasket_alloc_extended_subtable(struct gasket_page_table *pg_tbl, /* Map the page into DMA space. */ pte->dma_addr = dma_map_page(pg_tbl->device, pte->page, 0, PAGE_SIZE, DMA_BIDIRECTIONAL); - /* Wait until the page is mapped. */ - mb(); /* make the addresses available to the device */ dma_addr = (pte->dma_addr + pte->offset) | GASKET_VALID_SLOT_FLAG; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 04/16] staging: gasket: core: remove kobj_name param from gasket_alloc_dev
From: Todd Poynor gasket_alloc_dev can retrieve the device name from the parent parameter, a separate parameter isn't needed for this. Rename the variable to better reflect its meaning, as the name of the parent device for which a gasket device is being allocated. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 17 - 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 3fb805204d700..5f54b3615f67c 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -189,26 +189,26 @@ static int gasket_find_dev_slot(struct gasket_internal_desc *internal_desc, * Returns 0 if successful, a negative error code otherwise. */ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, - struct device *parent, struct gasket_dev **pdev, - const char *kobj_name) + struct device *parent, struct gasket_dev **pdev) { int dev_idx; const struct gasket_driver_desc *driver_desc = internal_desc->driver_desc; struct gasket_dev *gasket_dev; struct gasket_cdev_info *dev_info; + const char *parent_name = dev_name(parent); - pr_debug("Allocating a Gasket device %s.\n", kobj_name); + pr_debug("Allocating a Gasket device, parent %s.\n", parent_name); *pdev = NULL; - dev_idx = gasket_find_dev_slot(internal_desc, kobj_name); + dev_idx = gasket_find_dev_slot(internal_desc, parent_name); if (dev_idx < 0) return dev_idx; gasket_dev = *pdev = kzalloc(sizeof(*gasket_dev), GFP_KERNEL); if (!gasket_dev) { - pr_err("no memory for device %s\n", kobj_name); + pr_err("no memory for device, parent %s\n", parent_name); return -ENOMEM; } internal_desc->devs[dev_idx] = gasket_dev; @@ -217,7 +217,7 @@ static int gasket_alloc_dev(struct gasket_internal_desc *internal_desc, gasket_dev->internal_desc = internal_desc; gasket_dev->dev_idx = dev_idx; - snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", kobj_name); + snprintf(gasket_dev->kobj_name, GASKET_NAME_MAX, "%s", parent_name); gasket_dev->dev = get_device(parent); /* gasket_bar_data is uninitialized. */ gasket_dev->num_page_tables = driver_desc->num_page_tables; @@ -1431,13 +1431,12 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, struct gasket_dev **gasket_devp) { int ret; - const char *kobj_name = dev_name(_dev->dev); struct gasket_internal_desc *internal_desc; struct gasket_dev *gasket_dev; const struct gasket_driver_desc *driver_desc; struct device *parent; - pr_debug("add PCI device %s\n", kobj_name); + dev_dbg(_dev->dev, "add PCI gasket device\n"); mutex_lock(_mutex); internal_desc = lookup_internal_desc(pci_dev); @@ -1451,7 +1450,7 @@ int gasket_pci_add_device(struct pci_dev *pci_dev, driver_desc = internal_desc->driver_desc; parent = _dev->dev; - ret = gasket_alloc_dev(internal_desc, parent, _dev, kobj_name); + ret = gasket_alloc_dev(internal_desc, parent, _dev); if (ret) return ret; gasket_dev->pci_dev = pci_dev; -- 2.18.0.597.ga71716f1ad-goog
[PATCH 01/16] MAINTAINERS: Switch a maintainer for drivers/staging/gasket
From: Todd Poynor Todd Poynor takes over for John Joseph. Signed-off-by: John Joseph Signed-off-by: Todd Poynor --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index af64fe0f0b41f..f3466b5c50482 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5939,7 +5939,7 @@ F:Documentation/gcc-plugins.txt GASKET DRIVER FRAMEWORK M: Rob Springer -M: John Joseph +M: Todd Poynor M: Ben Chan S: Maintained F: drivers/staging/gasket/ -- 2.18.0.597.ga71716f1ad-goog
[PATCH 15/16] staging: gasket: interrupt: simplify interrupt init parameters
From: Todd Poynor Pass the gasket driver descriptor to the interrupt init function, rather than exploding out separate parameters from various fields of that structure. This allows us to make more localized changes to the types of interrupts supported (MSIX vs. wire, etc.) without affecting the calling sequence, and seems nicer for simplification purposes. Signed-off-by: Todd Poynor --- drivers/staging/gasket/gasket_core.c | 8 +-- drivers/staging/gasket/gasket_interrupt.c | 27 +++ drivers/staging/gasket/gasket_interrupt.h | 24 +--- 3 files changed, 15 insertions(+), 44 deletions(-) diff --git a/drivers/staging/gasket/gasket_core.c b/drivers/staging/gasket/gasket_core.c index 99f3f11d75ce2..f230bec76ae4e 100644 --- a/drivers/staging/gasket/gasket_core.c +++ b/drivers/staging/gasket/gasket_core.c @@ -1357,13 +1357,7 @@ int gasket_enable_device(struct gasket_dev *gasket_dev) const struct gasket_driver_desc *driver_desc = gasket_dev->internal_desc->driver_desc; - ret = gasket_interrupt_init(gasket_dev, driver_desc->name, - driver_desc->interrupt_type, - driver_desc->interrupts, - driver_desc->num_interrupts, - driver_desc->interrupt_pack_width, - driver_desc->interrupt_bar_index, - driver_desc->wire_interrupt_offsets); + ret = gasket_interrupt_init(gasket_dev); if (ret) { dev_err(gasket_dev->dev, "Critical failure to allocate interrupts: %d\n", ret); diff --git a/drivers/staging/gasket/gasket_interrupt.c b/drivers/staging/gasket/gasket_interrupt.c index f94e4ea9a7ded..eb5dfbe08e214 100644 --- a/drivers/staging/gasket/gasket_interrupt.c +++ b/drivers/staging/gasket/gasket_interrupt.c @@ -331,31 +331,30 @@ static struct gasket_sysfs_attribute interrupt_sysfs_attrs[] = { GASKET_END_OF_ATTR_ARRAY, }; -int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, - int type, - const struct gasket_interrupt_desc *interrupts, - int num_interrupts, int pack_width, int bar_index, - const struct gasket_wire_interrupt_offsets *wire_int_offsets) +int gasket_interrupt_init(struct gasket_dev *gasket_dev) { int ret; struct gasket_interrupt_data *interrupt_data; + const struct gasket_driver_desc *driver_desc = + gasket_get_driver_desc(gasket_dev); interrupt_data = kzalloc(sizeof(struct gasket_interrupt_data), GFP_KERNEL); if (!interrupt_data) return -ENOMEM; gasket_dev->interrupt_data = interrupt_data; - interrupt_data->name = name; - interrupt_data->type = type; + interrupt_data->name = driver_desc->name; + interrupt_data->type = driver_desc->interrupt_type; interrupt_data->pci_dev = gasket_dev->pci_dev; - interrupt_data->num_interrupts = num_interrupts; - interrupt_data->interrupts = interrupts; - interrupt_data->interrupt_bar_index = bar_index; - interrupt_data->pack_width = pack_width; + interrupt_data->num_interrupts = driver_desc->num_interrupts; + interrupt_data->interrupts = driver_desc->interrupts; + interrupt_data->interrupt_bar_index = driver_desc->interrupt_bar_index; + interrupt_data->pack_width = driver_desc->interrupt_pack_width; interrupt_data->num_configured = 0; - interrupt_data->wire_interrupt_offsets = wire_int_offsets; + interrupt_data->wire_interrupt_offsets = + driver_desc->wire_interrupt_offsets; - interrupt_data->eventfd_ctxs = kcalloc(num_interrupts, + interrupt_data->eventfd_ctxs = kcalloc(driver_desc->num_interrupts, sizeof(struct eventfd_ctx *), GFP_KERNEL); if (!interrupt_data->eventfd_ctxs) { @@ -363,7 +362,7 @@ int gasket_interrupt_init(struct gasket_dev *gasket_dev, const char *name, return -ENOMEM; } - interrupt_data->interrupt_counts = kcalloc(num_interrupts, + interrupt_data->interrupt_counts = kcalloc(driver_desc->num_interrupts, sizeof(ulong), GFP_KERNEL); if (!interrupt_data->interrupt_counts) { diff --git a/drivers/staging/gasket/gasket_interrupt.h b/drivers/staging/gasket/gasket_interrupt.h index 835af439e96a9..85526a1374a1a 100644 --- a/drivers/staging/gasket/gasket_interrupt.h +++ b/drivers/staging/gask