linux/drivers/misc/sgi-gru/grukservices.h
<<
>>
Prefs
   1
   2/*
   3 *  Copyright (c) 2008 Silicon Graphics, Inc.  All Rights Reserved.
   4 *
   5 *  This program is free software; you can redistribute it and/or modify
   6 *  it under the terms of the GNU General Public License as published by
   7 *  the Free Software Foundation; either version 2 of the License, or
   8 *  (at your option) any later version.
   9 *
  10 *  This program is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13 *  GNU General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU General Public License
  16 *  along with this program; if not, write to the Free Software
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  18 */
  19#ifndef __GRU_KSERVICES_H_
  20#define __GRU_KSERVICES_H_
  21
  22
  23/*
  24 * Message queues using the GRU to send/receive messages.
  25 *
  26 * These function allow the user to create a message queue for
  27 * sending/receiving 1 or 2 cacheline messages using the GRU.
  28 *
  29 * Processes SENDING messages will use a kernel CBR/DSR to send
  30 * the message. This is transparent to the caller.
  31 *
  32 * The receiver does not use any GRU resources.
  33 *
  34 * The functions support:
  35 *      - single receiver
  36 *      - multiple senders
  37 *      - cross partition message
  38 *
  39 * Missing features ZZZ:
  40 *      - user options for dealing with timeouts, queue full, etc.
  41 *      - gru_create_message_queue() needs interrupt vector info
  42 */
  43
  44struct gru_message_queue_desc {
  45        void            *mq;                    /* message queue vaddress */
  46        unsigned long   mq_gpa;                 /* global address of mq */
  47        int             qlines;                 /* queue size in CL */
  48        int             interrupt_vector;       /* interrupt vector */
  49        int             interrupt_pnode;        /* pnode for interrupt */
  50        int             interrupt_apicid;       /* lapicid for interrupt */
  51};
  52
  53/*
  54 * Initialize a user allocated chunk of memory to be used as
  55 * a message queue. The caller must ensure that the queue is
  56 * in contiguous physical memory and is cacheline aligned.
  57 *
  58 * Message queue size is the total number of bytes allocated
  59 * to the queue including a 2 cacheline header that is used
  60 * to manage the queue.
  61 *
  62 *  Input:
  63 *      mqd     pointer to message queue descriptor
  64 *      p       pointer to user allocated mesq memory.
  65 *      bytes   size of message queue in bytes
  66 *      vector  interrupt vector (zero if no interrupts)
  67 *      nasid   nasid of blade where interrupt is delivered
  68 *      apicid  apicid of cpu for interrupt
  69 *
  70 *  Errors:
  71 *      0       OK
  72 *      >0      error
  73 */
  74extern int gru_create_message_queue(struct gru_message_queue_desc *mqd,
  75                void *p, unsigned int bytes, int nasid, int vector, int apicid);
  76
  77/*
  78 * Send a message to a message queue.
  79 *
  80 * Note: The message queue transport mechanism uses the first 32
  81 * bits of the message. Users should avoid using these bits.
  82 *
  83 *
  84 *   Input:
  85 *      mqd     pointer to message queue descriptor
  86 *      mesg    pointer to message. Must be 64-bit aligned
  87 *      bytes   size of message in bytes
  88 *
  89 *   Output:
  90 *      0       message sent
  91 *     >0       Send failure - see error codes below
  92 *
  93 */
  94extern int gru_send_message_gpa(struct gru_message_queue_desc *mqd,
  95                        void *mesg, unsigned int bytes);
  96
  97/* Status values for gru_send_message() */
  98#define MQE_OK                  0       /* message sent successfully */
  99#define MQE_CONGESTION          1       /* temporary congestion, try again */
 100#define MQE_QUEUE_FULL          2       /* queue is full */
 101#define MQE_UNEXPECTED_CB_ERR   3       /* unexpected CB error */
 102#define MQE_PAGE_OVERFLOW       10      /* BUG - queue overflowed a page */
 103#define MQE_BUG_NO_RESOURCES    11      /* BUG - could not alloc GRU cb/dsr */
 104
 105/*
 106 * Advance the receive pointer for the message queue to the next message.
 107 * Note: current API requires messages to be gotten & freed in order. Future
 108 * API extensions may allow for out-of-order freeing.
 109 *
 110 *   Input
 111 *      mqd     pointer to message queue descriptor
 112 *      mesq    message being freed
 113 */
 114extern void gru_free_message(struct gru_message_queue_desc *mqd,
 115                             void *mesq);
 116
 117/*
 118 * Get next message from message queue. Returns pointer to
 119 * message OR NULL if no message present.
 120 * User must call gru_free_message() after message is processed
 121 * in order to move the queue pointers to next message.
 122 *
 123 *   Input
 124 *      mqd     pointer to message queue descriptor
 125 *
 126 *   Output:
 127 *      p       pointer to message
 128 *      NULL    no message available
 129 */
 130extern void *gru_get_next_message(struct gru_message_queue_desc *mqd);
 131
 132
 133/*
 134 * Read a GRU global GPA. Source can be located in a remote partition.
 135 *
 136 *    Input:
 137 *      value           memory address where MMR value is returned
 138 *      gpa             source numalink physical address of GPA
 139 *
 140 *    Output:
 141 *      0               OK
 142 *      >0              error
 143 */
 144int gru_read_gpa(unsigned long *value, unsigned long gpa);
 145
 146
 147/*
 148 * Copy data using the GRU. Source or destination can be located in a remote
 149 * partition.
 150 *
 151 *    Input:
 152 *      dest_gpa        destination global physical address
 153 *      src_gpa         source global physical address
 154 *      bytes           number of bytes to copy
 155 *
 156 *    Output:
 157 *      0               OK
 158 *      >0              error
 159 */
 160extern int gru_copy_gpa(unsigned long dest_gpa, unsigned long src_gpa,
 161                                                        unsigned int bytes);
 162
 163/*
 164 * Reserve GRU resources to be used asynchronously.
 165 *
 166 *      input:
 167 *              blade_id  - blade on which resources should be reserved
 168 *              cbrs      - number of CBRs
 169 *              dsr_bytes - number of DSR bytes needed
 170 *              cmp       - completion structure for waiting for
 171 *                          async completions
 172 *      output:
 173 *              handle to identify resource
 174 *              (0 = no resources)
 175 */
 176extern unsigned long gru_reserve_async_resources(int blade_id, int cbrs, int dsr_bytes,
 177                                struct completion *cmp);
 178
 179/*
 180 * Release async resources previously reserved.
 181 *
 182 *      input:
 183 *              han - handle to identify resources
 184 */
 185extern void gru_release_async_resources(unsigned long han);
 186
 187/*
 188 * Wait for async GRU instructions to complete.
 189 *
 190 *      input:
 191 *              han - handle to identify resources
 192 */
 193extern void gru_wait_async_cbr(unsigned long han);
 194
 195/*
 196 * Lock previous reserved async GRU resources
 197 *
 198 *      input:
 199 *              han - handle to identify resources
 200 *      output:
 201 *              cb  - pointer to first CBR
 202 *              dsr - pointer to first DSR
 203 */
 204extern void gru_lock_async_resource(unsigned long han,  void **cb, void **dsr);
 205
 206/*
 207 * Unlock previous reserved async GRU resources
 208 *
 209 *      input:
 210 *              han - handle to identify resources
 211 */
 212extern void gru_unlock_async_resource(unsigned long han);
 213
 214#endif          /* __GRU_KSERVICES_H_ */
 215