.bitmap = &cpu_bitmap
};
+/* USB devices plugged into the system */
+struct activity pwr_usb_act = {
+ .id = A_PWR_USB,
+ .options = AO_NULL,
+ .magic = ACTIVITY_MAGIC_BASE,
+ .group = G_POWER,
+#ifdef SOURCE_SADC
+ .f_count = wrap_get_usb_nr,
+ .f_count2 = NULL,
+ .f_read = wrap_read_bus_usb_dev,
+#endif
+#ifdef SOURCE_SAR
+ .f_print = print_pwr_usb_stats,
+ .f_print_avg = print_avg_pwr_usb_stats,
+#endif
+#ifdef SOURCE_SADF
+ .f_render = render_pwr_usb_stats,
+ .f_xml_print = xml_print_pwr_usb_stats,
+ .hdr_line = "manufact;product;BUS;idvendor;idprod;maxpower",
+ .name = "A_PWR_USB",
+#endif
+ .nr = -1,
+ .nr2 = 1,
+ .fsize = STATS_PWR_USB_SIZE,
+ .msize = STATS_PWR_USB_SIZE,
+ .opt_flags = 0,
+ .buf = {NULL, NULL, NULL},
+ .bitmap = NULL
+};
+
/*
* Array of activities.
&pwr_temp_act,
&pwr_in_act,
&huge_act,
- &pwr_wghfreq_act
+ &pwr_wghfreq_act,
+ &pwr_usb_act
};
#define S_STAT "stat"
#define DEVMAP_DIR "/dev/mapper"
#define DEVICES "/proc/devices"
+#define SYSFS_USBDEV "/sys/bus/usb/devices"
+#define SYSFS_IDVENDOR "idVendor"
+#define SYSFS_IDPRODUCT "idProduct"
+#define SYSFS_BMAXPOWER "bMaxPower"
+#define SYSFS_MANUFACTURER "manufacturer"
+#define SYSFS_PRODUCT "product"
#define MAX_FILE_LEN 256
#define MAX_PF_NAME 1024
}
}
}
+
+/*
+ ***************************************************************************
+ * Display USB devices statistics. This function is used to
+ * display instantaneous and summary statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in jiffies.
+ * @dispavg TRUE if displaying average statistics.
+ ***************************************************************************
+ */
+void stub_print_pwr_usb_stats(struct activity *a, int curr, int dispavg)
+{
+ int i, j;
+ struct stats_pwr_usb *suc, *sum;
+
+ if (dis) {
+ printf("\n%-11s BUS idvendor idprod maxpower",
+ (dispavg ? _("Summary") : timestamp[!curr]));
+ printf(" %*s", MAX_MANUF_LEN - 1, "manufact");
+ printf(" %*s\n", MAX_PROD_LEN - 1, "product");
+ }
+
+ for (i = 0; i < a->nr; i++) {
+ suc = (struct stats_pwr_usb *) ((char *) a->buf[curr] + i * a->msize);
+
+ if (!suc->bus_nr)
+ /* Bus#0 doesn't exist: We are at the end of the list */
+ break;
+
+ printf("%-11s %6d %9x %9x %9u",
+ (dispavg ? _("Summary") : timestamp[curr]),
+ suc->bus_nr,
+ suc->vendor_id, suc->product_id,
+ /* bMaxPower is expressed in 2 mA units */
+ suc->bmaxpower << 1);
+
+ printf(" %*s", MAX_MANUF_LEN - 1, suc->manufacturer);
+ printf(" %*s\n", MAX_PROD_LEN - 1, suc->product);
+
+ if (!dispavg) {
+ /* Save current USB device in summary list */
+ for (j = 0; j < a->nr; j++) {
+ sum = (struct stats_pwr_usb *) ((char *) a->buf[2] + j * a->msize);
+
+ if ((sum->bus_nr == suc->bus_nr) &&
+ (sum->vendor_id == suc->vendor_id) &&
+ (sum->product_id == suc->product_id))
+ /* USB device found in summary list */
+ break;
+ if (!sum->bus_nr) {
+ /*
+ * Current slot is free:
+ * Save USB device in summary list.
+ */
+ *sum = *suc;
+ break;
+ }
+ if (j == a->nr - 1) {
+ /*
+ * This is the last slot and
+ * we still havent't found the device.
+ * So create a dummy device here.
+ */
+ sum->bus_nr = ~0;
+ sum->vendor_id = sum->product_id = 0;
+ sum->bmaxpower = 0;
+ sum->manufacturer[0] = '\0';
+ snprintf(sum->product, MAX_PROD_LEN, "%s",
+ _("Other devices not listed here"));
+ sum->product[MAX_PROD_LEN - 1] = '\0';
+ }
+ }
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Display memory and swap statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in jiffies.
+ ***************************************************************************
+ */
+__print_funct_t print_pwr_usb_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_pwr_usb_stats(a, curr, FALSE);
+}
+
+/*
+ ***************************************************************************
+ * Display average memory statistics.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @prev Index in array where stats used as reference are.
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in jiffies.
+ ***************************************************************************
+ */
+__print_funct_t print_avg_pwr_usb_stats(struct activity *a, int prev, int curr,
+ unsigned long long itv)
+{
+ stub_print_pwr_usb_stats(a, 2, TRUE);
+}
(struct activity *, int, int, unsigned long long);
extern __print_funct_t print_pwr_wghfreq_stats
(struct activity *, int, int, unsigned long long);
+extern __print_funct_t print_pwr_usb_stats
+ (struct activity *, int, int, unsigned long long);
/* Functions used to display average statistics */
extern __print_funct_t print_avg_memory_stats
(struct activity *, int, int, unsigned long long);
extern __print_funct_t print_avg_huge_stats
(struct activity *, int, int, unsigned long long);
+extern __print_funct_t print_avg_pwr_usb_stats
+ (struct activity *, int, int, unsigned long long);
#endif /* _PR_STATS_H */
fclose(fp);
}
+/*
+ ***************************************************************************
+ * Read current USB device data.
+ *
+ * IN:
+ * @st_pwr_usb Structure where stats will be saved.
+ * @usb_device File name for current USB device.
+ *
+ * OUT:
+ * @st_pwr_usb Structure with statistics.
+ ***************************************************************************
+ */
+void read_usb_stats(struct stats_pwr_usb *st_pwr_usb, char *usb_device)
+{
+ int l;
+ FILE *fp;
+ char filename[MAX_PF_NAME];
+
+ /* Get USB device bus number */
+ sscanf(usb_device, "%u", &st_pwr_usb->bus_nr);
+
+ /* Read USB device vendor ID */
+ snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
+ SYSFS_USBDEV, usb_device, SYSFS_IDVENDOR);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ fscanf(fp, "%x",
+ &st_pwr_usb->vendor_id);
+ fclose(fp);
+ }
+
+ /* Read USB device product ID */
+ snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
+ SYSFS_USBDEV, usb_device, SYSFS_IDPRODUCT);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ fscanf(fp, "%x",
+ &st_pwr_usb->product_id);
+ fclose(fp);
+ }
+
+ /* Read USB device max power consumption */
+ snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
+ SYSFS_USBDEV, usb_device, SYSFS_BMAXPOWER);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ fscanf(fp, "%u",
+ &st_pwr_usb->bmaxpower);
+ fclose(fp);
+ }
+
+ /* Read USB device manufacturer */
+ snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
+ SYSFS_USBDEV, usb_device, SYSFS_MANUFACTURER);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ fgets(st_pwr_usb->manufacturer, MAX_MANUF_LEN - 1, fp);
+ fclose(fp);
+ if ((l = strlen(st_pwr_usb->manufacturer)) > 0) {
+ /* Remove trailing CR */
+ st_pwr_usb->manufacturer[l - 1] = '\0';
+ }
+ }
+
+ /* Read USB device product */
+ snprintf(filename, MAX_PF_NAME, "%s/%s/%s",
+ SYSFS_USBDEV, usb_device, SYSFS_PRODUCT);
+ if ((fp = fopen(filename, "r")) != NULL) {
+ fgets(st_pwr_usb->product, MAX_PROD_LEN - 1, fp);
+ fclose(fp);
+ if ((l = strlen(st_pwr_usb->product)) > 0) {
+ /* Remove trailing CR */
+ st_pwr_usb->product[l - 1] = '\0';
+ }
+ }
+}
+
+/*
+ ***************************************************************************
+ * Read USB devices statistics.
+ *
+ * IN:
+ * @st_pwr_usb Structure where stats will be saved.
+ * @nbr Total number of USB devices.
+ *
+ * OUT:
+ * @st_pwr_usb Structure with statistics.
+ ***************************************************************************
+ */
+void read_bus_usb_dev(struct stats_pwr_usb *st_pwr_usb, int nbr)
+{
+ DIR *dir;
+ struct dirent *drd;
+ struct stats_pwr_usb *st_pwr_usb_j;
+ int j = 0;
+
+ /* Open relevant /sys directory */
+ if ((dir = opendir(SYSFS_USBDEV)) == NULL)
+ return;
+
+ /* Get current file entry */
+ while ((drd = readdir(dir)) != NULL) {
+
+ if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
+ if (j < nbr) {
+ /* Read current USB device data */
+ st_pwr_usb_j = st_pwr_usb + j;
+ read_usb_stats(st_pwr_usb_j, drd->d_name);
+ j++;
+ }
+ else
+ break;
+ }
+ }
+
+ /* Close directory */
+ closedir(dir);
+}
+
/*
***************************************************************************
* Read machine uptime, independently of the number of processors.
return freq;
}
+
+/*
+ ***************************************************************************
+ * Count number of USB devices in /sys/bus/usb/devices.
+ *
+ * RETURNS:
+ * Number of USB devices plugged into the system.
+ * Don't count USB root hubs.
+ * Return -1 if directory doesn't exist in sysfs.
+ ***************************************************************************
+ */
+int get_usb_nr(void)
+{
+ DIR *dir;
+ struct dirent *drd;
+ int usb = 0;
+
+ /* Open relevant /sys directory */
+ if ((dir = opendir(SYSFS_USBDEV)) == NULL)
+ return -1;
+
+ /* Get current file entry */
+ while ((drd = readdir(dir)) != NULL) {
+
+ if (isdigit(drd->d_name[0]) && !strchr(drd->d_name, ':')) {
+ usb++;
+ }
+ }
+
+ /* Close directory */
+ closedir(dir);
+
+ return usb;
+}
/* Maximum length of network interface name */
#define MAX_IFACE_LEN IFNAMSIZ
+/* Maximum length of USB manufacturer string */
+#define MAX_MANUF_LEN 24
+/* Maximum length of USB product string */
+#define MAX_PROD_LEN 48
#define CNT_DEV 0
#define CNT_PART 1
#define STATS_PWR_WGHFREQ_SIZE (sizeof(struct stats_pwr_wghfreq))
+/*
+ * Structure for USB devices plugged into the system.
+ */
+struct stats_pwr_usb {
+ unsigned int bus_nr __attribute__ ((aligned (4)));
+ unsigned int vendor_id __attribute__ ((packed));
+ unsigned int product_id __attribute__ ((packed));
+ unsigned int bmaxpower __attribute__ ((packed));
+ char manufacturer[MAX_MANUF_LEN];
+ char product[MAX_PROD_LEN];
+};
+
+#define STATS_PWR_USB_SIZE (sizeof(struct stats_pwr_usb))
+
/*
***************************************************************************
* Prototypes for functions used to read system statistics
read_meminfo_huge(struct stats_huge *);
extern void
read_time_in_state(struct stats_pwr_wghfreq *, int, int);
+extern void
+ read_bus_usb_dev(struct stats_pwr_usb *, int);
/*
***************************************************************************
get_irqcpu_nr(char *, int, int);
extern int
get_freq_nr(void);
+extern int
+ get_usb_nr(void);
#endif /* _RD_STATS_H */
* does: load a static Cons with values using the t parameter to
* guide pulling values from the arglist
*
- * return: the address of it's static Cons. If you need to keep
+ * return: the address of its static Cons. If you need to keep
* the contents of this Cons, copy it somewhere before calling
* cons() against to avoid overwrite.
* ie. don't do this: f( cons( iv, i, j ), cons( iv, a, b ) );
(spc->temp_max - spc->temp_min) ?
(spc->temp - spc->temp_min) / (spc->temp_max - spc->temp_min) * 100 :
0.0);
-
}
else {
render(isdb, pre, PT_NOFLAG,
(spc->in_max - spc->in_min) ?
(spc->in - spc->in_min) / (spc->in_max - spc->in_min) * 100 :
0.0);
-
}
else {
render(isdb, pre, PT_NOFLAG,
}
}
}
+
+/*
+ ***************************************************************************
+ * Display USB devices statistics in selected format.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @isdb Flag, true if db printing, false if ppc printing.
+ * @pre Prefix string for output entries
+ * @curr Index in array for current sample statistics.
+ * @itv Interval of time in jiffies.
+ ***************************************************************************
+ */
+__print_funct_t render_pwr_usb_stats(struct activity *a, int isdb, char *pre,
+ int curr, unsigned long long itv)
+{
+/*
+FIXME
+*/
+}
(struct activity *, int, char *, int, unsigned long long);
extern __print_funct_t render_pwr_wghfreq_stats
(struct activity *, int, char *, int, unsigned long long);
+extern __print_funct_t render_pwr_usb_stats
+ (struct activity *, int, char *, int, unsigned long long);
#endif /* _RNDR_STATS_H */
*/
/* Number of activities */
-#define NR_ACT 35
+#define NR_ACT 36
/* Activities */
#define A_CPU 1
#define A_PWR_IN 33
#define A_HUGE 34
#define A_PWR_WGHFREQ 35
+#define A_PWR_USB 36
/* Macro used to flag an activity that should be collected */
#define K_SNMP "SNMP"
#define K_IPV6 "IPV6"
#define K_POWER "POWER"
+#define K_USB "USB"
/* Groups of activities */
#define G_DEFAULT 0x00
#define NR_SERIAL_PREALLOC 2
#define NR_DISK_PREALLOC 3
#define NR_FREQ_PREALLOC 0
+#define NR_USB_PREALLOC 5
#define UTSNAME_LEN 65
#define TIMESTAMP_LEN 16
wrap_get_in_nr(struct activity *);
extern __nr_t
wrap_get_freq_nr(struct activity *);
-
+extern __nr_t
+ wrap_get_usb_nr(struct activity *);
+
/* Functions used to read activities statistics */
extern __read_funct_t
wrap_read_stat_cpu(struct activity *);
wrap_read_meminfo_huge(struct activity *);
extern __read_funct_t
wrap_read_time_in_state(struct activity *);
+extern __read_funct_t
+ wrap_read_bus_usb_dev(struct activity *);
/* Other functions */
extern void
else if (!strcmp(t, K_FREQ)) {
SELECT_ACTIVITY(A_PWR_WGHFREQ);
}
+ else if (!strcmp(t, K_USB)) {
+ SELECT_ACTIVITY(A_PWR_USB);
+ }
else if (!strcmp(t, K_ALL)) {
SELECT_ACTIVITY(A_PWR_CPUFREQ);
SELECT_ACTIVITY(A_PWR_FAN);
SELECT_ACTIVITY(A_PWR_IN);
SELECT_ACTIVITY(A_PWR_TEMP);
SELECT_ACTIVITY(A_PWR_WGHFREQ);
+ SELECT_ACTIVITY(A_PWR_USB);
}
else
return 1;
return;
}
+/*
+ ***************************************************************************
+ * Read USB devices statistics.
+ *
+ * IN:
+ * @a Activity structure.
+ *
+ * OUT:
+ * @a Activity structure with statistics.
+ ***************************************************************************
+ */
+__read_funct_t wrap_read_bus_usb_dev(struct activity *a)
+{
+ struct stats_pwr_usb *st_pwr_usb
+ = (struct stats_pwr_usb *) a->_buf0;
+
+ /* Read USB devices stats */
+ read_bus_usb_dev(st_pwr_usb, a->nr);
+
+ return;
+}
+
/*
***************************************************************************
* Count number of interrupts that are in /proc/stat file.
* Count number of possible frequencies for CPU#0.
*
* IN:
- * @a Activity structure.
+ * @a Activity structure.
*
* RETURNS:
* Number of CPU frequencies + a pre-allocation constant.
return 0;
}
+
+/*
+ ***************************************************************************
+ * Count number of USB devices plugged into the system.
+ *
+ * IN:
+ * @a Activity structure.
+ *
+ * RETURNS:
+ * Number of USB devices + a pre-allocation constant.
+ ***************************************************************************
+ */
+__nr_t wrap_get_usb_nr(struct activity *a)
+{
+ __nr_t n = 0;
+
+ if ((n = get_usb_nr()) >= 0)
+ /* Return a positive number even if no USB devices have been found */
+ return (n + NR_USB_PREALLOC);
+
+ return 0;
+}
"\t\tFAN\tFans speed\n"
"\t\tFREQ\tCPU average clock frequency\n"
"\t\tIN\tVoltage inputs\n"
- "\t\tTEMP\tDevices temperature\n"));
+ "\t\tTEMP\tDevices temperature\n"
+ "\t\tUSB\tUSB devices plugged into the system\n"));
printf(_("\t-n { <keyword> [,...] | ALL }\n"
"\t\tNetwork statistics\n"
"\t\tKeywords are:\n"
xml_markup_power_management(tab, CLOSE_XML_MARKUP);
}
}
+
+/*
+ ***************************************************************************
+ * Display USB devices statistics in XML.
+ *
+ * IN:
+ * @a Activity structure with statistics.
+ * @curr Index in array for current sample statistics.
+ * @tab Indentation in XML output.
+ * @itv Interval of time in jiffies.
+ ***************************************************************************
+ */
+__print_funct_t xml_print_pwr_usb_stats(struct activity *a, int curr, int tab,
+ unsigned long long itv)
+{
+ /* FIXME */
+}
\ No newline at end of file
(struct activity *, int, int, unsigned long long);
extern __print_funct_t xml_print_pwr_wghfreq_stats
(struct activity *, int, int, unsigned long long);
+extern __print_funct_t xml_print_pwr_usb_stats
+ (struct activity *, int, int, unsigned long long);
#endif /* _XML_STATS_H */