#include <linux/mm.h>
#include <linux/poll.h>
#include <linux/wait.h>
+#include <linux/sched.h>
#include <linux/pci.h>
#include <linux/firmware.h>
#include <asm/ioctl.h>
void *virt_address)
{
dma_addr_t pa = sep->shared_bus + (virt_address - sep->shared_addr);
- edbg("sep: virt to bus b %08llx v %p\n", pa, virt_address);
+ edbg("sep: virt to bus b %08llx v %p\n",
+ (unsigned long long)pa, virt_address);
return pa;
}
return mask;
}
-/*
- calculates time and sets it at the predefined address
-*/
-static int sep_set_time(struct sep_device *sep, unsigned long *address_ptr, unsigned long *time_in_sec_ptr)
+/**
+ * sep_time_address - address in SEP memory of time
+ * @sep: SEP device we want the address from
+ *
+ * Return the address of the two dwords in memory used for time
+ * setting.
+ */
+
+static u32 *sep_time_address(struct sep_device *sep)
+{
+ return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
+}
+
+/**
+ * sep_set_time - set the SEP time
+ * @sep: the SEP we are setting the time for
+ *
+ * Calculates time and sets it at the predefined address.
+ * Called with the sep mutex held.
+ */
+static unsigned long sep_set_time(struct sep_device *sep)
{
struct timeval time;
- /* address of time in the kernel */
- u32 *time_addr;
+ u32 *time_addr; /* address of time as seen by the kernel */
- dbg("SEP Driver:--------> sep_set_time start\n");
+ dbg("sep:sep_set_time start\n");
do_gettimeofday(&time);
/* set value in the SYSTEM MEMORY offset */
- time_addr = sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES;
+ time_addr = sep_time_address(sep);
time_addr[0] = SEP_TIME_VAL_TOKEN;
time_addr[1] = time.tv_sec;
edbg("SEP Driver:time_addr is %p\n", time_addr);
edbg("SEP Driver:sep->shared_addr is %p\n", sep->shared_addr);
- /* set the output parameters if needed */
- if (address_ptr)
- *address_ptr = sep_shared_virt_to_bus(sep, time_addr);
-
- if (time_in_sec_ptr)
- *time_in_sec_ptr = time.tv_sec;
+ return time.tv_sec;
+}
- dbg("SEP Driver:<-------- sep_set_time end\n");
+/**
+ * sep_dump_message - dump the message that is pending
+ * @sep: sep device
+ *
+ * Dump out the message pending in the shared message area
+ */
- return 0;
+static void sep_dump_message(struct sep_device *sep)
+{
+ int count;
+ for (count = 0; count < 12 * 4; count += 4)
+ edbg("Word %d of the message is %u\n", count, *((u32 *) (sep->shared_addr + count)));
}
-/*
- This function raises interrupt to SEP that signals that is has a new
- command from HOST
-*/
+/**
+ * sep_send_command_handler - kick off a command
+ * @sep: sep being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ */
+
static void sep_send_command_handler(struct sep_device *sep)
{
- unsigned long count;
+ dbg("sep:sep_send_command_handler start\n");
- dbg("SEP Driver:--------> sep_send_command_handler start\n");
- sep_set_time(sep, 0, 0);
+ mutex_lock(&sep_mutex);
+ sep_set_time(sep);
- /* flash cache */
+ /* FIXME: flush cache */
flush_cache_all();
- for (count = 0; count < 12 * 4; count += 4)
- edbg("Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
-
+ sep_dump_message(sep);
/* update counter */
sep->send_ct++;
/* send interrupt to SEP */
sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2);
dbg("SEP Driver:<-------- sep_send_command_handler end\n");
+ mutex_unlock(&sep_mutex);
return;
}
-/*
- This function raises interrupt to SEPm that signals that is has a
- new command from HOST
-*/
+/**
+ * sep_send_reply_command_handler - kick off a command reply
+ * @sep: sep being signalled
+ *
+ * This function raises interrupt to SEP that signals that is has a new
+ * command from the host
+ */
+
static void sep_send_reply_command_handler(struct sep_device *sep)
{
- unsigned long count;
-
- dbg("SEP Driver:--------> sep_send_reply_command_handler start\n");
+ dbg("sep:sep_send_reply_command_handler start\n");
/* flash cache */
flush_cache_all();
- for (count = 0; count < 12 * 4; count += 4)
- edbg("Word %lu of the message is %lu\n", count, *((unsigned long *) (sep->shared_addr + count)));
- /* update counter */
- sep->send_ct++;
+
+ sep_dump_message(sep);
+
+ mutex_lock(&sep_mutex);
+ sep->send_ct++; /* update counter */
/* send the interrupt to SEP */
sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct);
/* update both counters */
sep->send_ct++;
sep->reply_ct++;
- dbg("SEP Driver:<-------- sep_send_reply_command_handler end\n");
+ mutex_unlock(&sep_mutex);
+ dbg("sep: sep_send_reply_command_handler end\n");
}
/*
first_table_data.physical_address = 0xffffffff;
/* find the free structure for flow data */
+ error = -EINVAL;
flow_context_ptr = sep_find_flow_context(sep, SEP_FREE_FLOW_ID);
if (flow_context_ptr == NULL)
goto end_function;
return 0;
}
-/*
- this function handles the request for get time
-*/
+/**
+ * sep_get_time_handler - time request from user space
+ * @sep: sep we are to set the time for
+ * @arg: pointer to user space arg buffer
+ *
+ * This function reports back the time and the address in the SEP
+ * shared buffer at which it has been placed. (Do we really need this!!!)
+ */
+
static int sep_get_time_handler(struct sep_device *sep, unsigned long arg)
{
- int error;
struct sep_driver_get_time_t command_args;
- error = sep_set_time(sep, &command_args.time_physical_address, &command_args.time_value);
- if (error == 0)
- error = copy_to_user((void __user *)arg,
- &command_args, sizeof(struct sep_driver_get_time_t));
- return error;
+ mutex_lock(&sep_mutex);
+ command_args.time_value = sep_set_time(sep);
+ command_args.time_physical_address = (unsigned long)sep_time_address(sep);
+ mutex_unlock(&sep_mutex);
+ if (copy_to_user((void __user *)arg,
+ &command_args, sizeof(struct sep_driver_get_time_t)))
+ return -EFAULT;
+ return 0;
}
struct sep_device *sep;
int counter;
int size; /* size of memory for allocation */
- unsigned long iosize;
- unsigned long bar0, end0;
edbg("Sep pci probe starting\n");
if (sep_dev != NULL) {
}
/* now set the memory regions */
#if (SEP_DRIVER_RECONFIG_MESSAGE_AREA == 1)
+ /* Note: this test section will need moving before it could ever
+ work as the registers are not yet mapped ! */
/* send the new SHARED MESSAGE AREA to the SEP */
sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus);
goto end_function_deallocate_sep_shared_area;
}
edbg("SEP Driver: create flow workqueue \n");
- /* load the rom code */
- sep_load_rom_code(sep);
-
sep->pdev = pci_dev_get(pdev);
- /* get the io memory start address */
- bar0 = pci_resource_start(pdev, 0);
- if (!bar0) {
- edbg("SEP Driver error pci resource start\n");
- goto end_function_deallocate_sep_shared_area;
- }
-
- /* get the io memory end address */
- end0 = pci_resource_end(pdev, 0);
- if (!end0) {
- edbg("SEP Driver error pci resource end\n");
- goto end_function_deallocate_sep_shared_area;
- }
-
- iosize = end0 - bar0 + 1;
-
- edbg("SEP Driver:io_bus is %08lx\n", bar0);
-
- edbg("SEP Driver:io_memory_end_phyaical_address is %08lx\n", end0);
-
- edbg("SEP Driver:io_memory_size is %08lx\n", iosize);
-
- sep->reg_addr = ioremap_nocache(bar0, iosize);
+ sep->reg_addr = pci_ioremap_bar(pdev, 0);
if (!sep->reg_addr) {
- edbg("SEP Driver error ioremap of io memory\n");
+ edbg("sep: ioremap of registers failed.\n");
goto end_function_deallocate_sep_shared_area;
}
+ edbg("SEP Driver:reg_addr is %p\n", sep->reg_addr);
- edbg("SEP Driver:io_addr is %p\n", sep->reg_addr);
+ /* load the rom code */
+ sep_load_rom_code(sep);
/* set up system base address and shared memory location */
-
sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev,
2 * SEP_RAR_IO_MEM_REGION_SIZE,
&sep->rar_bus, GFP_KERNEL);
goto end_function_uniomap;
}
+
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);
error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep);
if (error)
goto end_function_free_res;
-
- goto end_function;
+ return 0;
edbg("SEP Driver: about to write IMR REG_ADDR");
/* set the IMR register - open only GPR 2 */
{
int ret_val = alloc_chrdev_region(&sep_devno, 0, 1, "sep_sec_driver");
if (ret_val) {
- edbg("sep_driver:major number allocation failed, retval is %d\n", ret_val);
- goto end_function;
+ edbg("sep: major number allocation failed, retval is %d\n",
+ ret_val);
+ return ret_val;
}
-
/* init cdev */
cdev_init(&sep_cdev, &sep_file_operations);
sep_cdev.owner = THIS_MODULE;
/* register the driver with the kernel */
ret_val = cdev_add(&sep_cdev, sep_devno, 1);
-
if (ret_val) {
edbg("sep_driver:cdev_add failed, retval is %d\n", ret_val);
- goto end_function_unregister_devnum;
+ /* unregister dev numbers */
+ unregister_chrdev_region(sep_devno, 1);
}
-
- goto end_function;
-
-end_function_unregister_devnum:
-
- /* unregister dev numbers */
- unregister_chrdev_region(sep_devno, 1);
-
-end_function:
- return ret_val;
+ return ret_val;
}