1/* uisutils.c 2 * 3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION 4 * All rights reserved. 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or (at 9 * your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 14 * NON INFRINGEMENT. See the GNU General Public License for more 15 * details. 16 */ 17 18#include <linux/string.h> 19#include <linux/slab.h> 20#include <linux/types.h> 21#include <linux/uuid.h> 22#include <linux/spinlock.h> 23#include <linux/list.h> 24#include "uisutils.h" 25#include "version.h" 26#include "vbushelper.h" 27#include <linux/skbuff.h> 28#ifdef CONFIG_HIGHMEM 29#include <linux/highmem.h> 30#endif 31 32/* this is shorter than using __FILE__ (full path name) in 33 * debug/info/error messages 34 */ 35#define CURRENT_FILE_PC UISLIB_PC_uisutils_c 36#define __MYFILE__ "uisutils.c" 37 38/* exports */ 39atomic_t uisutils_registered_services = ATOMIC_INIT(0); 40 /* num registrations via 41 * uisctrl_register_req_handler() or 42 * uisctrl_register_req_handler_ex() */ 43 44/*****************************************************/ 45/* Utility functions */ 46/*****************************************************/ 47 48int 49uisutil_add_proc_line_ex(int *total, char **buffer, int *buffer_remaining, 50 char *format, ...) 51{ 52 va_list args; 53 int len; 54 55 va_start(args, format); 56 len = vsnprintf(*buffer, *buffer_remaining, format, args); 57 va_end(args); 58 if (len >= *buffer_remaining) { 59 *buffer += *buffer_remaining; 60 *total += *buffer_remaining; 61 *buffer_remaining = 0; 62 return -1; 63 } 64 *buffer_remaining -= len; 65 *buffer += len; 66 *total += len; 67 return len; 68} 69EXPORT_SYMBOL_GPL(uisutil_add_proc_line_ex); 70 71int 72uisctrl_register_req_handler(int type, void *fptr, 73 struct ultra_vbus_deviceinfo *chipset_driver_info) 74{ 75 switch (type) { 76 case 2: 77 if (fptr) { 78 if (!virt_control_chan_func) 79 atomic_inc(&uisutils_registered_services); 80 virt_control_chan_func = fptr; 81 } else { 82 if (virt_control_chan_func) 83 atomic_dec(&uisutils_registered_services); 84 virt_control_chan_func = NULL; 85 } 86 break; 87 88 default: 89 return 0; 90 } 91 if (chipset_driver_info) 92 bus_device_info_init(chipset_driver_info, "chipset", "uislib", 93 VERSION, NULL); 94 95 return 1; 96} 97EXPORT_SYMBOL_GPL(uisctrl_register_req_handler); 98 99/* 100 * unsigned int uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx, 101 * void *skb_in, 102 * unsigned int firstfraglen, 103 * unsigned int frags_max, 104 * struct phys_info frags[]) 105 * 106 * calling_ctx - input - a string that is displayed to show 107 * who called * this func 108 * void *skb_in - skb whose frag info we're copying type is hidden so we 109 * don't need to include skbbuff in uisutils.h which is 110 * included in non-networking code. 111 * unsigned int firstfraglen - input - length of first fragment in skb 112 * unsigned int frags_max - input - max len of frags array 113 * struct phys_info frags[] - output - frags array filled in on output 114 * return value indicates number of 115 * entries filled in frags 116 */ 117 118static LIST_HEAD(req_handler_info_list); /* list of struct req_handler_info */ 119static DEFINE_SPINLOCK(req_handler_info_list_lock); 120 121struct req_handler_info * 122req_handler_find(uuid_le switch_uuid) 123{ 124 struct list_head *lelt, *tmp; 125 struct req_handler_info *entry = NULL; 126 127 spin_lock(&req_handler_info_list_lock); 128 list_for_each_safe(lelt, tmp, &req_handler_info_list) { 129 entry = list_entry(lelt, struct req_handler_info, list_link); 130 if (uuid_le_cmp(entry->switch_uuid, switch_uuid) == 0) { 131 spin_unlock(&req_handler_info_list_lock); 132 return entry; 133 } 134 } 135 spin_unlock(&req_handler_info_list_lock); 136 return NULL; 137} 138