uisqueue.h revision b06bdf7d5bd4f817b481674d69a63174279e6662
1/* uisqueue.h 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/* 19 * Unisys IO Virtualization header NOTE: This file contains only Linux 20 * specific structs. All OS-independent structs are in iochannel.h.xx 21 */ 22 23#ifndef __UISQUEUE_H__ 24#define __UISQUEUE_H__ 25 26#include "linux/version.h" 27#include "iochannel.h" 28#include "uniklog.h" 29#include <linux/atomic.h> 30#include <linux/semaphore.h> 31#include <linux/uuid.h> 32 33#include "controlvmchannel.h" 34#include "controlvmcompletionstatus.h" 35 36struct uisqueue_info { 37 38 CHANNEL_HEADER __iomem *chan; 39 /* channel containing queues in which scsi commands & 40 * responses are queued 41 */ 42 U64 packets_sent; 43 U64 packets_received; 44 U64 interrupts_sent; 45 U64 interrupts_received; 46 U64 max_not_empty_cnt; 47 U64 total_wakeup_cnt; 48 U64 non_empty_wakeup_cnt; 49 50 struct { 51 SIGNAL_QUEUE_HEADER Reserved1; /* */ 52 SIGNAL_QUEUE_HEADER Reserved2; /* */ 53 } safe_uis_queue; 54 unsigned int (*send_int_if_needed)(struct uisqueue_info *info, 55 unsigned int whichcqueue, 56 unsigned char issueInterruptIfEmpty, 57 U64 interruptHandle, 58 unsigned char io_termination); 59}; 60 61/* uisqueue_put_cmdrsp_with_lock_client queues a commmand or response 62 * to the specified queue, at the tail if the queue is full but 63 * oktowait == 0, then it return 0 indicating failure. otherwise it 64 * wait for the queue to become non-full. If command is queued, return 65 * 1 for success. 66 */ 67#define DONT_ISSUE_INTERRUPT 0 68#define ISSUE_INTERRUPT 1 69 70#define DONT_WAIT 0 71#define OK_TO_WAIT 1 72#define UISLIB_LOCK_PREFIX \ 73 ".section .smp_locks,\"a\"\n" \ 74 _ASM_ALIGN "\n" \ 75 _ASM_PTR "661f\n" /* address */ \ 76 ".previous\n" \ 77 "661:\n\tlock; " 78 79unsigned long long uisqueue_InterlockedOr(unsigned long long __iomem *Target, 80 unsigned long long Set); 81unsigned long long uisqueue_InterlockedAnd(unsigned long long __iomem *Target, 82 unsigned long long Set); 83 84unsigned int uisqueue_send_int_if_needed(struct uisqueue_info *pqueueinfo, 85 unsigned int whichqueue, 86 unsigned char issueInterruptIfEmpty, 87 U64 interruptHandle, 88 unsigned char io_termination); 89 90int uisqueue_put_cmdrsp_with_lock_client(struct uisqueue_info *queueinfo, 91 struct uiscmdrsp *cmdrsp, 92 unsigned int queue, 93 void *insertlock, 94 unsigned char issueInterruptIfEmpty, 95 U64 interruptHandle, 96 char oktowait, 97 u8 *channelId); 98 99/* uisqueue_get_cmdrsp gets the cmdrsp entry at the head of the queue 100 * and copies it to the area pointed by cmdrsp param. 101 * returns 0 if queue is empty, 1 otherwise 102 */ 103int 104 105uisqueue_get_cmdrsp(struct uisqueue_info *queueinfo, void *cmdrsp, 106 unsigned int queue); 107 108#define MAX_NAME_SIZE_UISQUEUE 64 109 110struct extport_info { 111 u8 valid:1; 112 /* if 1, indicates this extport slot is occupied 113 * if 0, indicates that extport slot is unoccupied */ 114 115 U32 num_devs_using; 116 /* When extport is added, this is set to 0. For exports 117 * located in NETWORK switches: 118 * Each time a VNIC, i.e., intport, is added to the switch this 119 * is used to assign a pref_pnic for the VNIC and when assigned 120 * to a VNIC this counter is incremented. When a VNIC is 121 * deleted, the extport corresponding to the VNIC's pref_pnic 122 * is located and its num_devs_using is decremented. For VNICs, 123 * num_devs_using is basically used to load-balance transmit 124 * traffic from VNICs. 125 */ 126 127 struct switch_info *swtch; 128 struct PciId pci_id; 129 char name[MAX_NAME_SIZE_UISQUEUE]; 130 union { 131 struct vhba_wwnn wwnn; 132 unsigned char macaddr[MAX_MACADDR_LEN]; 133 }; 134}; 135 136struct device_info { 137 void __iomem *chanptr; 138 U64 channelAddr; 139 U64 channelBytes; 140 uuid_le channelTypeGuid; 141 uuid_le devInstGuid; 142 struct InterruptInfo intr; 143 struct switch_info *swtch; 144 char devid[30]; /* "vbus<busno>:dev<devno>" */ 145 u16 polling; 146 struct semaphore interrupt_callback_lock; 147 U32 busNo; 148 U32 devNo; 149 int (*interrupt)(void *); 150 void *interrupt_context; 151 void *private_data; 152 struct list_head list_polling_device_channels; 153 unsigned long long moved_to_tail_cnt; 154 unsigned long long first_busy_cnt; 155 unsigned long long last_on_list_cnt; 156}; 157 158typedef enum { 159 RECOVERY_LAN = 1, 160 IB_LAN = 2 161} SWITCH_TYPE; 162 163struct bus_info { 164 U32 busNo, deviceCount; 165 struct device_info **device; 166 U64 guestHandle, recvBusInterruptHandle; 167 uuid_le busInstGuid; 168 ULTRA_VBUS_CHANNEL_PROTOCOL __iomem *pBusChannel; 169 int busChannelBytes; 170 struct proc_dir_entry *proc_dir; /* proc/uislib/vbus/<x> */ 171 struct proc_dir_entry *proc_info; /* proc/uislib/vbus/<x>/info */ 172 char name[25]; 173 char partitionName[99]; 174 struct bus_info *next; 175 u8 localVnic; /* 1 if local vnic created internally 176 * by IOVM; 0 otherwise... */ 177}; 178 179#define DEDICATED_SWITCH(pSwitch) ((pSwitch->extPortCount == 1) && \ 180 (pSwitch->intPortCount == 1)) 181 182struct sn_list_entry { 183 struct uisscsi_dest pdest; /* scsi bus, target, lun for 184 * phys disk */ 185 u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical 186 * disk.. The length is always 187 * MAX_SERIAL_NUM, padded with 188 * spaces */ 189 struct sn_list_entry *next; 190}; 191 192struct networkPolicy { 193 U32 promiscuous:1; 194 U32 macassign:1; 195 U32 peerforwarding:1; 196 U32 nonotify:1; 197 U32 standby:1; 198 U32 callhome:2; 199 char ip_addr[30]; 200}; 201 202/* 203 * IO messages sent to UisnicControlChanFunc & UissdControlChanFunc by 204 * code that processes the ControlVm channel messages. 205 */ 206 207 208typedef enum { 209 IOPART_ADD_VNIC, 210 IOPART_DEL_VNIC, 211 IOPART_DEL_ALL_VNICS, 212 IOPART_ADD_VHBA, 213 IOPART_ADD_VDISK, 214 IOPART_DEL_VHBA, 215 IOPART_DEL_VDISK, 216 IOPART_DEL_ALL_VDISKS_FOR_VHBA, 217 IOPART_DEL_ALL_VHBAS, 218 IOPART_ATTACH_PHBA, 219 IOPART_DETACH_PHBA, /* 10 */ 220 IOPART_ATTACH_PNIC, 221 IOPART_DETACH_PNIC, 222 IOPART_DETACH_VHBA, 223 IOPART_DETACH_VNIC, 224 IOPART_PAUSE_VDISK, 225 IOPART_RESUME_VDISK, 226 IOPART_ADD_DEVICE, /* add generic device */ 227 IOPART_DEL_DEVICE, /* del generic device */ 228} IOPART_MSG_TYPE; 229 230struct add_virt_iopart { 231 void *chanptr; /* pointer to data channel */ 232 U64 guestHandle; /* used to convert guest physical 233 * address to real physical address 234 * for DMA, for ex. */ 235 U64 recvBusInterruptHandle; /* used to register to receive 236 * bus level interrupts. */ 237 struct InterruptInfo intr; /* contains recv & send 238 * interrupt info */ 239 /* recvInterruptHandle is used to register to receive 240 * interrupts on the data channel. Used by GuestLinux/Windows 241 * IO drivers to connect to interrupt. sendInterruptHandle is 242 * used by IOPart drivers as parameter to 243 * Issue_VMCALL_IO_QUEUE_TRANSITION to interrupt thread in 244 * guest linux/windows IO drivers when data channel queue for 245 * vhba/vnic goes from EMPTY to NON-EMPTY. */ 246 struct switch_info *swtch; /* pointer to the virtual 247 * switch to which the vnic is 248 * connected */ 249 250 u8 useG2GCopy; /* Used to determine if a virtual HBA 251 * needs to use G2G copy. */ 252 u8 Filler[7]; 253 254 U32 busNo; 255 U32 devNo; 256 char *params; 257 ulong params_bytes; 258 259}; 260 261struct add_vdisk_iopart { 262 void *chanptr; /* pointer to data channel */ 263 int implicit; 264 struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ 265 struct uisscsi_dest pdest; /* scsi bus, target, lun for phys disk */ 266 u8 sernum[MAX_SERIAL_NUM]; /* serial num of physical disk */ 267 U32 serlen; /* length of serial num */ 268 U32 busNo; 269 U32 devNo; 270}; 271 272struct del_vdisk_iopart { 273 void *chanptr; /* pointer to data channel */ 274 struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ 275 U32 busNo; 276 U32 devNo; 277}; 278 279struct del_virt_iopart { 280 void *chanptr; /* pointer to data channel */ 281 U32 busNo; 282 U32 devNo; 283}; 284 285struct det_virt_iopart { /* detach internal port */ 286 void *chanptr; /* pointer to data channel */ 287 struct switch_info *swtch; 288}; 289 290struct paures_vdisk_iopart { 291 void *chanptr; /* pointer to data channel */ 292 struct uisscsi_dest vdest; /* scsi bus, target, lun for virt disk */ 293}; 294 295struct add_switch_iopart { /* add switch */ 296 struct switch_info *swtch; 297 char *params; 298 ulong params_bytes; 299}; 300 301struct del_switch_iopart { /* destroy switch */ 302 struct switch_info *swtch; 303}; 304 305struct io_msgs { 306 307 IOPART_MSG_TYPE msgtype; 308 309 /* additional params needed by some messages */ 310 union { 311 struct add_virt_iopart add_vhba; 312 struct add_virt_iopart add_vnic; 313 struct add_vdisk_iopart add_vdisk; 314 struct del_virt_iopart del_vhba; 315 struct del_virt_iopart del_vnic; 316 struct det_virt_iopart det_vhba; 317 struct det_virt_iopart det_vnic; 318 struct del_vdisk_iopart del_vdisk; 319 struct del_virt_iopart del_all_vdisks_for_vhba; 320 struct add_virt_iopart add_device; 321 struct del_virt_iopart del_device; 322 struct det_virt_iopart det_intport; 323 struct add_switch_iopart add_switch; 324 struct del_switch_iopart del_switch; 325 struct extport_info *extPort; /* for attach or detach 326 * pnic/generic delete all 327 * vhbas/allvnics need no 328 * parameters */ 329 struct paures_vdisk_iopart paures_vdisk; 330 }; 331}; 332 333/* 334* Guest messages sent to VirtControlChanFunc by code that processes 335* the ControlVm channel messages. 336*/ 337 338typedef enum { 339 GUEST_ADD_VBUS, 340 GUEST_ADD_VHBA, 341 GUEST_ADD_VNIC, 342 GUEST_DEL_VBUS, 343 GUEST_DEL_VHBA, 344 GUEST_DEL_VNIC, 345 GUEST_DEL_ALL_VHBAS, 346 GUEST_DEL_ALL_VNICS, 347 GUEST_DEL_ALL_VBUSES, /* deletes all vhbas & vnics on all 348 * buses and deletes all buses */ 349 GUEST_PAUSE_VHBA, 350 GUEST_PAUSE_VNIC, 351 GUEST_RESUME_VHBA, 352 GUEST_RESUME_VNIC 353} GUESTPART_MSG_TYPE; 354 355struct add_vbus_guestpart { 356 void __iomem *chanptr; /* pointer to data channel for bus - 357 * NOT YET USED */ 358 U32 busNo; /* bus number to be created/deleted */ 359 U32 deviceCount; /* max num of devices on bus */ 360 uuid_le busTypeGuid; /* indicates type of bus */ 361 uuid_le busInstGuid; /* instance guid for device */ 362}; 363 364struct del_vbus_guestpart { 365 U32 busNo; /* bus number to be deleted */ 366 /* once we start using the bus's channel, add can dump busNo 367 * into the channel header and then delete will need only one 368 * parameter, chanptr. */ 369}; 370 371struct add_virt_guestpart { 372 void __iomem *chanptr; /* pointer to data channel */ 373 U32 busNo; /* bus number for the operation */ 374 U32 deviceNo; /* number of device on the bus */ 375 uuid_le devInstGuid; /* instance guid for device */ 376 struct InterruptInfo intr; /* recv/send interrupt info */ 377 /* recvInterruptHandle contains info needed in order to 378 * register to receive interrupts on the data channel. 379 * sendInterruptHandle contains handle which is provided to 380 * monitor VMCALL that will cause an interrupt to be generated 381 * for the other end. 382 */ 383}; 384 385struct pause_virt_guestpart { 386 void __iomem *chanptr; /* pointer to data channel */ 387}; 388 389struct resume_virt_guestpart { 390 void __iomem *chanptr; /* pointer to data channel */ 391}; 392 393struct del_virt_guestpart { 394 void __iomem *chanptr; /* pointer to data channel */ 395}; 396 397struct init_chipset_guestpart { 398 U32 busCount; /* indicates the max number of busses */ 399 U32 switchCount; /* indicates the max number of switches */ 400}; 401 402struct guest_msgs { 403 404 GUESTPART_MSG_TYPE msgtype; 405 406 /* additional params needed by messages */ 407 union { 408 struct add_vbus_guestpart add_vbus; 409 struct add_virt_guestpart add_vhba; 410 struct add_virt_guestpart add_vnic; 411 struct pause_virt_guestpart pause_vhba; 412 struct pause_virt_guestpart pause_vnic; 413 struct resume_virt_guestpart resume_vhba; 414 struct resume_virt_guestpart resume_vnic; 415 struct del_vbus_guestpart del_vbus; 416 struct del_virt_guestpart del_vhba; 417 struct del_virt_guestpart del_vnic; 418 struct del_vbus_guestpart del_all_vhbas; 419 struct del_vbus_guestpart del_all_vnics; 420 /* del_all_vbuses needs no parameters */ 421 }; 422 struct init_chipset_guestpart init_chipset; 423 424}; 425 426#ifndef __xg 427#define __xg(x) ((volatile long *)(x)) 428#endif 429 430/* 431* Below code is a copy of Linux kernel's cmpxchg function located at 432* this place 433* http://tcsxeon:8080/source/xref/00trunk-AppOS-linux/include/asm-x86/cmpxchg_64.h#84 434* Reason for creating our own version of cmpxchg along with 435* UISLIB_LOCK_PREFIX is to make the operation atomic even for non SMP 436* guests. 437*/ 438 439#define uislibcmpxchg64(p, o, n, s) cmpxchg(p, o, n) 440 441#endif /* __UISQUEUE_H__ */ 442