1229997Sken/*- 2229997Sken * Copyright (c) 2003 Silicon Graphics International Corp. 3229997Sken * All rights reserved. 4229997Sken * 5229997Sken * Redistribution and use in source and binary forms, with or without 6229997Sken * modification, are permitted provided that the following conditions 7229997Sken * are met: 8229997Sken * 1. Redistributions of source code must retain the above copyright 9229997Sken * notice, this list of conditions, and the following disclaimer, 10229997Sken * without modification. 11229997Sken * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12229997Sken * substantially similar to the "NO WARRANTY" disclaimer below 13229997Sken * ("Disclaimer") and any redistribution must be conditioned upon 14229997Sken * including a substantially similar Disclaimer requirement for further 15229997Sken * binary redistribution. 16229997Sken * 17229997Sken * NO WARRANTY 18229997Sken * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19229997Sken * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20229997Sken * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR 21229997Sken * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22229997Sken * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23229997Sken * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24229997Sken * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25229997Sken * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 26229997Sken * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 27229997Sken * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28229997Sken * POSSIBILITY OF SUCH DAMAGES. 29229997Sken * 30229997Sken * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_backend.c#3 $ 31229997Sken */ 32229997Sken/* 33229997Sken * CTL backend driver registration routines 34229997Sken * 35229997Sken * Author: Ken Merry <ken@FreeBSD.org> 36229997Sken */ 37229997Sken 38229997Sken#include <sys/cdefs.h> 39229997Sken__FBSDID("$FreeBSD: stable/10/sys/cam/ctl/ctl_backend.c 313369 2017-02-07 01:56:26Z mav $"); 40229997Sken 41229997Sken#include <sys/param.h> 42229997Sken#include <sys/systm.h> 43229997Sken#include <sys/kernel.h> 44229997Sken#include <sys/types.h> 45229997Sken#include <sys/malloc.h> 46229997Sken#include <sys/lock.h> 47229997Sken#include <sys/mutex.h> 48229997Sken#include <sys/condvar.h> 49229997Sken#include <sys/queue.h> 50233963Sken#include <sys/sysctl.h> 51229997Sken 52229997Sken#include <cam/scsi/scsi_all.h> 53229997Sken#include <cam/scsi/scsi_da.h> 54229997Sken#include <cam/ctl/ctl_io.h> 55229997Sken#include <cam/ctl/ctl.h> 56229997Sken#include <cam/ctl/ctl_frontend.h> 57229997Sken#include <cam/ctl/ctl_backend.h> 58229997Sken#include <cam/ctl/ctl_ioctl.h> 59229997Sken#include <cam/ctl/ctl_ha.h> 60229997Sken#include <cam/ctl/ctl_private.h> 61229997Sken#include <cam/ctl/ctl_debug.h> 62229997Sken 63229997Skenextern struct ctl_softc *control_softc; 64229997Sken 65229997Skenint 66229997Skenctl_backend_register(struct ctl_backend_driver *be) 67229997Sken{ 68288795Smav struct ctl_softc *softc = control_softc; 69229997Sken struct ctl_backend_driver *be_tmp; 70313369Smav int error; 71229997Sken 72313369Smav /* Sanity check, make sure this isn't a duplicate registration. */ 73276614Smav mtx_lock(&softc->ctl_lock); 74276614Smav STAILQ_FOREACH(be_tmp, &softc->be_list, links) { 75229997Sken if (strcmp(be_tmp->name, be->name) == 0) { 76276614Smav mtx_unlock(&softc->ctl_lock); 77229997Sken return (-1); 78229997Sken } 79229997Sken } 80276614Smav mtx_unlock(&softc->ctl_lock); 81313369Smav#ifdef CS_BE_CONFIG_MOVE_DONE_IS_NOT_USED 82313369Smav be->config_move_done = ctl_config_move_done; 83313369Smav#endif 84313369Smav be->num_luns = 0; 85229997Sken 86313369Smav /* Call the backend's initialization routine. */ 87313369Smav if (be->init != NULL) { 88313369Smav if ((error = be->init()) != 0) { 89313369Smav printf("%s backend init error: %d\n", 90313369Smav be->name, error); 91313369Smav return (error); 92313369Smav } 93313369Smav } 94229997Sken 95276614Smav mtx_lock(&softc->ctl_lock); 96276614Smav STAILQ_INSERT_TAIL(&softc->be_list, be, links); 97276614Smav softc->num_backends++; 98276614Smav mtx_unlock(&softc->ctl_lock); 99229997Sken return (0); 100229997Sken} 101229997Sken 102229997Skenint 103229997Skenctl_backend_deregister(struct ctl_backend_driver *be) 104229997Sken{ 105288795Smav struct ctl_softc *softc = control_softc; 106313369Smav int error; 107229997Sken 108313369Smav /* Call the backend's shutdown routine. */ 109313369Smav if (be->shutdown != NULL) { 110313369Smav if ((error = be->shutdown()) != 0) { 111313369Smav printf("%s backend shutdown error: %d\n", 112313369Smav be->name, error); 113313369Smav return (error); 114313369Smav } 115229997Sken } 116229997Sken 117313369Smav mtx_lock(&softc->ctl_lock); 118276614Smav STAILQ_REMOVE(&softc->be_list, be, ctl_backend_driver, links); 119276614Smav softc->num_backends--; 120276614Smav mtx_unlock(&softc->ctl_lock); 121229997Sken return (0); 122229997Sken} 123229997Sken 124229997Skenstruct ctl_backend_driver * 125229997Skenctl_backend_find(char *backend_name) 126229997Sken{ 127288795Smav struct ctl_softc *softc = control_softc; 128229997Sken struct ctl_backend_driver *be_tmp; 129229997Sken 130276614Smav mtx_lock(&softc->ctl_lock); 131276614Smav STAILQ_FOREACH(be_tmp, &softc->be_list, links) { 132229997Sken if (strcmp(be_tmp->name, backend_name) == 0) { 133276614Smav mtx_unlock(&softc->ctl_lock); 134229997Sken return (be_tmp); 135229997Sken } 136229997Sken } 137276614Smav mtx_unlock(&softc->ctl_lock); 138229997Sken 139229997Sken return (NULL); 140229997Sken} 141229997Sken 142268143Smavvoid 143268678Smavctl_init_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args) 144268143Smav{ 145268678Smav struct ctl_option *opt; 146268143Smav int i; 147268143Smav 148268678Smav STAILQ_INIT(opts); 149268678Smav for (i = 0; i < num_args; i++) { 150268681Smav if ((args[i].flags & CTL_BEARG_RD) == 0) 151268681Smav continue; 152268681Smav if ((args[i].flags & CTL_BEARG_ASCII) == 0) 153268681Smav continue; 154268143Smav opt = malloc(sizeof(*opt), M_CTL, M_WAITOK); 155288728Smav opt->name = strdup(args[i].kname, M_CTL); 156288728Smav opt->value = strdup(args[i].kvalue, M_CTL); 157268678Smav STAILQ_INSERT_TAIL(opts, opt, links); 158268143Smav } 159268143Smav} 160268143Smav 161268143Smavvoid 162288728Smavctl_update_opts(ctl_options_t *opts, int num_args, struct ctl_be_arg *args) 163288728Smav{ 164288728Smav struct ctl_option *opt; 165288728Smav int i; 166288728Smav 167288728Smav for (i = 0; i < num_args; i++) { 168288728Smav if ((args[i].flags & CTL_BEARG_RD) == 0) 169288728Smav continue; 170288728Smav if ((args[i].flags & CTL_BEARG_ASCII) == 0) 171288728Smav continue; 172288728Smav STAILQ_FOREACH(opt, opts, links) { 173288728Smav if (strcmp(opt->name, args[i].kname) == 0) 174288728Smav break; 175288728Smav } 176288728Smav if (args[i].kvalue != NULL && 177288728Smav ((char *)args[i].kvalue)[0] != 0) { 178288728Smav if (opt) { 179288728Smav free(opt->value, M_CTL); 180288728Smav opt->value = strdup(args[i].kvalue, M_CTL); 181288728Smav } else { 182288728Smav opt = malloc(sizeof(*opt), M_CTL, M_WAITOK); 183288728Smav opt->name = strdup(args[i].kname, M_CTL); 184288728Smav opt->value = strdup(args[i].kvalue, M_CTL); 185288728Smav STAILQ_INSERT_TAIL(opts, opt, links); 186288728Smav } 187288728Smav } else if (opt) { 188288728Smav STAILQ_REMOVE(opts, opt, ctl_option, links); 189288728Smav free(opt->name, M_CTL); 190288728Smav free(opt->value, M_CTL); 191288728Smav free(opt, M_CTL); 192288728Smav } 193288728Smav } 194288728Smav} 195288728Smav 196288728Smavvoid 197268678Smavctl_free_opts(ctl_options_t *opts) 198268143Smav{ 199268678Smav struct ctl_option *opt; 200268143Smav 201268678Smav while ((opt = STAILQ_FIRST(opts)) != NULL) { 202268678Smav STAILQ_REMOVE_HEAD(opts, links); 203268143Smav free(opt->name, M_CTL); 204268143Smav free(opt->value, M_CTL); 205268143Smav free(opt, M_CTL); 206268143Smav } 207268143Smav} 208268143Smav 209268143Smavchar * 210268678Smavctl_get_opt(ctl_options_t *opts, const char *name) 211268143Smav{ 212268678Smav struct ctl_option *opt; 213268143Smav 214268678Smav STAILQ_FOREACH(opt, opts, links) { 215268143Smav if (strcmp(opt->name, name) == 0) { 216268143Smav return (opt->value); 217268143Smav } 218268143Smav } 219268143Smav return (NULL); 220268143Smav} 221308078Smav 222308078Smavint 223308078Smavctl_get_opt_number(ctl_options_t *opts, const char *name, uint64_t *val) 224308078Smav{ 225308078Smav const char *value; 226308078Smav 227308078Smav value = ctl_get_opt(opts, name); 228308078Smav if (value == NULL) 229308078Smav return (-2); 230308078Smav return (ctl_expand_number(value, val)); 231308078Smav} 232