Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright (c) 2012-2016 VMware, Inc.  All rights reserved.
0003  *
0004  * This program is free software; you can redistribute it and/or
0005  * modify it under the terms of EITHER the GNU General Public License
0006  * version 2 as published by the Free Software Foundation or the BSD
0007  * 2-Clause License. This program is distributed in the hope that it
0008  * will be useful, but WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED
0009  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
0010  * See the GNU General Public License version 2 for more details at
0011  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html.
0012  *
0013  * You should have received a copy of the GNU General Public License
0014  * along with this program available in the file COPYING in the main
0015  * directory of this source tree.
0016  *
0017  * The BSD 2-Clause License
0018  *
0019  *     Redistribution and use in source and binary forms, with or
0020  *     without modification, are permitted provided that the following
0021  *     conditions are met:
0022  *
0023  *      - Redistributions of source code must retain the above
0024  *        copyright notice, this list of conditions and the following
0025  *        disclaimer.
0026  *
0027  *      - Redistributions in binary form must reproduce the above
0028  *        copyright notice, this list of conditions and the following
0029  *        disclaimer in the documentation and/or other materials
0030  *        provided with the distribution.
0031  *
0032  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
0033  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
0034  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
0035  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
0036  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
0037  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
0038  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
0039  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
0040  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
0041  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0042  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
0043  * OF THE POSSIBILITY OF SUCH DAMAGE.
0044  */
0045 
0046 #include <linux/list.h>
0047 
0048 #include "pvrdma.h"
0049 
0050 #define PVRDMA_CMD_TIMEOUT  10000 /* ms */
0051 
0052 static inline int pvrdma_cmd_recv(struct pvrdma_dev *dev,
0053                   union pvrdma_cmd_resp *resp,
0054                   unsigned resp_code)
0055 {
0056     int err;
0057 
0058     dev_dbg(&dev->pdev->dev, "receive response from device\n");
0059 
0060     err = wait_for_completion_interruptible_timeout(&dev->cmd_done,
0061             msecs_to_jiffies(PVRDMA_CMD_TIMEOUT));
0062     if (err == 0 || err == -ERESTARTSYS) {
0063         dev_warn(&dev->pdev->dev,
0064              "completion timeout or interrupted\n");
0065         return -ETIMEDOUT;
0066     }
0067 
0068     spin_lock(&dev->cmd_lock);
0069     memcpy(resp, dev->resp_slot, sizeof(*resp));
0070     spin_unlock(&dev->cmd_lock);
0071 
0072     if (resp->hdr.ack != resp_code) {
0073         dev_warn(&dev->pdev->dev,
0074              "unknown response %#x expected %#x\n",
0075              resp->hdr.ack, resp_code);
0076         return -EFAULT;
0077     }
0078 
0079     return 0;
0080 }
0081 
0082 int
0083 pvrdma_cmd_post(struct pvrdma_dev *dev, union pvrdma_cmd_req *req,
0084         union pvrdma_cmd_resp *resp, unsigned resp_code)
0085 {
0086     int err;
0087 
0088     dev_dbg(&dev->pdev->dev, "post request to device\n");
0089 
0090     /* Serializiation */
0091     down(&dev->cmd_sema);
0092 
0093     BUILD_BUG_ON(sizeof(union pvrdma_cmd_req) !=
0094              sizeof(struct pvrdma_cmd_modify_qp));
0095 
0096     spin_lock(&dev->cmd_lock);
0097     memcpy(dev->cmd_slot, req, sizeof(*req));
0098     spin_unlock(&dev->cmd_lock);
0099 
0100     init_completion(&dev->cmd_done);
0101     pvrdma_write_reg(dev, PVRDMA_REG_REQUEST, 0);
0102 
0103     /* Make sure the request is written before reading status. */
0104     mb();
0105 
0106     err = pvrdma_read_reg(dev, PVRDMA_REG_ERR);
0107     if (err == 0) {
0108         if (resp != NULL)
0109             err = pvrdma_cmd_recv(dev, resp, resp_code);
0110     } else {
0111         dev_warn(&dev->pdev->dev,
0112              "failed to write request error reg: %d\n", err);
0113         err = -EFAULT;
0114     }
0115 
0116     up(&dev->cmd_sema);
0117 
0118     return err;
0119 }