aboutsummaryrefslogtreecommitdiffstats
path: root/xenolinux-2.4.26-sparse/arch/xen/drivers/blkif/backend/control.c
blob: 0b2622465170313abbbe7de56581fb49e01e225a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/******************************************************************************
 * arch/xen/drivers/blkif/backend/control.c
 * 
 * Routines for interfacing with the control plane.
 * 
 * Copyright (c) 2004, Keir Fraser
 */

#include "common.h"

static void blkif_ctrlif_rx(ctrl_msg_t *msg, unsigned long id)
{
    DPRINTK("Received blkif backend message, subtype=%d\n", msg->subtype);
    
    switch ( msg->subtype )
    {
    case CMSG_BLKIF_BE_CREATE:
        if ( msg->length != sizeof(blkif_be_create_t) )
            goto parse_error;
        blkif_create((blkif_be_create_t *)&msg->msg[0]);
        break;        
    case CMSG_BLKIF_BE_DESTROY:
        if ( msg->length != sizeof(blkif_be_destroy_t) )
            goto parse_error;
        blkif_destroy((blkif_be_destroy_t *)&msg->msg[0]);
        break;        
    case CMSG_BLKIF_BE_CONNECT:
        if ( msg->length != sizeof(blkif_be_connect_t) )
            goto parse_error;
        blkif_connect((blkif_be_connect_t *)&msg->msg[0]);
        break;        
    case CMSG_BLKIF_BE_DISCONNECT:
        if ( msg->length != sizeof(blkif_be_disconnect_t) )
            goto parse_error;
        if ( !blkif_disconnect((blkif_be_disconnect_t *)&msg->msg[0],msg->id) )
            return; /* Sending the response is deferred until later. */
        break;        
    case CMSG_BLKIF_BE_VBD_CREATE:
        if ( msg->length != sizeof(blkif_be_vbd_create_t) )
            goto parse_error;
        vbd_create((blkif_be_vbd_create_t *)&msg->msg[0]);
        break;
    case CMSG_BLKIF_BE_VBD_DESTROY:
        if ( msg->length != sizeof(blkif_be_vbd_destroy_t) )
            goto parse_error;
        vbd_destroy((blkif_be_vbd_destroy_t *)&msg->msg[0]);
        break;
    case CMSG_BLKIF_BE_VBD_GROW:
        if ( msg->length != sizeof(blkif_be_vbd_grow_t) )
            goto parse_error;
        vbd_grow((blkif_be_vbd_grow_t *)&msg->msg[0]);
        break;
    case CMSG_BLKIF_BE_VBD_SHRINK:
        if ( msg->length != sizeof(blkif_be_vbd_shrink_t) )
            goto parse_error;
        vbd_shrink((blkif_be_vbd_shrink_t *)&msg->msg[0]);
        break;
    default:
        goto parse_error;
    }

    ctrl_if_send_response(msg);
    return;

 parse_error:
    DPRINTK("Parse error while reading message subtype %d, len %d\n",
            msg->subtype, msg->length);
    msg->length = 0;
    ctrl_if_send_response(msg);
}

void blkif_ctrlif_init(void)
{
    ctrl_msg_t                       cmsg;
    blkif_be_driver_status_changed_t st;

    (void)ctrl_if_register_receiver(CMSG_BLKIF_BE, blkif_ctrlif_rx, 
                                    CALLBACK_IN_BLOCKING_CONTEXT);

    /* Send a driver-UP notification to the domain controller. */
    cmsg.type      = CMSG_BLKIF_BE;
    cmsg.subtype   = CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED;
    cmsg.length    = sizeof(blkif_be_driver_status_changed_t);
    st.status      = BLKIF_DRIVER_STATUS_UP;
    memcpy(cmsg.msg, &st, sizeof(st));
    ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE);
}