1c89f2750SDavid 'Digit' Turner /* 2c89f2750SDavid 'Digit' Turner * Copyright (C) 2012 Intel, Inc. 3c89f2750SDavid 'Digit' Turner * Copyright (C) 2013 Intel, Inc. 42f3be882SChristoffer Dall * Copyright (C) 2014 Linaro Limited 5*726ea1a8SJin Qian * Copyright (C) 2011-2016 Google, Inc. 6c89f2750SDavid 'Digit' Turner * 7c89f2750SDavid 'Digit' Turner * This software is licensed under the terms of the GNU General Public 8c89f2750SDavid 'Digit' Turner * License version 2, as published by the Free Software Foundation, and 9c89f2750SDavid 'Digit' Turner * may be copied, distributed, and modified under those terms. 10c89f2750SDavid 'Digit' Turner * 11c89f2750SDavid 'Digit' Turner * This program is distributed in the hope that it will be useful, 12c89f2750SDavid 'Digit' Turner * but WITHOUT ANY WARRANTY; without even the implied warranty of 13c89f2750SDavid 'Digit' Turner * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14c89f2750SDavid 'Digit' Turner * GNU General Public License for more details. 15c89f2750SDavid 'Digit' Turner * 16c89f2750SDavid 'Digit' Turner */ 17c89f2750SDavid 'Digit' Turner 18c89f2750SDavid 'Digit' Turner /* This source file contains the implementation of a special device driver 19c89f2750SDavid 'Digit' Turner * that intends to provide a *very* fast communication channel between the 20c89f2750SDavid 'Digit' Turner * guest system and the QEMU emulator. 21c89f2750SDavid 'Digit' Turner * 22c89f2750SDavid 'Digit' Turner * Usage from the guest is simply the following (error handling simplified): 23c89f2750SDavid 'Digit' Turner * 24c89f2750SDavid 'Digit' Turner * int fd = open("/dev/qemu_pipe",O_RDWR); 25c89f2750SDavid 'Digit' Turner * .... write() or read() through the pipe. 26c89f2750SDavid 'Digit' Turner * 27c89f2750SDavid 'Digit' Turner * This driver doesn't deal with the exact protocol used during the session. 28c89f2750SDavid 'Digit' Turner * It is intended to be as simple as something like: 29c89f2750SDavid 'Digit' Turner * 30c89f2750SDavid 'Digit' Turner * // do this _just_ after opening the fd to connect to a specific 31c89f2750SDavid 'Digit' Turner * // emulator service. 32c89f2750SDavid 'Digit' Turner * const char* msg = "<pipename>"; 33c89f2750SDavid 'Digit' Turner * if (write(fd, msg, strlen(msg)+1) < 0) { 34c89f2750SDavid 'Digit' Turner * ... could not connect to <pipename> service 35c89f2750SDavid 'Digit' Turner * close(fd); 36c89f2750SDavid 'Digit' Turner * } 37c89f2750SDavid 'Digit' Turner * 38c89f2750SDavid 'Digit' Turner * // after this, simply read() and write() to communicate with the 39c89f2750SDavid 'Digit' Turner * // service. Exact protocol details left as an exercise to the reader. 40c89f2750SDavid 'Digit' Turner * 41c89f2750SDavid 'Digit' Turner * This driver is very fast because it doesn't copy any data through 42c89f2750SDavid 'Digit' Turner * intermediate buffers, since the emulator is capable of translating 43c89f2750SDavid 'Digit' Turner * guest user addresses into host ones. 44c89f2750SDavid 'Digit' Turner * 45c89f2750SDavid 'Digit' Turner * Note that we must however ensure that each user page involved in the 46c89f2750SDavid 'Digit' Turner * exchange is properly mapped during a transfer. 47c89f2750SDavid 'Digit' Turner */ 48c89f2750SDavid 'Digit' Turner 49*726ea1a8SJin Qian 50c89f2750SDavid 'Digit' Turner #include <linux/module.h> 51c89f2750SDavid 'Digit' Turner #include <linux/interrupt.h> 52c89f2750SDavid 'Digit' Turner #include <linux/kernel.h> 53c89f2750SDavid 'Digit' Turner #include <linux/spinlock.h> 54c89f2750SDavid 'Digit' Turner #include <linux/miscdevice.h> 55c89f2750SDavid 'Digit' Turner #include <linux/platform_device.h> 56c89f2750SDavid 'Digit' Turner #include <linux/poll.h> 57c89f2750SDavid 'Digit' Turner #include <linux/sched.h> 58c89f2750SDavid 'Digit' Turner #include <linux/bitops.h> 59c89f2750SDavid 'Digit' Turner #include <linux/slab.h> 60c89f2750SDavid 'Digit' Turner #include <linux/io.h> 61a99698faSAlan #include <linux/goldfish.h> 621d427da1SShraddha Barke #include <linux/dma-mapping.h> 632f3be882SChristoffer Dall #include <linux/mm.h> 64d62f324bSJason Hu #include <linux/acpi.h> 65c89f2750SDavid 'Digit' Turner 66c89f2750SDavid 'Digit' Turner /* 67*726ea1a8SJin Qian * Update this when something changes in the driver's behavior so the host 68*726ea1a8SJin Qian * can benefit from knowing it 69*726ea1a8SJin Qian */ 70*726ea1a8SJin Qian enum { 71*726ea1a8SJin Qian PIPE_DRIVER_VERSION = 2, 72*726ea1a8SJin Qian PIPE_CURRENT_DEVICE_VERSION = 2 73*726ea1a8SJin Qian }; 74*726ea1a8SJin Qian 75*726ea1a8SJin Qian /* 76c89f2750SDavid 'Digit' Turner * IMPORTANT: The following constants must match the ones used and defined 77c89f2750SDavid 'Digit' Turner * in external/qemu/hw/goldfish_pipe.c in the Android source tree. 78c89f2750SDavid 'Digit' Turner */ 79c89f2750SDavid 'Digit' Turner 80c89f2750SDavid 'Digit' Turner /* List of bitflags returned in status of CMD_POLL command */ 81*726ea1a8SJin Qian enum PipePollFlags { 82*726ea1a8SJin Qian PIPE_POLL_IN = 1 << 0, 83*726ea1a8SJin Qian PIPE_POLL_OUT = 1 << 1, 84*726ea1a8SJin Qian PIPE_POLL_HUP = 1 << 2 85*726ea1a8SJin Qian }; 86c89f2750SDavid 'Digit' Turner 87c89f2750SDavid 'Digit' Turner /* Possible status values used to signal errors - see goldfish_pipe_error_convert */ 88*726ea1a8SJin Qian enum PipeErrors { 89*726ea1a8SJin Qian PIPE_ERROR_INVAL = -1, 90*726ea1a8SJin Qian PIPE_ERROR_AGAIN = -2, 91*726ea1a8SJin Qian PIPE_ERROR_NOMEM = -3, 92*726ea1a8SJin Qian PIPE_ERROR_IO = -4 93*726ea1a8SJin Qian }; 94c89f2750SDavid 'Digit' Turner 95c89f2750SDavid 'Digit' Turner /* Bit-flags used to signal events from the emulator */ 96*726ea1a8SJin Qian enum PipeWakeFlags { 97*726ea1a8SJin Qian PIPE_WAKE_CLOSED = 1 << 0, /* emulator closed pipe */ 98*726ea1a8SJin Qian PIPE_WAKE_READ = 1 << 1, /* pipe can now be read from */ 99*726ea1a8SJin Qian PIPE_WAKE_WRITE = 1 << 2 /* pipe can now be written to */ 100*726ea1a8SJin Qian }; 101c89f2750SDavid 'Digit' Turner 102*726ea1a8SJin Qian /* Bit flags for the 'flags' field */ 103*726ea1a8SJin Qian enum PipeFlagsBits { 104*726ea1a8SJin Qian BIT_CLOSED_ON_HOST = 0, /* pipe closed by host */ 105*726ea1a8SJin Qian BIT_WAKE_ON_WRITE = 1, /* want to be woken on writes */ 106*726ea1a8SJin Qian BIT_WAKE_ON_READ = 2, /* want to be woken on reads */ 107*726ea1a8SJin Qian }; 108*726ea1a8SJin Qian 109*726ea1a8SJin Qian enum PipeRegs { 110*726ea1a8SJin Qian PIPE_REG_CMD = 0, 111*726ea1a8SJin Qian 112*726ea1a8SJin Qian PIPE_REG_SIGNAL_BUFFER_HIGH = 4, 113*726ea1a8SJin Qian PIPE_REG_SIGNAL_BUFFER = 8, 114*726ea1a8SJin Qian PIPE_REG_SIGNAL_BUFFER_COUNT = 12, 115*726ea1a8SJin Qian 116*726ea1a8SJin Qian PIPE_REG_OPEN_BUFFER_HIGH = 20, 117*726ea1a8SJin Qian PIPE_REG_OPEN_BUFFER = 24, 118*726ea1a8SJin Qian 119*726ea1a8SJin Qian PIPE_REG_VERSION = 36, 120*726ea1a8SJin Qian 121*726ea1a8SJin Qian PIPE_REG_GET_SIGNALLED = 48, 122*726ea1a8SJin Qian }; 123*726ea1a8SJin Qian 124*726ea1a8SJin Qian enum PipeCmdCode { 125*726ea1a8SJin Qian PIPE_CMD_OPEN = 1, /* to be used by the pipe device itself */ 126*726ea1a8SJin Qian PIPE_CMD_CLOSE, 127*726ea1a8SJin Qian PIPE_CMD_POLL, 128*726ea1a8SJin Qian PIPE_CMD_WRITE, 129*726ea1a8SJin Qian PIPE_CMD_WAKE_ON_WRITE, 130*726ea1a8SJin Qian PIPE_CMD_READ, 131*726ea1a8SJin Qian PIPE_CMD_WAKE_ON_READ, 132*726ea1a8SJin Qian 133*726ea1a8SJin Qian /* 134*726ea1a8SJin Qian * TODO(zyy): implement a deferred read/write execution to allow 135*726ea1a8SJin Qian * parallel processing of pipe operations on the host. 136*726ea1a8SJin Qian */ 137*726ea1a8SJin Qian PIPE_CMD_WAKE_ON_DONE_IO, 138*726ea1a8SJin Qian }; 139*726ea1a8SJin Qian 140*726ea1a8SJin Qian enum { 141*726ea1a8SJin Qian MAX_BUFFERS_PER_COMMAND = 336, 142*726ea1a8SJin Qian MAX_SIGNALLED_PIPES = 64, 143*726ea1a8SJin Qian INITIAL_PIPES_CAPACITY = 64 144*726ea1a8SJin Qian }; 145*726ea1a8SJin Qian 146*726ea1a8SJin Qian struct goldfish_pipe_dev; 147*726ea1a8SJin Qian struct goldfish_pipe; 148*726ea1a8SJin Qian struct goldfish_pipe_command; 149*726ea1a8SJin Qian 150*726ea1a8SJin Qian /* A per-pipe command structure, shared with the host */ 151*726ea1a8SJin Qian struct goldfish_pipe_command { 152*726ea1a8SJin Qian s32 cmd; /* PipeCmdCode, guest -> host */ 153*726ea1a8SJin Qian s32 id; /* pipe id, guest -> host */ 154*726ea1a8SJin Qian s32 status; /* command execution status, host -> guest */ 155*726ea1a8SJin Qian s32 reserved; /* to pad to 64-bit boundary */ 156*726ea1a8SJin Qian union { 157*726ea1a8SJin Qian /* Parameters for PIPE_CMD_{READ,WRITE} */ 158*726ea1a8SJin Qian struct { 159*726ea1a8SJin Qian /* number of buffers, guest -> host */ 160*726ea1a8SJin Qian u32 buffers_count; 161*726ea1a8SJin Qian /* number of consumed bytes, host -> guest */ 162*726ea1a8SJin Qian s32 consumed_size; 163*726ea1a8SJin Qian /* buffer pointers, guest -> host */ 164*726ea1a8SJin Qian u64 ptrs[MAX_BUFFERS_PER_COMMAND]; 165*726ea1a8SJin Qian /* buffer sizes, guest -> host */ 166*726ea1a8SJin Qian u32 sizes[MAX_BUFFERS_PER_COMMAND]; 167*726ea1a8SJin Qian } rw_params; 168*726ea1a8SJin Qian }; 169*726ea1a8SJin Qian }; 170*726ea1a8SJin Qian 171*726ea1a8SJin Qian /* A single signalled pipe information */ 172*726ea1a8SJin Qian struct signalled_pipe_buffer { 173*726ea1a8SJin Qian u32 id; 174c89f2750SDavid 'Digit' Turner u32 flags; 175c89f2750SDavid 'Digit' Turner }; 176c89f2750SDavid 'Digit' Turner 177*726ea1a8SJin Qian /* Parameters for the PIPE_CMD_OPEN command */ 178*726ea1a8SJin Qian struct open_command_param { 179*726ea1a8SJin Qian u64 command_buffer_ptr; 180*726ea1a8SJin Qian u32 rw_params_max_count; 181*726ea1a8SJin Qian }; 182*726ea1a8SJin Qian 183*726ea1a8SJin Qian /* Device-level set of buffers shared with the host */ 184*726ea1a8SJin Qian struct goldfish_pipe_dev_buffers { 185*726ea1a8SJin Qian struct open_command_param open_command_params; 186*726ea1a8SJin Qian struct signalled_pipe_buffer signalled_pipe_buffers[ 187*726ea1a8SJin Qian MAX_SIGNALLED_PIPES]; 188*726ea1a8SJin Qian }; 189*726ea1a8SJin Qian 190*726ea1a8SJin Qian /* This data type models a given pipe instance */ 191*726ea1a8SJin Qian struct goldfish_pipe { 192*726ea1a8SJin Qian /* pipe ID - index into goldfish_pipe_dev::pipes array */ 193*726ea1a8SJin Qian u32 id; 194*726ea1a8SJin Qian /* The wake flags pipe is waiting for 195*726ea1a8SJin Qian * Note: not protected with any lock, uses atomic operations 196*726ea1a8SJin Qian * and barriers to make it thread-safe. 197*726ea1a8SJin Qian */ 198*726ea1a8SJin Qian unsigned long flags; 199*726ea1a8SJin Qian /* wake flags host have signalled, 200*726ea1a8SJin Qian * - protected by goldfish_pipe_dev::lock 201*726ea1a8SJin Qian */ 202*726ea1a8SJin Qian unsigned long signalled_flags; 203*726ea1a8SJin Qian 204*726ea1a8SJin Qian /* A pointer to command buffer */ 205*726ea1a8SJin Qian struct goldfish_pipe_command *command_buffer; 206*726ea1a8SJin Qian 207*726ea1a8SJin Qian /* doubly linked list of signalled pipes, protected by 208*726ea1a8SJin Qian * goldfish_pipe_dev::lock 209*726ea1a8SJin Qian */ 210*726ea1a8SJin Qian struct goldfish_pipe *prev_signalled; 211*726ea1a8SJin Qian struct goldfish_pipe *next_signalled; 212*726ea1a8SJin Qian 213*726ea1a8SJin Qian /* 214*726ea1a8SJin Qian * A pipe's own lock. Protects the following: 215*726ea1a8SJin Qian * - *command_buffer - makes sure a command can safely write its 216*726ea1a8SJin Qian * parameters to the host and read the results back. 217*726ea1a8SJin Qian */ 218*726ea1a8SJin Qian struct mutex lock; 219*726ea1a8SJin Qian 220*726ea1a8SJin Qian /* A wake queue for sleeping until host signals an event */ 221*726ea1a8SJin Qian wait_queue_head_t wake_queue; 222*726ea1a8SJin Qian /* Pointer to the parent goldfish_pipe_dev instance */ 223*726ea1a8SJin Qian struct goldfish_pipe_dev *dev; 224*726ea1a8SJin Qian }; 225*726ea1a8SJin Qian 226c89f2750SDavid 'Digit' Turner /* The global driver data. Holds a reference to the i/o page used to 227c89f2750SDavid 'Digit' Turner * communicate with the emulator, and a wake queue for blocked tasks 228c89f2750SDavid 'Digit' Turner * waiting to be awoken. 229c89f2750SDavid 'Digit' Turner */ 230c89f2750SDavid 'Digit' Turner struct goldfish_pipe_dev { 231*726ea1a8SJin Qian /* 232*726ea1a8SJin Qian * Global device spinlock. Protects the following members: 233*726ea1a8SJin Qian * - pipes, pipes_capacity 234*726ea1a8SJin Qian * - [*pipes, *pipes + pipes_capacity) - array data 235*726ea1a8SJin Qian * - first_signalled_pipe, 236*726ea1a8SJin Qian * goldfish_pipe::prev_signalled, 237*726ea1a8SJin Qian * goldfish_pipe::next_signalled, 238*726ea1a8SJin Qian * goldfish_pipe::signalled_flags - all singnalled-related fields, 239*726ea1a8SJin Qian * in all allocated pipes 240*726ea1a8SJin Qian * - open_command_params - PIPE_CMD_OPEN-related buffers 241*726ea1a8SJin Qian * 242*726ea1a8SJin Qian * It looks like a lot of different fields, but the trick is that 243*726ea1a8SJin Qian * the only operation that happens often is the signalled pipes array 244*726ea1a8SJin Qian * manipulation. That's why it's OK for now to keep the rest of the 245*726ea1a8SJin Qian * fields under the same lock. If we notice too much contention because 246*726ea1a8SJin Qian * of PIPE_CMD_OPEN, then we should add a separate lock there. 247*726ea1a8SJin Qian */ 248c89f2750SDavid 'Digit' Turner spinlock_t lock; 249*726ea1a8SJin Qian 250*726ea1a8SJin Qian /* 251*726ea1a8SJin Qian * Array of the pipes of |pipes_capacity| elements, 252*726ea1a8SJin Qian * indexed by goldfish_pipe::id 253*726ea1a8SJin Qian */ 254*726ea1a8SJin Qian struct goldfish_pipe **pipes; 255*726ea1a8SJin Qian u32 pipes_capacity; 256*726ea1a8SJin Qian 257*726ea1a8SJin Qian /* Pointers to the buffers host uses for interaction with this driver */ 258*726ea1a8SJin Qian struct goldfish_pipe_dev_buffers *buffers; 259*726ea1a8SJin Qian 260*726ea1a8SJin Qian /* Head of a doubly linked list of signalled pipes */ 261*726ea1a8SJin Qian struct goldfish_pipe *first_signalled_pipe; 262*726ea1a8SJin Qian 263*726ea1a8SJin Qian /* Some device-specific data */ 264c89f2750SDavid 'Digit' Turner int irq; 265*726ea1a8SJin Qian int version; 266*726ea1a8SJin Qian unsigned char __iomem *base; 267c89f2750SDavid 'Digit' Turner }; 268c89f2750SDavid 'Digit' Turner 269*726ea1a8SJin Qian struct goldfish_pipe_dev pipe_dev[1] = {}; 270c89f2750SDavid 'Digit' Turner 271*726ea1a8SJin Qian static int goldfish_cmd_locked(struct goldfish_pipe *pipe, enum PipeCmdCode cmd) 272c89f2750SDavid 'Digit' Turner { 273*726ea1a8SJin Qian pipe->command_buffer->cmd = cmd; 274*726ea1a8SJin Qian /* failure by default */ 275*726ea1a8SJin Qian pipe->command_buffer->status = PIPE_ERROR_INVAL; 276*726ea1a8SJin Qian writel(pipe->id, pipe->dev->base + PIPE_REG_CMD); 277*726ea1a8SJin Qian return pipe->command_buffer->status; 278*726ea1a8SJin Qian } 279c89f2750SDavid 'Digit' Turner 280*726ea1a8SJin Qian static int goldfish_cmd(struct goldfish_pipe *pipe, enum PipeCmdCode cmd) 281*726ea1a8SJin Qian { 282*726ea1a8SJin Qian int status; 283*726ea1a8SJin Qian 284*726ea1a8SJin Qian if (mutex_lock_interruptible(&pipe->lock)) 285*726ea1a8SJin Qian return PIPE_ERROR_IO; 286*726ea1a8SJin Qian status = goldfish_cmd_locked(pipe, cmd); 287*726ea1a8SJin Qian mutex_unlock(&pipe->lock); 288c89f2750SDavid 'Digit' Turner return status; 289c89f2750SDavid 'Digit' Turner } 290c89f2750SDavid 'Digit' Turner 291*726ea1a8SJin Qian /* 292*726ea1a8SJin Qian * This function converts an error code returned by the emulator through 293c89f2750SDavid 'Digit' Turner * the PIPE_REG_STATUS i/o register into a valid negative errno value. 294c89f2750SDavid 'Digit' Turner */ 295c89f2750SDavid 'Digit' Turner static int goldfish_pipe_error_convert(int status) 296c89f2750SDavid 'Digit' Turner { 297c89f2750SDavid 'Digit' Turner switch (status) { 298c89f2750SDavid 'Digit' Turner case PIPE_ERROR_AGAIN: 299c89f2750SDavid 'Digit' Turner return -EAGAIN; 300c89f2750SDavid 'Digit' Turner case PIPE_ERROR_NOMEM: 301c89f2750SDavid 'Digit' Turner return -ENOMEM; 302c89f2750SDavid 'Digit' Turner case PIPE_ERROR_IO: 303c89f2750SDavid 'Digit' Turner return -EIO; 304c89f2750SDavid 'Digit' Turner default: 305c89f2750SDavid 'Digit' Turner return -EINVAL; 306c89f2750SDavid 'Digit' Turner } 307c89f2750SDavid 'Digit' Turner } 308c89f2750SDavid 'Digit' Turner 309*726ea1a8SJin Qian static int pin_user_pages(unsigned long first_page, unsigned long last_page, 310*726ea1a8SJin Qian unsigned int last_page_size, int is_write, 311*726ea1a8SJin Qian struct page *pages[MAX_BUFFERS_PER_COMMAND], 312*726ea1a8SJin Qian unsigned int *iter_last_page_size) 313c89f2750SDavid 'Digit' Turner { 314*726ea1a8SJin Qian int ret; 315*726ea1a8SJin Qian int requested_pages = ((last_page - first_page) >> PAGE_SHIFT) + 1; 316c89f2750SDavid 'Digit' Turner 317*726ea1a8SJin Qian if (requested_pages > MAX_BUFFERS_PER_COMMAND) { 318*726ea1a8SJin Qian requested_pages = MAX_BUFFERS_PER_COMMAND; 319*726ea1a8SJin Qian *iter_last_page_size = PAGE_SIZE; 320*726ea1a8SJin Qian } else { 321*726ea1a8SJin Qian *iter_last_page_size = last_page_size; 322c89f2750SDavid 'Digit' Turner } 323c89f2750SDavid 'Digit' Turner 324*726ea1a8SJin Qian ret = get_user_pages_fast( 325*726ea1a8SJin Qian first_page, requested_pages, !is_write, pages); 326*726ea1a8SJin Qian if (ret <= 0) 327c89f2750SDavid 'Digit' Turner return -EFAULT; 328*726ea1a8SJin Qian if (ret < requested_pages) 329*726ea1a8SJin Qian *iter_last_page_size = PAGE_SIZE; 330*726ea1a8SJin Qian return ret; 331c89f2750SDavid 'Digit' Turner 332*726ea1a8SJin Qian } 333*726ea1a8SJin Qian 334*726ea1a8SJin Qian static void release_user_pages(struct page **pages, int pages_count, 335*726ea1a8SJin Qian int is_write, s32 consumed_size) 336*726ea1a8SJin Qian { 337*726ea1a8SJin Qian int i; 338*726ea1a8SJin Qian 339*726ea1a8SJin Qian for (i = 0; i < pages_count; i++) { 340*726ea1a8SJin Qian if (!is_write && consumed_size > 0) 341*726ea1a8SJin Qian set_page_dirty(pages[i]); 342*726ea1a8SJin Qian put_page(pages[i]); 343*726ea1a8SJin Qian } 344*726ea1a8SJin Qian } 345*726ea1a8SJin Qian 346*726ea1a8SJin Qian /* Populate the call parameters, merging adjacent pages together */ 347*726ea1a8SJin Qian static void populate_rw_params( 348*726ea1a8SJin Qian struct page **pages, int pages_count, 349*726ea1a8SJin Qian unsigned long address, unsigned long address_end, 350*726ea1a8SJin Qian unsigned long first_page, unsigned long last_page, 351*726ea1a8SJin Qian unsigned int iter_last_page_size, int is_write, 352*726ea1a8SJin Qian struct goldfish_pipe_command *command) 353*726ea1a8SJin Qian { 354*726ea1a8SJin Qian /* 355*726ea1a8SJin Qian * Process the first page separately - it's the only page that 356*726ea1a8SJin Qian * needs special handling for its start address. 357*726ea1a8SJin Qian */ 358*726ea1a8SJin Qian unsigned long xaddr = page_to_phys(pages[0]); 359*726ea1a8SJin Qian unsigned long xaddr_prev = xaddr; 360*726ea1a8SJin Qian int buffer_idx = 0; 361*726ea1a8SJin Qian int i = 1; 362*726ea1a8SJin Qian int size_on_page = first_page == last_page 363*726ea1a8SJin Qian ? (int)(address_end - address) 364*726ea1a8SJin Qian : (PAGE_SIZE - (address & ~PAGE_MASK)); 365*726ea1a8SJin Qian command->rw_params.ptrs[0] = (u64)(xaddr | (address & ~PAGE_MASK)); 366*726ea1a8SJin Qian command->rw_params.sizes[0] = size_on_page; 367*726ea1a8SJin Qian for (; i < pages_count; ++i) { 368*726ea1a8SJin Qian xaddr = page_to_phys(pages[i]); 369*726ea1a8SJin Qian size_on_page = (i == pages_count - 1) ? 370*726ea1a8SJin Qian iter_last_page_size : PAGE_SIZE; 371*726ea1a8SJin Qian if (xaddr == xaddr_prev + PAGE_SIZE) { 372*726ea1a8SJin Qian command->rw_params.sizes[buffer_idx] += size_on_page; 373*726ea1a8SJin Qian } else { 374*726ea1a8SJin Qian ++buffer_idx; 375*726ea1a8SJin Qian command->rw_params.ptrs[buffer_idx] = (u64)xaddr; 376*726ea1a8SJin Qian command->rw_params.sizes[buffer_idx] = size_on_page; 377*726ea1a8SJin Qian } 378*726ea1a8SJin Qian xaddr_prev = xaddr; 379*726ea1a8SJin Qian } 380*726ea1a8SJin Qian command->rw_params.buffers_count = buffer_idx + 1; 381*726ea1a8SJin Qian } 382*726ea1a8SJin Qian 383*726ea1a8SJin Qian static int transfer_max_buffers(struct goldfish_pipe *pipe, 384*726ea1a8SJin Qian unsigned long address, unsigned long address_end, int is_write, 385*726ea1a8SJin Qian unsigned long last_page, unsigned int last_page_size, 386*726ea1a8SJin Qian s32 *consumed_size, int *status) 387*726ea1a8SJin Qian { 388*726ea1a8SJin Qian struct page *pages[MAX_BUFFERS_PER_COMMAND]; 389*726ea1a8SJin Qian unsigned long first_page = address & PAGE_MASK; 390*726ea1a8SJin Qian unsigned int iter_last_page_size; 391*726ea1a8SJin Qian int pages_count = pin_user_pages(first_page, last_page, 392*726ea1a8SJin Qian last_page_size, is_write, 393*726ea1a8SJin Qian pages, &iter_last_page_size); 394*726ea1a8SJin Qian 395*726ea1a8SJin Qian if (pages_count < 0) 396*726ea1a8SJin Qian return pages_count; 397*726ea1a8SJin Qian 398*726ea1a8SJin Qian /* Serialize access to the pipe command buffers */ 399c89f2750SDavid 'Digit' Turner if (mutex_lock_interruptible(&pipe->lock)) 400c89f2750SDavid 'Digit' Turner return -ERESTARTSYS; 401c89f2750SDavid 'Digit' Turner 402*726ea1a8SJin Qian populate_rw_params(pages, pages_count, address, address_end, 403*726ea1a8SJin Qian first_page, last_page, iter_last_page_size, is_write, 404*726ea1a8SJin Qian pipe->command_buffer); 405c89f2750SDavid 'Digit' Turner 406*726ea1a8SJin Qian /* Transfer the data */ 407*726ea1a8SJin Qian *status = goldfish_cmd_locked(pipe, 408*726ea1a8SJin Qian is_write ? PIPE_CMD_WRITE : PIPE_CMD_READ); 409c89f2750SDavid 'Digit' Turner 410*726ea1a8SJin Qian *consumed_size = pipe->command_buffer->rw_params.consumed_size; 4114f42071cSYu Ning 412*726ea1a8SJin Qian mutex_unlock(&pipe->lock); 413c89f2750SDavid 'Digit' Turner 414*726ea1a8SJin Qian release_user_pages(pages, pages_count, is_write, *consumed_size); 415*726ea1a8SJin Qian 416*726ea1a8SJin Qian return 0; 417c89f2750SDavid 'Digit' Turner } 418c89f2750SDavid 'Digit' Turner 419*726ea1a8SJin Qian static int wait_for_host_signal(struct goldfish_pipe *pipe, int is_write) 420*726ea1a8SJin Qian { 421*726ea1a8SJin Qian u32 wakeBit = is_write ? BIT_WAKE_ON_WRITE : BIT_WAKE_ON_READ; 422c89f2750SDavid 'Digit' Turner 423c89f2750SDavid 'Digit' Turner set_bit(wakeBit, &pipe->flags); 424c89f2750SDavid 'Digit' Turner 425c89f2750SDavid 'Digit' Turner /* Tell the emulator we're going to wait for a wake event */ 426*726ea1a8SJin Qian (void)goldfish_cmd(pipe, 427*726ea1a8SJin Qian is_write ? PIPE_CMD_WAKE_ON_WRITE : PIPE_CMD_WAKE_ON_READ); 428c89f2750SDavid 'Digit' Turner 429c89f2750SDavid 'Digit' Turner while (test_bit(wakeBit, &pipe->flags)) { 430c89f2750SDavid 'Digit' Turner if (wait_event_interruptible( 431c89f2750SDavid 'Digit' Turner pipe->wake_queue, 432c89f2750SDavid 'Digit' Turner !test_bit(wakeBit, &pipe->flags))) 433c89f2750SDavid 'Digit' Turner return -ERESTARTSYS; 434c89f2750SDavid 'Digit' Turner 435c89f2750SDavid 'Digit' Turner if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) 436c89f2750SDavid 'Digit' Turner return -EIO; 437c89f2750SDavid 'Digit' Turner } 438c89f2750SDavid 'Digit' Turner 439*726ea1a8SJin Qian return 0; 440c89f2750SDavid 'Digit' Turner } 4412f3be882SChristoffer Dall 442*726ea1a8SJin Qian static ssize_t goldfish_pipe_read_write(struct file *filp, 443*726ea1a8SJin Qian char __user *buffer, size_t bufflen, int is_write) 444*726ea1a8SJin Qian { 445*726ea1a8SJin Qian struct goldfish_pipe *pipe = filp->private_data; 446*726ea1a8SJin Qian int count = 0, ret = -EINVAL; 447*726ea1a8SJin Qian unsigned long address, address_end, last_page; 448*726ea1a8SJin Qian unsigned int last_page_size; 449*726ea1a8SJin Qian 450*726ea1a8SJin Qian /* If the emulator already closed the pipe, no need to go further */ 451*726ea1a8SJin Qian if (unlikely(test_bit(BIT_CLOSED_ON_HOST, &pipe->flags))) 452*726ea1a8SJin Qian return -EIO; 453*726ea1a8SJin Qian /* Null reads or writes succeeds */ 454*726ea1a8SJin Qian if (unlikely(bufflen == 0)) 455*726ea1a8SJin Qian return 0; 456*726ea1a8SJin Qian /* Check the buffer range for access */ 457*726ea1a8SJin Qian if (unlikely(!access_ok(is_write ? VERIFY_WRITE : VERIFY_READ, 458*726ea1a8SJin Qian buffer, bufflen))) 459*726ea1a8SJin Qian return -EFAULT; 460*726ea1a8SJin Qian 461*726ea1a8SJin Qian address = (unsigned long)buffer; 462*726ea1a8SJin Qian address_end = address + bufflen; 463*726ea1a8SJin Qian last_page = (address_end - 1) & PAGE_MASK; 464*726ea1a8SJin Qian last_page_size = ((address_end - 1) & ~PAGE_MASK) + 1; 465*726ea1a8SJin Qian 466*726ea1a8SJin Qian while (address < address_end) { 467*726ea1a8SJin Qian s32 consumed_size; 468*726ea1a8SJin Qian int status; 469*726ea1a8SJin Qian 470*726ea1a8SJin Qian ret = transfer_max_buffers(pipe, address, address_end, is_write, 471*726ea1a8SJin Qian last_page, last_page_size, &consumed_size, 472*726ea1a8SJin Qian &status); 4732f3be882SChristoffer Dall if (ret < 0) 474*726ea1a8SJin Qian break; 475*726ea1a8SJin Qian 476*726ea1a8SJin Qian if (consumed_size > 0) { 477*726ea1a8SJin Qian /* No matter what's the status, we've transferred 478*726ea1a8SJin Qian * something. 479*726ea1a8SJin Qian */ 480*726ea1a8SJin Qian count += consumed_size; 481*726ea1a8SJin Qian address += consumed_size; 482*726ea1a8SJin Qian } 483*726ea1a8SJin Qian if (status > 0) 484*726ea1a8SJin Qian continue; 485*726ea1a8SJin Qian if (status == 0) { 486*726ea1a8SJin Qian /* EOF */ 487*726ea1a8SJin Qian ret = 0; 488*726ea1a8SJin Qian break; 489*726ea1a8SJin Qian } 490*726ea1a8SJin Qian if (count > 0) { 491*726ea1a8SJin Qian /* 492*726ea1a8SJin Qian * An error occurred, but we already transferred 493*726ea1a8SJin Qian * something on one of the previous iterations. 494*726ea1a8SJin Qian * Just return what we already copied and log this 495*726ea1a8SJin Qian * err. 496*726ea1a8SJin Qian */ 497*726ea1a8SJin Qian if (status != PIPE_ERROR_AGAIN) 498*726ea1a8SJin Qian pr_info_ratelimited("goldfish_pipe: backend error %d on %s\n", 499*726ea1a8SJin Qian status, is_write ? "write" : "read"); 500*726ea1a8SJin Qian break; 501*726ea1a8SJin Qian } 502*726ea1a8SJin Qian 503*726ea1a8SJin Qian /* 504*726ea1a8SJin Qian * If the error is not PIPE_ERROR_AGAIN, or if we are in 505*726ea1a8SJin Qian * non-blocking mode, just return the error code. 506*726ea1a8SJin Qian */ 507*726ea1a8SJin Qian if (status != PIPE_ERROR_AGAIN || 508*726ea1a8SJin Qian (filp->f_flags & O_NONBLOCK) != 0) { 509*726ea1a8SJin Qian ret = goldfish_pipe_error_convert(status); 510*726ea1a8SJin Qian break; 511*726ea1a8SJin Qian } 512*726ea1a8SJin Qian 513*726ea1a8SJin Qian status = wait_for_host_signal(pipe, is_write); 514*726ea1a8SJin Qian if (status < 0) 515*726ea1a8SJin Qian return status; 516*726ea1a8SJin Qian } 517*726ea1a8SJin Qian 518*726ea1a8SJin Qian if (count > 0) 5192f3be882SChristoffer Dall return count; 520*726ea1a8SJin Qian return ret; 521c89f2750SDavid 'Digit' Turner } 522c89f2750SDavid 'Digit' Turner 523c89f2750SDavid 'Digit' Turner static ssize_t goldfish_pipe_read(struct file *filp, char __user *buffer, 524c89f2750SDavid 'Digit' Turner size_t bufflen, loff_t *ppos) 525c89f2750SDavid 'Digit' Turner { 526*726ea1a8SJin Qian return goldfish_pipe_read_write(filp, buffer, bufflen, 527*726ea1a8SJin Qian /* is_write */ 0); 528c89f2750SDavid 'Digit' Turner } 529c89f2750SDavid 'Digit' Turner 530c89f2750SDavid 'Digit' Turner static ssize_t goldfish_pipe_write(struct file *filp, 531c89f2750SDavid 'Digit' Turner const char __user *buffer, size_t bufflen, 532c89f2750SDavid 'Digit' Turner loff_t *ppos) 533c89f2750SDavid 'Digit' Turner { 534*726ea1a8SJin Qian return goldfish_pipe_read_write(filp, 535*726ea1a8SJin Qian /* cast away the const */(char __user *)buffer, bufflen, 536*726ea1a8SJin Qian /* is_write */ 1); 537c89f2750SDavid 'Digit' Turner } 538c89f2750SDavid 'Digit' Turner 539c89f2750SDavid 'Digit' Turner static unsigned int goldfish_pipe_poll(struct file *filp, poll_table *wait) 540c89f2750SDavid 'Digit' Turner { 541c89f2750SDavid 'Digit' Turner struct goldfish_pipe *pipe = filp->private_data; 542c89f2750SDavid 'Digit' Turner unsigned int mask = 0; 543c89f2750SDavid 'Digit' Turner int status; 544c89f2750SDavid 'Digit' Turner 545c89f2750SDavid 'Digit' Turner poll_wait(filp, &pipe->wake_queue, wait); 546c89f2750SDavid 'Digit' Turner 547*726ea1a8SJin Qian status = goldfish_cmd(pipe, PIPE_CMD_POLL); 548*726ea1a8SJin Qian if (status < 0) 549*726ea1a8SJin Qian return -ERESTARTSYS; 550c89f2750SDavid 'Digit' Turner 551c89f2750SDavid 'Digit' Turner if (status & PIPE_POLL_IN) 552c89f2750SDavid 'Digit' Turner mask |= POLLIN | POLLRDNORM; 553c89f2750SDavid 'Digit' Turner if (status & PIPE_POLL_OUT) 554c89f2750SDavid 'Digit' Turner mask |= POLLOUT | POLLWRNORM; 555c89f2750SDavid 'Digit' Turner if (status & PIPE_POLL_HUP) 556c89f2750SDavid 'Digit' Turner mask |= POLLHUP; 557c89f2750SDavid 'Digit' Turner if (test_bit(BIT_CLOSED_ON_HOST, &pipe->flags)) 558c89f2750SDavid 'Digit' Turner mask |= POLLERR; 559c89f2750SDavid 'Digit' Turner 560c89f2750SDavid 'Digit' Turner return mask; 561c89f2750SDavid 'Digit' Turner } 562c89f2750SDavid 'Digit' Turner 563*726ea1a8SJin Qian static void signalled_pipes_add_locked(struct goldfish_pipe_dev *dev, 564*726ea1a8SJin Qian u32 id, u32 flags) 565c89f2750SDavid 'Digit' Turner { 566c89f2750SDavid 'Digit' Turner struct goldfish_pipe *pipe; 56749a75c44SJun Tian 568*726ea1a8SJin Qian if (WARN_ON(id >= dev->pipes_capacity)) 569*726ea1a8SJin Qian return; 57025c72c78SJun Tian 571*726ea1a8SJin Qian pipe = dev->pipes[id]; 572*726ea1a8SJin Qian if (!pipe) 573*726ea1a8SJin Qian return; 574*726ea1a8SJin Qian pipe->signalled_flags |= flags; 575c89f2750SDavid 'Digit' Turner 576*726ea1a8SJin Qian if (pipe->prev_signalled || pipe->next_signalled 577*726ea1a8SJin Qian || dev->first_signalled_pipe == pipe) 578*726ea1a8SJin Qian return; /* already in the list */ 579*726ea1a8SJin Qian pipe->next_signalled = dev->first_signalled_pipe; 580*726ea1a8SJin Qian if (dev->first_signalled_pipe) 581*726ea1a8SJin Qian dev->first_signalled_pipe->prev_signalled = pipe; 582*726ea1a8SJin Qian dev->first_signalled_pipe = pipe; 583c89f2750SDavid 'Digit' Turner } 584*726ea1a8SJin Qian 585*726ea1a8SJin Qian static void signalled_pipes_remove_locked(struct goldfish_pipe_dev *dev, 586*726ea1a8SJin Qian struct goldfish_pipe *pipe) { 587*726ea1a8SJin Qian if (pipe->prev_signalled) 588*726ea1a8SJin Qian pipe->prev_signalled->next_signalled = pipe->next_signalled; 589*726ea1a8SJin Qian if (pipe->next_signalled) 590*726ea1a8SJin Qian pipe->next_signalled->prev_signalled = pipe->prev_signalled; 591*726ea1a8SJin Qian if (pipe == dev->first_signalled_pipe) 592*726ea1a8SJin Qian dev->first_signalled_pipe = pipe->next_signalled; 593*726ea1a8SJin Qian pipe->prev_signalled = NULL; 594*726ea1a8SJin Qian pipe->next_signalled = NULL; 595*726ea1a8SJin Qian } 596*726ea1a8SJin Qian 597*726ea1a8SJin Qian static struct goldfish_pipe *signalled_pipes_pop_front( 598*726ea1a8SJin Qian struct goldfish_pipe_dev *dev, int *wakes) 599*726ea1a8SJin Qian { 600*726ea1a8SJin Qian struct goldfish_pipe *pipe; 601*726ea1a8SJin Qian unsigned long flags; 602*726ea1a8SJin Qian 603*726ea1a8SJin Qian spin_lock_irqsave(&dev->lock, flags); 604*726ea1a8SJin Qian 605*726ea1a8SJin Qian pipe = dev->first_signalled_pipe; 606*726ea1a8SJin Qian if (pipe) { 607*726ea1a8SJin Qian *wakes = pipe->signalled_flags; 608*726ea1a8SJin Qian pipe->signalled_flags = 0; 609*726ea1a8SJin Qian /* 610*726ea1a8SJin Qian * This is an optimized version of 611*726ea1a8SJin Qian * signalled_pipes_remove_locked() 612*726ea1a8SJin Qian * - We want to make it as fast as possible to 613*726ea1a8SJin Qian * wake the sleeping pipe operations faster. 614*726ea1a8SJin Qian */ 615*726ea1a8SJin Qian dev->first_signalled_pipe = pipe->next_signalled; 616*726ea1a8SJin Qian if (dev->first_signalled_pipe) 617*726ea1a8SJin Qian dev->first_signalled_pipe->prev_signalled = NULL; 618*726ea1a8SJin Qian pipe->next_signalled = NULL; 619*726ea1a8SJin Qian } 620*726ea1a8SJin Qian 621*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 622*726ea1a8SJin Qian return pipe; 623*726ea1a8SJin Qian } 624*726ea1a8SJin Qian 625*726ea1a8SJin Qian static void goldfish_interrupt_task(unsigned long unused) 626*726ea1a8SJin Qian { 627*726ea1a8SJin Qian struct goldfish_pipe_dev *dev = pipe_dev; 628*726ea1a8SJin Qian /* Iterate over the signalled pipes and wake them one by one */ 629*726ea1a8SJin Qian struct goldfish_pipe *pipe; 630*726ea1a8SJin Qian int wakes; 631*726ea1a8SJin Qian 632*726ea1a8SJin Qian while ((pipe = signalled_pipes_pop_front(dev, &wakes)) != NULL) { 633*726ea1a8SJin Qian if (wakes & PIPE_WAKE_CLOSED) { 634*726ea1a8SJin Qian pipe->flags = 1 << BIT_CLOSED_ON_HOST; 635*726ea1a8SJin Qian } else { 636c89f2750SDavid 'Digit' Turner if (wakes & PIPE_WAKE_READ) 637c89f2750SDavid 'Digit' Turner clear_bit(BIT_WAKE_ON_READ, &pipe->flags); 638c89f2750SDavid 'Digit' Turner if (wakes & PIPE_WAKE_WRITE) 639c89f2750SDavid 'Digit' Turner clear_bit(BIT_WAKE_ON_WRITE, &pipe->flags); 640c89f2750SDavid 'Digit' Turner } 641*726ea1a8SJin Qian /* 642*726ea1a8SJin Qian * wake_up_interruptible() implies a write barrier, so don't 643*726ea1a8SJin Qian * explicitly add another one here. 644*726ea1a8SJin Qian */ 645*726ea1a8SJin Qian wake_up_interruptible(&pipe->wake_queue); 646*726ea1a8SJin Qian } 647*726ea1a8SJin Qian } 648*726ea1a8SJin Qian DECLARE_TASKLET(goldfish_interrupt_tasklet, goldfish_interrupt_task, 0); 649c89f2750SDavid 'Digit' Turner 650*726ea1a8SJin Qian /* 651*726ea1a8SJin Qian * The general idea of the interrupt handling: 652*726ea1a8SJin Qian * 653*726ea1a8SJin Qian * 1. device raises an interrupt if there's at least one signalled pipe 654*726ea1a8SJin Qian * 2. IRQ handler reads the signalled pipes and their count from the device 655*726ea1a8SJin Qian * 3. device writes them into a shared buffer and returns the count 656*726ea1a8SJin Qian * it only resets the IRQ if it has returned all signalled pipes, 657*726ea1a8SJin Qian * otherwise it leaves it raised, so IRQ handler will be called 658*726ea1a8SJin Qian * again for the next chunk 659*726ea1a8SJin Qian * 4. IRQ handler adds all returned pipes to the device's signalled pipes list 660*726ea1a8SJin Qian * 5. IRQ handler launches a tasklet to process the signalled pipes from the 661*726ea1a8SJin Qian * list in a separate context 662*726ea1a8SJin Qian */ 663*726ea1a8SJin Qian static irqreturn_t goldfish_pipe_interrupt(int irq, void *dev_id) 664*726ea1a8SJin Qian { 665*726ea1a8SJin Qian u32 count; 666*726ea1a8SJin Qian u32 i; 667*726ea1a8SJin Qian unsigned long flags; 668*726ea1a8SJin Qian struct goldfish_pipe_dev *dev = dev_id; 669*726ea1a8SJin Qian 670*726ea1a8SJin Qian if (dev != pipe_dev) 671*726ea1a8SJin Qian return IRQ_NONE; 672*726ea1a8SJin Qian 673*726ea1a8SJin Qian /* Request the signalled pipes from the device */ 674*726ea1a8SJin Qian spin_lock_irqsave(&dev->lock, flags); 675*726ea1a8SJin Qian 676*726ea1a8SJin Qian count = readl(dev->base + PIPE_REG_GET_SIGNALLED); 677*726ea1a8SJin Qian if (count == 0) { 678*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 679*726ea1a8SJin Qian return IRQ_NONE; 680*726ea1a8SJin Qian } 681*726ea1a8SJin Qian if (count > MAX_SIGNALLED_PIPES) 682*726ea1a8SJin Qian count = MAX_SIGNALLED_PIPES; 683*726ea1a8SJin Qian 684*726ea1a8SJin Qian for (i = 0; i < count; ++i) 685*726ea1a8SJin Qian signalled_pipes_add_locked(dev, 686*726ea1a8SJin Qian dev->buffers->signalled_pipe_buffers[i].id, 687*726ea1a8SJin Qian dev->buffers->signalled_pipe_buffers[i].flags); 688*726ea1a8SJin Qian 689*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 690*726ea1a8SJin Qian 691*726ea1a8SJin Qian tasklet_schedule(&goldfish_interrupt_tasklet); 692*726ea1a8SJin Qian return IRQ_HANDLED; 693*726ea1a8SJin Qian } 694*726ea1a8SJin Qian 695*726ea1a8SJin Qian static int get_free_pipe_id_locked(struct goldfish_pipe_dev *dev) 696*726ea1a8SJin Qian { 697*726ea1a8SJin Qian int id; 698*726ea1a8SJin Qian 699*726ea1a8SJin Qian for (id = 0; id < dev->pipes_capacity; ++id) 700*726ea1a8SJin Qian if (!dev->pipes[id]) 701*726ea1a8SJin Qian return id; 702*726ea1a8SJin Qian 703*726ea1a8SJin Qian { 704*726ea1a8SJin Qian /* Reallocate the array */ 705*726ea1a8SJin Qian u32 new_capacity = 2 * dev->pipes_capacity; 706*726ea1a8SJin Qian struct goldfish_pipe **pipes = 707*726ea1a8SJin Qian kcalloc(new_capacity, sizeof(*pipes), GFP_KERNEL); 708*726ea1a8SJin Qian if (!pipes) 709*726ea1a8SJin Qian return -ENOMEM; 710*726ea1a8SJin Qian memcpy(pipes, dev->pipes, sizeof(*pipes) * dev->pipes_capacity); 711*726ea1a8SJin Qian kfree(dev->pipes); 712*726ea1a8SJin Qian dev->pipes = pipes; 713*726ea1a8SJin Qian id = dev->pipes_capacity; 714*726ea1a8SJin Qian dev->pipes_capacity = new_capacity; 715*726ea1a8SJin Qian } 716*726ea1a8SJin Qian return id; 717c89f2750SDavid 'Digit' Turner } 718c89f2750SDavid 'Digit' Turner 719c89f2750SDavid 'Digit' Turner /** 720c89f2750SDavid 'Digit' Turner * goldfish_pipe_open - open a channel to the AVD 721c89f2750SDavid 'Digit' Turner * @inode: inode of device 722c89f2750SDavid 'Digit' Turner * @file: file struct of opener 723c89f2750SDavid 'Digit' Turner * 724c89f2750SDavid 'Digit' Turner * Create a new pipe link between the emulator and the use application. 725c89f2750SDavid 'Digit' Turner * Each new request produces a new pipe. 726c89f2750SDavid 'Digit' Turner * 727c89f2750SDavid 'Digit' Turner * Note: we use the pipe ID as a mux. All goldfish emulations are 32bit 728c89f2750SDavid 'Digit' Turner * right now so this is fine. A move to 64bit will need this addressing 729c89f2750SDavid 'Digit' Turner */ 730c89f2750SDavid 'Digit' Turner static int goldfish_pipe_open(struct inode *inode, struct file *file) 731c89f2750SDavid 'Digit' Turner { 732c89f2750SDavid 'Digit' Turner struct goldfish_pipe_dev *dev = pipe_dev; 733*726ea1a8SJin Qian unsigned long flags; 734*726ea1a8SJin Qian int id; 735*726ea1a8SJin Qian int status; 736c89f2750SDavid 'Digit' Turner 737c89f2750SDavid 'Digit' Turner /* Allocate new pipe kernel object */ 738*726ea1a8SJin Qian struct goldfish_pipe *pipe = kzalloc(sizeof(*pipe), GFP_KERNEL); 739c89f2750SDavid 'Digit' Turner if (pipe == NULL) 740c89f2750SDavid 'Digit' Turner return -ENOMEM; 741c89f2750SDavid 'Digit' Turner 742c89f2750SDavid 'Digit' Turner pipe->dev = dev; 743c89f2750SDavid 'Digit' Turner mutex_init(&pipe->lock); 744c89f2750SDavid 'Digit' Turner init_waitqueue_head(&pipe->wake_queue); 745c89f2750SDavid 'Digit' Turner 746c89f2750SDavid 'Digit' Turner /* 747*726ea1a8SJin Qian * Command buffer needs to be allocated on its own page to make sure 748*726ea1a8SJin Qian * it is physically contiguous in host's address space. 749c89f2750SDavid 'Digit' Turner */ 750*726ea1a8SJin Qian pipe->command_buffer = 751*726ea1a8SJin Qian (struct goldfish_pipe_command *)__get_free_page(GFP_KERNEL); 752*726ea1a8SJin Qian if (!pipe->command_buffer) { 753*726ea1a8SJin Qian status = -ENOMEM; 754*726ea1a8SJin Qian goto err_pipe; 755*726ea1a8SJin Qian } 756c89f2750SDavid 'Digit' Turner 757*726ea1a8SJin Qian spin_lock_irqsave(&dev->lock, flags); 758*726ea1a8SJin Qian 759*726ea1a8SJin Qian id = get_free_pipe_id_locked(dev); 760*726ea1a8SJin Qian if (id < 0) { 761*726ea1a8SJin Qian status = id; 762*726ea1a8SJin Qian goto err_id_locked; 763*726ea1a8SJin Qian } 764*726ea1a8SJin Qian 765*726ea1a8SJin Qian dev->pipes[id] = pipe; 766*726ea1a8SJin Qian pipe->id = id; 767*726ea1a8SJin Qian pipe->command_buffer->id = id; 768*726ea1a8SJin Qian 769*726ea1a8SJin Qian /* Now tell the emulator we're opening a new pipe. */ 770*726ea1a8SJin Qian dev->buffers->open_command_params.rw_params_max_count = 771*726ea1a8SJin Qian MAX_BUFFERS_PER_COMMAND; 772*726ea1a8SJin Qian dev->buffers->open_command_params.command_buffer_ptr = 773*726ea1a8SJin Qian (u64)(unsigned long)__pa(pipe->command_buffer); 774*726ea1a8SJin Qian status = goldfish_cmd_locked(pipe, PIPE_CMD_OPEN); 775*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 776*726ea1a8SJin Qian if (status < 0) 777*726ea1a8SJin Qian goto err_cmd; 778*726ea1a8SJin Qian /* All is done, save the pipe into the file's private data field */ 779*726ea1a8SJin Qian file->private_data = pipe; 780*726ea1a8SJin Qian return 0; 781*726ea1a8SJin Qian 782*726ea1a8SJin Qian err_cmd: 783*726ea1a8SJin Qian spin_lock_irqsave(&dev->lock, flags); 784*726ea1a8SJin Qian dev->pipes[id] = NULL; 785*726ea1a8SJin Qian err_id_locked: 786*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 787*726ea1a8SJin Qian free_page((unsigned long)pipe->command_buffer); 788*726ea1a8SJin Qian err_pipe: 789c89f2750SDavid 'Digit' Turner kfree(pipe); 790c89f2750SDavid 'Digit' Turner return status; 791c89f2750SDavid 'Digit' Turner } 792c89f2750SDavid 'Digit' Turner 793c89f2750SDavid 'Digit' Turner static int goldfish_pipe_release(struct inode *inode, struct file *filp) 794c89f2750SDavid 'Digit' Turner { 795*726ea1a8SJin Qian unsigned long flags; 796c89f2750SDavid 'Digit' Turner struct goldfish_pipe *pipe = filp->private_data; 797*726ea1a8SJin Qian struct goldfish_pipe_dev *dev = pipe->dev; 798c89f2750SDavid 'Digit' Turner 799c89f2750SDavid 'Digit' Turner /* The guest is closing the channel, so tell the emulator right now */ 800*726ea1a8SJin Qian (void)goldfish_cmd(pipe, PIPE_CMD_CLOSE); 801*726ea1a8SJin Qian 802*726ea1a8SJin Qian spin_lock_irqsave(&dev->lock, flags); 803*726ea1a8SJin Qian dev->pipes[pipe->id] = NULL; 804*726ea1a8SJin Qian signalled_pipes_remove_locked(dev, pipe); 805*726ea1a8SJin Qian spin_unlock_irqrestore(&dev->lock, flags); 806*726ea1a8SJin Qian 807c89f2750SDavid 'Digit' Turner filp->private_data = NULL; 808*726ea1a8SJin Qian free_page((unsigned long)pipe->command_buffer); 809*726ea1a8SJin Qian kfree(pipe); 810c89f2750SDavid 'Digit' Turner return 0; 811c89f2750SDavid 'Digit' Turner } 812c89f2750SDavid 'Digit' Turner 813c89f2750SDavid 'Digit' Turner static const struct file_operations goldfish_pipe_fops = { 814c89f2750SDavid 'Digit' Turner .owner = THIS_MODULE, 815c89f2750SDavid 'Digit' Turner .read = goldfish_pipe_read, 816c89f2750SDavid 'Digit' Turner .write = goldfish_pipe_write, 817c89f2750SDavid 'Digit' Turner .poll = goldfish_pipe_poll, 818c89f2750SDavid 'Digit' Turner .open = goldfish_pipe_open, 819c89f2750SDavid 'Digit' Turner .release = goldfish_pipe_release, 820c89f2750SDavid 'Digit' Turner }; 821c89f2750SDavid 'Digit' Turner 822*726ea1a8SJin Qian static struct miscdevice goldfish_pipe_dev = { 823c89f2750SDavid 'Digit' Turner .minor = MISC_DYNAMIC_MINOR, 824c89f2750SDavid 'Digit' Turner .name = "goldfish_pipe", 825c89f2750SDavid 'Digit' Turner .fops = &goldfish_pipe_fops, 826c89f2750SDavid 'Digit' Turner }; 827c89f2750SDavid 'Digit' Turner 828*726ea1a8SJin Qian static int goldfish_pipe_device_init(struct platform_device *pdev) 829*726ea1a8SJin Qian { 830*726ea1a8SJin Qian char *page; 831*726ea1a8SJin Qian struct goldfish_pipe_dev *dev = pipe_dev; 832*726ea1a8SJin Qian int err = devm_request_irq(&pdev->dev, dev->irq, 833*726ea1a8SJin Qian goldfish_pipe_interrupt, 834*726ea1a8SJin Qian IRQF_SHARED, "goldfish_pipe", dev); 835*726ea1a8SJin Qian if (err) { 836*726ea1a8SJin Qian dev_err(&pdev->dev, "unable to allocate IRQ for v2\n"); 837*726ea1a8SJin Qian return err; 838*726ea1a8SJin Qian } 839*726ea1a8SJin Qian 840*726ea1a8SJin Qian err = misc_register(&goldfish_pipe_dev); 841*726ea1a8SJin Qian if (err) { 842*726ea1a8SJin Qian dev_err(&pdev->dev, "unable to register v2 device\n"); 843*726ea1a8SJin Qian return err; 844*726ea1a8SJin Qian } 845*726ea1a8SJin Qian 846*726ea1a8SJin Qian dev->first_signalled_pipe = NULL; 847*726ea1a8SJin Qian dev->pipes_capacity = INITIAL_PIPES_CAPACITY; 848*726ea1a8SJin Qian dev->pipes = kcalloc(dev->pipes_capacity, sizeof(*dev->pipes), 849*726ea1a8SJin Qian GFP_KERNEL); 850*726ea1a8SJin Qian if (!dev->pipes) 851*726ea1a8SJin Qian return -ENOMEM; 852*726ea1a8SJin Qian 853*726ea1a8SJin Qian /* 854*726ea1a8SJin Qian * We're going to pass two buffers, open_command_params and 855*726ea1a8SJin Qian * signalled_pipe_buffers, to the host. This means each of those buffers 856*726ea1a8SJin Qian * needs to be contained in a single physical page. The easiest choice 857*726ea1a8SJin Qian * is to just allocate a page and place the buffers in it. 858*726ea1a8SJin Qian */ 859*726ea1a8SJin Qian if (WARN_ON(sizeof(*dev->buffers) > PAGE_SIZE)) 860*726ea1a8SJin Qian return -ENOMEM; 861*726ea1a8SJin Qian 862*726ea1a8SJin Qian page = (char *)__get_free_page(GFP_KERNEL); 863*726ea1a8SJin Qian if (!page) { 864*726ea1a8SJin Qian kfree(dev->pipes); 865*726ea1a8SJin Qian return -ENOMEM; 866*726ea1a8SJin Qian } 867*726ea1a8SJin Qian dev->buffers = (struct goldfish_pipe_dev_buffers *)page; 868*726ea1a8SJin Qian 869*726ea1a8SJin Qian /* Send the buffer addresses to the host */ 870*726ea1a8SJin Qian { 871*726ea1a8SJin Qian u64 paddr = __pa(&dev->buffers->signalled_pipe_buffers); 872*726ea1a8SJin Qian 873*726ea1a8SJin Qian writel((u32)(unsigned long)(paddr >> 32), 874*726ea1a8SJin Qian dev->base + PIPE_REG_SIGNAL_BUFFER_HIGH); 875*726ea1a8SJin Qian writel((u32)(unsigned long)paddr, 876*726ea1a8SJin Qian dev->base + PIPE_REG_SIGNAL_BUFFER); 877*726ea1a8SJin Qian writel((u32)MAX_SIGNALLED_PIPES, 878*726ea1a8SJin Qian dev->base + PIPE_REG_SIGNAL_BUFFER_COUNT); 879*726ea1a8SJin Qian 880*726ea1a8SJin Qian paddr = __pa(&dev->buffers->open_command_params); 881*726ea1a8SJin Qian writel((u32)(unsigned long)(paddr >> 32), 882*726ea1a8SJin Qian dev->base + PIPE_REG_OPEN_BUFFER_HIGH); 883*726ea1a8SJin Qian writel((u32)(unsigned long)paddr, 884*726ea1a8SJin Qian dev->base + PIPE_REG_OPEN_BUFFER); 885*726ea1a8SJin Qian } 886*726ea1a8SJin Qian return 0; 887*726ea1a8SJin Qian } 888*726ea1a8SJin Qian 889*726ea1a8SJin Qian static void goldfish_pipe_device_deinit(struct platform_device *pdev) 890*726ea1a8SJin Qian { 891*726ea1a8SJin Qian struct goldfish_pipe_dev *dev = pipe_dev; 892*726ea1a8SJin Qian 893*726ea1a8SJin Qian misc_deregister(&goldfish_pipe_dev); 894*726ea1a8SJin Qian kfree(dev->pipes); 895*726ea1a8SJin Qian free_page((unsigned long)dev->buffers); 896*726ea1a8SJin Qian } 897*726ea1a8SJin Qian 898c89f2750SDavid 'Digit' Turner static int goldfish_pipe_probe(struct platform_device *pdev) 899c89f2750SDavid 'Digit' Turner { 900c89f2750SDavid 'Digit' Turner int err; 901c89f2750SDavid 'Digit' Turner struct resource *r; 902c89f2750SDavid 'Digit' Turner struct goldfish_pipe_dev *dev = pipe_dev; 903c89f2750SDavid 'Digit' Turner 904*726ea1a8SJin Qian if (WARN_ON(sizeof(struct goldfish_pipe_command) > PAGE_SIZE)) 905*726ea1a8SJin Qian return -ENOMEM; 906*726ea1a8SJin Qian 907c89f2750SDavid 'Digit' Turner /* not thread safe, but this should not happen */ 908c89f2750SDavid 'Digit' Turner WARN_ON(dev->base != NULL); 909c89f2750SDavid 'Digit' Turner 910c89f2750SDavid 'Digit' Turner spin_lock_init(&dev->lock); 911c89f2750SDavid 'Digit' Turner 912c89f2750SDavid 'Digit' Turner r = platform_get_resource(pdev, IORESOURCE_MEM, 0); 913c89f2750SDavid 'Digit' Turner if (r == NULL || resource_size(r) < PAGE_SIZE) { 914c89f2750SDavid 'Digit' Turner dev_err(&pdev->dev, "can't allocate i/o page\n"); 915c89f2750SDavid 'Digit' Turner return -EINVAL; 916c89f2750SDavid 'Digit' Turner } 917c89f2750SDavid 'Digit' Turner dev->base = devm_ioremap(&pdev->dev, r->start, PAGE_SIZE); 918c89f2750SDavid 'Digit' Turner if (dev->base == NULL) { 919c89f2750SDavid 'Digit' Turner dev_err(&pdev->dev, "ioremap failed\n"); 920c89f2750SDavid 'Digit' Turner return -EINVAL; 921c89f2750SDavid 'Digit' Turner } 922c89f2750SDavid 'Digit' Turner 923c89f2750SDavid 'Digit' Turner r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); 924c89f2750SDavid 'Digit' Turner if (r == NULL) { 925c89f2750SDavid 'Digit' Turner err = -EINVAL; 926c89f2750SDavid 'Digit' Turner goto error; 927c89f2750SDavid 'Digit' Turner } 928c89f2750SDavid 'Digit' Turner dev->irq = r->start; 929c89f2750SDavid 'Digit' Turner 930*726ea1a8SJin Qian /* 931*726ea1a8SJin Qian * Exchange the versions with the host device 932*726ea1a8SJin Qian * 933*726ea1a8SJin Qian * Note: v1 driver used to not report its version, so we write it before 934*726ea1a8SJin Qian * reading device version back: this allows the host implementation to 935*726ea1a8SJin Qian * detect the old driver (if there was no version write before read). 9364f42071cSYu Ning */ 937*726ea1a8SJin Qian writel((u32)PIPE_DRIVER_VERSION, dev->base + PIPE_REG_VERSION); 9384f42071cSYu Ning dev->version = readl(dev->base + PIPE_REG_VERSION); 939*726ea1a8SJin Qian if (WARN_ON(dev->version < PIPE_CURRENT_DEVICE_VERSION)) 940*726ea1a8SJin Qian return -EINVAL; 941*726ea1a8SJin Qian 942*726ea1a8SJin Qian err = goldfish_pipe_device_init(pdev); 943*726ea1a8SJin Qian if (!err) 944c89f2750SDavid 'Digit' Turner return 0; 945c89f2750SDavid 'Digit' Turner 946c89f2750SDavid 'Digit' Turner error: 947c89f2750SDavid 'Digit' Turner dev->base = NULL; 948c89f2750SDavid 'Digit' Turner return err; 949c89f2750SDavid 'Digit' Turner } 950c89f2750SDavid 'Digit' Turner 951c89f2750SDavid 'Digit' Turner static int goldfish_pipe_remove(struct platform_device *pdev) 952c89f2750SDavid 'Digit' Turner { 953c89f2750SDavid 'Digit' Turner struct goldfish_pipe_dev *dev = pipe_dev; 954*726ea1a8SJin Qian goldfish_pipe_device_deinit(pdev); 955c89f2750SDavid 'Digit' Turner dev->base = NULL; 956c89f2750SDavid 'Digit' Turner return 0; 957c89f2750SDavid 'Digit' Turner } 958c89f2750SDavid 'Digit' Turner 959d62f324bSJason Hu static const struct acpi_device_id goldfish_pipe_acpi_match[] = { 960d62f324bSJason Hu { "GFSH0003", 0 }, 961d62f324bSJason Hu { }, 962d62f324bSJason Hu }; 963d62f324bSJason Hu MODULE_DEVICE_TABLE(acpi, goldfish_pipe_acpi_match); 964d62f324bSJason Hu 96591a18a41SGreg Hackmann static const struct of_device_id goldfish_pipe_of_match[] = { 96691a18a41SGreg Hackmann { .compatible = "google,android-pipe", }, 96791a18a41SGreg Hackmann {}, 96891a18a41SGreg Hackmann }; 96991a18a41SGreg Hackmann MODULE_DEVICE_TABLE(of, goldfish_pipe_of_match); 97091a18a41SGreg Hackmann 971*726ea1a8SJin Qian static struct platform_driver goldfish_pipe_driver = { 972c89f2750SDavid 'Digit' Turner .probe = goldfish_pipe_probe, 973c89f2750SDavid 'Digit' Turner .remove = goldfish_pipe_remove, 974c89f2750SDavid 'Digit' Turner .driver = { 97591a18a41SGreg Hackmann .name = "goldfish_pipe", 97691a18a41SGreg Hackmann .of_match_table = goldfish_pipe_of_match, 977d62f324bSJason Hu .acpi_match_table = ACPI_PTR(goldfish_pipe_acpi_match), 978c89f2750SDavid 'Digit' Turner } 979c89f2750SDavid 'Digit' Turner }; 980c89f2750SDavid 'Digit' Turner 981*726ea1a8SJin Qian module_platform_driver(goldfish_pipe_driver); 982c89f2750SDavid 'Digit' Turner MODULE_AUTHOR("David Turner <digit@google.com>"); 983c89f2750SDavid 'Digit' Turner MODULE_LICENSE("GPL"); 984