3 * Copyright (C) 2010 - 2013 UNISYS CORPORATION
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.
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
19 * Unisys Virtual HBA utilities header
22 #ifndef __UISUTILS__H__
23 #define __UISUTILS__H__
24 #include <linux/string.h>
26 #include <linux/sched.h>
27 #include <linux/gfp.h>
28 #include <linux/uuid.h>
30 #include "vmcallinterface.h"
32 #include "uisthread.h"
34 #include "diagnostics/appos_subsystems.h"
35 #include "vbusdeviceinfo.h"
36 #include <linux/atomic.h>
38 /* This is the MAGIC number stuffed by virthba in host->this_id. Used to
39 * identify virtual hbas.
41 #define UIS_MAGIC_VHBA 707
43 /* global function pointers that act as callback functions into
44 * uisnicmod, uissdmod, and virtpcimod
46 extern int (*UisnicControlChanFunc
)(struct io_msgs
*);
47 extern int (*UissdControlChanFunc
)(struct io_msgs
*);
48 extern int (*VirtControlChanFunc
)(struct guest_msgs
*);
50 /* Return values of above callback functions: */
51 #define CCF_ERROR 0 /* completed and failed */
52 #define CCF_OK 1 /* completed successfully */
53 #define CCF_PENDING 2 /* operation still pending */
54 extern atomic_t UisUtils_Registered_Services
;
56 typedef unsigned int MACARRAY
[MAX_MACADDR_LEN
];
57 typedef struct ReqHandlerInfo_struct
{
58 uuid_le switchTypeGuid
;
59 int (*controlfunc
)(struct io_msgs
*);
60 unsigned long min_channel_bytes
;
61 int (*Server_Channel_Ok
)(unsigned long channelBytes
);
62 int (*Server_Channel_Init
)
63 (void *x
, unsigned char *clientStr
, u32 clientStrLen
, u64 bytes
);
64 char switch_type_name
[99];
65 struct list_head list_link
; /* links into ReqHandlerInfo_list */
68 ReqHandlerInfo_t
*ReqHandlerAdd(uuid_le switchTypeGuid
,
69 const char *switch_type_name
,
70 int (*controlfunc
)(struct io_msgs
*),
71 unsigned long min_channel_bytes
,
72 int (*Server_Channel_Ok
)(unsigned long
74 int (*Server_Channel_Init
)
75 (void *x
, unsigned char *clientStr
,
76 u32 clientStrLen
, u64 bytes
));
77 ReqHandlerInfo_t
*ReqHandlerFind(uuid_le switchTypeGuid
);
78 int ReqHandlerDel(uuid_le switchTypeGuid
);
80 #define uislib_ioremap_cache(addr, size) \
81 dbg_ioremap_cache(addr, size, __FILE__, __LINE__)
83 static inline void __iomem
*
84 dbg_ioremap_cache(u64 addr
, unsigned long size
, char *file
, int line
)
88 new = ioremap_cache(addr
, size
);
92 #define uislib_ioremap(addr, size) dbg_ioremap(addr, size, __FILE__, __LINE__)
95 dbg_ioremap(u64 addr
, unsigned long size
, char *file
, int line
)
99 new = ioremap(addr
, size
);
103 #define uislib_iounmap(addr) dbg_iounmap(addr, __FILE__, __LINE__)
106 dbg_iounmap(void __iomem
*addr
, char *file
, int line
)
111 #define PROC_READ_BUFFER_SIZE 131072 /* size of the buffer to allocate to
112 * hold all of /proc/XXX/info */
113 int uisutil_add_proc_line_ex(int *total
, char **buffer
, int *buffer_remaining
,
116 int uisctrl_register_req_handler(int type
, void *fptr
,
117 ULTRA_VBUS_DEVICEINFO
*chipset_driver_info
);
118 int uisctrl_register_req_handler_ex(uuid_le switchTypeGuid
,
119 const char *switch_type_name
,
120 int (*fptr
)(struct io_msgs
*),
121 unsigned long min_channel_bytes
,
122 int (*Server_Channel_Ok
)(unsigned long
124 int (*Server_Channel_Init
)
125 (void *x
, unsigned char *clientStr
,
126 u32 clientStrLen
, u64 bytes
),
127 ULTRA_VBUS_DEVICEINFO
*chipset_DriverInfo
);
129 int uisctrl_unregister_req_handler_ex(uuid_le switchTypeGuid
);
130 unsigned char *util_map_virt(struct phys_info
*sg
);
131 void util_unmap_virt(struct phys_info
*sg
);
132 unsigned char *util_map_virt_atomic(struct phys_info
*sg
);
133 void util_unmap_virt_atomic(void *buf
);
134 int uislib_server_inject_add_vnic(u32 switchNo
, u32 BusNo
, u32 numIntPorts
,
135 u32 numExtPorts
, MACARRAY pmac
[],
136 pCHANNEL_HEADER
**chan
);
137 void uislib_server_inject_del_vnic(u32 switchNo
, u32 busNo
, u32 numIntPorts
,
139 int uislib_client_inject_add_bus(u32 busNo
, uuid_le instGuid
,
140 u64 channelAddr
, ulong nChannelBytes
);
141 int uislib_client_inject_del_bus(u32 busNo
);
143 int uislib_client_inject_add_vhba(u32 busNo
, u32 devNo
,
144 u64 phys_chan_addr
, u32 chan_bytes
,
145 int is_test_addr
, uuid_le instGuid
,
146 struct InterruptInfo
*intr
);
147 int uislib_client_inject_pause_vhba(u32 busNo
, u32 devNo
);
148 int uislib_client_inject_resume_vhba(u32 busNo
, u32 devNo
);
149 int uislib_client_inject_del_vhba(u32 busNo
, u32 devNo
);
150 int uislib_client_inject_add_vnic(u32 busNo
, u32 devNo
,
151 u64 phys_chan_addr
, u32 chan_bytes
,
152 int is_test_addr
, uuid_le instGuid
,
153 struct InterruptInfo
*intr
);
154 int uislib_client_inject_pause_vnic(u32 busNo
, u32 devNo
);
155 int uislib_client_inject_resume_vnic(u32 busNo
, u32 devNo
);
156 int uislib_client_inject_del_vnic(u32 busNo
, u32 devNo
);
157 #ifdef STORAGE_CHANNEL
158 u64
uislib_storage_channel(int client_id
);
160 int uislib_get_owned_pdest(struct uisscsi_dest
*pdest
);
162 int uislib_send_event(CONTROLVM_ID id
, CONTROLVM_MESSAGE_PACKET
*event
);
164 /* structure used by vhba & vnic to keep track of queue & thread info */
166 struct uisqueue_info
*queueinfo
;
167 /* this specifies the queue structures for a channel */
168 /* ALLOCATED BY THE OTHER END - WE JUST GET A POINTER TO THE MEMORY */
169 spinlock_t insertlock
;
170 /* currently used only in virtnic when sending data to uisnic */
171 /* to synchronize the inserts into the signal queue */
172 struct uisthread_info threadinfo
;
173 /* this specifies the thread structures used by the thread that */
174 /* handles this channel */
177 /* this is the wait code for all the threads - it is used to get
178 * something from a queue choices: wait_for_completion_interruptible,
179 * _timeout, interruptible_timeout
181 #define UIS_THREAD_WAIT_MSEC(x) { \
182 set_current_state(TASK_INTERRUPTIBLE); \
183 schedule_timeout(msecs_to_jiffies(x)); \
185 #define UIS_THREAD_WAIT_USEC(x) { \
186 set_current_state(TASK_INTERRUPTIBLE); \
187 schedule_timeout(usecs_to_jiffies(x)); \
189 #define UIS_THREAD_WAIT UIS_THREAD_WAIT_MSEC(5)
190 #define UIS_THREAD_WAIT_SEC(x) { \
191 set_current_state(TASK_INTERRUPTIBLE); \
192 schedule_timeout((x)*HZ); \
195 /* This is a hack until we fix IOVM to initialize the channel header
196 * correctly at DEVICE_CREATE time, INSTEAD OF waiting until
197 * DEVICE_CONFIGURE time.
200 wait_for_valid_guid(uuid_le __iomem
*guid
)
205 memcpy_fromio((void *)&tmpguid
,
206 (void __iomem
*)guid
, sizeof(uuid_le
));
207 if (uuid_le_cmp(tmpguid
, NULL_UUID_LE
) != 0)
209 LOGERR("Waiting for non-0 GUID (why???)...\n");
210 UIS_THREAD_WAIT_SEC(5);
212 LOGERR("OK... GUID is non-0 now\n");
215 /* CopyFragsInfoFromSkb returns the number of entries added to frags array
216 * Returns -1 on failure.
218 unsigned int uisutil_copy_fragsinfo_from_skb(unsigned char *calling_ctx
,
220 unsigned int firstfraglen
,
221 unsigned int frags_max
,
222 struct phys_info frags
[]);
224 static inline unsigned int
225 issue_vmcall_io_controlvm_addr(u64
*control_addr
, u32
*control_bytes
)
227 VMCALL_IO_CONTROLVM_ADDR_PARAMS params
;
228 int result
= VMCALL_SUCCESS
;
231 physaddr
= virt_to_phys(¶ms
);
232 ISSUE_IO_VMCALL(VMCALL_IO_CONTROLVM_ADDR
, physaddr
, result
);
233 if (VMCALL_SUCCESSFUL(result
)) {
234 *control_addr
= params
.ChannelAddress
;
235 *control_bytes
= params
.ChannelBytes
;
240 static inline unsigned int Issue_VMCALL_IO_DIAG_ADDR(u64
*DiagChannelAddress
)
242 VMCALL_IO_DIAG_ADDR_PARAMS params
;
243 int result
= VMCALL_SUCCESS
;
246 physaddr
= virt_to_phys(¶ms
);
247 ISSUE_IO_VMCALL(VMCALL_IO_DIAG_ADDR
, physaddr
, result
);
248 if (VMCALL_SUCCESSFUL(result
))
249 *DiagChannelAddress
= params
.ChannelAddress
;
253 static inline unsigned int
254 Issue_VMCALL_IO_VISORSERIAL_ADDR(u64
*DiagChannelAddress
)
256 VMCALL_IO_VISORSERIAL_ADDR_PARAMS params
;
257 int result
= VMCALL_SUCCESS
;
260 physaddr
= virt_to_phys(¶ms
);
261 ISSUE_IO_VMCALL(VMCALL_IO_VISORSERIAL_ADDR
, physaddr
, result
);
262 if (VMCALL_SUCCESSFUL(result
))
263 *DiagChannelAddress
= params
.ChannelAddress
;
267 static inline s64
Issue_VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET(void)
269 u64 result
= VMCALL_SUCCESS
;
272 ISSUE_IO_VMCALL(VMCALL_QUERY_GUEST_VIRTUAL_TIME_OFFSET
, physaddr
,
277 static inline s64
Issue_VMCALL_MEASUREMENT_DO_NOTHING(void)
279 u64 result
= VMCALL_SUCCESS
;
282 ISSUE_IO_VMCALL(VMCALL_MEASUREMENT_DO_NOTHING
, physaddr
, result
);
287 volatile unsigned long long last_cycles
;
288 unsigned long long delta_sum
[64];
289 unsigned long long delta_cnt
[64];
290 unsigned long long max_delta
[64];
291 unsigned long long min_delta
[64];
294 static inline int Issue_VMCALL_UPDATE_PHYSICAL_TIME(u64 adjustment
)
296 int result
= VMCALL_SUCCESS
;
298 ISSUE_IO_VMCALL(VMCALL_UPDATE_PHYSICAL_TIME
, adjustment
, result
);
302 static inline unsigned int
303 Issue_VMCALL_CHANNEL_MISMATCH(const char *ChannelName
,
304 const char *ItemName
,
305 u32 SourceLineNumber
, const char *path_n_fn
)
307 VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS params
;
308 int result
= VMCALL_SUCCESS
;
310 char *last_slash
= NULL
;
312 strlcpy(params
.ChannelName
, ChannelName
,
313 lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS
, ChannelName
));
314 strlcpy(params
.ItemName
, ItemName
,
315 lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS
, ItemName
));
316 params
.SourceLineNumber
= SourceLineNumber
;
318 last_slash
= strrchr(path_n_fn
, '/');
319 if (last_slash
!= NULL
) {
321 strlcpy(params
.SourceFileName
, last_slash
,
322 lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS
,
325 strlcpy(params
.SourceFileName
,
326 "Cannot determine source filename",
327 lengthof(VMCALL_CHANNEL_VERSION_MISMATCH_PARAMS
,
330 physaddr
= virt_to_phys(¶ms
);
331 ISSUE_IO_VMCALL(VMCALL_CHANNEL_VERSION_MISMATCH
, physaddr
, result
);
335 static inline unsigned int Issue_VMCALL_FATAL_BYE_BYE(void)
337 int result
= VMCALL_SUCCESS
;
340 ISSUE_IO_VMCALL(VMCALL_GENERIC_SURRENDER_QUANTUM_FOREVER
, physaddr
,
345 #define UIS_DAEMONIZE(nam)
346 void *uislib_cache_alloc(struct kmem_cache
*cur_pool
, char *fn
, int ln
);
347 #define UISCACHEALLOC(cur_pool) uislib_cache_alloc(cur_pool, __FILE__, __LINE__)
348 void uislib_cache_free(struct kmem_cache
*cur_pool
, void *p
, char *fn
, int ln
);
349 #define UISCACHEFREE(cur_pool, p) \
350 uislib_cache_free(cur_pool, p, __FILE__, __LINE__)
352 void uislib_enable_channel_interrupts(u32 busNo
, u32 devNo
,
353 int (*interrupt
)(void *),
354 void *interrupt_context
);
355 void uislib_disable_channel_interrupts(u32 busNo
, u32 devNo
);
356 void uislib_force_channel_interrupt(u32 busNo
, u32 devNo
);
358 #endif /* __UISUTILS__H__ */