Allows an external utility to read/write flash for
firmware upgrades.

Signed-off-by: Glenn Grundstrom <[EMAIL PROTECTED]>

---

diff --git a/drivers/infiniband/hw/nes/nes.c b/drivers/infiniband/hw/nes/nes.c
index a5e0bb5..1088330 100644
--- a/drivers/infiniband/hw/nes/nes.c
+++ b/drivers/infiniband/hw/nes/nes.c
@@ -780,6 +780,136 @@ static struct pci_driver nes_pci_driver = {
        .remove = __devexit_p(nes_remove),
 };
 
+static ssize_t nes_show_ee_cmd(struct device_driver *ddp, char *buf)
+{
+       u32 eeprom_cmd;
+       struct nes_device *nesdev;
+
+       nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+       eeprom_cmd = nes_read32(nesdev->regs + NES_EEPROM_COMMAND);
+
+       return snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_cmd);
+}
+
+static ssize_t nes_store_ee_cmd(struct device_driver *ddp,
+       const char *buf, size_t count)
+{
+       char *p = (char *)buf;
+       u32 val;
+       struct nes_device *nesdev;
+
+       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+               val = simple_strtoul(p, &p, 16);
+               nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+               nes_write32(nesdev->regs + NES_EEPROM_COMMAND, val);
+       }
+       return strnlen(buf, count);
+}
+
+static ssize_t nes_show_ee_data(struct device_driver *ddp, char *buf)
+{
+       u32 eeprom_data;
+       struct nes_device *nesdev;
+
+       nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+       eeprom_data = nes_read32(nesdev->regs + NES_EEPROM_DATA);
+
+       return  snprintf(buf, PAGE_SIZE, "0x%x\n", eeprom_data);
+}
+
+static ssize_t nes_store_ee_data(struct device_driver *ddp,
+       const char *buf, size_t count)
+{
+       char *p = (char *)buf;
+       u32 val;
+       struct nes_device *nesdev;
+
+       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+               val = simple_strtoul(p, &p, 16);
+               nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+               nes_write32(nesdev->regs + NES_EEPROM_DATA, val);
+       }
+       return strnlen(buf, count);
+}
+
+static ssize_t nes_show_flash_cmd(struct device_driver *ddp, char *buf)
+{
+       u32 flash_cmd;
+       struct nes_device *nesdev;
+
+       nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+       flash_cmd = nes_read32(nesdev->regs + NES_FLASH_COMMAND);
+
+       return  snprintf(buf, PAGE_SIZE, "0x%x\n", flash_cmd);
+}
+
+static ssize_t nes_store_flash_cmd(struct device_driver *ddp,
+       const char *buf, size_t count)
+{
+       char *p = (char *)buf;
+       u32 val;
+       struct nes_device *nesdev;
+
+       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+               val = simple_strtoul(p, &p, 16);
+               nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+               nes_write32(nesdev->regs + NES_FLASH_COMMAND, val);
+       }
+       return strnlen(buf, count);
+}
+
+static ssize_t nes_show_flash_data(struct device_driver *ddp, char *buf)
+{
+       u32 flash_data;
+       struct nes_device *nesdev;
+
+       nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+       flash_data = nes_read32(nesdev->regs + NES_FLASH_DATA);
+
+       return  snprintf(buf, PAGE_SIZE, "0x%x\n", flash_data);
+}
+
+static ssize_t nes_store_flash_data(struct device_driver *ddp,
+       const char *buf, size_t count)
+{
+       char *p = (char *)buf;
+       u32 val;
+       struct nes_device *nesdev;
+
+       if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+               val = simple_strtoul(p, &p, 16);
+               nesdev = list_entry(nes_dev_list.next, typeof(*nesdev), list);
+               nes_write32(nesdev->regs + NES_FLASH_DATA, val);
+       }
+       return strnlen(buf, count);
+}
+
+DRIVER_ATTR(eeprom_cmd, S_IRUSR | S_IWUSR,
+       nes_show_ee_cmd, nes_store_ee_cmd);
+DRIVER_ATTR(eeprom_data, S_IRUSR | S_IWUSR,
+       nes_show_ee_data, nes_store_ee_data);
+DRIVER_ATTR(flash_cmd, S_IRUSR | S_IWUSR,
+       nes_show_flash_cmd, nes_store_flash_cmd);
+DRIVER_ATTR(flash_data, S_IRUSR | S_IWUSR,
+       nes_show_flash_data, nes_store_flash_data);
+
+int nes_create_driver_sysfs(struct pci_driver *drv)
+{
+       int error;
+       error  = driver_create_file(&drv->driver, &driver_attr_eeprom_cmd);
+       error |= driver_create_file(&drv->driver, &driver_attr_eeprom_data);
+       error |= driver_create_file(&drv->driver, &driver_attr_flash_cmd);
+       error |= driver_create_file(&drv->driver, &driver_attr_flash_data);
+       return error;
+}
+
+void nes_remove_driver_sysfs(struct pci_driver *drv)
+{
+       driver_remove_file(&drv->driver, &driver_attr_eeprom_cmd);
+       driver_remove_file(&drv->driver, &driver_attr_eeprom_data);
+       driver_remove_file(&drv->driver, &driver_attr_flash_cmd);
+       driver_remove_file(&drv->driver, &driver_attr_flash_data);
+}
 
 /**
  * nes_init_module - module initialization entry point
@@ -787,12 +917,20 @@ static struct pci_driver nes_pci_driver = {
 static int __init nes_init_module(void)
 {
        int retval;
+       int retval1;
+
        retval = nes_cm_start();
        if (retval) {
                printk(KERN_ERR PFX "Unable to start NetEffect iWARP CM.\n");
                return retval;
        }
-       return pci_register_driver(&nes_pci_driver);
+       retval = pci_register_driver(&nes_pci_driver);
+       if (retval >= 0) {
+               retval1 = nes_create_driver_sysfs(&nes_pci_driver);
+               if (retval1 < 0)
+                       printk(KERN_ERR PFX "Unable to create NetEffect sys 
files.\n");
+       }
+       return retval;
 }
 
 
@@ -802,6 +940,8 @@ static int __init nes_init_module(void)
 static void __exit nes_exit_module(void)
 {
        nes_cm_stop();
+       nes_remove_driver_sysfs(&nes_pci_driver);
+
        pci_unregister_driver(&nes_pci_driver);
 }
 
diff --git a/drivers/infiniband/hw/nes/nes_hw.h 
b/drivers/infiniband/hw/nes/nes_hw.h
index 178f3d5..25cfda2 100644
--- a/drivers/infiniband/hw/nes/nes_hw.h
+++ b/drivers/infiniband/hw/nes/nes_hw.h
@@ -49,6 +49,8 @@ enum pci_regs {
        NES_ONE_SHOT_CONTROL = 0x001C,
        NES_EEPROM_COMMAND = 0x0020,
        NES_EEPROM_DATA = 0x0024,
+       NES_FLASH_COMMAND = 0x0028,
+       NES_FLASH_DATA  = 0x002C,
        NES_SOFTWARE_RESET = 0x0030,
        NES_CQ_ACK = 0x0034,
        NES_WQE_ALLOC = 0x0040,
_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to