root/include/linux/hil_mlc.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


   1 /*
   2  * HP Human Interface Loop Master Link Controller driver.
   3  *
   4  * Copyright (c) 2001 Brian S. Julin
   5  * All rights reserved.
   6  *
   7  * Redistribution and use in source and binary forms, with or without
   8  * modification, are permitted provided that the following conditions
   9  * are met:
  10  * 1. Redistributions of source code must retain the above copyright
  11  *    notice, this list of conditions, and the following disclaimer,
  12  *    without modification.
  13  * 2. The name of the author may not be used to endorse or promote products
  14  *    derived from this software without specific prior written permission.
  15  *
  16  * Alternatively, this software may be distributed under the terms of the
  17  * GNU General Public License ("GPL").
  18  *
  19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
  23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28  *
  29  * References:
  30  * HP-HIL Technical Reference Manual.  Hewlett Packard Product No. 45918A
  31  *
  32  */
  33 
  34 #include <linux/hil.h>
  35 #include <linux/time.h>
  36 #include <linux/interrupt.h>
  37 #include <linux/semaphore.h>
  38 #include <linux/serio.h>
  39 #include <linux/list.h>
  40 
  41 typedef struct hil_mlc hil_mlc;
  42 
  43 /* The HIL has a complicated state engine.
  44  * We define the structure of nodes in the state engine here.
  45  */
  46 enum hilse_act {
  47         /* HILSE_OUT prepares to receive input if the next node
  48          * is an IN or EXPECT, and then sends the given packet.
  49          */
  50         HILSE_OUT = 0,
  51 
  52         /* HILSE_CTS checks if the loop is busy. */
  53         HILSE_CTS,
  54 
  55         /* HILSE_OUT_LAST sends the given command packet to 
  56          * the last configured/running device on the loop.
  57          */
  58         HILSE_OUT_LAST,
  59 
  60         /* HILSE_OUT_DISC sends the given command packet to
  61          * the next device past the last configured/running one.
  62          */
  63         HILSE_OUT_DISC,
  64 
  65         /* HILSE_FUNC runs a callback function with given arguments.
  66          * a positive return value causes the "ugly" branch to be taken.
  67          */
  68         HILSE_FUNC,
  69 
  70         /* HILSE_IN simply expects any non-errored packet to arrive 
  71          * within arg usecs.
  72          */
  73         HILSE_IN                = 0x100,
  74 
  75         /* HILSE_EXPECT expects a particular packet to arrive 
  76          * within arg usecs, any other packet is considered an error.
  77          */
  78         HILSE_EXPECT,
  79 
  80         /* HILSE_EXPECT_LAST as above but dev field should be last 
  81          * discovered/operational device.
  82          */
  83         HILSE_EXPECT_LAST,
  84 
  85         /* HILSE_EXPECT_LAST as above but dev field should be first 
  86          * undiscovered/inoperational device.
  87          */
  88         HILSE_EXPECT_DISC
  89 };
  90 
  91 typedef int     (hilse_func) (hil_mlc *mlc, int arg);
  92 struct hilse_node {
  93         enum hilse_act          act;    /* How to process this node         */
  94         union {
  95                 hilse_func      *func;  /* Function to call if HILSE_FUNC   */
  96                 hil_packet      packet; /* Packet to send or to compare     */
  97         } object;
  98         int                     arg;    /* Timeout in usec or parm for func */
  99         int                     good;   /* Node to jump to on success       */
 100         int                     bad;    /* Node to jump to on error         */
 101         int                     ugly;   /* Node to jump to on timeout       */
 102 };
 103 
 104 /* Methods for back-end drivers, e.g. hp_sdc_mlc */
 105 typedef int     (hil_mlc_cts) (hil_mlc *mlc);
 106 typedef void    (hil_mlc_out) (hil_mlc *mlc);
 107 typedef int     (hil_mlc_in)  (hil_mlc *mlc, suseconds_t timeout);
 108 
 109 struct hil_mlc_devinfo {
 110         uint8_t idd[16];        /* Device ID Byte and Describe Record */
 111         uint8_t rsc[16];        /* Security Code Header and Record */
 112         uint8_t exd[16];        /* Extended Describe Record */
 113         uint8_t rnm[16];        /* Device name as returned by RNM command */
 114 };
 115 
 116 struct hil_mlc_serio_map {
 117         hil_mlc *mlc;
 118         int di_revmap;
 119         int didx;
 120 };
 121 
 122 /* How many (possibly old/detached) devices the we try to keep track of */
 123 #define HIL_MLC_DEVMEM 16
 124 
 125 struct hil_mlc {
 126         struct list_head        list;   /* hil_mlc is organized as linked list */
 127 
 128         rwlock_t                lock;
 129 
 130         void *priv; /* Data specific to a particular type of MLC */
 131 
 132         int                     seidx;  /* Current node in state engine */
 133         int                     istarted, ostarted;
 134 
 135         hil_mlc_cts             *cts;
 136         struct semaphore        csem;   /* Raised when loop idle */
 137 
 138         hil_mlc_out             *out;
 139         struct semaphore        osem;   /* Raised when outpacket dispatched */
 140         hil_packet              opacket;
 141 
 142         hil_mlc_in              *in;
 143         struct semaphore        isem;   /* Raised when a packet arrives */
 144         hil_packet              ipacket[16];
 145         hil_packet              imatch;
 146         int                     icount;
 147         unsigned long           instart;
 148         unsigned long           intimeout;
 149 
 150         int                     ddi;    /* Last operational device id */
 151         int                     lcv;    /* LCV to throttle loops */
 152         time64_t                lcv_time; /* Time loop was started */
 153 
 154         int                     di_map[7]; /* Maps below items to live devs */
 155         struct hil_mlc_devinfo  di[HIL_MLC_DEVMEM];
 156         struct serio            *serio[HIL_MLC_DEVMEM];
 157         struct hil_mlc_serio_map serio_map[HIL_MLC_DEVMEM];
 158         hil_packet              serio_opacket[HIL_MLC_DEVMEM];
 159         int                     serio_oidx[HIL_MLC_DEVMEM];
 160         struct hil_mlc_devinfo  di_scratch; /* Temporary area */
 161 
 162         int                     opercnt;
 163 
 164         struct tasklet_struct   *tasklet;
 165 };
 166 
 167 int hil_mlc_register(hil_mlc *mlc);
 168 int hil_mlc_unregister(hil_mlc *mlc);

/* [<][>][^][v][top][bottom][index][help] */