xref: /freebsd/sys/cam/ctl/ctl_frontend.c (revision d184218c)
1 /*-
2  * Copyright (c) 2003 Silicon Graphics International Corp.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions, and the following disclaimer,
10  *    without modification.
11  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12  *    substantially similar to the "NO WARRANTY" disclaimer below
13  *    ("Disclaimer") and any redistribution must be conditioned upon
14  *    including a substantially similar Disclaimer requirement for further
15  *    binary redistribution.
16  *
17  * NO WARRANTY
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGES.
29  *
30  * $Id: //depot/users/kenm/FreeBSD-test2/sys/cam/ctl/ctl_frontend.c#4 $
31  */
32 /*
33  * CAM Target Layer front end interface code
34  *
35  * Author: Ken Merry <ken@FreeBSD.org>
36  */
37 
38 #include <sys/cdefs.h>
39 __FBSDID("$FreeBSD$");
40 
41 #include <sys/param.h>
42 #include <sys/systm.h>
43 #include <sys/kernel.h>
44 #include <sys/types.h>
45 #include <sys/malloc.h>
46 #include <sys/lock.h>
47 #include <sys/mutex.h>
48 #include <sys/condvar.h>
49 #include <sys/endian.h>
50 #include <sys/queue.h>
51 #include <sys/sysctl.h>
52 
53 #include <cam/scsi/scsi_all.h>
54 #include <cam/scsi/scsi_da.h>
55 #include <cam/ctl/ctl_io.h>
56 #include <cam/ctl/ctl.h>
57 #include <cam/ctl/ctl_frontend.h>
58 #include <cam/ctl/ctl_frontend_internal.h>
59 #include <cam/ctl/ctl_backend.h>
60 /* XXX KDM move defines from ctl_ioctl.h to somewhere else */
61 #include <cam/ctl/ctl_ioctl.h>
62 #include <cam/ctl/ctl_ha.h>
63 #include <cam/ctl/ctl_private.h>
64 #include <cam/ctl/ctl_debug.h>
65 
66 extern struct ctl_softc *control_softc;
67 
68 int
69 ctl_frontend_register(struct ctl_frontend *fe, int master_shelf)
70 {
71 	struct ctl_io_pool *pool;
72 	int port_num;
73 	int retval;
74 
75 	retval = 0;
76 
77 	KASSERT(control_softc != NULL, ("CTL is not initialized"));
78 
79 	mtx_lock(&control_softc->ctl_lock);
80 	port_num = ctl_ffz(&control_softc->ctl_port_mask, CTL_MAX_PORTS);
81 	if ((port_num == -1)
82 	 || (ctl_set_mask(&control_softc->ctl_port_mask, port_num) == -1)) {
83 		fe->targ_port = -1;
84 		mtx_unlock(&control_softc->ctl_lock);
85 		return (1);
86 	}
87 	control_softc->num_frontends++;
88 
89 	mtx_unlock(&control_softc->ctl_lock);
90 	/*
91 	 * We add 20 to whatever the caller requests, so he doesn't get
92 	 * burned by queueing things back to the pending sense queue.  In
93 	 * theory, there should probably only be one outstanding item, at
94 	 * most, on the pending sense queue for a LUN.  We'll clear the
95 	 * pending sense queue on the next command, whether or not it is
96 	 * a REQUEST SENSE.
97 	 */
98 	retval = ctl_pool_create(control_softc,
99 				 (fe->port_type != CTL_PORT_IOCTL) ?
100 				 CTL_POOL_FETD : CTL_POOL_IOCTL,
101 				 fe->num_requested_ctl_io + 20, &pool);
102 	if (retval != 0) {
103 		fe->targ_port = -1;
104 		mtx_lock(&control_softc->ctl_lock);
105 		ctl_clear_mask(&control_softc->ctl_port_mask, port_num);
106 		mtx_unlock(&control_softc->ctl_lock);
107 		return (retval);
108 	}
109 
110 	mtx_lock(&control_softc->ctl_lock);
111 
112 	/* For now assume master shelf */
113 	//fe->targ_port = port_num;
114 	fe->targ_port = port_num + (master_shelf!=0 ? 0 : CTL_MAX_PORTS);
115 	fe->max_initiators = CTL_MAX_INIT_PER_PORT;
116 	STAILQ_INSERT_TAIL(&control_softc->fe_list, fe, links);
117 	ctl_pool_acquire(pool);
118 	control_softc->ctl_ports[port_num] = fe;
119 
120 	mtx_unlock(&control_softc->ctl_lock);
121 
122 	fe->ctl_pool_ref = pool;
123 
124 	return (retval);
125 }
126 
127 int
128 ctl_frontend_deregister(struct ctl_frontend *fe)
129 {
130 	struct ctl_io_pool *pool;
131 	int port_num;
132 	int retval;
133 
134 	retval = 0;
135 
136 	pool = (struct ctl_io_pool *)fe->ctl_pool_ref;
137 
138 	if (fe->targ_port == -1) {
139 		retval = 1;
140 		goto bailout;
141 	}
142 
143 	mtx_lock(&control_softc->ctl_lock);
144 
145 	ctl_pool_invalidate(pool);
146 	ctl_pool_release(pool);
147 
148 	STAILQ_REMOVE(&control_softc->fe_list, fe, ctl_frontend, links);
149 	control_softc->num_frontends--;
150 	port_num = (fe->targ_port < CTL_MAX_PORTS) ? fe->targ_port :
151 	                                             fe->targ_port - CTL_MAX_PORTS;
152 	ctl_clear_mask(&control_softc->ctl_port_mask, port_num);
153 	control_softc->ctl_ports[port_num] = NULL;
154 	mtx_unlock(&control_softc->ctl_lock);
155 bailout:
156 	return (retval);
157 }
158 
159 void
160 ctl_frontend_set_wwns(struct ctl_frontend *fe, int wwnn_valid, uint64_t wwnn,
161 		      int wwpn_valid, uint64_t wwpn)
162 {
163 	if (wwnn_valid)
164 		fe->wwnn = wwnn;
165 
166 	if (wwpn_valid)
167 		fe->wwpn = wwpn;
168 }
169 
170 void
171 ctl_frontend_online(struct ctl_frontend *fe)
172 {
173 	fe->port_online(fe->onoff_arg);
174 	/* XXX KDM need a lock here? */
175 	fe->status |= CTL_PORT_STATUS_ONLINE;
176 }
177 
178 void
179 ctl_frontend_offline(struct ctl_frontend *fe)
180 {
181 	fe->port_offline(fe->onoff_arg);
182 	/* XXX KDM need a lock here? */
183 	fe->status &= ~CTL_PORT_STATUS_ONLINE;
184 }
185 
186 /*
187  * vim: ts=8
188  */
189