1 /*- 2 * BSD LICENSE 3 * 4 * Copyright (c) Intel Corporation. 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 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include "spdk/stdinc.h" 35 36 #include "utils.h" 37 #include "vbdev_ocf.h" 38 39 static char *cache_modes[ocf_cache_mode_max] = { 40 [ocf_cache_mode_wt] = "wt", 41 [ocf_cache_mode_wb] = "wb", 42 [ocf_cache_mode_wa] = "wa", 43 [ocf_cache_mode_pt] = "pt", 44 [ocf_cache_mode_wi] = "wi" 45 }; 46 47 ocf_cache_mode_t 48 ocf_get_cache_mode(const char *cache_mode) 49 { 50 int i; 51 52 for (i = 0; i < ocf_cache_mode_max; i++) { 53 if (strcmp(cache_mode, cache_modes[i]) == 0) { 54 return i; 55 } 56 } 57 58 return ocf_cache_mode_none; 59 } 60 61 const char * 62 ocf_get_cache_modename(ocf_cache_mode_t mode) 63 { 64 if (mode > ocf_cache_mode_none && mode < ocf_cache_mode_max) { 65 return cache_modes[mode]; 66 } else { 67 return NULL; 68 } 69 } 70 71 static int 72 mngt_poll_fn(void *opaque) 73 { 74 struct vbdev_ocf *vbdev = opaque; 75 76 if (vbdev->mngt_ctx.poller_fn) { 77 if (vbdev->mngt_ctx.timeout_ts && 78 spdk_get_ticks() >= vbdev->mngt_ctx.timeout_ts) { 79 vbdev_ocf_mngt_continue(vbdev, -ETIMEDOUT); 80 } else { 81 vbdev->mngt_ctx.poller_fn(vbdev); 82 } 83 } 84 85 return 0; 86 } 87 88 int 89 vbdev_ocf_mngt_start(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn *path, 90 vbdev_ocf_mngt_callback cb, void *cb_arg) 91 { 92 if (vbdev->mngt_ctx.current_step) { 93 return -EBUSY; 94 } 95 96 memset(&vbdev->mngt_ctx, 0, sizeof(vbdev->mngt_ctx)); 97 98 vbdev->mngt_ctx.poller = spdk_poller_register(mngt_poll_fn, vbdev, 200); 99 if (vbdev->mngt_ctx.poller == NULL) { 100 return -ENOMEM; 101 } 102 103 vbdev->mngt_ctx.current_step = path; 104 vbdev->mngt_ctx.cb = cb; 105 vbdev->mngt_ctx.cb_arg = cb_arg; 106 107 (*vbdev->mngt_ctx.current_step)(vbdev); 108 109 return 0; 110 } 111 112 113 static void 114 vbdev_ocf_mngt_poll_set_timeout(struct vbdev_ocf *vbdev, uint64_t millisec) 115 { 116 uint64_t ticks; 117 118 ticks = millisec * spdk_get_ticks_hz() / 1000; 119 vbdev->mngt_ctx.timeout_ts = spdk_get_ticks() + ticks; 120 } 121 122 void 123 vbdev_ocf_mngt_poll(struct vbdev_ocf *vbdev, vbdev_ocf_mngt_fn fn) 124 { 125 assert(vbdev->mngt_ctx.poller != NULL); 126 vbdev->mngt_ctx.poller_fn = fn; 127 vbdev_ocf_mngt_poll_set_timeout(vbdev, 5000); 128 } 129 130 void 131 vbdev_ocf_mngt_stop(struct vbdev_ocf *vbdev) 132 { 133 spdk_poller_unregister(&vbdev->mngt_ctx.poller); 134 135 if (vbdev->mngt_ctx.cb) { 136 vbdev->mngt_ctx.cb(vbdev->mngt_ctx.status, vbdev, vbdev->mngt_ctx.cb_arg); 137 } 138 139 memset(&vbdev->mngt_ctx, 0, sizeof(vbdev->mngt_ctx)); 140 } 141 142 void 143 vbdev_ocf_mngt_continue(struct vbdev_ocf *vbdev, int status) 144 { 145 if (vbdev->mngt_ctx.current_step == NULL) { 146 return; 147 } 148 149 assert((*vbdev->mngt_ctx.current_step) != NULL); 150 151 vbdev->mngt_ctx.status = status; 152 vbdev->mngt_ctx.poller_fn = NULL; 153 154 vbdev->mngt_ctx.current_step++; 155 if (*vbdev->mngt_ctx.current_step) { 156 (*vbdev->mngt_ctx.current_step)(vbdev); 157 return; 158 } 159 160 vbdev_ocf_mngt_stop(vbdev); 161 } 162