Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

misc: IBM Virtual Management Channel Driver (VMC)

This driver is a logical device which provides an
interface between the hypervisor and a management
partition. This interface is like a message
passing interface. This management partition
is intended to provide an alternative to HMC-based
system management.

VMC enables the Management LPAR to provide basic
logical partition functions:
- Logical Partition Configuration
- Boot, start, and stop actions for individual
partitions
- Display of partition status
- Management of virtual Ethernet
- Management of virtual Storage
- Basic system management

This driver is to be used for the POWER Virtual
Management Channel Virtual Adapter on the PowerPC
platform. It provides a character device which
allows for both request/response and async message
support through the /dev/ibmvmc node.

Signed-off-by: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
Reviewed-by: Steven Royer <seroyer@linux.vnet.ibm.com>
Reviewed-by: Adam Reznechek <adreznec@linux.vnet.ibm.com>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Tested-by: Taylor Jakobson <tjakobs@us.ibm.com>
Tested-by: Brad Warrum <bwarrum@us.ibm.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bryant G. Ly and committed by
Greg Kroah-Hartman
0eca353e 5b7d1277

+2876
+1
Documentation/ioctl/ioctl-number.txt
··· 327 327 0xCA 80-BF uapi/scsi/cxlflash_ioctl.h 328 328 0xCB 00-1F CBM serial IEC bus in development: 329 329 <mailto:michael.klein@puffin.lb.shuttle.de> 330 + 0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver 330 331 0xCD 01 linux/reiserfs_fs.h 331 332 0xCF 02 fs/cifs/ioctl.c 332 333 0xDB 00-0F drivers/char/mwave/mwavepub.h
+226
Documentation/misc-devices/ibmvmc.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0+ 2 + ====================================================== 3 + IBM Virtual Management Channel Kernel Driver (IBMVMC) 4 + ====================================================== 5 + 6 + :Authors: 7 + Dave Engebretsen <engebret@us.ibm.com>, 8 + Adam Reznechek <adreznec@linux.vnet.ibm.com>, 9 + Steven Royer <seroyer@linux.vnet.ibm.com>, 10 + Bryant G. Ly <bryantly@linux.vnet.ibm.com>, 11 + 12 + Introduction 13 + ============ 14 + 15 + Note: Knowledge of virtualization technology is required to understand 16 + this document. 17 + 18 + A good reference document would be: 19 + 20 + https://openpowerfoundation.org/wp-content/uploads/2016/05/LoPAPR_DRAFT_v11_24March2016_cmt1.pdf 21 + 22 + The Virtual Management Channel (VMC) is a logical device which provides an 23 + interface between the hypervisor and a management partition. This interface 24 + is like a message passing interface. This management partition is intended 25 + to provide an alternative to systems that use a Hardware Management 26 + Console (HMC) - based system management. 27 + 28 + The primary hardware management solution that is developed by IBM relies 29 + on an appliance server named the Hardware Management Console (HMC), 30 + packaged as an external tower or rack-mounted personal computer. In a 31 + Power Systems environment, a single HMC can manage multiple POWER 32 + processor-based systems. 33 + 34 + Management Application 35 + ---------------------- 36 + 37 + In the management partition, a management application exists which enables 38 + a system administrator to configure the system’s partitioning 39 + characteristics via a command line interface (CLI) or Representational 40 + State Transfer Application (REST API's). 41 + 42 + The management application runs on a Linux logical partition on a 43 + POWER8 or newer processor-based server that is virtualized by PowerVM. 44 + System configuration, maintenance, and control functions which 45 + traditionally require an HMC can be implemented in the management 46 + application using a combination of HMC to hypervisor interfaces and 47 + existing operating system methods. This tool provides a subset of the 48 + functions implemented by the HMC and enables basic partition configuration. 49 + The set of HMC to hypervisor messages supported by the management 50 + application component are passed to the hypervisor over a VMC interface, 51 + which is defined below. 52 + 53 + The VMC enables the management partition to provide basic partitioning 54 + functions: 55 + 56 + - Logical Partitioning Configuration 57 + - Start, and stop actions for individual partitions 58 + - Display of partition status 59 + - Management of virtual Ethernet 60 + - Management of virtual Storage 61 + - Basic system management 62 + 63 + Virtual Management Channel (VMC) 64 + -------------------------------- 65 + 66 + A logical device, called the Virtual Management Channel (VMC), is defined 67 + for communicating between the management application and the hypervisor. It 68 + basically creates the pipes that enable virtualization management 69 + software. This device is presented to a designated management partition as 70 + a virtual device. 71 + 72 + This communication device uses Command/Response Queue (CRQ) and the 73 + Remote Direct Memory Access (RDMA) interfaces. A three-way handshake is 74 + defined that must take place to establish that both the hypervisor and 75 + management partition sides of the channel are running prior to 76 + sending/receiving any of the protocol messages. 77 + 78 + This driver also utilizes Transport Event CRQs. CRQ messages are sent 79 + when the hypervisor detects one of the peer partitions has abnormally 80 + terminated, or one side has called H_FREE_CRQ to close their CRQ. 81 + Two new classes of CRQ messages are introduced for the VMC device. VMC 82 + Administrative messages are used for each partition using the VMC to 83 + communicate capabilities to their partner. HMC Interface messages are used 84 + for the actual flow of HMC messages between the management partition and 85 + the hypervisor. As most HMC messages far exceed the size of a CRQ buffer, 86 + a virtual DMA (RMDA) of the HMC message data is done prior to each HMC 87 + Interface CRQ message. Only the management partition drives RDMA 88 + operations; hypervisors never directly cause the movement of message data. 89 + 90 + 91 + Terminology 92 + ----------- 93 + RDMA 94 + Remote Direct Memory Access is DMA transfer from the server to its 95 + client or from the server to its partner partition. DMA refers 96 + to both physical I/O to and from memory operations and to memory 97 + to memory move operations. 98 + CRQ 99 + Command/Response Queue a facility which is used to communicate 100 + between partner partitions. Transport events which are signaled 101 + from the hypervisor to partition are also reported in this queue. 102 + 103 + Example Management Partition VMC Driver Interface 104 + ================================================= 105 + 106 + This section provides an example for the management application 107 + implementation where a device driver is used to interface to the VMC 108 + device. This driver consists of a new device, for example /dev/ibmvmc, 109 + which provides interfaces to open, close, read, write, and perform 110 + ioctl’s against the VMC device. 111 + 112 + VMC Interface Initialization 113 + ---------------------------- 114 + 115 + The device driver is responsible for initializing the VMC when the driver 116 + is loaded. It first creates and initializes the CRQ. Next, an exchange of 117 + VMC capabilities is performed to indicate the code version and number of 118 + resources available in both the management partition and the hypervisor. 119 + Finally, the hypervisor requests that the management partition create an 120 + initial pool of VMC buffers, one buffer for each possible HMC connection, 121 + which will be used for management application session initialization. 122 + Prior to completion of this initialization sequence, the device returns 123 + EBUSY to open() calls. EIO is returned for all open() failures. 124 + 125 + :: 126 + 127 + Management Partition Hypervisor 128 + CRQ INIT 129 + ----------------------------------------> 130 + CRQ INIT COMPLETE 131 + <---------------------------------------- 132 + CAPABILITIES 133 + ----------------------------------------> 134 + CAPABILITIES RESPONSE 135 + <---------------------------------------- 136 + ADD BUFFER (HMC IDX=0,1,..) _ 137 + <---------------------------------------- | 138 + ADD BUFFER RESPONSE | - Perform # HMCs Iterations 139 + ----------------------------------------> - 140 + 141 + VMC Interface Open 142 + ------------------ 143 + 144 + After the basic VMC channel has been initialized, an HMC session level 145 + connection can be established. The application layer performs an open() to 146 + the VMC device and executes an ioctl() against it, indicating the HMC ID 147 + (32 bytes of data) for this session. If the VMC device is in an invalid 148 + state, EIO will be returned for the ioctl(). The device driver creates a 149 + new HMC session value (ranging from 1 to 255) and HMC index value (starting 150 + at index 0 and ranging to 254) for this HMC ID. The driver then does an 151 + RDMA of the HMC ID to the hypervisor, and then sends an Interface Open 152 + message to the hypervisor to establish the session over the VMC. After the 153 + hypervisor receives this information, it sends Add Buffer messages to the 154 + management partition to seed an initial pool of buffers for the new HMC 155 + connection. Finally, the hypervisor sends an Interface Open Response 156 + message, to indicate that it is ready for normal runtime messaging. The 157 + following illustrates this VMC flow: 158 + 159 + :: 160 + 161 + Management Partition Hypervisor 162 + RDMA HMC ID 163 + ----------------------------------------> 164 + Interface Open 165 + ----------------------------------------> 166 + Add Buffer _ 167 + <---------------------------------------- | 168 + Add Buffer Response | - Perform N Iterations 169 + ----------------------------------------> - 170 + Interface Open Response 171 + <---------------------------------------- 172 + 173 + VMC Interface Runtime 174 + --------------------- 175 + 176 + During normal runtime, the management application and the hypervisor 177 + exchange HMC messages via the Signal VMC message and RDMA operations. When 178 + sending data to the hypervisor, the management application performs a 179 + write() to the VMC device, and the driver RDMA’s the data to the hypervisor 180 + and then sends a Signal Message. If a write() is attempted before VMC 181 + device buffers have been made available by the hypervisor, or no buffers 182 + are currently available, EBUSY is returned in response to the write(). A 183 + write() will return EIO for all other errors, such as an invalid device 184 + state. When the hypervisor sends a message to the management, the data is 185 + put into a VMC buffer and an Signal Message is sent to the VMC driver in 186 + the management partition. The driver RDMA’s the buffer into the partition 187 + and passes the data up to the appropriate management application via a 188 + read() to the VMC device. The read() request blocks if there is no buffer 189 + available to read. The management application may use select() to wait for 190 + the VMC device to become ready with data to read. 191 + 192 + :: 193 + 194 + Management Partition Hypervisor 195 + MSG RDMA 196 + ----------------------------------------> 197 + SIGNAL MSG 198 + ----------------------------------------> 199 + SIGNAL MSG 200 + <---------------------------------------- 201 + MSG RDMA 202 + <---------------------------------------- 203 + 204 + VMC Interface Close 205 + ------------------- 206 + 207 + HMC session level connections are closed by the management partition when 208 + the application layer performs a close() against the device. This action 209 + results in an Interface Close message flowing to the hypervisor, which 210 + causes the session to be terminated. The device driver must free any 211 + storage allocated for buffers for this HMC connection. 212 + 213 + :: 214 + 215 + Management Partition Hypervisor 216 + INTERFACE CLOSE 217 + ----------------------------------------> 218 + INTERFACE CLOSE RESPONSE 219 + <---------------------------------------- 220 + 221 + Additional Information 222 + ====================== 223 + 224 + For more information on the documentation for CRQ Messages, VMC Messages, 225 + HMC interface Buffers, and signal messages please refer to the Linux on 226 + Power Architecture Platform Reference. Section F.
+6
MAINTAINERS
··· 6757 6757 S: Supported 6758 6758 F: drivers/scsi/ibmvscsi/ibmvfc* 6759 6759 6760 + IBM Power Virtual Management Channel Driver 6761 + M: Bryant G. Ly <bryantly@linux.vnet.ibm.com> 6762 + M: Steven Royer <seroyer@linux.vnet.ibm.com> 6763 + S: Supported 6764 + F: drivers/misc/ibmvmc.* 6765 + 6760 6766 IBM Power Virtual SCSI Device Drivers 6761 6767 M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com> 6762 6768 L: linux-scsi@vger.kernel.org
+1
arch/powerpc/include/asm/hvcall.h
··· 279 279 #define H_GET_MPP_X 0x314 280 280 #define H_SET_MODE 0x31C 281 281 #define H_CLEAR_HPT 0x358 282 + #define H_REQUEST_VMC 0x360 282 283 #define H_RESIZE_HPT_PREPARE 0x36C 283 284 #define H_RESIZE_HPT_COMMIT 0x370 284 285 #define H_REGISTER_PROC_TBL 0x37C
+14
drivers/misc/Kconfig
··· 113 113 for information on the specific driver level and support statement 114 114 for your IBM server. 115 115 116 + config IBMVMC 117 + tristate "IBM Virtual Management Channel support" 118 + depends on PPC_PSERIES 119 + help 120 + This is the IBM POWER Virtual Management Channel 121 + 122 + This driver is to be used for the POWER Virtual 123 + Management Channel virtual adapter on the PowerVM 124 + platform. It provides both request/response and 125 + async message support through the /dev/ibmvmc node. 126 + 127 + To compile this driver as a module, choose M here: the 128 + module will be called ibmvmc. 129 + 116 130 config PHANTOM 117 131 tristate "Sensable PHANToM (PCI)" 118 132 depends on PCI
+1
drivers/misc/Makefile
··· 4 4 # 5 5 6 6 obj-$(CONFIG_IBM_ASM) += ibmasm/ 7 + obj-$(CONFIG_IBMVMC) += ibmvmc.o 7 8 obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o 8 9 obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o 9 10 obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
+2418
drivers/misc/ibmvmc.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * IBM Power Systems Virtual Management Channel Support. 4 + * 5 + * Copyright (c) 2004, 2018 IBM Corp. 6 + * Dave Engebretsen engebret@us.ibm.com 7 + * Steven Royer seroyer@linux.vnet.ibm.com 8 + * Adam Reznechek adreznec@linux.vnet.ibm.com 9 + * Bryant G. Ly <bryantly@linux.vnet.ibm.com> 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/kernel.h> 14 + #include <linux/kthread.h> 15 + #include <linux/major.h> 16 + #include <linux/string.h> 17 + #include <linux/fcntl.h> 18 + #include <linux/slab.h> 19 + #include <linux/poll.h> 20 + #include <linux/init.h> 21 + #include <linux/fs.h> 22 + #include <linux/interrupt.h> 23 + #include <linux/spinlock.h> 24 + #include <linux/percpu.h> 25 + #include <linux/delay.h> 26 + #include <linux/uaccess.h> 27 + #include <linux/io.h> 28 + #include <linux/miscdevice.h> 29 + #include <linux/sched/signal.h> 30 + 31 + #include <asm/byteorder.h> 32 + #include <asm/irq.h> 33 + #include <asm/vio.h> 34 + 35 + #include "ibmvmc.h" 36 + 37 + #define IBMVMC_DRIVER_VERSION "1.0" 38 + 39 + /* 40 + * Static global variables 41 + */ 42 + static DECLARE_WAIT_QUEUE_HEAD(ibmvmc_read_wait); 43 + 44 + static const char ibmvmc_driver_name[] = "ibmvmc"; 45 + 46 + static struct ibmvmc_struct ibmvmc; 47 + static struct ibmvmc_hmc hmcs[MAX_HMCS]; 48 + static struct crq_server_adapter ibmvmc_adapter; 49 + 50 + static int ibmvmc_max_buf_pool_size = DEFAULT_BUF_POOL_SIZE; 51 + static int ibmvmc_max_hmcs = DEFAULT_HMCS; 52 + static int ibmvmc_max_mtu = DEFAULT_MTU; 53 + 54 + static inline long h_copy_rdma(s64 length, u64 sliobn, u64 slioba, 55 + u64 dliobn, u64 dlioba) 56 + { 57 + long rc = 0; 58 + 59 + /* Ensure all writes to source memory are visible before hcall */ 60 + dma_wmb(); 61 + pr_debug("ibmvmc: h_copy_rdma(0x%llx, 0x%llx, 0x%llx, 0x%llx, 0x%llx\n", 62 + length, sliobn, slioba, dliobn, dlioba); 63 + rc = plpar_hcall_norets(H_COPY_RDMA, length, sliobn, slioba, 64 + dliobn, dlioba); 65 + pr_debug("ibmvmc: h_copy_rdma rc = 0x%lx\n", rc); 66 + 67 + return rc; 68 + } 69 + 70 + static inline void h_free_crq(uint32_t unit_address) 71 + { 72 + long rc = 0; 73 + 74 + do { 75 + if (H_IS_LONG_BUSY(rc)) 76 + msleep(get_longbusy_msecs(rc)); 77 + 78 + rc = plpar_hcall_norets(H_FREE_CRQ, unit_address); 79 + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); 80 + } 81 + 82 + /** 83 + * h_request_vmc: - request a hypervisor virtual management channel device 84 + * @vmc_index: drc index of the vmc device created 85 + * 86 + * Requests the hypervisor create a new virtual management channel device, 87 + * allowing this partition to send hypervisor virtualization control 88 + * commands. 89 + * 90 + * Return: 91 + * 0 - Success 92 + * Non-zero - Failure 93 + */ 94 + static inline long h_request_vmc(u32 *vmc_index) 95 + { 96 + long rc = 0; 97 + unsigned long retbuf[PLPAR_HCALL_BUFSIZE]; 98 + 99 + do { 100 + if (H_IS_LONG_BUSY(rc)) 101 + msleep(get_longbusy_msecs(rc)); 102 + 103 + /* Call to request the VMC device from phyp */ 104 + rc = plpar_hcall(H_REQUEST_VMC, retbuf); 105 + pr_debug("ibmvmc: %s rc = 0x%lx\n", __func__, rc); 106 + *vmc_index = retbuf[0]; 107 + } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); 108 + 109 + return rc; 110 + } 111 + 112 + /* routines for managing a command/response queue */ 113 + /** 114 + * ibmvmc_handle_event: - Interrupt handler for crq events 115 + * @irq: number of irq to handle, not used 116 + * @dev_instance: crq_server_adapter that received interrupt 117 + * 118 + * Disables interrupts and schedules ibmvmc_task 119 + * 120 + * Always returns IRQ_HANDLED 121 + */ 122 + static irqreturn_t ibmvmc_handle_event(int irq, void *dev_instance) 123 + { 124 + struct crq_server_adapter *adapter = 125 + (struct crq_server_adapter *)dev_instance; 126 + 127 + vio_disable_interrupts(to_vio_dev(adapter->dev)); 128 + tasklet_schedule(&adapter->work_task); 129 + 130 + return IRQ_HANDLED; 131 + } 132 + 133 + /** 134 + * ibmvmc_release_crq_queue - Release CRQ Queue 135 + * 136 + * @adapter: crq_server_adapter struct 137 + * 138 + * Return: 139 + * 0 - Success 140 + * Non-Zero - Failure 141 + */ 142 + static void ibmvmc_release_crq_queue(struct crq_server_adapter *adapter) 143 + { 144 + struct vio_dev *vdev = to_vio_dev(adapter->dev); 145 + struct crq_queue *queue = &adapter->queue; 146 + 147 + free_irq(vdev->irq, (void *)adapter); 148 + tasklet_kill(&adapter->work_task); 149 + 150 + if (adapter->reset_task) 151 + kthread_stop(adapter->reset_task); 152 + 153 + h_free_crq(vdev->unit_address); 154 + dma_unmap_single(adapter->dev, 155 + queue->msg_token, 156 + queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); 157 + free_page((unsigned long)queue->msgs); 158 + } 159 + 160 + /** 161 + * ibmvmc_reset_crq_queue - Reset CRQ Queue 162 + * 163 + * @adapter: crq_server_adapter struct 164 + * 165 + * This function calls h_free_crq and then calls H_REG_CRQ and does all the 166 + * bookkeeping to get us back to where we can communicate. 167 + * 168 + * Return: 169 + * 0 - Success 170 + * Non-Zero - Failure 171 + */ 172 + static int ibmvmc_reset_crq_queue(struct crq_server_adapter *adapter) 173 + { 174 + struct vio_dev *vdev = to_vio_dev(adapter->dev); 175 + struct crq_queue *queue = &adapter->queue; 176 + int rc = 0; 177 + 178 + /* Close the CRQ */ 179 + h_free_crq(vdev->unit_address); 180 + 181 + /* Clean out the queue */ 182 + memset(queue->msgs, 0x00, PAGE_SIZE); 183 + queue->cur = 0; 184 + 185 + /* And re-open it again */ 186 + rc = plpar_hcall_norets(H_REG_CRQ, 187 + vdev->unit_address, 188 + queue->msg_token, PAGE_SIZE); 189 + if (rc == 2) 190 + /* Adapter is good, but other end is not ready */ 191 + dev_warn(adapter->dev, "Partner adapter not ready\n"); 192 + else if (rc != 0) 193 + dev_err(adapter->dev, "couldn't register crq--rc 0x%x\n", rc); 194 + 195 + return rc; 196 + } 197 + 198 + /** 199 + * crq_queue_next_crq: - Returns the next entry in message queue 200 + * @queue: crq_queue to use 201 + * 202 + * Returns pointer to next entry in queue, or NULL if there are no new 203 + * entried in the CRQ. 204 + */ 205 + static struct ibmvmc_crq_msg *crq_queue_next_crq(struct crq_queue *queue) 206 + { 207 + struct ibmvmc_crq_msg *crq; 208 + unsigned long flags; 209 + 210 + spin_lock_irqsave(&queue->lock, flags); 211 + crq = &queue->msgs[queue->cur]; 212 + if (crq->valid & 0x80) { 213 + if (++queue->cur == queue->size) 214 + queue->cur = 0; 215 + 216 + /* Ensure the read of the valid bit occurs before reading any 217 + * other bits of the CRQ entry 218 + */ 219 + dma_rmb(); 220 + } else { 221 + crq = NULL; 222 + } 223 + 224 + spin_unlock_irqrestore(&queue->lock, flags); 225 + 226 + return crq; 227 + } 228 + 229 + /** 230 + * ibmvmc_send_crq - Send CRQ 231 + * 232 + * @adapter: crq_server_adapter struct 233 + * @word1: Word1 Data field 234 + * @word2: Word2 Data field 235 + * 236 + * Return: 237 + * 0 - Success 238 + * Non-Zero - Failure 239 + */ 240 + static long ibmvmc_send_crq(struct crq_server_adapter *adapter, 241 + u64 word1, u64 word2) 242 + { 243 + struct vio_dev *vdev = to_vio_dev(adapter->dev); 244 + long rc = 0; 245 + 246 + dev_dbg(adapter->dev, "(0x%x, 0x%016llx, 0x%016llx)\n", 247 + vdev->unit_address, word1, word2); 248 + 249 + /* 250 + * Ensure the command buffer is flushed to memory before handing it 251 + * over to the other side to prevent it from fetching any stale data. 252 + */ 253 + dma_wmb(); 254 + rc = plpar_hcall_norets(H_SEND_CRQ, vdev->unit_address, word1, word2); 255 + dev_dbg(adapter->dev, "rc = 0x%lx\n", rc); 256 + 257 + return rc; 258 + } 259 + 260 + /** 261 + * alloc_dma_buffer - Create DMA Buffer 262 + * 263 + * @vdev: vio_dev struct 264 + * @size: Size field 265 + * @dma_handle: DMA address field 266 + * 267 + * Allocates memory for the command queue and maps remote memory into an 268 + * ioba. 269 + * 270 + * Returns a pointer to the buffer 271 + */ 272 + static void *alloc_dma_buffer(struct vio_dev *vdev, size_t size, 273 + dma_addr_t *dma_handle) 274 + { 275 + /* allocate memory */ 276 + void *buffer = kzalloc(size, GFP_KERNEL); 277 + 278 + if (!buffer) { 279 + *dma_handle = 0; 280 + return NULL; 281 + } 282 + 283 + /* DMA map */ 284 + *dma_handle = dma_map_single(&vdev->dev, buffer, size, 285 + DMA_BIDIRECTIONAL); 286 + 287 + if (dma_mapping_error(&vdev->dev, *dma_handle)) { 288 + *dma_handle = 0; 289 + kzfree(buffer); 290 + return NULL; 291 + } 292 + 293 + return buffer; 294 + } 295 + 296 + /** 297 + * free_dma_buffer - Free DMA Buffer 298 + * 299 + * @vdev: vio_dev struct 300 + * @size: Size field 301 + * @vaddr: Address field 302 + * @dma_handle: DMA address field 303 + * 304 + * Releases memory for a command queue and unmaps mapped remote memory. 305 + */ 306 + static void free_dma_buffer(struct vio_dev *vdev, size_t size, void *vaddr, 307 + dma_addr_t dma_handle) 308 + { 309 + /* DMA unmap */ 310 + dma_unmap_single(&vdev->dev, dma_handle, size, DMA_BIDIRECTIONAL); 311 + 312 + /* deallocate memory */ 313 + kzfree(vaddr); 314 + } 315 + 316 + /** 317 + * ibmvmc_get_valid_hmc_buffer - Retrieve Valid HMC Buffer 318 + * 319 + * @hmc_index: HMC Index Field 320 + * 321 + * Return: 322 + * Pointer to ibmvmc_buffer 323 + */ 324 + static struct ibmvmc_buffer *ibmvmc_get_valid_hmc_buffer(u8 hmc_index) 325 + { 326 + struct ibmvmc_buffer *buffer; 327 + struct ibmvmc_buffer *ret_buf = NULL; 328 + unsigned long i; 329 + 330 + if (hmc_index > ibmvmc.max_hmc_index) 331 + return NULL; 332 + 333 + buffer = hmcs[hmc_index].buffer; 334 + 335 + for (i = 0; i < ibmvmc_max_buf_pool_size; i++) { 336 + if (buffer[i].valid && buffer[i].free && 337 + buffer[i].owner == VMC_BUF_OWNER_ALPHA) { 338 + buffer[i].free = 0; 339 + ret_buf = &buffer[i]; 340 + break; 341 + } 342 + } 343 + 344 + return ret_buf; 345 + } 346 + 347 + /** 348 + * ibmvmc_get_free_hmc_buffer - Get Free HMC Buffer 349 + * 350 + * @adapter: crq_server_adapter struct 351 + * @hmc_index: Hmc Index field 352 + * 353 + * Return: 354 + * Pointer to ibmvmc_buffer 355 + */ 356 + static struct ibmvmc_buffer *ibmvmc_get_free_hmc_buffer(struct crq_server_adapter *adapter, 357 + u8 hmc_index) 358 + { 359 + struct ibmvmc_buffer *buffer; 360 + struct ibmvmc_buffer *ret_buf = NULL; 361 + unsigned long i; 362 + 363 + if (hmc_index > ibmvmc.max_hmc_index) { 364 + dev_info(adapter->dev, "get_free_hmc_buffer: invalid hmc_index=0x%x\n", 365 + hmc_index); 366 + return NULL; 367 + } 368 + 369 + buffer = hmcs[hmc_index].buffer; 370 + 371 + for (i = 0; i < ibmvmc_max_buf_pool_size; i++) { 372 + if (buffer[i].free && 373 + buffer[i].owner == VMC_BUF_OWNER_ALPHA) { 374 + buffer[i].free = 0; 375 + ret_buf = &buffer[i]; 376 + break; 377 + } 378 + } 379 + 380 + return ret_buf; 381 + } 382 + 383 + /** 384 + * ibmvmc_free_hmc_buffer - Free an HMC Buffer 385 + * 386 + * @hmc: ibmvmc_hmc struct 387 + * @buffer: ibmvmc_buffer struct 388 + * 389 + */ 390 + static void ibmvmc_free_hmc_buffer(struct ibmvmc_hmc *hmc, 391 + struct ibmvmc_buffer *buffer) 392 + { 393 + unsigned long flags; 394 + 395 + spin_lock_irqsave(&hmc->lock, flags); 396 + buffer->free = 1; 397 + spin_unlock_irqrestore(&hmc->lock, flags); 398 + } 399 + 400 + /** 401 + * ibmvmc_count_hmc_buffers - Count HMC Buffers 402 + * 403 + * @hmc_index: HMC Index field 404 + * @valid: Valid number of buffers field 405 + * @free: Free number of buffers field 406 + * 407 + */ 408 + static void ibmvmc_count_hmc_buffers(u8 hmc_index, unsigned int *valid, 409 + unsigned int *free) 410 + { 411 + struct ibmvmc_buffer *buffer; 412 + unsigned long i; 413 + unsigned long flags; 414 + 415 + if (hmc_index > ibmvmc.max_hmc_index) 416 + return; 417 + 418 + if (!valid || !free) 419 + return; 420 + 421 + *valid = 0; *free = 0; 422 + 423 + buffer = hmcs[hmc_index].buffer; 424 + spin_lock_irqsave(&hmcs[hmc_index].lock, flags); 425 + 426 + for (i = 0; i < ibmvmc_max_buf_pool_size; i++) { 427 + if (buffer[i].valid) { 428 + *valid = *valid + 1; 429 + if (buffer[i].free) 430 + *free = *free + 1; 431 + } 432 + } 433 + 434 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 435 + } 436 + 437 + /** 438 + * ibmvmc_get_free_hmc - Get Free HMC 439 + * 440 + * Return: 441 + * Pointer to an available HMC Connection 442 + * Null otherwise 443 + */ 444 + static struct ibmvmc_hmc *ibmvmc_get_free_hmc(void) 445 + { 446 + unsigned long i; 447 + unsigned long flags; 448 + 449 + /* 450 + * Find an available HMC connection. 451 + */ 452 + for (i = 0; i <= ibmvmc.max_hmc_index; i++) { 453 + spin_lock_irqsave(&hmcs[i].lock, flags); 454 + if (hmcs[i].state == ibmhmc_state_free) { 455 + hmcs[i].index = i; 456 + hmcs[i].state = ibmhmc_state_initial; 457 + spin_unlock_irqrestore(&hmcs[i].lock, flags); 458 + return &hmcs[i]; 459 + } 460 + spin_unlock_irqrestore(&hmcs[i].lock, flags); 461 + } 462 + 463 + return NULL; 464 + } 465 + 466 + /** 467 + * ibmvmc_return_hmc - Return an HMC Connection 468 + * 469 + * @hmc: ibmvmc_hmc struct 470 + * @release_readers: Number of readers connected to session 471 + * 472 + * This function releases the HMC connections back into the pool. 473 + * 474 + * Return: 475 + * 0 - Success 476 + * Non-zero - Failure 477 + */ 478 + static int ibmvmc_return_hmc(struct ibmvmc_hmc *hmc, bool release_readers) 479 + { 480 + struct ibmvmc_buffer *buffer; 481 + struct crq_server_adapter *adapter; 482 + struct vio_dev *vdev; 483 + unsigned long i; 484 + unsigned long flags; 485 + 486 + if (!hmc || !hmc->adapter) 487 + return -EIO; 488 + 489 + if (release_readers) { 490 + if (hmc->file_session) { 491 + struct ibmvmc_file_session *session = hmc->file_session; 492 + 493 + session->valid = 0; 494 + wake_up_interruptible(&ibmvmc_read_wait); 495 + } 496 + } 497 + 498 + adapter = hmc->adapter; 499 + vdev = to_vio_dev(adapter->dev); 500 + 501 + spin_lock_irqsave(&hmc->lock, flags); 502 + hmc->index = 0; 503 + hmc->state = ibmhmc_state_free; 504 + hmc->queue_head = 0; 505 + hmc->queue_tail = 0; 506 + buffer = hmc->buffer; 507 + for (i = 0; i < ibmvmc_max_buf_pool_size; i++) { 508 + if (buffer[i].valid) { 509 + free_dma_buffer(vdev, 510 + ibmvmc.max_mtu, 511 + buffer[i].real_addr_local, 512 + buffer[i].dma_addr_local); 513 + dev_dbg(adapter->dev, "Forgot buffer id 0x%lx\n", i); 514 + } 515 + memset(&buffer[i], 0, sizeof(struct ibmvmc_buffer)); 516 + 517 + hmc->queue_outbound_msgs[i] = VMC_INVALID_BUFFER_ID; 518 + } 519 + 520 + spin_unlock_irqrestore(&hmc->lock, flags); 521 + 522 + return 0; 523 + } 524 + 525 + /** 526 + * ibmvmc_send_open - Interface Open 527 + * @buffer: Pointer to ibmvmc_buffer struct 528 + * @hmc: Pointer to ibmvmc_hmc struct 529 + * 530 + * This command is sent by the management partition as the result of a 531 + * management partition device request. It causes the hypervisor to 532 + * prepare a set of data buffers for the management application connection 533 + * indicated HMC idx. A unique HMC Idx would be used if multiple management 534 + * applications running concurrently were desired. Before responding to this 535 + * command, the hypervisor must provide the management partition with at 536 + * least one of these new buffers via the Add Buffer. This indicates whether 537 + * the messages are inbound or outbound from the hypervisor. 538 + * 539 + * Return: 540 + * 0 - Success 541 + * Non-zero - Failure 542 + */ 543 + static int ibmvmc_send_open(struct ibmvmc_buffer *buffer, 544 + struct ibmvmc_hmc *hmc) 545 + { 546 + struct ibmvmc_crq_msg crq_msg; 547 + struct crq_server_adapter *adapter; 548 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 549 + int rc = 0; 550 + 551 + if (!hmc || !hmc->adapter) 552 + return -EIO; 553 + 554 + adapter = hmc->adapter; 555 + 556 + dev_dbg(adapter->dev, "send_open: 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", 557 + (unsigned long)buffer->size, (unsigned long)adapter->liobn, 558 + (unsigned long)buffer->dma_addr_local, 559 + (unsigned long)adapter->riobn, 560 + (unsigned long)buffer->dma_addr_remote); 561 + 562 + rc = h_copy_rdma(buffer->size, 563 + adapter->liobn, 564 + buffer->dma_addr_local, 565 + adapter->riobn, 566 + buffer->dma_addr_remote); 567 + if (rc) { 568 + dev_err(adapter->dev, "Error: In send_open, h_copy_rdma rc 0x%x\n", 569 + rc); 570 + return -EIO; 571 + } 572 + 573 + hmc->state = ibmhmc_state_opening; 574 + 575 + crq_msg.valid = 0x80; 576 + crq_msg.type = VMC_MSG_OPEN; 577 + crq_msg.status = 0; 578 + crq_msg.var1.rsvd = 0; 579 + crq_msg.hmc_session = hmc->session; 580 + crq_msg.hmc_index = hmc->index; 581 + crq_msg.var2.buffer_id = cpu_to_be16(buffer->id); 582 + crq_msg.rsvd = 0; 583 + crq_msg.var3.rsvd = 0; 584 + 585 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 586 + be64_to_cpu(crq_as_u64[1])); 587 + 588 + return rc; 589 + } 590 + 591 + /** 592 + * ibmvmc_send_close - Interface Close 593 + * @hmc: Pointer to ibmvmc_hmc struct 594 + * 595 + * This command is sent by the management partition to terminate a 596 + * management application to hypervisor connection. When this command is 597 + * sent, the management partition has quiesced all I/O operations to all 598 + * buffers associated with this management application connection, and 599 + * has freed any storage for these buffers. 600 + * 601 + * Return: 602 + * 0 - Success 603 + * Non-zero - Failure 604 + */ 605 + static int ibmvmc_send_close(struct ibmvmc_hmc *hmc) 606 + { 607 + struct ibmvmc_crq_msg crq_msg; 608 + struct crq_server_adapter *adapter; 609 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 610 + int rc = 0; 611 + 612 + if (!hmc || !hmc->adapter) 613 + return -EIO; 614 + 615 + adapter = hmc->adapter; 616 + 617 + dev_info(adapter->dev, "CRQ send: close\n"); 618 + 619 + crq_msg.valid = 0x80; 620 + crq_msg.type = VMC_MSG_CLOSE; 621 + crq_msg.status = 0; 622 + crq_msg.var1.rsvd = 0; 623 + crq_msg.hmc_session = hmc->session; 624 + crq_msg.hmc_index = hmc->index; 625 + crq_msg.var2.rsvd = 0; 626 + crq_msg.rsvd = 0; 627 + crq_msg.var3.rsvd = 0; 628 + 629 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 630 + be64_to_cpu(crq_as_u64[1])); 631 + 632 + return rc; 633 + } 634 + 635 + /** 636 + * ibmvmc_send_capabilities - Send VMC Capabilities 637 + * 638 + * @adapter: crq_server_adapter struct 639 + * 640 + * The capabilities message is an administrative message sent after the CRQ 641 + * initialization sequence of messages and is used to exchange VMC capabilities 642 + * between the management partition and the hypervisor. The management 643 + * partition must send this message and the hypervisor must respond with VMC 644 + * capabilities Response message before HMC interface message can begin. Any 645 + * HMC interface messages received before the exchange of capabilities has 646 + * complete are dropped. 647 + * 648 + * Return: 649 + * 0 - Success 650 + */ 651 + static int ibmvmc_send_capabilities(struct crq_server_adapter *adapter) 652 + { 653 + struct ibmvmc_admin_crq_msg crq_msg; 654 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 655 + 656 + dev_dbg(adapter->dev, "ibmvmc: CRQ send: capabilities\n"); 657 + crq_msg.valid = 0x80; 658 + crq_msg.type = VMC_MSG_CAP; 659 + crq_msg.status = 0; 660 + crq_msg.rsvd[0] = 0; 661 + crq_msg.rsvd[1] = 0; 662 + crq_msg.max_hmc = ibmvmc_max_hmcs; 663 + crq_msg.max_mtu = cpu_to_be32(ibmvmc_max_mtu); 664 + crq_msg.pool_size = cpu_to_be16(ibmvmc_max_buf_pool_size); 665 + crq_msg.crq_size = cpu_to_be16(adapter->queue.size); 666 + crq_msg.version = cpu_to_be16(IBMVMC_PROTOCOL_VERSION); 667 + 668 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 669 + be64_to_cpu(crq_as_u64[1])); 670 + 671 + ibmvmc.state = ibmvmc_state_capabilities; 672 + 673 + return 0; 674 + } 675 + 676 + /** 677 + * ibmvmc_send_add_buffer_resp - Add Buffer Response 678 + * 679 + * @adapter: crq_server_adapter struct 680 + * @status: Status field 681 + * @hmc_session: HMC Session field 682 + * @hmc_index: HMC Index field 683 + * @buffer_id: Buffer Id field 684 + * 685 + * This command is sent by the management partition to the hypervisor in 686 + * response to the Add Buffer message. The Status field indicates the result of 687 + * the command. 688 + * 689 + * Return: 690 + * 0 - Success 691 + */ 692 + static int ibmvmc_send_add_buffer_resp(struct crq_server_adapter *adapter, 693 + u8 status, u8 hmc_session, 694 + u8 hmc_index, u16 buffer_id) 695 + { 696 + struct ibmvmc_crq_msg crq_msg; 697 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 698 + 699 + dev_dbg(adapter->dev, "CRQ send: add_buffer_resp\n"); 700 + crq_msg.valid = 0x80; 701 + crq_msg.type = VMC_MSG_ADD_BUF_RESP; 702 + crq_msg.status = status; 703 + crq_msg.var1.rsvd = 0; 704 + crq_msg.hmc_session = hmc_session; 705 + crq_msg.hmc_index = hmc_index; 706 + crq_msg.var2.buffer_id = cpu_to_be16(buffer_id); 707 + crq_msg.rsvd = 0; 708 + crq_msg.var3.rsvd = 0; 709 + 710 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 711 + be64_to_cpu(crq_as_u64[1])); 712 + 713 + return 0; 714 + } 715 + 716 + /** 717 + * ibmvmc_send_rem_buffer_resp - Remove Buffer Response 718 + * 719 + * @adapter: crq_server_adapter struct 720 + * @status: Status field 721 + * @hmc_session: HMC Session field 722 + * @hmc_index: HMC Index field 723 + * @buffer_id: Buffer Id field 724 + * 725 + * This command is sent by the management partition to the hypervisor in 726 + * response to the Remove Buffer message. The Buffer ID field indicates 727 + * which buffer the management partition selected to remove. The Status 728 + * field indicates the result of the command. 729 + * 730 + * Return: 731 + * 0 - Success 732 + */ 733 + static int ibmvmc_send_rem_buffer_resp(struct crq_server_adapter *adapter, 734 + u8 status, u8 hmc_session, 735 + u8 hmc_index, u16 buffer_id) 736 + { 737 + struct ibmvmc_crq_msg crq_msg; 738 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 739 + 740 + dev_dbg(adapter->dev, "CRQ send: rem_buffer_resp\n"); 741 + crq_msg.valid = 0x80; 742 + crq_msg.type = VMC_MSG_REM_BUF_RESP; 743 + crq_msg.status = status; 744 + crq_msg.var1.rsvd = 0; 745 + crq_msg.hmc_session = hmc_session; 746 + crq_msg.hmc_index = hmc_index; 747 + crq_msg.var2.buffer_id = cpu_to_be16(buffer_id); 748 + crq_msg.rsvd = 0; 749 + crq_msg.var3.rsvd = 0; 750 + 751 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 752 + be64_to_cpu(crq_as_u64[1])); 753 + 754 + return 0; 755 + } 756 + 757 + /** 758 + * ibmvmc_send_msg - Signal Message 759 + * 760 + * @adapter: crq_server_adapter struct 761 + * @buffer: ibmvmc_buffer struct 762 + * @hmc: ibmvmc_hmc struct 763 + * @msg_length: message length field 764 + * 765 + * This command is sent between the management partition and the hypervisor 766 + * in order to signal the arrival of an HMC protocol message. The command 767 + * can be sent by both the management partition and the hypervisor. It is 768 + * used for all traffic between the management application and the hypervisor, 769 + * regardless of who initiated the communication. 770 + * 771 + * There is no response to this message. 772 + * 773 + * Return: 774 + * 0 - Success 775 + * Non-zero - Failure 776 + */ 777 + static int ibmvmc_send_msg(struct crq_server_adapter *adapter, 778 + struct ibmvmc_buffer *buffer, 779 + struct ibmvmc_hmc *hmc, int msg_len) 780 + { 781 + struct ibmvmc_crq_msg crq_msg; 782 + __be64 *crq_as_u64 = (__be64 *)&crq_msg; 783 + int rc = 0; 784 + 785 + dev_dbg(adapter->dev, "CRQ send: rdma to HV\n"); 786 + rc = h_copy_rdma(msg_len, 787 + adapter->liobn, 788 + buffer->dma_addr_local, 789 + adapter->riobn, 790 + buffer->dma_addr_remote); 791 + if (rc) { 792 + dev_err(adapter->dev, "Error in send_msg, h_copy_rdma rc 0x%x\n", 793 + rc); 794 + return rc; 795 + } 796 + 797 + crq_msg.valid = 0x80; 798 + crq_msg.type = VMC_MSG_SIGNAL; 799 + crq_msg.status = 0; 800 + crq_msg.var1.rsvd = 0; 801 + crq_msg.hmc_session = hmc->session; 802 + crq_msg.hmc_index = hmc->index; 803 + crq_msg.var2.buffer_id = cpu_to_be16(buffer->id); 804 + crq_msg.var3.msg_len = cpu_to_be32(msg_len); 805 + dev_dbg(adapter->dev, "CRQ send: msg to HV 0x%llx 0x%llx\n", 806 + be64_to_cpu(crq_as_u64[0]), be64_to_cpu(crq_as_u64[1])); 807 + 808 + buffer->owner = VMC_BUF_OWNER_HV; 809 + ibmvmc_send_crq(adapter, be64_to_cpu(crq_as_u64[0]), 810 + be64_to_cpu(crq_as_u64[1])); 811 + 812 + return rc; 813 + } 814 + 815 + /** 816 + * ibmvmc_open - Open Session 817 + * 818 + * @inode: inode struct 819 + * @file: file struct 820 + * 821 + * Return: 822 + * 0 - Success 823 + */ 824 + static int ibmvmc_open(struct inode *inode, struct file *file) 825 + { 826 + struct ibmvmc_file_session *session; 827 + int rc = 0; 828 + 829 + pr_debug("%s: inode = 0x%lx, file = 0x%lx, state = 0x%x\n", __func__, 830 + (unsigned long)inode, (unsigned long)file, 831 + ibmvmc.state); 832 + 833 + session = kzalloc(sizeof(*session), GFP_KERNEL); 834 + session->file = file; 835 + file->private_data = session; 836 + 837 + return rc; 838 + } 839 + 840 + /** 841 + * ibmvmc_close - Close Session 842 + * 843 + * @inode: inode struct 844 + * @file: file struct 845 + * 846 + * Return: 847 + * 0 - Success 848 + * Non-zero - Failure 849 + */ 850 + static int ibmvmc_close(struct inode *inode, struct file *file) 851 + { 852 + struct ibmvmc_file_session *session; 853 + struct ibmvmc_hmc *hmc; 854 + int rc = 0; 855 + unsigned long flags; 856 + 857 + pr_debug("%s: file = 0x%lx, state = 0x%x\n", __func__, 858 + (unsigned long)file, ibmvmc.state); 859 + 860 + session = file->private_data; 861 + if (!session) 862 + return -EIO; 863 + 864 + hmc = session->hmc; 865 + if (hmc) { 866 + if (!hmc->adapter) 867 + return -EIO; 868 + 869 + if (ibmvmc.state == ibmvmc_state_failed) { 870 + dev_warn(hmc->adapter->dev, "close: state_failed\n"); 871 + return -EIO; 872 + } 873 + 874 + spin_lock_irqsave(&hmc->lock, flags); 875 + if (hmc->state >= ibmhmc_state_opening) { 876 + rc = ibmvmc_send_close(hmc); 877 + if (rc) 878 + dev_warn(hmc->adapter->dev, "close: send_close failed.\n"); 879 + } 880 + spin_unlock_irqrestore(&hmc->lock, flags); 881 + } 882 + 883 + kzfree(session); 884 + 885 + return rc; 886 + } 887 + 888 + /** 889 + * ibmvmc_read - Read 890 + * 891 + * @file: file struct 892 + * @buf: Character buffer 893 + * @nbytes: Size in bytes 894 + * @ppos: Offset 895 + * 896 + * Return: 897 + * 0 - Success 898 + * Non-zero - Failure 899 + */ 900 + static ssize_t ibmvmc_read(struct file *file, char *buf, size_t nbytes, 901 + loff_t *ppos) 902 + { 903 + struct ibmvmc_file_session *session; 904 + struct ibmvmc_hmc *hmc; 905 + struct crq_server_adapter *adapter; 906 + struct ibmvmc_buffer *buffer; 907 + ssize_t n; 908 + ssize_t retval = 0; 909 + unsigned long flags; 910 + DEFINE_WAIT(wait); 911 + 912 + pr_debug("ibmvmc: read: file = 0x%lx, buf = 0x%lx, nbytes = 0x%lx\n", 913 + (unsigned long)file, (unsigned long)buf, 914 + (unsigned long)nbytes); 915 + 916 + if (nbytes == 0) 917 + return 0; 918 + 919 + if (nbytes > ibmvmc.max_mtu) { 920 + pr_warn("ibmvmc: read: nbytes invalid 0x%x\n", 921 + (unsigned int)nbytes); 922 + return -EINVAL; 923 + } 924 + 925 + session = file->private_data; 926 + if (!session) { 927 + pr_warn("ibmvmc: read: no session\n"); 928 + return -EIO; 929 + } 930 + 931 + hmc = session->hmc; 932 + if (!hmc) { 933 + pr_warn("ibmvmc: read: no hmc\n"); 934 + return -EIO; 935 + } 936 + 937 + adapter = hmc->adapter; 938 + if (!adapter) { 939 + pr_warn("ibmvmc: read: no adapter\n"); 940 + return -EIO; 941 + } 942 + 943 + do { 944 + prepare_to_wait(&ibmvmc_read_wait, &wait, TASK_INTERRUPTIBLE); 945 + 946 + spin_lock_irqsave(&hmc->lock, flags); 947 + if (hmc->queue_tail != hmc->queue_head) 948 + /* Data is available */ 949 + break; 950 + 951 + spin_unlock_irqrestore(&hmc->lock, flags); 952 + 953 + if (!session->valid) { 954 + retval = -EBADFD; 955 + goto out; 956 + } 957 + if (file->f_flags & O_NONBLOCK) { 958 + retval = -EAGAIN; 959 + goto out; 960 + } 961 + 962 + schedule(); 963 + 964 + if (signal_pending(current)) { 965 + retval = -ERESTARTSYS; 966 + goto out; 967 + } 968 + } while (1); 969 + 970 + buffer = &(hmc->buffer[hmc->queue_outbound_msgs[hmc->queue_tail]]); 971 + hmc->queue_tail++; 972 + if (hmc->queue_tail == ibmvmc_max_buf_pool_size) 973 + hmc->queue_tail = 0; 974 + spin_unlock_irqrestore(&hmc->lock, flags); 975 + 976 + nbytes = min_t(size_t, nbytes, buffer->msg_len); 977 + n = copy_to_user((void *)buf, buffer->real_addr_local, nbytes); 978 + dev_dbg(adapter->dev, "read: copy to user nbytes = 0x%lx.\n", nbytes); 979 + ibmvmc_free_hmc_buffer(hmc, buffer); 980 + retval = nbytes; 981 + 982 + if (n) { 983 + dev_warn(adapter->dev, "read: copy to user failed.\n"); 984 + retval = -EFAULT; 985 + } 986 + 987 + out: 988 + finish_wait(&ibmvmc_read_wait, &wait); 989 + dev_dbg(adapter->dev, "read: out %ld\n", retval); 990 + return retval; 991 + } 992 + 993 + /** 994 + * ibmvmc_poll - Poll 995 + * 996 + * @file: file struct 997 + * @wait: Poll Table 998 + * 999 + * Return: 1000 + * poll.h return values 1001 + */ 1002 + static unsigned int ibmvmc_poll(struct file *file, poll_table *wait) 1003 + { 1004 + struct ibmvmc_file_session *session; 1005 + struct ibmvmc_hmc *hmc; 1006 + unsigned int mask = 0; 1007 + 1008 + session = file->private_data; 1009 + if (!session) 1010 + return 0; 1011 + 1012 + hmc = session->hmc; 1013 + if (!hmc) 1014 + return 0; 1015 + 1016 + poll_wait(file, &ibmvmc_read_wait, wait); 1017 + 1018 + if (hmc->queue_head != hmc->queue_tail) 1019 + mask |= POLLIN | POLLRDNORM; 1020 + 1021 + return mask; 1022 + } 1023 + 1024 + /** 1025 + * ibmvmc_write - Write 1026 + * 1027 + * @file: file struct 1028 + * @buf: Character buffer 1029 + * @count: Count field 1030 + * @ppos: Offset 1031 + * 1032 + * Return: 1033 + * 0 - Success 1034 + * Non-zero - Failure 1035 + */ 1036 + static ssize_t ibmvmc_write(struct file *file, const char *buffer, 1037 + size_t count, loff_t *ppos) 1038 + { 1039 + struct ibmvmc_buffer *vmc_buffer; 1040 + struct ibmvmc_file_session *session; 1041 + struct crq_server_adapter *adapter; 1042 + struct ibmvmc_hmc *hmc; 1043 + unsigned char *buf; 1044 + unsigned long flags; 1045 + size_t bytes; 1046 + const char *p = buffer; 1047 + size_t c = count; 1048 + int ret = 0; 1049 + 1050 + session = file->private_data; 1051 + if (!session) 1052 + return -EIO; 1053 + 1054 + hmc = session->hmc; 1055 + if (!hmc) 1056 + return -EIO; 1057 + 1058 + spin_lock_irqsave(&hmc->lock, flags); 1059 + if (hmc->state == ibmhmc_state_free) { 1060 + /* HMC connection is not valid (possibly was reset under us). */ 1061 + ret = -EIO; 1062 + goto out; 1063 + } 1064 + 1065 + adapter = hmc->adapter; 1066 + if (!adapter) { 1067 + ret = -EIO; 1068 + goto out; 1069 + } 1070 + 1071 + if (count > ibmvmc.max_mtu) { 1072 + dev_warn(adapter->dev, "invalid buffer size 0x%lx\n", 1073 + (unsigned long)count); 1074 + ret = -EIO; 1075 + goto out; 1076 + } 1077 + 1078 + /* Waiting for the open resp message to the ioctl(1) - retry */ 1079 + if (hmc->state == ibmhmc_state_opening) { 1080 + ret = -EBUSY; 1081 + goto out; 1082 + } 1083 + 1084 + /* Make sure the ioctl() was called & the open msg sent, and that 1085 + * the HMC connection has not failed. 1086 + */ 1087 + if (hmc->state != ibmhmc_state_ready) { 1088 + ret = -EIO; 1089 + goto out; 1090 + } 1091 + 1092 + vmc_buffer = ibmvmc_get_valid_hmc_buffer(hmc->index); 1093 + if (!vmc_buffer) { 1094 + /* No buffer available for the msg send, or we have not yet 1095 + * completed the open/open_resp sequence. Retry until this is 1096 + * complete. 1097 + */ 1098 + ret = -EBUSY; 1099 + goto out; 1100 + } 1101 + if (!vmc_buffer->real_addr_local) { 1102 + dev_err(adapter->dev, "no buffer storage assigned\n"); 1103 + ret = -EIO; 1104 + goto out; 1105 + } 1106 + buf = vmc_buffer->real_addr_local; 1107 + 1108 + while (c > 0) { 1109 + bytes = min_t(size_t, c, vmc_buffer->size); 1110 + 1111 + bytes -= copy_from_user(buf, p, bytes); 1112 + if (!bytes) { 1113 + ret = -EFAULT; 1114 + goto out; 1115 + } 1116 + c -= bytes; 1117 + p += bytes; 1118 + } 1119 + if (p == buffer) 1120 + goto out; 1121 + 1122 + file->f_path.dentry->d_inode->i_mtime = current_time(file_inode(file)); 1123 + mark_inode_dirty(file->f_path.dentry->d_inode); 1124 + 1125 + dev_dbg(adapter->dev, "write: file = 0x%lx, count = 0x%lx\n", 1126 + (unsigned long)file, (unsigned long)count); 1127 + 1128 + ibmvmc_send_msg(adapter, vmc_buffer, hmc, count); 1129 + ret = p - buffer; 1130 + out: 1131 + spin_unlock_irqrestore(&hmc->lock, flags); 1132 + return (ssize_t)(ret); 1133 + } 1134 + 1135 + /** 1136 + * ibmvmc_setup_hmc - Setup the HMC 1137 + * 1138 + * @session: ibmvmc_file_session struct 1139 + * 1140 + * Return: 1141 + * 0 - Success 1142 + * Non-zero - Failure 1143 + */ 1144 + static long ibmvmc_setup_hmc(struct ibmvmc_file_session *session) 1145 + { 1146 + struct ibmvmc_hmc *hmc; 1147 + unsigned int valid, free, index; 1148 + 1149 + if (ibmvmc.state == ibmvmc_state_failed) { 1150 + pr_warn("ibmvmc: Reserve HMC: state_failed\n"); 1151 + return -EIO; 1152 + } 1153 + 1154 + if (ibmvmc.state < ibmvmc_state_ready) { 1155 + pr_warn("ibmvmc: Reserve HMC: not state_ready\n"); 1156 + return -EAGAIN; 1157 + } 1158 + 1159 + /* Device is busy until capabilities have been exchanged and we 1160 + * have a generic buffer for each possible HMC connection. 1161 + */ 1162 + for (index = 0; index <= ibmvmc.max_hmc_index; index++) { 1163 + valid = 0; 1164 + ibmvmc_count_hmc_buffers(index, &valid, &free); 1165 + if (valid == 0) { 1166 + pr_warn("ibmvmc: buffers not ready for index %d\n", 1167 + index); 1168 + return -ENOBUFS; 1169 + } 1170 + } 1171 + 1172 + /* Get an hmc object, and transition to ibmhmc_state_initial */ 1173 + hmc = ibmvmc_get_free_hmc(); 1174 + if (!hmc) { 1175 + pr_warn("%s: free hmc not found\n", __func__); 1176 + return -EBUSY; 1177 + } 1178 + 1179 + hmc->session = hmc->session + 1; 1180 + if (hmc->session == 0xff) 1181 + hmc->session = 1; 1182 + 1183 + session->hmc = hmc; 1184 + hmc->adapter = &ibmvmc_adapter; 1185 + hmc->file_session = session; 1186 + session->valid = 1; 1187 + 1188 + return 0; 1189 + } 1190 + 1191 + /** 1192 + * ibmvmc_ioctl_sethmcid - IOCTL Set HMC ID 1193 + * 1194 + * @session: ibmvmc_file_session struct 1195 + * @new_hmc_id: HMC id field 1196 + * 1197 + * IOCTL command to setup the hmc id 1198 + * 1199 + * Return: 1200 + * 0 - Success 1201 + * Non-zero - Failure 1202 + */ 1203 + static long ibmvmc_ioctl_sethmcid(struct ibmvmc_file_session *session, 1204 + unsigned char __user *new_hmc_id) 1205 + { 1206 + struct ibmvmc_hmc *hmc; 1207 + struct ibmvmc_buffer *buffer; 1208 + size_t bytes; 1209 + char print_buffer[HMC_ID_LEN + 1]; 1210 + unsigned long flags; 1211 + long rc = 0; 1212 + 1213 + /* Reserve HMC session */ 1214 + hmc = session->hmc; 1215 + if (!hmc) { 1216 + rc = ibmvmc_setup_hmc(session); 1217 + if (rc) 1218 + return rc; 1219 + 1220 + hmc = session->hmc; 1221 + if (!hmc) { 1222 + pr_err("ibmvmc: setup_hmc success but no hmc\n"); 1223 + return -EIO; 1224 + } 1225 + } 1226 + 1227 + if (hmc->state != ibmhmc_state_initial) { 1228 + pr_warn("ibmvmc: sethmcid: invalid state to send open 0x%x\n", 1229 + hmc->state); 1230 + return -EIO; 1231 + } 1232 + 1233 + bytes = copy_from_user(hmc->hmc_id, new_hmc_id, HMC_ID_LEN); 1234 + if (bytes) 1235 + return -EFAULT; 1236 + 1237 + /* Send Open Session command */ 1238 + spin_lock_irqsave(&hmc->lock, flags); 1239 + buffer = ibmvmc_get_valid_hmc_buffer(hmc->index); 1240 + spin_unlock_irqrestore(&hmc->lock, flags); 1241 + 1242 + if (!buffer || !buffer->real_addr_local) { 1243 + pr_warn("ibmvmc: sethmcid: no buffer available\n"); 1244 + return -EIO; 1245 + } 1246 + 1247 + /* Make sure buffer is NULL terminated before trying to print it */ 1248 + memset(print_buffer, 0, HMC_ID_LEN + 1); 1249 + strncpy(print_buffer, hmc->hmc_id, HMC_ID_LEN); 1250 + pr_info("ibmvmc: sethmcid: Set HMC ID: \"%s\"\n", print_buffer); 1251 + 1252 + memcpy(buffer->real_addr_local, hmc->hmc_id, HMC_ID_LEN); 1253 + /* RDMA over ID, send open msg, change state to ibmhmc_state_opening */ 1254 + rc = ibmvmc_send_open(buffer, hmc); 1255 + 1256 + return rc; 1257 + } 1258 + 1259 + /** 1260 + * ibmvmc_ioctl_query - IOCTL Query 1261 + * 1262 + * @session: ibmvmc_file_session struct 1263 + * @ret_struct: ibmvmc_query_struct 1264 + * 1265 + * Return: 1266 + * 0 - Success 1267 + * Non-zero - Failure 1268 + */ 1269 + static long ibmvmc_ioctl_query(struct ibmvmc_file_session *session, 1270 + struct ibmvmc_query_struct __user *ret_struct) 1271 + { 1272 + struct ibmvmc_query_struct query_struct; 1273 + size_t bytes; 1274 + 1275 + memset(&query_struct, 0, sizeof(query_struct)); 1276 + query_struct.have_vmc = (ibmvmc.state > ibmvmc_state_initial); 1277 + query_struct.state = ibmvmc.state; 1278 + query_struct.vmc_drc_index = ibmvmc.vmc_drc_index; 1279 + 1280 + bytes = copy_to_user(ret_struct, &query_struct, 1281 + sizeof(query_struct)); 1282 + if (bytes) 1283 + return -EFAULT; 1284 + 1285 + return 0; 1286 + } 1287 + 1288 + /** 1289 + * ibmvmc_ioctl_requestvmc - IOCTL Request VMC 1290 + * 1291 + * @session: ibmvmc_file_session struct 1292 + * @ret_vmc_index: VMC Index 1293 + * 1294 + * Return: 1295 + * 0 - Success 1296 + * Non-zero - Failure 1297 + */ 1298 + static long ibmvmc_ioctl_requestvmc(struct ibmvmc_file_session *session, 1299 + u32 __user *ret_vmc_index) 1300 + { 1301 + /* TODO: (adreznec) Add locking to control multiple process access */ 1302 + size_t bytes; 1303 + long rc; 1304 + u32 vmc_drc_index; 1305 + 1306 + /* Call to request the VMC device from phyp*/ 1307 + rc = h_request_vmc(&vmc_drc_index); 1308 + pr_debug("ibmvmc: requestvmc: H_REQUEST_VMC rc = 0x%lx\n", rc); 1309 + 1310 + if (rc == H_SUCCESS) { 1311 + rc = 0; 1312 + } else if (rc == H_FUNCTION) { 1313 + pr_err("ibmvmc: requestvmc: h_request_vmc not supported\n"); 1314 + return -EPERM; 1315 + } else if (rc == H_AUTHORITY) { 1316 + pr_err("ibmvmc: requestvmc: hypervisor denied vmc request\n"); 1317 + return -EPERM; 1318 + } else if (rc == H_HARDWARE) { 1319 + pr_err("ibmvmc: requestvmc: hypervisor hardware fault\n"); 1320 + return -EIO; 1321 + } else if (rc == H_RESOURCE) { 1322 + pr_err("ibmvmc: requestvmc: vmc resource unavailable\n"); 1323 + return -ENODEV; 1324 + } else if (rc == H_NOT_AVAILABLE) { 1325 + pr_err("ibmvmc: requestvmc: system cannot be vmc managed\n"); 1326 + return -EPERM; 1327 + } else if (rc == H_PARAMETER) { 1328 + pr_err("ibmvmc: requestvmc: invalid parameter\n"); 1329 + return -EINVAL; 1330 + } 1331 + 1332 + /* Success, set the vmc index in global struct */ 1333 + ibmvmc.vmc_drc_index = vmc_drc_index; 1334 + 1335 + bytes = copy_to_user(ret_vmc_index, &vmc_drc_index, 1336 + sizeof(*ret_vmc_index)); 1337 + if (bytes) { 1338 + pr_warn("ibmvmc: requestvmc: copy to user failed.\n"); 1339 + return -EFAULT; 1340 + } 1341 + return rc; 1342 + } 1343 + 1344 + /** 1345 + * ibmvmc_ioctl - IOCTL 1346 + * 1347 + * @session: ibmvmc_file_session struct 1348 + * @cmd: cmd field 1349 + * @arg: Argument field 1350 + * 1351 + * Return: 1352 + * 0 - Success 1353 + * Non-zero - Failure 1354 + */ 1355 + static long ibmvmc_ioctl(struct file *file, 1356 + unsigned int cmd, unsigned long arg) 1357 + { 1358 + struct ibmvmc_file_session *session = file->private_data; 1359 + 1360 + pr_debug("ibmvmc: ioctl file=0x%lx, cmd=0x%x, arg=0x%lx, ses=0x%lx\n", 1361 + (unsigned long)file, cmd, arg, 1362 + (unsigned long)session); 1363 + 1364 + if (!session) { 1365 + pr_warn("ibmvmc: ioctl: no session\n"); 1366 + return -EIO; 1367 + } 1368 + 1369 + switch (cmd) { 1370 + case VMC_IOCTL_SETHMCID: 1371 + return ibmvmc_ioctl_sethmcid(session, 1372 + (unsigned char __user *)arg); 1373 + case VMC_IOCTL_QUERY: 1374 + return ibmvmc_ioctl_query(session, 1375 + (struct ibmvmc_query_struct __user *)arg); 1376 + case VMC_IOCTL_REQUESTVMC: 1377 + return ibmvmc_ioctl_requestvmc(session, 1378 + (unsigned int __user *)arg); 1379 + default: 1380 + pr_warn("ibmvmc: unknown ioctl 0x%x\n", cmd); 1381 + return -EINVAL; 1382 + } 1383 + } 1384 + 1385 + static const struct file_operations ibmvmc_fops = { 1386 + .owner = THIS_MODULE, 1387 + .read = ibmvmc_read, 1388 + .write = ibmvmc_write, 1389 + .poll = ibmvmc_poll, 1390 + .unlocked_ioctl = ibmvmc_ioctl, 1391 + .open = ibmvmc_open, 1392 + .release = ibmvmc_close, 1393 + }; 1394 + 1395 + /** 1396 + * ibmvmc_add_buffer - Add Buffer 1397 + * 1398 + * @adapter: crq_server_adapter struct 1399 + * @crq: ibmvmc_crq_msg struct 1400 + * 1401 + * This message transfers a buffer from hypervisor ownership to management 1402 + * partition ownership. The LIOBA is obtained from the virtual TCE table 1403 + * associated with the hypervisor side of the VMC device, and points to a 1404 + * buffer of size MTU (as established in the capabilities exchange). 1405 + * 1406 + * Typical flow for ading buffers: 1407 + * 1. A new management application connection is opened by the management 1408 + * partition. 1409 + * 2. The hypervisor assigns new buffers for the traffic associated with 1410 + * that connection. 1411 + * 3. The hypervisor sends VMC Add Buffer messages to the management 1412 + * partition, informing it of the new buffers. 1413 + * 4. The hypervisor sends an HMC protocol message (to the management 1414 + * application) notifying it of the new buffers. This informs the 1415 + * application that it has buffers available for sending HMC 1416 + * commands. 1417 + * 1418 + * Return: 1419 + * 0 - Success 1420 + * Non-zero - Failure 1421 + */ 1422 + static int ibmvmc_add_buffer(struct crq_server_adapter *adapter, 1423 + struct ibmvmc_crq_msg *crq) 1424 + { 1425 + struct ibmvmc_buffer *buffer; 1426 + u8 hmc_index; 1427 + u8 hmc_session; 1428 + u16 buffer_id; 1429 + unsigned long flags; 1430 + int rc = 0; 1431 + 1432 + if (!crq) 1433 + return -1; 1434 + 1435 + hmc_session = crq->hmc_session; 1436 + hmc_index = crq->hmc_index; 1437 + buffer_id = be16_to_cpu(crq->var2.buffer_id); 1438 + 1439 + if (hmc_index > ibmvmc.max_hmc_index) { 1440 + dev_err(adapter->dev, "add_buffer: invalid hmc_index = 0x%x\n", 1441 + hmc_index); 1442 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX, 1443 + hmc_session, hmc_index, buffer_id); 1444 + return -1; 1445 + } 1446 + 1447 + if (buffer_id >= ibmvmc.max_buffer_pool_size) { 1448 + dev_err(adapter->dev, "add_buffer: invalid buffer_id = 0x%x\n", 1449 + buffer_id); 1450 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID, 1451 + hmc_session, hmc_index, buffer_id); 1452 + return -1; 1453 + } 1454 + 1455 + spin_lock_irqsave(&hmcs[hmc_index].lock, flags); 1456 + buffer = &hmcs[hmc_index].buffer[buffer_id]; 1457 + 1458 + if (buffer->real_addr_local || buffer->dma_addr_local) { 1459 + dev_warn(adapter->dev, "add_buffer: already allocated id = 0x%lx\n", 1460 + (unsigned long)buffer_id); 1461 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 1462 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID, 1463 + hmc_session, hmc_index, buffer_id); 1464 + return -1; 1465 + } 1466 + 1467 + buffer->real_addr_local = alloc_dma_buffer(to_vio_dev(adapter->dev), 1468 + ibmvmc.max_mtu, 1469 + &buffer->dma_addr_local); 1470 + 1471 + if (!buffer->real_addr_local) { 1472 + dev_err(adapter->dev, "add_buffer: alloc_dma_buffer failed.\n"); 1473 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 1474 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INTERFACE_FAILURE, 1475 + hmc_session, hmc_index, buffer_id); 1476 + return -1; 1477 + } 1478 + 1479 + buffer->dma_addr_remote = be32_to_cpu(crq->var3.lioba); 1480 + buffer->size = ibmvmc.max_mtu; 1481 + buffer->owner = crq->var1.owner; 1482 + buffer->free = 1; 1483 + /* Must ensure valid==1 is observable only after all other fields are */ 1484 + dma_wmb(); 1485 + buffer->valid = 1; 1486 + buffer->id = buffer_id; 1487 + 1488 + dev_dbg(adapter->dev, "add_buffer: successfully added a buffer:\n"); 1489 + dev_dbg(adapter->dev, " index: %d, session: %d, buffer: 0x%x, owner: %d\n", 1490 + hmc_index, hmc_session, buffer_id, buffer->owner); 1491 + dev_dbg(adapter->dev, " local: 0x%x, remote: 0x%x\n", 1492 + (u32)buffer->dma_addr_local, 1493 + (u32)buffer->dma_addr_remote); 1494 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 1495 + 1496 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_SUCCESS, hmc_session, 1497 + hmc_index, buffer_id); 1498 + 1499 + return rc; 1500 + } 1501 + 1502 + /** 1503 + * ibmvmc_rem_buffer - Remove Buffer 1504 + * 1505 + * @adapter: crq_server_adapter struct 1506 + * @crq: ibmvmc_crq_msg struct 1507 + * 1508 + * This message requests an HMC buffer to be transferred from management 1509 + * partition ownership to hypervisor ownership. The management partition may 1510 + * not be able to satisfy the request at a particular point in time if all its 1511 + * buffers are in use. The management partition requires a depth of at least 1512 + * one inbound buffer to allow management application commands to flow to the 1513 + * hypervisor. It is, therefore, an interface error for the hypervisor to 1514 + * attempt to remove the management partition's last buffer. 1515 + * 1516 + * The hypervisor is expected to manage buffer usage with the management 1517 + * application directly and inform the management partition when buffers may be 1518 + * removed. The typical flow for removing buffers: 1519 + * 1520 + * 1. The management application no longer needs a communication path to a 1521 + * particular hypervisor function. That function is closed. 1522 + * 2. The hypervisor and the management application quiesce all traffic to that 1523 + * function. The hypervisor requests a reduction in buffer pool size. 1524 + * 3. The management application acknowledges the reduction in buffer pool size. 1525 + * 4. The hypervisor sends a Remove Buffer message to the management partition, 1526 + * informing it of the reduction in buffers. 1527 + * 5. The management partition verifies it can remove the buffer. This is 1528 + * possible if buffers have been quiesced. 1529 + * 1530 + * Return: 1531 + * 0 - Success 1532 + * Non-zero - Failure 1533 + */ 1534 + /* 1535 + * The hypervisor requested that we pick an unused buffer, and return it. 1536 + * Before sending the buffer back, we free any storage associated with the 1537 + * buffer. 1538 + */ 1539 + static int ibmvmc_rem_buffer(struct crq_server_adapter *adapter, 1540 + struct ibmvmc_crq_msg *crq) 1541 + { 1542 + struct ibmvmc_buffer *buffer; 1543 + u8 hmc_index; 1544 + u8 hmc_session; 1545 + u16 buffer_id = 0; 1546 + unsigned long flags; 1547 + int rc = 0; 1548 + 1549 + if (!crq) 1550 + return -1; 1551 + 1552 + hmc_session = crq->hmc_session; 1553 + hmc_index = crq->hmc_index; 1554 + 1555 + if (hmc_index > ibmvmc.max_hmc_index) { 1556 + dev_warn(adapter->dev, "rem_buffer: invalid hmc_index = 0x%x\n", 1557 + hmc_index); 1558 + ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX, 1559 + hmc_session, hmc_index, buffer_id); 1560 + return -1; 1561 + } 1562 + 1563 + spin_lock_irqsave(&hmcs[hmc_index].lock, flags); 1564 + buffer = ibmvmc_get_free_hmc_buffer(adapter, hmc_index); 1565 + if (!buffer) { 1566 + dev_info(adapter->dev, "rem_buffer: no buffer to remove\n"); 1567 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 1568 + ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_NO_BUFFER, 1569 + hmc_session, hmc_index, 1570 + VMC_INVALID_BUFFER_ID); 1571 + return -1; 1572 + } 1573 + 1574 + buffer_id = buffer->id; 1575 + 1576 + if (buffer->valid) 1577 + free_dma_buffer(to_vio_dev(adapter->dev), 1578 + ibmvmc.max_mtu, 1579 + buffer->real_addr_local, 1580 + buffer->dma_addr_local); 1581 + 1582 + memset(buffer, 0, sizeof(struct ibmvmc_buffer)); 1583 + spin_unlock_irqrestore(&hmcs[hmc_index].lock, flags); 1584 + 1585 + dev_dbg(adapter->dev, "rem_buffer: removed buffer 0x%x.\n", buffer_id); 1586 + ibmvmc_send_rem_buffer_resp(adapter, VMC_MSG_SUCCESS, hmc_session, 1587 + hmc_index, buffer_id); 1588 + 1589 + return rc; 1590 + } 1591 + 1592 + static int ibmvmc_recv_msg(struct crq_server_adapter *adapter, 1593 + struct ibmvmc_crq_msg *crq) 1594 + { 1595 + struct ibmvmc_buffer *buffer; 1596 + struct ibmvmc_hmc *hmc; 1597 + unsigned long msg_len; 1598 + u8 hmc_index; 1599 + u8 hmc_session; 1600 + u16 buffer_id; 1601 + unsigned long flags; 1602 + int rc = 0; 1603 + 1604 + if (!crq) 1605 + return -1; 1606 + 1607 + /* Hypervisor writes CRQs directly into our memory in big endian */ 1608 + dev_dbg(adapter->dev, "Recv_msg: msg from HV 0x%016llx 0x%016llx\n", 1609 + be64_to_cpu(*((unsigned long *)crq)), 1610 + be64_to_cpu(*(((unsigned long *)crq) + 1))); 1611 + 1612 + hmc_session = crq->hmc_session; 1613 + hmc_index = crq->hmc_index; 1614 + buffer_id = be16_to_cpu(crq->var2.buffer_id); 1615 + msg_len = be32_to_cpu(crq->var3.msg_len); 1616 + 1617 + if (hmc_index > ibmvmc.max_hmc_index) { 1618 + dev_err(adapter->dev, "Recv_msg: invalid hmc_index = 0x%x\n", 1619 + hmc_index); 1620 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_HMC_INDEX, 1621 + hmc_session, hmc_index, buffer_id); 1622 + return -1; 1623 + } 1624 + 1625 + if (buffer_id >= ibmvmc.max_buffer_pool_size) { 1626 + dev_err(adapter->dev, "Recv_msg: invalid buffer_id = 0x%x\n", 1627 + buffer_id); 1628 + ibmvmc_send_add_buffer_resp(adapter, VMC_MSG_INVALID_BUFFER_ID, 1629 + hmc_session, hmc_index, buffer_id); 1630 + return -1; 1631 + } 1632 + 1633 + hmc = &hmcs[hmc_index]; 1634 + spin_lock_irqsave(&hmc->lock, flags); 1635 + 1636 + if (hmc->state == ibmhmc_state_free) { 1637 + dev_err(adapter->dev, "Recv_msg: invalid hmc state = 0x%x\n", 1638 + hmc->state); 1639 + /* HMC connection is not valid (possibly was reset under us). */ 1640 + spin_unlock_irqrestore(&hmc->lock, flags); 1641 + return -1; 1642 + } 1643 + 1644 + buffer = &hmc->buffer[buffer_id]; 1645 + 1646 + if (buffer->valid == 0 || buffer->owner == VMC_BUF_OWNER_ALPHA) { 1647 + dev_err(adapter->dev, "Recv_msg: not valid, or not HV. 0x%x 0x%x\n", 1648 + buffer->valid, buffer->owner); 1649 + spin_unlock_irqrestore(&hmc->lock, flags); 1650 + return -1; 1651 + } 1652 + 1653 + /* RDMA the data into the partition. */ 1654 + rc = h_copy_rdma(msg_len, 1655 + adapter->riobn, 1656 + buffer->dma_addr_remote, 1657 + adapter->liobn, 1658 + buffer->dma_addr_local); 1659 + 1660 + dev_dbg(adapter->dev, "Recv_msg: msg_len = 0x%x, buffer_id = 0x%x, queue_head = 0x%x, hmc_idx = 0x%x\n", 1661 + (unsigned int)msg_len, (unsigned int)buffer_id, 1662 + (unsigned int)hmc->queue_head, (unsigned int)hmc_index); 1663 + buffer->msg_len = msg_len; 1664 + buffer->free = 0; 1665 + buffer->owner = VMC_BUF_OWNER_ALPHA; 1666 + 1667 + if (rc) { 1668 + dev_err(adapter->dev, "Failure in recv_msg: h_copy_rdma = 0x%x\n", 1669 + rc); 1670 + spin_unlock_irqrestore(&hmc->lock, flags); 1671 + return -1; 1672 + } 1673 + 1674 + /* Must be locked because read operates on the same data */ 1675 + hmc->queue_outbound_msgs[hmc->queue_head] = buffer_id; 1676 + hmc->queue_head++; 1677 + if (hmc->queue_head == ibmvmc_max_buf_pool_size) 1678 + hmc->queue_head = 0; 1679 + 1680 + if (hmc->queue_head == hmc->queue_tail) 1681 + dev_err(adapter->dev, "outbound buffer queue wrapped.\n"); 1682 + 1683 + spin_unlock_irqrestore(&hmc->lock, flags); 1684 + 1685 + wake_up_interruptible(&ibmvmc_read_wait); 1686 + 1687 + return 0; 1688 + } 1689 + 1690 + /** 1691 + * ibmvmc_process_capabilities - Process Capabilities 1692 + * 1693 + * @adapter: crq_server_adapter struct 1694 + * @crqp: ibmvmc_crq_msg struct 1695 + * 1696 + */ 1697 + static void ibmvmc_process_capabilities(struct crq_server_adapter *adapter, 1698 + struct ibmvmc_crq_msg *crqp) 1699 + { 1700 + struct ibmvmc_admin_crq_msg *crq = (struct ibmvmc_admin_crq_msg *)crqp; 1701 + 1702 + if ((be16_to_cpu(crq->version) >> 8) != 1703 + (IBMVMC_PROTOCOL_VERSION >> 8)) { 1704 + dev_err(adapter->dev, "init failed, incompatible versions 0x%x 0x%x\n", 1705 + be16_to_cpu(crq->version), 1706 + IBMVMC_PROTOCOL_VERSION); 1707 + ibmvmc.state = ibmvmc_state_failed; 1708 + return; 1709 + } 1710 + 1711 + ibmvmc.max_mtu = min_t(u32, ibmvmc_max_mtu, be32_to_cpu(crq->max_mtu)); 1712 + ibmvmc.max_buffer_pool_size = min_t(u16, ibmvmc_max_buf_pool_size, 1713 + be16_to_cpu(crq->pool_size)); 1714 + ibmvmc.max_hmc_index = min_t(u8, ibmvmc_max_hmcs, crq->max_hmc) - 1; 1715 + ibmvmc.state = ibmvmc_state_ready; 1716 + 1717 + dev_info(adapter->dev, "Capabilities: mtu=0x%x, pool_size=0x%x, max_hmc=0x%x\n", 1718 + ibmvmc.max_mtu, ibmvmc.max_buffer_pool_size, 1719 + ibmvmc.max_hmc_index); 1720 + } 1721 + 1722 + /** 1723 + * ibmvmc_validate_hmc_session - Validate HMC Session 1724 + * 1725 + * @adapter: crq_server_adapter struct 1726 + * @crq: ibmvmc_crq_msg struct 1727 + * 1728 + * Return: 1729 + * 0 - Success 1730 + * Non-zero - Failure 1731 + */ 1732 + static int ibmvmc_validate_hmc_session(struct crq_server_adapter *adapter, 1733 + struct ibmvmc_crq_msg *crq) 1734 + { 1735 + unsigned char hmc_index; 1736 + 1737 + hmc_index = crq->hmc_index; 1738 + 1739 + if (crq->hmc_session == 0) 1740 + return 0; 1741 + 1742 + if (hmc_index > ibmvmc.max_hmc_index) 1743 + return -1; 1744 + 1745 + if (hmcs[hmc_index].session != crq->hmc_session) { 1746 + dev_warn(adapter->dev, "Drop, bad session: expected 0x%x, recv 0x%x\n", 1747 + hmcs[hmc_index].session, crq->hmc_session); 1748 + return -1; 1749 + } 1750 + 1751 + return 0; 1752 + } 1753 + 1754 + /** 1755 + * ibmvmc_reset - Reset 1756 + * 1757 + * @adapter: crq_server_adapter struct 1758 + * @xport_event: export_event field 1759 + * 1760 + * Closes all HMC sessions and conditionally schedules a CRQ reset. 1761 + * @xport_event: If true, the partner closed their CRQ; we don't need to reset. 1762 + * If false, we need to schedule a CRQ reset. 1763 + */ 1764 + static void ibmvmc_reset(struct crq_server_adapter *adapter, bool xport_event) 1765 + { 1766 + int i; 1767 + 1768 + if (ibmvmc.state != ibmvmc_state_sched_reset) { 1769 + dev_info(adapter->dev, "*** Reset to initial state.\n"); 1770 + for (i = 0; i < ibmvmc_max_hmcs; i++) 1771 + ibmvmc_return_hmc(&hmcs[i], xport_event); 1772 + 1773 + if (xport_event) { 1774 + /* CRQ was closed by the partner. We don't need to do 1775 + * anything except set ourself to the correct state to 1776 + * handle init msgs. 1777 + */ 1778 + ibmvmc.state = ibmvmc_state_crqinit; 1779 + } else { 1780 + /* The partner did not close their CRQ - instead, we're 1781 + * closing the CRQ on our end. Need to schedule this 1782 + * for process context, because CRQ reset may require a 1783 + * sleep. 1784 + * 1785 + * Setting ibmvmc.state here immediately prevents 1786 + * ibmvmc_open from completing until the reset 1787 + * completes in process context. 1788 + */ 1789 + ibmvmc.state = ibmvmc_state_sched_reset; 1790 + dev_dbg(adapter->dev, "Device reset scheduled"); 1791 + wake_up_interruptible(&adapter->reset_wait_queue); 1792 + } 1793 + } 1794 + } 1795 + 1796 + /** 1797 + * ibmvmc_reset_task - Reset Task 1798 + * 1799 + * @data: Data field 1800 + * 1801 + * Performs a CRQ reset of the VMC device in process context. 1802 + * NOTE: This function should not be called directly, use ibmvmc_reset. 1803 + */ 1804 + static int ibmvmc_reset_task(void *data) 1805 + { 1806 + struct crq_server_adapter *adapter = data; 1807 + int rc; 1808 + 1809 + set_user_nice(current, -20); 1810 + 1811 + while (!kthread_should_stop()) { 1812 + wait_event_interruptible(adapter->reset_wait_queue, 1813 + (ibmvmc.state == ibmvmc_state_sched_reset) || 1814 + kthread_should_stop()); 1815 + 1816 + if (kthread_should_stop()) 1817 + break; 1818 + 1819 + dev_dbg(adapter->dev, "CRQ resetting in process context"); 1820 + tasklet_disable(&adapter->work_task); 1821 + 1822 + rc = ibmvmc_reset_crq_queue(adapter); 1823 + 1824 + if (rc != H_SUCCESS && rc != H_RESOURCE) { 1825 + dev_err(adapter->dev, "Error initializing CRQ. rc = 0x%x\n", 1826 + rc); 1827 + ibmvmc.state = ibmvmc_state_failed; 1828 + } else { 1829 + ibmvmc.state = ibmvmc_state_crqinit; 1830 + 1831 + if (ibmvmc_send_crq(adapter, 0xC001000000000000LL, 0) 1832 + != 0 && rc != H_RESOURCE) 1833 + dev_warn(adapter->dev, "Failed to send initialize CRQ message\n"); 1834 + } 1835 + 1836 + vio_enable_interrupts(to_vio_dev(adapter->dev)); 1837 + tasklet_enable(&adapter->work_task); 1838 + } 1839 + 1840 + return 0; 1841 + } 1842 + 1843 + /** 1844 + * ibmvmc_process_open_resp - Process Open Response 1845 + * 1846 + * @crq: ibmvmc_crq_msg struct 1847 + * @adapter: crq_server_adapter struct 1848 + * 1849 + * This command is sent by the hypervisor in response to the Interface 1850 + * Open message. When this message is received, the indicated buffer is 1851 + * again available for management partition use. 1852 + */ 1853 + static void ibmvmc_process_open_resp(struct ibmvmc_crq_msg *crq, 1854 + struct crq_server_adapter *adapter) 1855 + { 1856 + unsigned char hmc_index; 1857 + unsigned short buffer_id; 1858 + 1859 + hmc_index = crq->hmc_index; 1860 + if (hmc_index > ibmvmc.max_hmc_index) { 1861 + /* Why would PHYP give an index > max negotiated? */ 1862 + ibmvmc_reset(adapter, false); 1863 + return; 1864 + } 1865 + 1866 + if (crq->status) { 1867 + dev_warn(adapter->dev, "open_resp: failed - status 0x%x\n", 1868 + crq->status); 1869 + ibmvmc_return_hmc(&hmcs[hmc_index], false); 1870 + return; 1871 + } 1872 + 1873 + if (hmcs[hmc_index].state == ibmhmc_state_opening) { 1874 + buffer_id = be16_to_cpu(crq->var2.buffer_id); 1875 + if (buffer_id >= ibmvmc.max_buffer_pool_size) { 1876 + dev_err(adapter->dev, "open_resp: invalid buffer_id = 0x%x\n", 1877 + buffer_id); 1878 + hmcs[hmc_index].state = ibmhmc_state_failed; 1879 + } else { 1880 + ibmvmc_free_hmc_buffer(&hmcs[hmc_index], 1881 + &hmcs[hmc_index].buffer[buffer_id]); 1882 + hmcs[hmc_index].state = ibmhmc_state_ready; 1883 + dev_dbg(adapter->dev, "open_resp: set hmc state = ready\n"); 1884 + } 1885 + } else { 1886 + dev_warn(adapter->dev, "open_resp: invalid hmc state (0x%x)\n", 1887 + hmcs[hmc_index].state); 1888 + } 1889 + } 1890 + 1891 + /** 1892 + * ibmvmc_process_close_resp - Process Close Response 1893 + * 1894 + * @crq: ibmvmc_crq_msg struct 1895 + * @adapter: crq_server_adapter struct 1896 + * 1897 + * This command is sent by the hypervisor in response to the managemant 1898 + * application Interface Close message. 1899 + * 1900 + * If the close fails, simply reset the entire driver as the state of the VMC 1901 + * must be in tough shape. 1902 + */ 1903 + static void ibmvmc_process_close_resp(struct ibmvmc_crq_msg *crq, 1904 + struct crq_server_adapter *adapter) 1905 + { 1906 + unsigned char hmc_index; 1907 + 1908 + hmc_index = crq->hmc_index; 1909 + if (hmc_index > ibmvmc.max_hmc_index) { 1910 + ibmvmc_reset(adapter, false); 1911 + return; 1912 + } 1913 + 1914 + if (crq->status) { 1915 + dev_warn(adapter->dev, "close_resp: failed - status 0x%x\n", 1916 + crq->status); 1917 + ibmvmc_reset(adapter, false); 1918 + return; 1919 + } 1920 + 1921 + ibmvmc_return_hmc(&hmcs[hmc_index], false); 1922 + } 1923 + 1924 + /** 1925 + * ibmvmc_crq_process - Process CRQ 1926 + * 1927 + * @adapter: crq_server_adapter struct 1928 + * @crq: ibmvmc_crq_msg struct 1929 + * 1930 + * Process the CRQ message based upon the type of message received. 1931 + * 1932 + */ 1933 + static void ibmvmc_crq_process(struct crq_server_adapter *adapter, 1934 + struct ibmvmc_crq_msg *crq) 1935 + { 1936 + switch (crq->type) { 1937 + case VMC_MSG_CAP_RESP: 1938 + dev_dbg(adapter->dev, "CRQ recv: capabilities resp (0x%x)\n", 1939 + crq->type); 1940 + if (ibmvmc.state == ibmvmc_state_capabilities) 1941 + ibmvmc_process_capabilities(adapter, crq); 1942 + else 1943 + dev_warn(adapter->dev, "caps msg invalid in state 0x%x\n", 1944 + ibmvmc.state); 1945 + break; 1946 + case VMC_MSG_OPEN_RESP: 1947 + dev_dbg(adapter->dev, "CRQ recv: open resp (0x%x)\n", 1948 + crq->type); 1949 + if (ibmvmc_validate_hmc_session(adapter, crq) == 0) 1950 + ibmvmc_process_open_resp(crq, adapter); 1951 + break; 1952 + case VMC_MSG_ADD_BUF: 1953 + dev_dbg(adapter->dev, "CRQ recv: add buf (0x%x)\n", 1954 + crq->type); 1955 + if (ibmvmc_validate_hmc_session(adapter, crq) == 0) 1956 + ibmvmc_add_buffer(adapter, crq); 1957 + break; 1958 + case VMC_MSG_REM_BUF: 1959 + dev_dbg(adapter->dev, "CRQ recv: rem buf (0x%x)\n", 1960 + crq->type); 1961 + if (ibmvmc_validate_hmc_session(adapter, crq) == 0) 1962 + ibmvmc_rem_buffer(adapter, crq); 1963 + break; 1964 + case VMC_MSG_SIGNAL: 1965 + dev_dbg(adapter->dev, "CRQ recv: signal msg (0x%x)\n", 1966 + crq->type); 1967 + if (ibmvmc_validate_hmc_session(adapter, crq) == 0) 1968 + ibmvmc_recv_msg(adapter, crq); 1969 + break; 1970 + case VMC_MSG_CLOSE_RESP: 1971 + dev_dbg(adapter->dev, "CRQ recv: close resp (0x%x)\n", 1972 + crq->type); 1973 + if (ibmvmc_validate_hmc_session(adapter, crq) == 0) 1974 + ibmvmc_process_close_resp(crq, adapter); 1975 + break; 1976 + case VMC_MSG_CAP: 1977 + case VMC_MSG_OPEN: 1978 + case VMC_MSG_CLOSE: 1979 + case VMC_MSG_ADD_BUF_RESP: 1980 + case VMC_MSG_REM_BUF_RESP: 1981 + dev_warn(adapter->dev, "CRQ recv: unexpected msg (0x%x)\n", 1982 + crq->type); 1983 + break; 1984 + default: 1985 + dev_warn(adapter->dev, "CRQ recv: unknown msg (0x%x)\n", 1986 + crq->type); 1987 + break; 1988 + } 1989 + } 1990 + 1991 + /** 1992 + * ibmvmc_handle_crq_init - Handle CRQ Init 1993 + * 1994 + * @crq: ibmvmc_crq_msg struct 1995 + * @adapter: crq_server_adapter struct 1996 + * 1997 + * Handle the type of crq initialization based on whether 1998 + * it is a message or a response. 1999 + * 2000 + */ 2001 + static void ibmvmc_handle_crq_init(struct ibmvmc_crq_msg *crq, 2002 + struct crq_server_adapter *adapter) 2003 + { 2004 + switch (crq->type) { 2005 + case 0x01: /* Initialization message */ 2006 + dev_dbg(adapter->dev, "CRQ recv: CRQ init msg - state 0x%x\n", 2007 + ibmvmc.state); 2008 + if (ibmvmc.state == ibmvmc_state_crqinit) { 2009 + /* Send back a response */ 2010 + if (ibmvmc_send_crq(adapter, 0xC002000000000000, 2011 + 0) == 0) 2012 + ibmvmc_send_capabilities(adapter); 2013 + else 2014 + dev_err(adapter->dev, " Unable to send init rsp\n"); 2015 + } else { 2016 + dev_err(adapter->dev, "Invalid state 0x%x mtu = 0x%x\n", 2017 + ibmvmc.state, ibmvmc.max_mtu); 2018 + } 2019 + 2020 + break; 2021 + case 0x02: /* Initialization response */ 2022 + dev_dbg(adapter->dev, "CRQ recv: initialization resp msg - state 0x%x\n", 2023 + ibmvmc.state); 2024 + if (ibmvmc.state == ibmvmc_state_crqinit) 2025 + ibmvmc_send_capabilities(adapter); 2026 + break; 2027 + default: 2028 + dev_warn(adapter->dev, "Unknown crq message type 0x%lx\n", 2029 + (unsigned long)crq->type); 2030 + } 2031 + } 2032 + 2033 + /** 2034 + * ibmvmc_handle_crq - Handle CRQ 2035 + * 2036 + * @crq: ibmvmc_crq_msg struct 2037 + * @adapter: crq_server_adapter struct 2038 + * 2039 + * Read the command elements from the command queue and execute the 2040 + * requests based upon the type of crq message. 2041 + * 2042 + */ 2043 + static void ibmvmc_handle_crq(struct ibmvmc_crq_msg *crq, 2044 + struct crq_server_adapter *adapter) 2045 + { 2046 + switch (crq->valid) { 2047 + case 0xC0: /* initialization */ 2048 + ibmvmc_handle_crq_init(crq, adapter); 2049 + break; 2050 + case 0xFF: /* Hypervisor telling us the connection is closed */ 2051 + dev_warn(adapter->dev, "CRQ recv: virtual adapter failed - resetting.\n"); 2052 + ibmvmc_reset(adapter, true); 2053 + break; 2054 + case 0x80: /* real payload */ 2055 + ibmvmc_crq_process(adapter, crq); 2056 + break; 2057 + default: 2058 + dev_warn(adapter->dev, "CRQ recv: unknown msg 0x%02x.\n", 2059 + crq->valid); 2060 + break; 2061 + } 2062 + } 2063 + 2064 + static void ibmvmc_task(unsigned long data) 2065 + { 2066 + struct crq_server_adapter *adapter = 2067 + (struct crq_server_adapter *)data; 2068 + struct vio_dev *vdev = to_vio_dev(adapter->dev); 2069 + struct ibmvmc_crq_msg *crq; 2070 + int done = 0; 2071 + 2072 + while (!done) { 2073 + /* Pull all the valid messages off the CRQ */ 2074 + while ((crq = crq_queue_next_crq(&adapter->queue)) != NULL) { 2075 + ibmvmc_handle_crq(crq, adapter); 2076 + crq->valid = 0x00; 2077 + /* CRQ reset was requested, stop processing CRQs. 2078 + * Interrupts will be re-enabled by the reset task. 2079 + */ 2080 + if (ibmvmc.state == ibmvmc_state_sched_reset) 2081 + return; 2082 + } 2083 + 2084 + vio_enable_interrupts(vdev); 2085 + crq = crq_queue_next_crq(&adapter->queue); 2086 + if (crq) { 2087 + vio_disable_interrupts(vdev); 2088 + ibmvmc_handle_crq(crq, adapter); 2089 + crq->valid = 0x00; 2090 + /* CRQ reset was requested, stop processing CRQs. 2091 + * Interrupts will be re-enabled by the reset task. 2092 + */ 2093 + if (ibmvmc.state == ibmvmc_state_sched_reset) 2094 + return; 2095 + } else { 2096 + done = 1; 2097 + } 2098 + } 2099 + } 2100 + 2101 + /** 2102 + * ibmvmc_init_crq_queue - Init CRQ Queue 2103 + * 2104 + * @adapter: crq_server_adapter struct 2105 + * 2106 + * Return: 2107 + * 0 - Success 2108 + * Non-zero - Failure 2109 + */ 2110 + static int ibmvmc_init_crq_queue(struct crq_server_adapter *adapter) 2111 + { 2112 + struct vio_dev *vdev = to_vio_dev(adapter->dev); 2113 + struct crq_queue *queue = &adapter->queue; 2114 + int rc = 0; 2115 + int retrc = 0; 2116 + 2117 + queue->msgs = (struct ibmvmc_crq_msg *)get_zeroed_page(GFP_KERNEL); 2118 + 2119 + if (!queue->msgs) 2120 + goto malloc_failed; 2121 + 2122 + queue->size = PAGE_SIZE / sizeof(*queue->msgs); 2123 + 2124 + queue->msg_token = dma_map_single(adapter->dev, queue->msgs, 2125 + queue->size * sizeof(*queue->msgs), 2126 + DMA_BIDIRECTIONAL); 2127 + 2128 + if (dma_mapping_error(adapter->dev, queue->msg_token)) 2129 + goto map_failed; 2130 + 2131 + retrc = plpar_hcall_norets(H_REG_CRQ, 2132 + vdev->unit_address, 2133 + queue->msg_token, PAGE_SIZE); 2134 + retrc = rc; 2135 + 2136 + if (rc == H_RESOURCE) 2137 + rc = ibmvmc_reset_crq_queue(adapter); 2138 + 2139 + if (rc == 2) { 2140 + dev_warn(adapter->dev, "Partner adapter not ready\n"); 2141 + retrc = 0; 2142 + } else if (rc != 0) { 2143 + dev_err(adapter->dev, "Error %d opening adapter\n", rc); 2144 + goto reg_crq_failed; 2145 + } 2146 + 2147 + queue->cur = 0; 2148 + spin_lock_init(&queue->lock); 2149 + 2150 + tasklet_init(&adapter->work_task, ibmvmc_task, (unsigned long)adapter); 2151 + 2152 + if (request_irq(vdev->irq, 2153 + ibmvmc_handle_event, 2154 + 0, "ibmvmc", (void *)adapter) != 0) { 2155 + dev_err(adapter->dev, "couldn't register irq 0x%x\n", 2156 + vdev->irq); 2157 + goto req_irq_failed; 2158 + } 2159 + 2160 + rc = vio_enable_interrupts(vdev); 2161 + if (rc != 0) { 2162 + dev_err(adapter->dev, "Error %d enabling interrupts!!!\n", rc); 2163 + goto req_irq_failed; 2164 + } 2165 + 2166 + return retrc; 2167 + 2168 + req_irq_failed: 2169 + /* Cannot have any work since we either never got our IRQ registered, 2170 + * or never got interrupts enabled 2171 + */ 2172 + tasklet_kill(&adapter->work_task); 2173 + h_free_crq(vdev->unit_address); 2174 + reg_crq_failed: 2175 + dma_unmap_single(adapter->dev, 2176 + queue->msg_token, 2177 + queue->size * sizeof(*queue->msgs), DMA_BIDIRECTIONAL); 2178 + map_failed: 2179 + free_page((unsigned long)queue->msgs); 2180 + malloc_failed: 2181 + return -ENOMEM; 2182 + } 2183 + 2184 + /* Fill in the liobn and riobn fields on the adapter */ 2185 + static int read_dma_window(struct vio_dev *vdev, 2186 + struct crq_server_adapter *adapter) 2187 + { 2188 + const __be32 *dma_window; 2189 + const __be32 *prop; 2190 + 2191 + /* TODO Using of_parse_dma_window would be better, but it doesn't give 2192 + * a way to read multiple windows without already knowing the size of 2193 + * a window or the number of windows 2194 + */ 2195 + dma_window = 2196 + (const __be32 *)vio_get_attribute(vdev, "ibm,my-dma-window", 2197 + NULL); 2198 + if (!dma_window) { 2199 + dev_warn(adapter->dev, "Couldn't find ibm,my-dma-window property\n"); 2200 + return -1; 2201 + } 2202 + 2203 + adapter->liobn = be32_to_cpu(*dma_window); 2204 + dma_window++; 2205 + 2206 + prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-address-cells", 2207 + NULL); 2208 + if (!prop) { 2209 + dev_warn(adapter->dev, "Couldn't find ibm,#dma-address-cells property\n"); 2210 + dma_window++; 2211 + } else { 2212 + dma_window += be32_to_cpu(*prop); 2213 + } 2214 + 2215 + prop = (const __be32 *)vio_get_attribute(vdev, "ibm,#dma-size-cells", 2216 + NULL); 2217 + if (!prop) { 2218 + dev_warn(adapter->dev, "Couldn't find ibm,#dma-size-cells property\n"); 2219 + dma_window++; 2220 + } else { 2221 + dma_window += be32_to_cpu(*prop); 2222 + } 2223 + 2224 + /* dma_window should point to the second window now */ 2225 + adapter->riobn = be32_to_cpu(*dma_window); 2226 + 2227 + return 0; 2228 + } 2229 + 2230 + static int ibmvmc_probe(struct vio_dev *vdev, const struct vio_device_id *id) 2231 + { 2232 + struct crq_server_adapter *adapter = &ibmvmc_adapter; 2233 + int rc; 2234 + 2235 + dev_set_drvdata(&vdev->dev, NULL); 2236 + memset(adapter, 0, sizeof(*adapter)); 2237 + adapter->dev = &vdev->dev; 2238 + 2239 + dev_info(adapter->dev, "Probe for UA 0x%x\n", vdev->unit_address); 2240 + 2241 + rc = read_dma_window(vdev, adapter); 2242 + if (rc != 0) { 2243 + ibmvmc.state = ibmvmc_state_failed; 2244 + return -1; 2245 + } 2246 + 2247 + dev_dbg(adapter->dev, "Probe: liobn 0x%x, riobn 0x%x\n", 2248 + adapter->liobn, adapter->riobn); 2249 + 2250 + init_waitqueue_head(&adapter->reset_wait_queue); 2251 + adapter->reset_task = kthread_run(ibmvmc_reset_task, adapter, "ibmvmc"); 2252 + if (IS_ERR(adapter->reset_task)) { 2253 + dev_err(adapter->dev, "Failed to start reset thread\n"); 2254 + ibmvmc.state = ibmvmc_state_failed; 2255 + rc = PTR_ERR(adapter->reset_task); 2256 + adapter->reset_task = NULL; 2257 + return rc; 2258 + } 2259 + 2260 + rc = ibmvmc_init_crq_queue(adapter); 2261 + if (rc != 0 && rc != H_RESOURCE) { 2262 + dev_err(adapter->dev, "Error initializing CRQ. rc = 0x%x\n", 2263 + rc); 2264 + ibmvmc.state = ibmvmc_state_failed; 2265 + goto crq_failed; 2266 + } 2267 + 2268 + ibmvmc.state = ibmvmc_state_crqinit; 2269 + 2270 + /* Try to send an initialization message. Note that this is allowed 2271 + * to fail if the other end is not acive. In that case we just wait 2272 + * for the other side to initialize. 2273 + */ 2274 + if (ibmvmc_send_crq(adapter, 0xC001000000000000LL, 0) != 0 && 2275 + rc != H_RESOURCE) 2276 + dev_warn(adapter->dev, "Failed to send initialize CRQ message\n"); 2277 + 2278 + dev_set_drvdata(&vdev->dev, adapter); 2279 + 2280 + return 0; 2281 + 2282 + crq_failed: 2283 + kthread_stop(adapter->reset_task); 2284 + adapter->reset_task = NULL; 2285 + return -EPERM; 2286 + } 2287 + 2288 + static int ibmvmc_remove(struct vio_dev *vdev) 2289 + { 2290 + struct crq_server_adapter *adapter = dev_get_drvdata(&vdev->dev); 2291 + 2292 + dev_info(adapter->dev, "Entering remove for UA 0x%x\n", 2293 + vdev->unit_address); 2294 + ibmvmc_release_crq_queue(adapter); 2295 + 2296 + return 0; 2297 + } 2298 + 2299 + static struct vio_device_id ibmvmc_device_table[] = { 2300 + { "ibm,vmc", "IBM,vmc" }, 2301 + { "", "" } 2302 + }; 2303 + MODULE_DEVICE_TABLE(vio, ibmvmc_device_table); 2304 + 2305 + static struct vio_driver ibmvmc_driver = { 2306 + .name = ibmvmc_driver_name, 2307 + .id_table = ibmvmc_device_table, 2308 + .probe = ibmvmc_probe, 2309 + .remove = ibmvmc_remove, 2310 + }; 2311 + 2312 + static void __init ibmvmc_scrub_module_parms(void) 2313 + { 2314 + if (ibmvmc_max_mtu > MAX_MTU) { 2315 + pr_warn("ibmvmc: Max MTU reduced to %d\n", MAX_MTU); 2316 + ibmvmc_max_mtu = MAX_MTU; 2317 + } else if (ibmvmc_max_mtu < MIN_MTU) { 2318 + pr_warn("ibmvmc: Max MTU increased to %d\n", MIN_MTU); 2319 + ibmvmc_max_mtu = MIN_MTU; 2320 + } 2321 + 2322 + if (ibmvmc_max_buf_pool_size > MAX_BUF_POOL_SIZE) { 2323 + pr_warn("ibmvmc: Max buffer pool size reduced to %d\n", 2324 + MAX_BUF_POOL_SIZE); 2325 + ibmvmc_max_buf_pool_size = MAX_BUF_POOL_SIZE; 2326 + } else if (ibmvmc_max_buf_pool_size < MIN_BUF_POOL_SIZE) { 2327 + pr_warn("ibmvmc: Max buffer pool size increased to %d\n", 2328 + MIN_BUF_POOL_SIZE); 2329 + ibmvmc_max_buf_pool_size = MIN_BUF_POOL_SIZE; 2330 + } 2331 + 2332 + if (ibmvmc_max_hmcs > MAX_HMCS) { 2333 + pr_warn("ibmvmc: Max HMCs reduced to %d\n", MAX_HMCS); 2334 + ibmvmc_max_hmcs = MAX_HMCS; 2335 + } else if (ibmvmc_max_hmcs < MIN_HMCS) { 2336 + pr_warn("ibmvmc: Max HMCs increased to %d\n", MIN_HMCS); 2337 + ibmvmc_max_hmcs = MIN_HMCS; 2338 + } 2339 + } 2340 + 2341 + static struct miscdevice ibmvmc_miscdev = { 2342 + .name = ibmvmc_driver_name, 2343 + .minor = MISC_DYNAMIC_MINOR, 2344 + .fops = &ibmvmc_fops, 2345 + }; 2346 + 2347 + static int __init ibmvmc_module_init(void) 2348 + { 2349 + int rc, i, j; 2350 + 2351 + ibmvmc.state = ibmvmc_state_initial; 2352 + pr_info("ibmvmc: version %s\n", IBMVMC_DRIVER_VERSION); 2353 + 2354 + rc = misc_register(&ibmvmc_miscdev); 2355 + if (rc) { 2356 + pr_err("ibmvmc: misc registration failed\n"); 2357 + goto misc_register_failed; 2358 + } 2359 + pr_info("ibmvmc: node %d:%d\n", MISC_MAJOR, 2360 + ibmvmc_miscdev.minor); 2361 + 2362 + /* Initialize data structures */ 2363 + memset(hmcs, 0, sizeof(struct ibmvmc_hmc) * MAX_HMCS); 2364 + for (i = 0; i < MAX_HMCS; i++) { 2365 + spin_lock_init(&hmcs[i].lock); 2366 + hmcs[i].state = ibmhmc_state_free; 2367 + for (j = 0; j < MAX_BUF_POOL_SIZE; j++) 2368 + hmcs[i].queue_outbound_msgs[j] = VMC_INVALID_BUFFER_ID; 2369 + } 2370 + 2371 + /* Sanity check module parms */ 2372 + ibmvmc_scrub_module_parms(); 2373 + 2374 + /* 2375 + * Initialize some reasonable values. Might be negotiated smaller 2376 + * values during the capabilities exchange. 2377 + */ 2378 + ibmvmc.max_mtu = ibmvmc_max_mtu; 2379 + ibmvmc.max_buffer_pool_size = ibmvmc_max_buf_pool_size; 2380 + ibmvmc.max_hmc_index = ibmvmc_max_hmcs - 1; 2381 + 2382 + rc = vio_register_driver(&ibmvmc_driver); 2383 + 2384 + if (rc) { 2385 + pr_err("ibmvmc: rc %d from vio_register_driver\n", rc); 2386 + goto vio_reg_failed; 2387 + } 2388 + 2389 + return 0; 2390 + 2391 + vio_reg_failed: 2392 + misc_deregister(&ibmvmc_miscdev); 2393 + misc_register_failed: 2394 + return rc; 2395 + } 2396 + 2397 + static void __exit ibmvmc_module_exit(void) 2398 + { 2399 + pr_info("ibmvmc: module exit\n"); 2400 + vio_unregister_driver(&ibmvmc_driver); 2401 + misc_deregister(&ibmvmc_miscdev); 2402 + } 2403 + 2404 + module_init(ibmvmc_module_init); 2405 + module_exit(ibmvmc_module_exit); 2406 + 2407 + module_param_named(buf_pool_size, ibmvmc_max_buf_pool_size, 2408 + int, 0644); 2409 + MODULE_PARM_DESC(buf_pool_size, "Buffer pool size"); 2410 + module_param_named(max_hmcs, ibmvmc_max_hmcs, int, 0644); 2411 + MODULE_PARM_DESC(max_hmcs, "Max HMCs"); 2412 + module_param_named(max_mtu, ibmvmc_max_mtu, int, 0644); 2413 + MODULE_PARM_DESC(max_mtu, "Max MTU"); 2414 + 2415 + MODULE_AUTHOR("Steven Royer <seroyer@linux.vnet.ibm.com>"); 2416 + MODULE_DESCRIPTION("IBM VMC"); 2417 + MODULE_VERSION(IBMVMC_DRIVER_VERSION); 2418 + MODULE_LICENSE("GPL v2");
+209
drivers/misc/ibmvmc.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0+ 2 + * 3 + * linux/drivers/misc/ibmvmc.h 4 + * 5 + * IBM Power Systems Virtual Management Channel Support. 6 + * 7 + * Copyright (c) 2004, 2018 IBM Corp. 8 + * Dave Engebretsen engebret@us.ibm.com 9 + * Steven Royer seroyer@linux.vnet.ibm.com 10 + * Adam Reznechek adreznec@linux.vnet.ibm.com 11 + * Bryant G. Ly <bryantly@linux.vnet.ibm.com> 12 + */ 13 + #ifndef IBMVMC_H 14 + #define IBMVMC_H 15 + 16 + #include <linux/types.h> 17 + #include <linux/cdev.h> 18 + 19 + #include <asm/vio.h> 20 + 21 + #define IBMVMC_PROTOCOL_VERSION 0x0101 22 + 23 + #define MIN_BUF_POOL_SIZE 16 24 + #define MIN_HMCS 1 25 + #define MIN_MTU 4096 26 + #define MAX_BUF_POOL_SIZE 64 27 + #define MAX_HMCS 2 28 + #define MAX_MTU (4 * 4096) 29 + #define DEFAULT_BUF_POOL_SIZE 32 30 + #define DEFAULT_HMCS 1 31 + #define DEFAULT_MTU 4096 32 + #define HMC_ID_LEN 32 33 + 34 + #define VMC_INVALID_BUFFER_ID 0xFFFF 35 + 36 + /* ioctl numbers */ 37 + #define VMC_BASE 0xCC 38 + #define VMC_IOCTL_SETHMCID _IOW(VMC_BASE, 0x00, unsigned char *) 39 + #define VMC_IOCTL_QUERY _IOR(VMC_BASE, 0x01, struct ibmvmc_query_struct) 40 + #define VMC_IOCTL_REQUESTVMC _IOR(VMC_BASE, 0x02, u32) 41 + 42 + #define VMC_MSG_CAP 0x01 43 + #define VMC_MSG_CAP_RESP 0x81 44 + #define VMC_MSG_OPEN 0x02 45 + #define VMC_MSG_OPEN_RESP 0x82 46 + #define VMC_MSG_CLOSE 0x03 47 + #define VMC_MSG_CLOSE_RESP 0x83 48 + #define VMC_MSG_ADD_BUF 0x04 49 + #define VMC_MSG_ADD_BUF_RESP 0x84 50 + #define VMC_MSG_REM_BUF 0x05 51 + #define VMC_MSG_REM_BUF_RESP 0x85 52 + #define VMC_MSG_SIGNAL 0x06 53 + 54 + #define VMC_MSG_SUCCESS 0 55 + #define VMC_MSG_INVALID_HMC_INDEX 1 56 + #define VMC_MSG_INVALID_BUFFER_ID 2 57 + #define VMC_MSG_CLOSED_HMC 3 58 + #define VMC_MSG_INTERFACE_FAILURE 4 59 + #define VMC_MSG_NO_BUFFER 5 60 + 61 + #define VMC_BUF_OWNER_ALPHA 0 62 + #define VMC_BUF_OWNER_HV 1 63 + 64 + enum ibmvmc_states { 65 + ibmvmc_state_sched_reset = -1, 66 + ibmvmc_state_initial = 0, 67 + ibmvmc_state_crqinit = 1, 68 + ibmvmc_state_capabilities = 2, 69 + ibmvmc_state_ready = 3, 70 + ibmvmc_state_failed = 4, 71 + }; 72 + 73 + enum ibmhmc_states { 74 + /* HMC connection not established */ 75 + ibmhmc_state_free = 0, 76 + 77 + /* HMC connection established (open called) */ 78 + ibmhmc_state_initial = 1, 79 + 80 + /* open msg sent to HV, due to ioctl(1) call */ 81 + ibmhmc_state_opening = 2, 82 + 83 + /* HMC connection ready, open resp msg from HV */ 84 + ibmhmc_state_ready = 3, 85 + 86 + /* HMC connection failure */ 87 + ibmhmc_state_failed = 4, 88 + }; 89 + 90 + struct ibmvmc_buffer { 91 + u8 valid; /* 1 when DMA storage allocated to buffer */ 92 + u8 free; /* 1 when buffer available for the Alpha Partition */ 93 + u8 owner; 94 + u16 id; 95 + u32 size; 96 + u32 msg_len; 97 + dma_addr_t dma_addr_local; 98 + dma_addr_t dma_addr_remote; 99 + void *real_addr_local; 100 + }; 101 + 102 + struct ibmvmc_admin_crq_msg { 103 + u8 valid; /* RPA Defined */ 104 + u8 type; /* ibmvmc msg type */ 105 + u8 status; /* Response msg status. Zero is success and on failure, 106 + * either 1 - General Failure, or 2 - Invalid Version is 107 + * returned. 108 + */ 109 + u8 rsvd[2]; 110 + u8 max_hmc; /* Max # of independent HMC connections supported */ 111 + __be16 pool_size; /* Maximum number of buffers supported per HMC 112 + * connection 113 + */ 114 + __be32 max_mtu; /* Maximum message size supported (bytes) */ 115 + __be16 crq_size; /* # of entries available in the CRQ for the 116 + * source partition. The target partition must 117 + * limit the number of outstanding messages to 118 + * one half or less. 119 + */ 120 + __be16 version; /* Indicates the code level of the management partition 121 + * or the hypervisor with the high-order byte 122 + * indicating a major version and the low-order byte 123 + * indicating a minor version. 124 + */ 125 + }; 126 + 127 + struct ibmvmc_crq_msg { 128 + u8 valid; /* RPA Defined */ 129 + u8 type; /* ibmvmc msg type */ 130 + u8 status; /* Response msg status */ 131 + union { 132 + u8 rsvd; /* Reserved */ 133 + u8 owner; 134 + } var1; 135 + u8 hmc_session; /* Session Identifier for the current VMC connection */ 136 + u8 hmc_index; /* A unique HMC Idx would be used if multiple management 137 + * applications running concurrently were desired 138 + */ 139 + union { 140 + __be16 rsvd; 141 + __be16 buffer_id; 142 + } var2; 143 + __be32 rsvd; 144 + union { 145 + __be32 rsvd; 146 + __be32 lioba; 147 + __be32 msg_len; 148 + } var3; 149 + }; 150 + 151 + /* an RPA command/response transport queue */ 152 + struct crq_queue { 153 + struct ibmvmc_crq_msg *msgs; 154 + int size, cur; 155 + dma_addr_t msg_token; 156 + spinlock_t lock; 157 + }; 158 + 159 + /* VMC server adapter settings */ 160 + struct crq_server_adapter { 161 + struct device *dev; 162 + struct crq_queue queue; 163 + u32 liobn; 164 + u32 riobn; 165 + struct tasklet_struct work_task; 166 + wait_queue_head_t reset_wait_queue; 167 + struct task_struct *reset_task; 168 + }; 169 + 170 + /* Driver wide settings */ 171 + struct ibmvmc_struct { 172 + u32 state; 173 + u32 max_mtu; 174 + u32 max_buffer_pool_size; 175 + u32 max_hmc_index; 176 + struct crq_server_adapter *adapter; 177 + struct cdev cdev; 178 + u32 vmc_drc_index; 179 + }; 180 + 181 + struct ibmvmc_file_session; 182 + 183 + /* Connection specific settings */ 184 + struct ibmvmc_hmc { 185 + u8 session; 186 + u8 index; 187 + u32 state; 188 + struct crq_server_adapter *adapter; 189 + spinlock_t lock; 190 + unsigned char hmc_id[HMC_ID_LEN]; 191 + struct ibmvmc_buffer buffer[MAX_BUF_POOL_SIZE]; 192 + unsigned short queue_outbound_msgs[MAX_BUF_POOL_SIZE]; 193 + int queue_head, queue_tail; 194 + struct ibmvmc_file_session *file_session; 195 + }; 196 + 197 + struct ibmvmc_file_session { 198 + struct file *file; 199 + struct ibmvmc_hmc *hmc; 200 + bool valid; 201 + }; 202 + 203 + struct ibmvmc_query_struct { 204 + int have_vmc; 205 + int state; 206 + int vmc_drc_index; 207 + }; 208 + 209 + #endif /* __IBMVMC_H */