summaryrefslogtreecommitdiff
path: root/cleopatre
diff options
context:
space:
mode:
authorsave2009-11-26 18:29:59 +0000
committersave2009-11-26 18:29:59 +0000
commit5b461dae119d042fd2b5be8f7477e3d671ff6acc (patch)
treec7904cfd0df263197995fac1aed847c707ba2f08 /cleopatre
parenta4d6ca2445639b4cb619b75b0387bc666b0d9ff2 (diff)
cleo/devkit/plcdrv: implement /proc/net/plc/version
This proc will show plcdr.ko and plc.rom version number. git-svn-id: svn+ssh://pessac/svn/cesar/trunk@6481 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre')
-rw-r--r--cleopatre/devkit/plcdrv/arm/src/linux_drv.c135
1 files changed, 128 insertions, 7 deletions
diff --git a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
index 9e567fcbff..d19c1fcc65 100644
--- a/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
+++ b/cleopatre/devkit/plcdrv/arm/src/linux_drv.c
@@ -60,6 +60,13 @@ MODULE_LICENSE("SPiDCOM Technologies 2009");
#define TRACE(...) if(test_bit(TRACE_LINUX, (const volatile unsigned long*)&trace)) printk(KERN_INFO DRV_NAME": "DRV_LAYER": " __VA_ARGS__)
#define PRINTPKT(a,b,c) if(test_bit(TRACE_PACKET, (const volatile unsigned long*)&trace)) print_packet(a,b,c)
+/** Define plc.rom informations */
+#define ROM_INFO_DELIMITER '\n'
+#define ROM_INFO_KEY_DELIMITER ':'
+#define ROM_INFO_MAX_SIZE 1024
+#define ROM_VERSION_SIZE 64
+#define ROM_VERSION_KEY "version"
+
/** Define DSU trace modes */
#define DSU_TRACE_NONE 0
#define DSU_TRACE_PROC 1
@@ -94,8 +101,9 @@ struct net_priv {
struct net_device_stats stats;
struct tasklet_struct tasklet_it_rx;
struct sock *nl_sock;
- uint8_t firmware_written;
uint32_t plcd_pid;
+ uint8_t firmware_written;
+ uint8_t version[ROM_VERSION_SIZE];
};
/** Our global netlink mutex */
@@ -238,6 +246,37 @@ static int afe_write(uint32_t addr, uint8_t value)
}
/**
+ * Read Version number by /proc.
+ *
+ * \param file file structure.
+ * \param buffer string pointer given by user.
+ * \param start string pointer begin.
+ * \param offset offset value.
+ * \param count count parameter.
+ * \param eof end of file.
+ * \param data network device structure.
+ * \return new pointer position.
+ */
+static int plcdrv_readproc_version(char *buf, char **start, off_t offset, int count, int *eof, void *data)
+{
+ struct net_device *dev = (struct net_device*)data;
+ struct net_priv *priv;
+ char *p;
+
+ if(dev == NULL)
+ return -1;
+ priv = (struct net_priv *)dev->priv;
+ if(priv == NULL)
+ return -1;
+
+ p = buf;
+ p += sprintf(p, "%s: %s\n", "PLC Driver", DRV_VERSION);
+ p += sprintf(p, "%s: %s\n", "PLC Firmware", priv->version);
+ *eof = 1;
+ return p-buf+1;
+}
+
+/**
* Read the AFE configuration by /proc.
*
* \param file file structure.
@@ -412,6 +451,76 @@ int plcdrv_launch_leon(void)
}
/**
+ * Get plc.rom version number.
+ *
+ * \param file_end end of plc.rom memory copy.
+ * \param version version result buffer.
+ * \return error code.
+ */
+int get_rom_version(uint32_t file_end, uint8_t *version)
+{
+ uint8_t *infos, *p;
+ uint32_t infos_limit;
+ int infos_size;
+
+ //Check arguments
+ if((version == NULL) || (file_end == 0))
+ return -1;
+
+ infos = (uint8_t*)file_end;
+ infos_limit = (uint32_t)infos - ROM_INFO_MAX_SIZE;
+ infos_size = 0;
+
+ //No informations area
+ if(*infos != ROM_INFO_DELIMITER)
+ {
+ //File ending hasn't an information delimiter,
+ //there isn't any informations area
+ strcpy(version, "Unknown");
+ return -1;
+ }
+
+ //Search informations area
+ while(((uint32_t)infos > infos_limit-1) && ((*infos != ROM_INFO_DELIMITER) || (*(infos-1) != ROM_INFO_DELIMITER)))
+ {
+ infos--;
+ infos_size++;
+ }
+
+ //Informations not found
+ if((uint32_t)infos <= infos_limit)
+ {
+ strcpy(version, "Unknown");
+ return -1;
+ }
+
+ //Suppress first delimiter
+ infos++;
+
+ //Split informations, format is "key: value\n"
+ for(p=infos ; p <(infos+infos_size) ; p++)
+ {
+ if((*p == ROM_INFO_DELIMITER) || (*p == ROM_INFO_KEY_DELIMITER))
+ *p = '\0';
+ }
+
+ //Find version key
+ while(strcmp(infos, ROM_VERSION_KEY))
+ {
+ infos += strlen(infos)+1; //to skip the key
+ infos += strlen(infos)+1; //to skip the associated value
+ }
+
+ //Skip version key
+ infos += strlen(infos)+1;
+
+ //Copy version value without first space
+ strncpy(version, infos+1, ROM_INFO_MAX_SIZE);
+
+ return 0;
+}
+
+/**
* Open the character device.
*
* \param inp inode structure.
@@ -443,9 +552,14 @@ int plcdrv_char_close(struct inode *inp, struct file *filp)
if(priv == NULL)
return -1;
- //LEON code downloaded let's start network device
if(write_called)
+ {
+ //Get firmware version number
+ get_rom_version(VIRT_PLCCODE_BASE + filp->f_pos - 1, priv->version);
+
+ //LEON code downloaded let's start network device
priv->firmware_written = 1;
+ }
return 0;
}
@@ -1498,9 +1612,15 @@ int __init plcdrv_module_init(void)
plcdrv_device = dev;
}
- //Create proc entries for AFE configuration
- plc_dir = proc_mkdir("plc", &proc_root);
- entry = create_proc_entry("afe",0,plc_dir);
+ //Create a proc entry for version
+ plc_dir = proc_mkdir("plc", init_net.proc_net);
+ entry = create_proc_entry("version", 0, plc_dir);
+ entry->read_proc = plcdrv_readproc_version;
+ entry->data = (int*)plcdrv_device;
+
+
+ //Create proc entry for AFE configuration
+ entry = create_proc_entry("afe", 0, plc_dir);
entry->read_proc = plcdrv_readproc_afe;
entry->write_proc = plcdrv_writeproc_afe;
entry->data = (int*)plcdrv_device;
@@ -1523,8 +1643,9 @@ void __exit plcdrv_module_exit(void)
if(plcdrv_device)
{
//Remove proc
- remove_proc_entry("plc/afe", NULL);
- remove_proc_entry("plc", NULL);
+ remove_proc_entry("plc/afe", init_net.proc_net);
+ remove_proc_entry("plc/version", init_net.proc_net);
+ remove_proc_entry("plc", init_net.proc_net);
//Unmap IP address
if(plcdrv_device->base_addr)