[package] iwinfo: iwinfo_hardware_id_from_mtd() never writes, so do not request write...
[openwrt.git] / package / iwinfo / src / iwinfo_utils.c
index 081464a..5ca1016 100644 (file)
@@ -124,3 +124,100 @@ void iwinfo_close(void)
        if( ioctl_socket > -1 )
                close(ioctl_socket);
 }
+
+struct iwinfo_hardware_entry * iwinfo_hardware(struct iwinfo_hardware_id *id)
+{
+       const struct iwinfo_hardware_entry *e;
+
+       for (e = IWINFO_HARDWARE_ENTRIES; e->vendor_name; e++)
+       {
+               if ((e->vendor_id != 0xffff) && (e->vendor_id != id->vendor_id))
+                       continue;
+
+               if ((e->device_id != 0xffff) && (e->device_id != id->device_id))
+                       continue;
+
+               if ((e->subsystem_vendor_id != 0xffff) &&
+                       (e->subsystem_vendor_id != id->subsystem_vendor_id))
+                       continue;
+
+               if ((e->subsystem_device_id != 0xffff) &&
+                       (e->subsystem_device_id != id->subsystem_device_id))
+                       continue;
+
+               return e;
+       }
+
+       return NULL;
+}
+
+int iwinfo_hardware_id_from_mtd(struct iwinfo_hardware_id *id)
+{
+       FILE *mtd;
+       uint16_t *bc;
+
+       int fd, len, off;
+       char buf[128];
+
+       if (!(mtd = fopen("/proc/mtd", "r")))
+               return -1;
+
+       while (fgets(buf, sizeof(buf), mtd) > 0)
+       {
+               if (fscanf(mtd, "mtd%d: %*x %x %127s", &off, &len, buf) < 3 ||
+                   strcmp(buf, "\"boardconfig\"") || strcmp(buf, "\"EEPROM\""))
+               {
+                       off = -1;
+                       continue;
+               }
+
+               break;
+       }
+
+       fclose(mtd);
+
+       if (off < 0)
+               return -1;
+
+       snprintf(buf, sizeof(buf), "/dev/mtdblock%d", off);
+
+       if ((fd = open(buf, O_RDONLY)) < 0)
+               return -1;
+
+       bc = mmap(NULL, len, PROT_READ, MAP_PRIVATE|MAP_LOCKED, fd, 0);
+
+       if ((void *)bc != MAP_FAILED)
+       {
+               id->vendor_id = 0;
+               id->device_id = 0;
+
+               for (off = len / 2 - 0x800; off >= 0; off -= 0x800)
+               {
+                       /* AR531X board data magic */
+                       if ((bc[off] == 0x3533) && (bc[off + 1] == 0x3131))
+                       {
+                               id->vendor_id = bc[off + 0x7d];
+                               id->device_id = bc[off + 0x7c];
+                               id->subsystem_vendor_id = bc[off + 0x84];
+                               id->subsystem_device_id = bc[off + 0x83];
+                               break;
+                       }
+
+                       /* AR5416 EEPROM magic */
+                       else if ((bc[off] == 0xA55A) || (bc[off] == 0x5AA5))
+                       {
+                               id->vendor_id = bc[off + 0x0D];
+                               id->device_id = bc[off + 0x0E];
+                               id->subsystem_vendor_id = bc[off + 0x13];
+                               id->subsystem_device_id = bc[off + 0x14];
+                               break;
+                       }
+               }
+
+               munmap(bc, len);
+       }
+
+       close(fd);
+
+       return (id->vendor_id && id->device_id) ? 0 : -1;
+}