1/**
2 * \file
3 * \brief MMCHS Driver main routine.
4 */
5/*
6 * Copyright (c) 2013, ETH Zurich.
7 * All rights reserved.
8 *
9 * This file is distributed under the terms in the attached LICENSE file.
10 * If you do not find this file, copies can be found by writing to:
11 * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
12 */
13
14#include <stdlib.h>
15#include <stdio.h>
16#include <string.h>
17#include <assert.h>
18
19#include <barrelfish/barrelfish.h>
20#include <driverkit/driverkit.h>
21
22#include "cm2.h"
23
24/**
25 * Driver initialization function. This function is called by the driver domain
26 * (see also 'create_handler' in ddomain_service.c).
27 * Typically through a request from the device manager.
28 *
29 * The init function is supposed to set `dev` to the exported service iref.
30 * The init function may use `bfi->dstate` to store additional state about the device.
31 *
32 * \param[in]   bfi   The instance of this driver.
33 * \param[in]   name  The name of this driver instance.
34 * \param[in]   flags Additional flags (The exact flags supported is device/driver specific).
35 * \param[in]   c     Capabilities (for registers etc.) as provided by the device manager.
36 *                    The exact layout of the `c` is device specific.
37 * \param[out]  dev   The service iref over which the device can be contacted.
38 *
39 * \retval SYS_ERR_OK Device initialized successfully.
40 * \retval LIB_ERR_MALLOC_FAIL Unable to allocate memory for the driver.
41 */
42static errval_t init(struct bfdriver_instance* bfi, const char* name, uint64_t flags,
43                     struct capref* caps, size_t caps_len, char** args, size_t args_len, iref_t* dev) {
44    CM2_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
45
46    bfi->dstate = malloc(sizeof(struct cm2_driver_state));
47    if (bfi->dstate == NULL) {
48        return LIB_ERR_MALLOC_FAIL;
49    }
50
51    assert(bfi->dstate != NULL);
52
53    struct cm2_driver_state* st = (struct cm2_driver_state*) bfi->dstate;
54    st->cap = caps[0];
55
56    cm2_init(st);
57    cm2_init_service(st, dev);
58
59    return SYS_ERR_OK;
60}
61
62/**
63 * Instructs driver to attach to the device.
64 * This function is only called if the driver has previously detached
65 * from the device (see also detach).
66 *
67 * \note After detachment the driver can not assume anything about the
68 * configuration of the device.
69 *
70 * \param[in]   bfi   The instance of this driver.
71 * \retval SYS_ERR_OK Device initialized successfully.
72 */
73static errval_t attach(struct bfdriver_instance* bfi) {
74    CM2_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
75
76    return SYS_ERR_OK;
77}
78
79/**
80 * Instructs driver to detach from the device.
81 * The driver must yield any control over to the device after this function returns.
82 * The device may be left in any state.
83 *
84 * \param[in]   bfi   The instance of this driver.
85 * \retval SYS_ERR_OK Device initialized successfully.
86 */
87static errval_t detach(struct bfdriver_instance* bfi) {
88    CM2_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
89
90    return SYS_ERR_OK;
91}
92
93/**
94 * Instructs the driver to go in a particular sleep state.
95 * Supported states are platform/device specific.
96 *
97 * \param[in]   bfi   The instance of this driver.
98 * \retval SYS_ERR_OK Device initialized successfully.
99 */
100static errval_t set_sleep_level(struct bfdriver_instance* bfi, uint32_t level) {
101    CM2_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
102
103    struct cm2_driver_state* uds = bfi->dstate;
104    uds->level = level;
105
106    return SYS_ERR_OK;
107}
108
109/**
110 * Destroys this driver instance. The driver will yield any
111 * control over the device and free any state allocated.
112 *
113 * \param[in]   bfi   The instance of this driver.
114 * \retval SYS_ERR_OK Device initialized successfully.
115 */
116static errval_t destroy(struct bfdriver_instance* bfi) {
117    CM2_DEBUG("%s:%s:%d: %s\n", __FILE__, __FUNCTION__, __LINE__, bfi->driver->name);
118    struct cm2_driver_state* uds = bfi->dstate;
119    free(uds);
120    bfi->dstate = NULL;
121
122    // XXX: Tear-down the service
123    bfi->device = 0x0;
124
125    return SYS_ERR_OK;
126}
127
128/**
129 * Registers the driver module with the system.
130 */
131DEFINE_MODULE(cm2, init, attach, detach, set_sleep_level, destroy);
132