/*****************************************************************************

 @(#) $Id: lm.h,v 0.7.2.11 2001/02/03 05:48:39 brian Test $

 -----------------------------------------------------------------------------

 Copyright (C) 1997-2001  Brian Bidulock <bidulock@dallas.net>

 All Rights Reserved.

 This program is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free Software
 Foundation; either version 2 of the License, or (at your option) any later
 version.

 This program is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 details.

 You should have received a copy of the GNU General Public License along with
 this program; if not, write to the Free Software Foundation, Inc., 675 Mass
 Ave, Cambridge, MA 02139, USA.

 -----------------------------------------------------------------------------

 Last Modified $Date: 2001/02/03 05:48:39 $ by $Author: brian $

 *****************************************************************************/

#ifndef __LMI_LM_H__
#define __LMI_LM_H__

struct lmi;

typedef struct lmi_devops {
    struct lmi *(*attach )(dev_t);
    int         (*open   )(struct lmi *);
    int         (*close  )(struct lmi *);
} lmi_devops_t;

typedef struct lmi_lmiops {
    int (*info   )(struct lmi *, void **, int *);
    int (*attach )(struct lmi *, void *, int);
    int (*detach )(struct lmi *);
    int (*enable )(struct lmi *);
    int (*disable)(struct lmi *);
    int (*ioctl  )(struct lmi *, int, void *);
} lmi_lmiops_t;

typedef struct lmi_ops {
    lmi_devops_t   dev;     /*  device management           */
    lmi_lmiops_t   lmi;     /*  local management calls      */
} lmi_ops_t;

typedef struct lmi_driver {
    struct lmi_driver   *next;      /* next driver structure        */
    int                 cmajor;     /* major device number          */
    int                 nminor;     /* number of minor devices      */
    struct lmi          *list;      /* list of device structures    */
    struct streamtab    *info;      /* streamtab for this driver    */
    struct lmi_ops      ops;        /* device operations            */
    void                *dcalls;    /* module calling driver        */
    void                *ucalls;    /* driver calling module        */
} lmi_driver_t;

typedef struct lmi {
    struct lmi      *next;      /* next device in device list       */
    struct lmi      *module;    /* upper for dev/mux, other for mod */
    void            *ucalls;    /* upper module calls               */
    void            *dcalls;    /* lower device calls               */
    struct lmi      *device;    /* driver device (lower for mux)    */
    lmi_driver_t    *driver;    /* driver struct for driver         */
    dev_t           devnum;     /* driver device (null for module)  */
    struct queue    *rq;        /* read queue                       */
    struct queue    *wq;        /* write queue                      */
    lmi_ulong       state;      /* LM interface state               */
    lmi_ulong       flags;      /* LM interface flags               */
    lmi_ulong       ids[0];     /* Protocol structure follows       */
} lmi_t;

extern int lmi_info   (struct lmi *, void **, int *);
extern int lmi_attach (struct lmi *, void *, int);
extern int lmi_detach (struct lmi *);
extern int lmi_enable (struct lmi *);
extern int lmi_disable(struct lmi *);

extern int (*lmi_lmi_ops[5])(lmi_t *, mblk_t *);

extern lmi_t * lmi_drv_attach(dev_t, lmi_driver_t *, size_t);
extern int lmi_drv_open(lmi_t *lmi);
extern int lmi_drv_close(lmi_t *lmi, lmi_ulong *tids, int ntids,
                lmi_ulong *bids, int nbids);

extern int lmi_open(queue_t *q, dev_t *devp, int flag, int sflag,
                cred_t *crp, lmi_driver_t *list, size_t size);
extern int lmi_close(queue_t *q, int flag, cred_t *crp,
                lmi_ulong *tids, int ntids, lmi_ulong *bids, int nbids);

extern int lmi_register_driver(lmi_driver_t **list, major_t cmajor,
                struct streamtab *strtab, int nminor, char *name,
                lmi_ops_t *ops, void *dcalls, void *ucalls);
extern int lmi_unregister_driver(lmi_driver_t **, major_t);

#endif  __LMI_LM_H__
