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