Commit 6f13ea3d authored by Alan Cox's avatar Alan Cox Committed by Greg Kroah-Hartman

Staging: sep: tidy firmware load

Start by removing unused fields and then work this back to eliminate unused
chunks of the firmware loading ioctl (ie almost all of it)

Also fix the wrong handling of shared allocations and allocate the rar
region properly with dma_alloc_coherent not kmalloc, as it is device shared.
Signed-off-by: default avatarAlan Cox <alan@linux.intel.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@suse.de>
parent 51faa9d2
...@@ -54,7 +54,7 @@ struct sep_device { ...@@ -54,7 +54,7 @@ struct sep_device {
unsigned long resident_size; unsigned long resident_size;
void *resident_addr; void *resident_addr;
unsigned long rar_region_addr; void *rar_region_addr;
/* start address of the access to the SEP registers from driver */ /* start address of the access to the SEP registers from driver */
void __iomem *reg_addr; void __iomem *reg_addr;
......
...@@ -170,39 +170,25 @@ static DEFINE_MUTEX(sep_mutex); ...@@ -170,39 +170,25 @@ static DEFINE_MUTEX(sep_mutex);
/* wait queue head (event) of the driver */ /* wait queue head (event) of the driver */
static DECLARE_WAIT_QUEUE_HEAD(sep_event); static DECLARE_WAIT_QUEUE_HEAD(sep_event);
/* /**
This functions copies the cache and resident from their source location into * sep_load_firmware - copy firmware cache/resident
destination memory, which is external to Linux VM and is given as * @sep: device we are loading
bus address *
*/ * This functions copies the cache and resident from their source
static int sep_copy_cache_resident_to_area(struct sep_device *sep, * location into destination shared memory.
unsigned long src_cache_addr, */
unsigned long cache_size_in_bytes,
unsigned long src_resident_addr, static int sep_load_firmware(struct sep_device *sep)
unsigned long resident_size_in_bytes,
unsigned long *dst_new_cache_addr_ptr,
unsigned long *dst_new_resident_addr_ptr)
{ {
void *resident_addr;
void *cache_addr;
const struct firmware *fw; const struct firmware *fw;
char *cache_name = "cache.image.bin"; char *cache_name = "cache.image.bin";
char *res_name = "resident.image.bin"; char *res_name = "resident.image.bin";
/* error */
int error; int error;
/*--------------------------------
CODE
-------------------------------------*/
error = 0;
edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
sep->rar_region_addr = (unsigned long) sep->rar_addr; sep->rar_region_addr = sep->rar_addr;
sep->cache_bus = sep->rar_bus; sep->cache_bus = sep->rar_bus;
sep->cache_addr = sep->rar_addr; sep->cache_addr = sep->rar_addr;
...@@ -210,18 +196,12 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep, ...@@ -210,18 +196,12 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep,
error = request_firmware(&fw, cache_name, &sep->pdev->dev); error = request_firmware(&fw, cache_name, &sep->pdev->dev);
if (error) { if (error) {
edbg("SEP Driver:cant request cache fw\n"); edbg("SEP Driver:cant request cache fw\n");
goto end_function; return error;
} }
edbg("SEP Driver:cache %08Zx@%p\n", fw->size, (void *) fw->data);
edbg("SEP Driver:cache data loc is %p\n", (void *) fw->data); memcpy(sep->cache_addr, (void *)fw->data, fw->size);
edbg("SEP Driver:cache data size is %08Zx\n", fw->size);
memcpy(sep->cache_addr, (void *) fw->data, fw->size);
sep->cache_size = fw->size; sep->cache_size = fw->size;
cache_addr = sep->cache_addr;
release_firmware(fw); release_firmware(fw);
sep->resident_bus = sep->cache_bus + sep->cache_size; sep->resident_bus = sep->cache_bus + sep->cache_size;
...@@ -231,36 +211,18 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep, ...@@ -231,36 +211,18 @@ static int sep_copy_cache_resident_to_area(struct sep_device *sep,
error = request_firmware(&fw, res_name, &sep->pdev->dev); error = request_firmware(&fw, res_name, &sep->pdev->dev);
if (error) { if (error) {
edbg("SEP Driver:cant request res fw\n"); edbg("SEP Driver:cant request res fw\n");
goto end_function; return error;
} }
edbg("sep: res %08Zx@%p\n", fw->size, (void *)fw->data);
edbg("SEP Driver:res data loc is %p\n", (void *) fw->data); memcpy(sep->resident_addr, (void *) fw->data, fw->size);
edbg("SEP Driver:res data size is %08Zx\n", fw->size);
memcpy((void *) sep->resident_addr, (void *) fw->data, fw->size);
sep->resident_size = fw->size; sep->resident_size = fw->size;
release_firmware(fw); release_firmware(fw);
resident_addr = sep->resident_addr; edbg("sep: resident v %p b %08llx cache v %p b %08llx\n",
sep->resident_addr, (unsigned long long)sep->resident_bus,
edbg("SEP Driver:resident_addr (bus)is %08llx\n", (unsigned long long)sep->resident_bus); sep->cache_addr, (unsigned long long)sep->cache_bus);
edbg("SEP Driver:cache_addr (bus) is %08llx\n", (unsigned long long)sep->cache_bus); return 0;
edbg("SEP Driver:resident_addr (virtual)is %p\n", resident_addr);
edbg("SEP Driver:cache_addr (virtual) is %08llx\n", (unsigned long long)cache_addr);
edbg("SEP Driver:resident_size is %08lx\n", sep->resident_size);
edbg("SEP Driver:cache_size is %08llx\n", (unsigned long long)sep->cache_size);
/* bus addresses */
*dst_new_cache_addr_ptr = sep->cache_bus;
*dst_new_resident_addr_ptr = sep->resident_bus;
end_function:
return error;
} }
/** /**
...@@ -2125,46 +2087,39 @@ end_function: ...@@ -2125,46 +2087,39 @@ end_function:
static int sep_realloc_cache_resident_handler(struct sep_device *sep, static int sep_realloc_cache_resident_handler(struct sep_device *sep,
unsigned long arg) unsigned long arg)
{ {
int error;
unsigned long bus_cache_address;
unsigned long bus_resident_address;
struct sep_driver_realloc_cache_resident_t command_args; struct sep_driver_realloc_cache_resident_t command_args;
int error;
/* copy the data */
error = copy_from_user(&command_args, (void *) arg, sizeof(struct sep_driver_realloc_cache_resident_t));
if (error)
goto end_function;
/* copy cache and resident to the their intended locations */ /* copy cache and resident to the their intended locations */
error = sep_copy_cache_resident_to_area(sep, command_args.cache_addr, command_args.cache_size_in_bytes, command_args.resident_addr, command_args.resident_size_in_bytes, &bus_cache_address, &bus_resident_address); error = sep_load_firmware(sep);
if (error) if (error)
goto end_function; return error;
command_args.new_base_addr = sep->shared_area_bus; command_args.new_base_addr = sep->shared_area_bus;
/* find the new base address according to the lowest address between /* find the new base address according to the lowest address between
cache, resident and shared area */ cache, resident and shared area */
if (bus_resident_address < command_args.new_base_addr) if (sep->resident_bus < command_args.new_base_addr)
command_args.new_base_addr = bus_resident_address; command_args.new_base_addr = sep->resident_bus;
if (bus_cache_address < command_args.new_base_addr) if (sep->cache_bus < command_args.new_base_addr)
command_args.new_base_addr = bus_cache_address; command_args.new_base_addr = sep->cache_bus;
/* set the return parameters */ /* set the return parameters */
command_args.new_cache_addr = bus_cache_address; command_args.new_cache_addr = sep->cache_bus;
command_args.new_resident_addr = bus_resident_address; command_args.new_resident_addr = sep->resident_bus;
/* set the new shared area */ /* set the new shared area */
command_args.new_shared_area_addr = sep->shared_area_bus; command_args.new_shared_area_addr = sep->shared_area_bus;
edbg("SEP Driver:command_args.new_shared_area is %08lx\n", command_args.new_shared_area_addr); edbg("SEP Driver:command_args.new_shared_area is %08llx\n", command_args.new_shared_area_addr);
edbg("SEP Driver:command_args.new_base_addr is %08lx\n", command_args.new_base_addr); edbg("SEP Driver:command_args.new_base_addr is %08llx\n", command_args.new_base_addr);
edbg("SEP Driver:command_args.new_resident_addr is %08lx\n", command_args.new_resident_addr); edbg("SEP Driver:command_args.new_resident_addr is %08llx\n", command_args.new_resident_addr);
edbg("SEP Driver:command_args.new_cache_addr is %08lx\n", command_args.new_cache_addr); edbg("SEP Driver:command_args.new_cache_addr is %08llx\n", command_args.new_cache_addr);
/* return to user */ /* return to user */
error = copy_to_user((void *) arg, (void *) &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)); if (copy_to_user((void *) arg, &command_args, sizeof(struct sep_driver_realloc_cache_resident_t)))
end_function: return -EFAULT;
return error; return 0;
} }
/* /*
...@@ -2573,14 +2528,14 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id ...@@ -2573,14 +2528,14 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id
/* set up system base address and shared memory location */ /* set up system base address and shared memory location */
sep->rar_addr = kmalloc(2 * SEP_RAR_IO_MEM_REGION_SIZE, GFP_KERNEL); sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
2 * SEP_RAR_IO_MEM_REGION_SIZE,
&sep->rar_bus, GFP_KERNEL);
if (!sep->rar_addr) { if (!sep->rar_addr) {
edbg("SEP Driver:cant kmalloc rar\n"); edbg("SEP Driver:can't allocate rar\n");
goto end_function_uniomap; goto end_function_uniomap;
} }
/* FIXME */
sep->rar_bus = __pa(sep->rar_addr);
edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus); edbg("SEP Driver:rar_bus is %08llx\n", (unsigned long long)sep->rar_bus);
edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr); edbg("SEP Driver:rar_virtual is %p\n", sep->rar_addr);
...@@ -2608,7 +2563,8 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id ...@@ -2608,7 +2563,8 @@ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id
sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13)));
end_function_free_res: end_function_free_res:
kfree(sep->rar_addr); dma_free_coherent(&sep->pdev->dev, 2 * SEP_RAR_IO_MEM_REGION_SIZE,
sep->rar_addr, sep->rar_bus);
#endif /* SEP_DRIVER_POLLING_MODE */ #endif /* SEP_DRIVER_POLLING_MODE */
end_function_uniomap: end_function_uniomap:
iounmap(sep->io_addr); iounmap(sep->io_addr);
......
...@@ -116,32 +116,14 @@ struct sep_driver_init_t { ...@@ -116,32 +116,14 @@ struct sep_driver_init_t {
realloc cache resident command realloc cache resident command
*/ */
struct sep_driver_realloc_cache_resident_t { struct sep_driver_realloc_cache_resident_t {
/* base address */
unsigned long base_addr;
/* current cache address */
unsigned long cache_addr;
/* cache size in bytes */
unsigned long cache_size_in_bytes;
/* current resident address */
unsigned long resident_addr;
/* resident size in bytes */
unsigned long resident_size_in_bytes;
/* new cache address */ /* new cache address */
unsigned long new_cache_addr; u64 new_cache_addr;
/* new resident address */ /* new resident address */
unsigned long new_resident_addr; u64 new_resident_addr;
/* new resident address */ /* new resident address */
unsigned long new_shared_area_addr; u64 new_shared_area_addr;
/* new base address */ /* new base address */
unsigned long new_base_addr; u64 new_base_addr;
}; };
struct sep_driver_alloc_t { struct sep_driver_alloc_t {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment