1/*-
| 1/*-
|
2 * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
| 2 * Copyright (c) 2005-2010 Daniel Braniss <danny@cs.huji.ac.il>
|
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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27/* 28 | iSCSI - Session Manager
| 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 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27/* 28 | iSCSI - Session Manager
|
29 | $Id: isc_sm.c,v 1.30 2007/04/22 09:53:09 danny Exp danny $
| 29 | $Id: isc_sm.c 743 2009-08-08 10:54:53Z danny $
|
30 */ 31 32#include <sys/cdefs.h>
| 30 */ 31 32#include <sys/cdefs.h>
|
33__FBSDID("$FreeBSD: head/sys/dev/iscsi/initiator/isc_sm.c 201758 2010-01-07 21:01:37Z mbr $");
| 33__FBSDID("$FreeBSD: head/sys/dev/iscsi/initiator/isc_sm.c 211095 2010-08-09 12:36:36Z des $");
|
34 35#include "opt_iscsi_initiator.h" 36 37#include <sys/param.h> 38#include <sys/kernel.h> 39#include <sys/conf.h> 40#include <sys/systm.h> 41#include <sys/malloc.h> 42#include <sys/ctype.h> 43#include <sys/errno.h> 44#include <sys/sysctl.h> 45#include <sys/file.h> 46#include <sys/uio.h> 47#include <sys/socketvar.h> 48#include <sys/socket.h> 49#include <sys/protosw.h> 50#include <sys/proc.h> 51#include <sys/ioccom.h> 52#include <sys/queue.h> 53#include <sys/kthread.h> 54#include <sys/syslog.h> 55#include <sys/mbuf.h> 56#include <sys/bus.h>
| 34 35#include "opt_iscsi_initiator.h" 36 37#include <sys/param.h> 38#include <sys/kernel.h> 39#include <sys/conf.h> 40#include <sys/systm.h> 41#include <sys/malloc.h> 42#include <sys/ctype.h> 43#include <sys/errno.h> 44#include <sys/sysctl.h> 45#include <sys/file.h> 46#include <sys/uio.h> 47#include <sys/socketvar.h> 48#include <sys/socket.h> 49#include <sys/protosw.h> 50#include <sys/proc.h> 51#include <sys/ioccom.h> 52#include <sys/queue.h> 53#include <sys/kthread.h> 54#include <sys/syslog.h> 55#include <sys/mbuf.h> 56#include <sys/bus.h>
|
| 57#include <sys/sx.h>
|
57 58#include <cam/cam.h> 59#include <cam/cam_ccb.h> 60#include <cam/cam_sim.h> 61#include <cam/cam_xpt_sim.h> 62#include <cam/cam_periph.h> 63 64#include <dev/iscsi/initiator/iscsi.h> 65#include <dev/iscsi/initiator/iscsivar.h> 66 67static void 68_async(isc_session_t *sp, pduq_t *pq) 69{ 70 debug_called(8); 71 72 iscsi_async(sp, pq); 73 74 pdu_free(sp->isc, pq); 75} 76 77static void 78_reject(isc_session_t *sp, pduq_t *pq) 79{ 80 pduq_t *opq; 81 pdu_t *pdu; 82 reject_t *reject; 83 int itt; 84 85 debug_called(8); 86 pdu = mtod(pq->mp, pdu_t *); 87 itt = pdu->ipdu.bhs.itt; 88 reject = &pq->pdu.ipdu.reject; 89 sdebug(2, "itt=%x reason=0x%x", ntohl(itt), reject->reason); 90 opq = i_search_hld(sp, itt, 0); 91 if(opq != NULL) 92 iscsi_reject(sp, opq, pq); 93 else { 94 switch(pq->pdu.ipdu.bhs.opcode) { 95 case ISCSI_LOGOUT_CMD: // XXX: wasabi does this - can't figure out why 96 sdebug(2, "ISCSI_LOGOUT_CMD ..."); 97 break; 98 default: 99 xdebug("%d] we lost something itt=%x", 100 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 101 } 102 } 103 pdu_free(sp->isc, pq); 104} 105 106static void 107_r2t(isc_session_t *sp, pduq_t *pq) 108{ 109 pduq_t *opq; 110 111 debug_called(8); 112 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); 113 if(opq != NULL) { 114 iscsi_r2t(sp, opq, pq); 115 } 116 else { 117 r2t_t *r2t = &pq->pdu.ipdu.r2t; 118 119 xdebug("%d] we lost something itt=%x r2tSN=%d bo=%x ddtl=%x", 120 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt), 121 ntohl(r2t->r2tSN), ntohl(r2t->bo), ntohl(r2t->ddtl)); 122 } 123 pdu_free(sp->isc, pq); 124} 125 126static void 127_scsi_rsp(isc_session_t *sp, pduq_t *pq) 128{ 129 pduq_t *opq; 130 131 debug_called(8); 132 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 0); 133 debug(5, "itt=%x pq=%p opq=%p", ntohl(pq->pdu.ipdu.bhs.itt), pq, opq);
| 58 59#include <cam/cam.h> 60#include <cam/cam_ccb.h> 61#include <cam/cam_sim.h> 62#include <cam/cam_xpt_sim.h> 63#include <cam/cam_periph.h> 64 65#include <dev/iscsi/initiator/iscsi.h> 66#include <dev/iscsi/initiator/iscsivar.h> 67 68static void 69_async(isc_session_t *sp, pduq_t *pq) 70{ 71 debug_called(8); 72 73 iscsi_async(sp, pq); 74 75 pdu_free(sp->isc, pq); 76} 77 78static void 79_reject(isc_session_t *sp, pduq_t *pq) 80{ 81 pduq_t *opq; 82 pdu_t *pdu; 83 reject_t *reject; 84 int itt; 85 86 debug_called(8); 87 pdu = mtod(pq->mp, pdu_t *); 88 itt = pdu->ipdu.bhs.itt; 89 reject = &pq->pdu.ipdu.reject; 90 sdebug(2, "itt=%x reason=0x%x", ntohl(itt), reject->reason); 91 opq = i_search_hld(sp, itt, 0); 92 if(opq != NULL) 93 iscsi_reject(sp, opq, pq); 94 else { 95 switch(pq->pdu.ipdu.bhs.opcode) { 96 case ISCSI_LOGOUT_CMD: // XXX: wasabi does this - can't figure out why 97 sdebug(2, "ISCSI_LOGOUT_CMD ..."); 98 break; 99 default: 100 xdebug("%d] we lost something itt=%x", 101 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 102 } 103 } 104 pdu_free(sp->isc, pq); 105} 106 107static void 108_r2t(isc_session_t *sp, pduq_t *pq) 109{ 110 pduq_t *opq; 111 112 debug_called(8); 113 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); 114 if(opq != NULL) { 115 iscsi_r2t(sp, opq, pq); 116 } 117 else { 118 r2t_t *r2t = &pq->pdu.ipdu.r2t; 119 120 xdebug("%d] we lost something itt=%x r2tSN=%d bo=%x ddtl=%x", 121 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt), 122 ntohl(r2t->r2tSN), ntohl(r2t->bo), ntohl(r2t->ddtl)); 123 } 124 pdu_free(sp->isc, pq); 125} 126 127static void 128_scsi_rsp(isc_session_t *sp, pduq_t *pq) 129{ 130 pduq_t *opq; 131 132 debug_called(8); 133 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 0); 134 debug(5, "itt=%x pq=%p opq=%p", ntohl(pq->pdu.ipdu.bhs.itt), pq, opq);
|
134 if(opq != NULL)
| 135 if(opq != NULL) {
|
135 iscsi_done(sp, opq, pq);
| 136 iscsi_done(sp, opq, pq);
|
| 137 i_acked_hld(sp, &pq->pdu); 138 }
|
136 else 137 xdebug("%d] we lost something itt=%x", 138 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 139 pdu_free(sp->isc, pq); 140} 141 142static void 143_read_data(isc_session_t *sp, pduq_t *pq) 144{ 145 pduq_t *opq; 146 147 debug_called(8); 148 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); 149 if(opq != NULL) { 150 if(scsi_decap(sp, opq, pq) != 1) { 151 i_remove_hld(sp, opq); // done 152 pdu_free(sp->isc, opq); 153 } 154 } 155 else 156 xdebug("%d] we lost something itt=%x", 157 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 158 pdu_free(sp->isc, pq); 159} 160/* 161 | this is a kludge, 162 | the jury is not back with a veredict, user or kernel 163 */ 164static void 165_nop_out(isc_session_t *sp) 166{ 167 pduq_t *pq; 168 nop_out_t *nop_out; 169 170 debug_called(8); 171 172 sdebug(4, "cws=%d", sp->cws); 173 if(sp->cws == 0) { 174 /* 175 | only send a nop if window is closed. 176 */ 177 if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) 178 // I guess we ran out of resources 179 return; 180 nop_out = &pq->pdu.ipdu.nop_out; 181 nop_out->opcode = ISCSI_NOP_OUT; 182 nop_out->itt = htonl(sp->sn.itt); 183 nop_out->ttt = -1; 184 nop_out->I = 1; 185 nop_out->F = 1; 186 if(isc_qout(sp, pq) != 0) { 187 sdebug(1, "failed"); 188 pdu_free(sp->isc, pq); 189 } 190 } 191} 192 193static void 194_nop_in(isc_session_t *sp, pduq_t *pq) 195{ 196 pdu_t *pp = &pq->pdu; 197 nop_in_t *nop_in = &pp->ipdu.nop_in; 198 bhs_t *bhs = &pp->ipdu.bhs; 199 200 debug_called(8); 201 202 sdebug(5, "itt=%x ttt=%x", htonl(nop_in->itt), htonl(nop_in->ttt)); 203 if(nop_in->itt == -1) { 204 if(pp->ds_len != 0) { 205 /* 206 | according to RFC 3720 this should be zero 207 | what to do if not? 208 */ 209 xdebug("%d] dslen not zero", sp->sid); 210 } 211 if(nop_in->ttt != -1) { 212 nop_out_t *nop_out; 213 /* 214 | target wants a nop_out 215 */ 216 bhs->opcode = ISCSI_NOP_OUT; 217 bhs->I = 1; 218 bhs->F = 1; 219 /* 220 | we are reusing the pdu, so bhs->ttt == nop_in->ttt; 221 | and need to zero out 'Reserved' 222 | small cludge here. 223 */ 224 nop_out = &pp->ipdu.nop_out; 225 nop_out->sn.maxcmd = 0; 226 memset(nop_out->mbz, 0, sizeof(nop_out->mbz)); 227 (void)isc_qout(sp, pq); //XXX: should check return? 228 return; 229 } 230 //else { 231 // just making noise? 232 // see 10.9.1: target does not want and answer. 233 //} 234 235 } else 236 if(nop_in->ttt == -1) { 237 /* 238 | it is an answer to a nop_in from us 239 */ 240 if(nop_in->itt != -1) { 241#ifdef ISC_WAIT4PING 242 // XXX: MUTEX please 243 if(sp->flags & ISC_WAIT4PING) { 244 i_nqueue_rsp(sp, pq); 245 wakeup(&sp->rsp); 246 return; 247 } 248#endif 249 } 250 } 251 /* 252 | drop it 253 */ 254 pdu_free(sp->isc, pq); 255 return; 256} 257 258int 259i_prepPDU(isc_session_t *sp, pduq_t *pq) 260{ 261 size_t len, n; 262 pdu_t *pp = &pq->pdu; 263 bhs_t *bhp = &pp->ipdu.bhs; 264 265 len = sizeof(bhs_t); 266 if(pp->ahs_len) { 267 len += pp->ahs_len; 268 bhp->AHSLength = pp->ahs_len / 4; 269 }
| 139 else 140 xdebug("%d] we lost something itt=%x", 141 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 142 pdu_free(sp->isc, pq); 143} 144 145static void 146_read_data(isc_session_t *sp, pduq_t *pq) 147{ 148 pduq_t *opq; 149 150 debug_called(8); 151 opq = i_search_hld(sp, pq->pdu.ipdu.bhs.itt, 1); 152 if(opq != NULL) { 153 if(scsi_decap(sp, opq, pq) != 1) { 154 i_remove_hld(sp, opq); // done 155 pdu_free(sp->isc, opq); 156 } 157 } 158 else 159 xdebug("%d] we lost something itt=%x", 160 sp->sid, ntohl(pq->pdu.ipdu.bhs.itt)); 161 pdu_free(sp->isc, pq); 162} 163/* 164 | this is a kludge, 165 | the jury is not back with a veredict, user or kernel 166 */ 167static void 168_nop_out(isc_session_t *sp) 169{ 170 pduq_t *pq; 171 nop_out_t *nop_out; 172 173 debug_called(8); 174 175 sdebug(4, "cws=%d", sp->cws); 176 if(sp->cws == 0) { 177 /* 178 | only send a nop if window is closed. 179 */ 180 if((pq = pdu_alloc(sp->isc, M_NOWAIT)) == NULL) 181 // I guess we ran out of resources 182 return; 183 nop_out = &pq->pdu.ipdu.nop_out; 184 nop_out->opcode = ISCSI_NOP_OUT; 185 nop_out->itt = htonl(sp->sn.itt); 186 nop_out->ttt = -1; 187 nop_out->I = 1; 188 nop_out->F = 1; 189 if(isc_qout(sp, pq) != 0) { 190 sdebug(1, "failed"); 191 pdu_free(sp->isc, pq); 192 } 193 } 194} 195 196static void 197_nop_in(isc_session_t *sp, pduq_t *pq) 198{ 199 pdu_t *pp = &pq->pdu; 200 nop_in_t *nop_in = &pp->ipdu.nop_in; 201 bhs_t *bhs = &pp->ipdu.bhs; 202 203 debug_called(8); 204 205 sdebug(5, "itt=%x ttt=%x", htonl(nop_in->itt), htonl(nop_in->ttt)); 206 if(nop_in->itt == -1) { 207 if(pp->ds_len != 0) { 208 /* 209 | according to RFC 3720 this should be zero 210 | what to do if not? 211 */ 212 xdebug("%d] dslen not zero", sp->sid); 213 } 214 if(nop_in->ttt != -1) { 215 nop_out_t *nop_out; 216 /* 217 | target wants a nop_out 218 */ 219 bhs->opcode = ISCSI_NOP_OUT; 220 bhs->I = 1; 221 bhs->F = 1; 222 /* 223 | we are reusing the pdu, so bhs->ttt == nop_in->ttt; 224 | and need to zero out 'Reserved' 225 | small cludge here. 226 */ 227 nop_out = &pp->ipdu.nop_out; 228 nop_out->sn.maxcmd = 0; 229 memset(nop_out->mbz, 0, sizeof(nop_out->mbz)); 230 (void)isc_qout(sp, pq); //XXX: should check return? 231 return; 232 } 233 //else { 234 // just making noise? 235 // see 10.9.1: target does not want and answer. 236 //} 237 238 } else 239 if(nop_in->ttt == -1) { 240 /* 241 | it is an answer to a nop_in from us 242 */ 243 if(nop_in->itt != -1) { 244#ifdef ISC_WAIT4PING 245 // XXX: MUTEX please 246 if(sp->flags & ISC_WAIT4PING) { 247 i_nqueue_rsp(sp, pq); 248 wakeup(&sp->rsp); 249 return; 250 } 251#endif 252 } 253 } 254 /* 255 | drop it 256 */ 257 pdu_free(sp->isc, pq); 258 return; 259} 260 261int 262i_prepPDU(isc_session_t *sp, pduq_t *pq) 263{ 264 size_t len, n; 265 pdu_t *pp = &pq->pdu; 266 bhs_t *bhp = &pp->ipdu.bhs; 267 268 len = sizeof(bhs_t); 269 if(pp->ahs_len) { 270 len += pp->ahs_len; 271 bhp->AHSLength = pp->ahs_len / 4; 272 }
|
270 if(sp->hdrDigest)
| 273 if(ISOK2DIG(sp->hdrDigest, pp))
|
271 len += 4; 272 if(pp->ds_len) { 273 n = pp->ds_len; 274 len += n; 275#if BYTE_ORDER == LITTLE_ENDIAN 276 bhp->DSLength = ((n & 0x00ff0000) >> 16) 277 | (n & 0x0000ff00) 278 | ((n & 0x000000ff) << 16); 279#else 280 bhp->DSLength = n; 281#endif 282 if(len & 03) { 283 n = 4 - (len & 03); 284 len += n; 285 }
| 274 len += 4; 275 if(pp->ds_len) { 276 n = pp->ds_len; 277 len += n; 278#if BYTE_ORDER == LITTLE_ENDIAN 279 bhp->DSLength = ((n & 0x00ff0000) >> 16) 280 | (n & 0x0000ff00) 281 | ((n & 0x000000ff) << 16); 282#else 283 bhp->DSLength = n; 284#endif 285 if(len & 03) { 286 n = 4 - (len & 03); 287 len += n; 288 }
|
286 if(sp->dataDigest)
| 289 if(ISOK2DIG(sp->dataDigest, pp))
|
287 len += 4; 288 } 289 290 pq->len = len; 291 len -= sizeof(bhs_t); 292 if(sp->opt.maxBurstLength && (len > sp->opt.maxBurstLength)) { 293 xdebug("%d] pdu len=%zd > %d", 294 sp->sid, len, sp->opt.maxBurstLength); 295 // XXX: when this happens it used to hang ... 296 return E2BIG; 297 } 298 return 0; 299} 300 301int 302isc_qout(isc_session_t *sp, pduq_t *pq) 303{ 304 int error = 0; 305 306 debug_called(8); 307 308 if(pq->len == 0 && (error = i_prepPDU(sp, pq))) 309 return error; 310 311 if(pq->pdu.ipdu.bhs.I) 312 i_nqueue_isnd(sp, pq); 313 else 314 if(pq->pdu.ipdu.data_out.opcode == ISCSI_WRITE_DATA) 315 i_nqueue_wsnd(sp, pq); 316 else 317 i_nqueue_csnd(sp, pq); 318 319 sdebug(5, "enqued: pq=%p", pq); 320 321 mtx_lock(&sp->io_mtx); 322 sp->flags |= ISC_OQNOTEMPTY; 323 if(sp->flags & ISC_OWAITING)
| 290 len += 4; 291 } 292 293 pq->len = len; 294 len -= sizeof(bhs_t); 295 if(sp->opt.maxBurstLength && (len > sp->opt.maxBurstLength)) { 296 xdebug("%d] pdu len=%zd > %d", 297 sp->sid, len, sp->opt.maxBurstLength); 298 // XXX: when this happens it used to hang ... 299 return E2BIG; 300 } 301 return 0; 302} 303 304int 305isc_qout(isc_session_t *sp, pduq_t *pq) 306{ 307 int error = 0; 308 309 debug_called(8); 310 311 if(pq->len == 0 && (error = i_prepPDU(sp, pq))) 312 return error; 313 314 if(pq->pdu.ipdu.bhs.I) 315 i_nqueue_isnd(sp, pq); 316 else 317 if(pq->pdu.ipdu.data_out.opcode == ISCSI_WRITE_DATA) 318 i_nqueue_wsnd(sp, pq); 319 else 320 i_nqueue_csnd(sp, pq); 321 322 sdebug(5, "enqued: pq=%p", pq); 323 324 mtx_lock(&sp->io_mtx); 325 sp->flags |= ISC_OQNOTEMPTY; 326 if(sp->flags & ISC_OWAITING)
|
324 wakeup(&sp->flags);
| 327 wakeup(&sp->flags);
|
325 mtx_unlock(&sp->io_mtx); 326 327 return error; 328} 329/* 330 | called when a fullPhase is restarted 331 */
| 328 mtx_unlock(&sp->io_mtx); 329 330 return error; 331} 332/* 333 | called when a fullPhase is restarted 334 */
|
332static void
| 335void
|
333ism_restart(isc_session_t *sp) 334{ 335 int lastcmd; 336 337 sdebug(2, "restart ..."); 338 lastcmd = iscsi_requeue(sp); 339#if 0 340 if(lastcmd != sp->sn.cmd) { 341 sdebug(1, "resetting CmdSN to=%d (from %d)", lastcmd, sp->sn.cmd); 342 sp->sn.cmd = lastcmd; 343 } 344#endif 345 mtx_lock(&sp->io_mtx); 346 if(sp->flags & ISC_OWAITING) { 347 wakeup(&sp->flags); 348 } 349 mtx_unlock(&sp->io_mtx); 350
| 336ism_restart(isc_session_t *sp) 337{ 338 int lastcmd; 339 340 sdebug(2, "restart ..."); 341 lastcmd = iscsi_requeue(sp); 342#if 0 343 if(lastcmd != sp->sn.cmd) { 344 sdebug(1, "resetting CmdSN to=%d (from %d)", lastcmd, sp->sn.cmd); 345 sp->sn.cmd = lastcmd; 346 } 347#endif 348 mtx_lock(&sp->io_mtx); 349 if(sp->flags & ISC_OWAITING) { 350 wakeup(&sp->flags); 351 } 352 mtx_unlock(&sp->io_mtx); 353
|
351 sdebug(2, "restarted lastcmd=0x%x", lastcmd);
| 354 sdebug(2, "restarted sn.cmd=0x%x lastcmd=0x%x", sp->sn.cmd, lastcmd);
|
352} 353
| 355} 356
|
354int 355ism_fullfeature(struct cdev *dev, int flag) 356{ 357 isc_session_t *sp = (isc_session_t *)dev->si_drv2; 358 int error; 359 360 sdebug(2, "flag=%d", flag); 361 362 error = 0; 363 switch(flag) { 364 case 0: // stop 365 sp->flags &= ~ISC_FFPHASE; 366 break; 367 case 1: // start 368 error = ic_fullfeature(dev); 369 break; 370 case 2: // restart 371 ism_restart(sp); 372 break; 373 } 374 return error; 375} 376
| |
377void 378ism_recv(isc_session_t *sp, pduq_t *pq) 379{ 380 bhs_t *bhs; 381 int statSN; 382 383 debug_called(8); 384 385 bhs = &pq->pdu.ipdu.bhs; 386 statSN = ntohl(bhs->OpcodeSpecificFields[1]);
| 357void 358ism_recv(isc_session_t *sp, pduq_t *pq) 359{ 360 bhs_t *bhs; 361 int statSN; 362 363 debug_called(8); 364 365 bhs = &pq->pdu.ipdu.bhs; 366 statSN = ntohl(bhs->OpcodeSpecificFields[1]);
|
387#if 0 388 { 389 /* 390 | this code is only for debugging. 391 */ 392 sn_t *sn = &sp->sn; 393 if(sp->cws == 0) { 394 if((sp->flags & ISC_STALLED) == 0) { 395 sdebug(4, "window closed: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", 396 sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); 397 sp->flags |= ISC_STALLED; 398 } else 399 if(sp->flags & ISC_STALLED) { 400 sdebug(4, "window opened: max=0x%x exp=0x%x opcode=0x%x cmd=0x%x cws=%d.", 401 sn->maxCmd, sn->expCmd, bhs->opcode, sn->cmd, sp->cws); 402 sp->flags &= ~ISC_STALLED; 403 } 404 } 405 } 406#endif
| |
407 408#ifdef notyet 409 if(sp->sn.expCmd != sn->cmd) { 410 sdebug(1, "we lost something ... exp=0x%x cmd=0x%x", 411 sn->expCmd, sn->cmd); 412 } 413#endif 414 sdebug(5, "opcode=0x%x itt=0x%x stat#0x%x maxcmd=0x%0x", 415 bhs->opcode, ntohl(bhs->itt), statSN, sp->sn.maxCmd); 416 417 switch(bhs->opcode) { 418 case ISCSI_READ_DATA: { 419 data_in_t *cmd = &pq->pdu.ipdu.data_in; 420 421 if(cmd->S == 0) 422 break; 423 } 424 425 default: 426 if(statSN > (sp->sn.stat + 1)) { 427 sdebug(1, "we lost some rec=0x%x exp=0x%x", 428 statSN, sp->sn.stat); 429 // XXX: must do some error recovery here. 430 } 431 sp->sn.stat = statSN; 432 } 433 434 switch(bhs->opcode) { 435 case ISCSI_LOGIN_RSP: 436 case ISCSI_TEXT_RSP: 437 case ISCSI_LOGOUT_RSP: 438 i_nqueue_rsp(sp, pq); 439 wakeup(&sp->rsp); 440 sdebug(3, "wakeup rsp"); 441 break; 442 443 case ISCSI_NOP_IN: _nop_in(sp, pq); break; 444 case ISCSI_SCSI_RSP: _scsi_rsp(sp, pq); break; 445 case ISCSI_READ_DATA: _read_data(sp, pq); break; 446 case ISCSI_R2T: _r2t(sp, pq); break; 447 case ISCSI_REJECT: _reject(sp, pq); break; 448 case ISCSI_ASYNC: _async(sp, pq); break; 449 450 case ISCSI_TASK_RSP: 451 default: 452 sdebug(1, "opcode=0x%x itt=0x%x not implemented yet", 453 bhs->opcode, ntohl(bhs->itt)); 454 break; 455 } 456}
| 367 368#ifdef notyet 369 if(sp->sn.expCmd != sn->cmd) { 370 sdebug(1, "we lost something ... exp=0x%x cmd=0x%x", 371 sn->expCmd, sn->cmd); 372 } 373#endif 374 sdebug(5, "opcode=0x%x itt=0x%x stat#0x%x maxcmd=0x%0x", 375 bhs->opcode, ntohl(bhs->itt), statSN, sp->sn.maxCmd); 376 377 switch(bhs->opcode) { 378 case ISCSI_READ_DATA: { 379 data_in_t *cmd = &pq->pdu.ipdu.data_in; 380 381 if(cmd->S == 0) 382 break; 383 } 384 385 default: 386 if(statSN > (sp->sn.stat + 1)) { 387 sdebug(1, "we lost some rec=0x%x exp=0x%x", 388 statSN, sp->sn.stat); 389 // XXX: must do some error recovery here. 390 } 391 sp->sn.stat = statSN; 392 } 393 394 switch(bhs->opcode) { 395 case ISCSI_LOGIN_RSP: 396 case ISCSI_TEXT_RSP: 397 case ISCSI_LOGOUT_RSP: 398 i_nqueue_rsp(sp, pq); 399 wakeup(&sp->rsp); 400 sdebug(3, "wakeup rsp"); 401 break; 402 403 case ISCSI_NOP_IN: _nop_in(sp, pq); break; 404 case ISCSI_SCSI_RSP: _scsi_rsp(sp, pq); break; 405 case ISCSI_READ_DATA: _read_data(sp, pq); break; 406 case ISCSI_R2T: _r2t(sp, pq); break; 407 case ISCSI_REJECT: _reject(sp, pq); break; 408 case ISCSI_ASYNC: _async(sp, pq); break; 409 410 case ISCSI_TASK_RSP: 411 default: 412 sdebug(1, "opcode=0x%x itt=0x%x not implemented yet", 413 bhs->opcode, ntohl(bhs->itt)); 414 break; 415 } 416}
|
457
| 417
|
458/* 459 | go through the out queues looking for work 460 | if either nothing to do, or window is closed 461 | return. 462 */ 463static int 464proc_out(isc_session_t *sp) 465{ 466 sn_t *sn = &sp->sn; 467 pduq_t *pq;
| 418/* 419 | go through the out queues looking for work 420 | if either nothing to do, or window is closed 421 | return. 422 */ 423static int 424proc_out(isc_session_t *sp) 425{ 426 sn_t *sn = &sp->sn; 427 pduq_t *pq;
|
468 int error, ndone; 469 int which;
| 428 int error, which;
|
470 471 debug_called(8);
| 429 430 debug_called(8);
|
472 error = ndone = 0;
| 431 error = 0;
|
473 474 while(sp->flags & ISC_LINK_UP) { 475 pdu_t *pp; 476 bhs_t *bhs; 477 /* 478 | check if there is outstanding work in: 479 | 1- the Immediate queue 480 | 2- the R2T queue 481 | 3- the cmd queue, only if the command window allows it. 482 */ 483 which = BIT(0) | BIT(1); 484 if(SNA_GT(sn->cmd, sn->maxCmd) == 0) // if(sn->maxCmd - sn->smc + 1) > 0 485 which |= BIT(2); 486 487 sdebug(4, "which=%d sn->maxCmd=%d sn->cmd=%d", which, sn->maxCmd, sn->cmd); 488 489 if((pq = i_dqueue_snd(sp, which)) == NULL) 490 break; 491 sdebug(4, "pq=%p", pq); 492 493 pp = &pq->pdu; 494 bhs = &pp->ipdu.bhs; 495 switch(bhs->opcode) { 496 case ISCSI_SCSI_CMD: 497 sn->itt++; 498 bhs->itt = htonl(sn->itt); 499 500 case ISCSI_LOGIN_CMD: 501 case ISCSI_TEXT_CMD: 502 case ISCSI_LOGOUT_CMD: 503 case ISCSI_SNACK: 504 case ISCSI_NOP_OUT: 505 case ISCSI_TASK_CMD: 506 bhs->CmdSN = htonl(sn->cmd); 507 if(bhs->I == 0) 508 sn->cmd++; 509 510 case ISCSI_WRITE_DATA:
| 432 433 while(sp->flags & ISC_LINK_UP) { 434 pdu_t *pp; 435 bhs_t *bhs; 436 /* 437 | check if there is outstanding work in: 438 | 1- the Immediate queue 439 | 2- the R2T queue 440 | 3- the cmd queue, only if the command window allows it. 441 */ 442 which = BIT(0) | BIT(1); 443 if(SNA_GT(sn->cmd, sn->maxCmd) == 0) // if(sn->maxCmd - sn->smc + 1) > 0 444 which |= BIT(2); 445 446 sdebug(4, "which=%d sn->maxCmd=%d sn->cmd=%d", which, sn->maxCmd, sn->cmd); 447 448 if((pq = i_dqueue_snd(sp, which)) == NULL) 449 break; 450 sdebug(4, "pq=%p", pq); 451 452 pp = &pq->pdu; 453 bhs = &pp->ipdu.bhs; 454 switch(bhs->opcode) { 455 case ISCSI_SCSI_CMD: 456 sn->itt++; 457 bhs->itt = htonl(sn->itt); 458 459 case ISCSI_LOGIN_CMD: 460 case ISCSI_TEXT_CMD: 461 case ISCSI_LOGOUT_CMD: 462 case ISCSI_SNACK: 463 case ISCSI_NOP_OUT: 464 case ISCSI_TASK_CMD: 465 bhs->CmdSN = htonl(sn->cmd); 466 if(bhs->I == 0) 467 sn->cmd++; 468 469 case ISCSI_WRITE_DATA:
|
511 bhs->ExpStSN = htonl(sn->stat);
| 470 bhs->ExpStSN = htonl(sn->stat + 1);
|
512 break; 513 514 default: 515 // XXX: can this happen? 516 xdebug("bad opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)", 517 bhs->opcode, 518 sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); 519 // XXX: and now? 520 } 521 522 sdebug(4, "opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)", 523 bhs->opcode, 524 sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); 525
| 471 break; 472 473 default: 474 // XXX: can this happen? 475 xdebug("bad opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)", 476 bhs->opcode, 477 sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); 478 // XXX: and now? 479 } 480 481 sdebug(4, "opcode=0x%x sn(cmd=0x%x expCmd=0x%x maxCmd=0x%x expStat=0x%x itt=0x%x)", 482 bhs->opcode, 483 sn->cmd, sn->expCmd, sn->maxCmd, sn->expStat, sn->itt); 484
|
526 if(pq->ccb)
| 485 if(bhs->opcode != ISCSI_NOP_OUT) 486 /* 487 | enqued till ack is received 488 | note: sosend(...) does not mean the packet left 489 | the host so that freeing resources has to wait 490 */
|
527 i_nqueue_hld(sp, pq); 528
| 491 i_nqueue_hld(sp, pq); 492
|
529 if((error = isc_sendPDU(sp, pq)) == 0) { 530 ndone++; 531 if(pq->ccb == NULL) 532 pdu_free(sp->isc, pq); 533 } 534 else { 535 xdebug("error=%d ndone=%d opcode=0x%x ccb=%p itt=%x", 536 error, ndone, bhs->opcode, pq->ccb, ntohl(bhs->itt)); 537 if(pq->ccb) 538 i_remove_hld(sp, pq);
| 493 error = isc_sendPDU(sp, pq); 494 if(bhs->opcode == ISCSI_NOP_OUT) 495 pdu_free(sp->isc, pq); 496 if(error) { 497 xdebug("error=%d opcode=0x%x ccb=%p itt=%x", 498 error, bhs->opcode, pq->ccb, ntohl(bhs->itt)); 499 i_remove_hld(sp, pq);
|
539 switch(error) { 540 case EPIPE: 541 sp->flags &= ~ISC_LINK_UP; 542 543 case EAGAIN: 544 xdebug("requed"); 545 i_rqueue_pdu(sp, pq); 546 break; 547 548 default:
| 500 switch(error) { 501 case EPIPE: 502 sp->flags &= ~ISC_LINK_UP; 503 504 case EAGAIN: 505 xdebug("requed"); 506 i_rqueue_pdu(sp, pq); 507 break; 508 509 default:
|
549 if(pq->ccb) {
| 510 if(pq->ccb) {
|
550 xdebug("back to cam"); 551 pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error?
| 511 xdebug("back to cam"); 512 pq->ccb->ccb_h.status |= CAM_REQUEUE_REQ; // some better error?
|
552 XPT_DONE(sp->isc, pq->ccb);
| 513 XPT_DONE(sp, pq->ccb);
|
553 pdu_free(sp->isc, pq);
| 514 pdu_free(sp->isc, pq);
|
554 }
| 515 }
|
555 else 556 xdebug("we lost it!"); 557 } 558 } 559 } 560 return error; 561}
| 516 else 517 xdebug("we lost it!"); 518 } 519 } 520 } 521 return error; 522}
|
562
| 523
|
563/* 564 | survives link breakdowns. 565 */ 566static void
| 524/* 525 | survives link breakdowns. 526 */ 527static void
|
567ism_proc(void *vp)
| 528ism_out(void *vp)
|
568{ 569 isc_session_t *sp = (isc_session_t *)vp; 570 int error; 571 572 debug_called(8); 573 574 sp->flags |= ISC_SM_RUNNING; 575 sdebug(3, "started sp->flags=%x", sp->flags); 576 do { 577 if((sp->flags & ISC_HOLD) == 0) { 578 error = proc_out(sp); 579 if(error) { 580 sdebug(3, "error=%d", error); 581 } 582 }
| 529{ 530 isc_session_t *sp = (isc_session_t *)vp; 531 int error; 532 533 debug_called(8); 534 535 sp->flags |= ISC_SM_RUNNING; 536 sdebug(3, "started sp->flags=%x", sp->flags); 537 do { 538 if((sp->flags & ISC_HOLD) == 0) { 539 error = proc_out(sp); 540 if(error) { 541 sdebug(3, "error=%d", error); 542 } 543 }
|
583 mtx_lock(&sp->io_mtx);
| 544 mtx_lock(&sp->io_mtx);
|
584 if((sp->flags & ISC_LINK_UP) == 0) {
| 545 if((sp->flags & ISC_LINK_UP) == 0) {
|
| 546 sdebug(3, "ISC_LINK_UP==0, sp->flags=%x ", sp->flags); 547 if(sp->soc != NULL) 548 sdebug(3, "so_state=%x", sp->soc->so_state);
|
585 wakeup(&sp->soc); 586 } 587 588 if(!(sp->flags & ISC_OQNOTEMPTY)) { 589 sp->flags |= ISC_OWAITING; 590 if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) { 591 if(sp->flags & ISC_CON_RUNNING)
| 549 wakeup(&sp->soc); 550 } 551 552 if(!(sp->flags & ISC_OQNOTEMPTY)) { 553 sp->flags |= ISC_OWAITING; 554 if(msleep(&sp->flags, &sp->io_mtx, PRIBIO, "isc_proc", hz*30) == EWOULDBLOCK) { 555 if(sp->flags & ISC_CON_RUNNING)
|
592 _nop_out(sp);
| 556 _nop_out(sp);
|
593 } 594 sp->flags &= ~ISC_OWAITING; 595 } 596 sp->flags &= ~ISC_OQNOTEMPTY; 597 mtx_unlock(&sp->io_mtx); 598 } while(sp->flags & ISC_SM_RUN); 599 600 sp->flags &= ~ISC_SM_RUNNING; 601 sdebug(3, "dropped ISC_SM_RUNNING"); 602
| 557 } 558 sp->flags &= ~ISC_OWAITING; 559 } 560 sp->flags &= ~ISC_OQNOTEMPTY; 561 mtx_unlock(&sp->io_mtx); 562 } while(sp->flags & ISC_SM_RUN); 563 564 sp->flags &= ~ISC_SM_RUNNING; 565 sdebug(3, "dropped ISC_SM_RUNNING"); 566
|
| 567 wakeup(&sp->soc); 568 wakeup(sp); // XXX: do we need this one? 569
|
603#if __FreeBSD_version >= 700000 604 destroy_dev(sp->dev); 605#endif
| 570#if __FreeBSD_version >= 700000 571 destroy_dev(sp->dev); 572#endif
|
606 wakeup(sp);
| |
607 608 debug(3, "terminated sp=%p sp->sid=%d", sp, sp->sid); 609
| 573 574 debug(3, "terminated sp=%p sp->sid=%d", sp, sp->sid); 575
|
| 576#if __FreeBSD_version >= 800000
|
610 kproc_exit(0);
| 577 kproc_exit(0);
|
| 578#else 579 kthread_exit(0); 580#endif
|
611} 612 613#if 0 614static int 615isc_dump_options(SYSCTL_HANDLER_ARGS) 616{ 617 int error; 618 isc_session_t *sp; 619 char buf[1024], *bp; 620 621 sp = (isc_session_t *)arg1; 622 bp = buf; 623 sprintf(bp, "targetname='%s'", sp->opt.targetName); 624 bp += strlen(bp); 625 sprintf(bp, " targetname='%s'", sp->opt.targetAddress); 626 error = SYSCTL_OUT(req, buf, strlen(buf)); 627 return error; 628} 629#endif 630 631static int 632isc_dump_stats(SYSCTL_HANDLER_ARGS) 633{ 634 isc_session_t *sp; 635 struct isc_softc *sc; 636 char buf[1024], *bp; 637 int error, n; 638 639 sp = (isc_session_t *)arg1; 640 sc = sp->isc; 641 642 bp = buf; 643 n = sizeof(buf); 644 snprintf(bp, n, "recv=%d sent=%d", sp->stats.nrecv, sp->stats.nsent); 645 bp += strlen(bp); 646 n -= strlen(bp); 647 snprintf(bp, n, " flags=0x%08x pdus-alloc=%d pdus-max=%d", 648 sp->flags, sc->npdu_alloc, sc->npdu_max); 649 bp += strlen(bp); 650 n -= strlen(bp); 651 snprintf(bp, n, " cws=%d cmd=%x exp=%x max=%x stat=%x itt=%x", 652 sp->cws, sp->sn.cmd, sp->sn.expCmd, sp->sn.maxCmd, sp->sn.stat, sp->sn.itt); 653 error = SYSCTL_OUT(req, buf, strlen(buf)); 654 return error; 655} 656 657static int 658isc_sysctl_targetName(SYSCTL_HANDLER_ARGS) 659{ 660 char buf[128], **cp; 661 int error; 662 663 cp = (char **)arg1; 664 snprintf(buf, sizeof(buf), "%s", *cp); 665 error = SYSCTL_OUT(req, buf, strlen(buf)); 666 return error; 667} 668 669static int 670isc_sysctl_targetAddress(SYSCTL_HANDLER_ARGS) 671{ 672 char buf[128], **cp; 673 int error; 674 675 cp = (char **)arg1; 676 snprintf(buf, sizeof(buf), "%s", *cp); 677 error = SYSCTL_OUT(req, buf, strlen(buf)); 678 return error; 679} 680 681static void 682isc_add_sysctls(isc_session_t *sp) 683{ 684 debug_called(8); 685 sdebug(6, "sid=%d %s", sp->sid, sp->dev->si_name); 686 687 sysctl_ctx_init(&sp->clist); 688 sp->oid = SYSCTL_ADD_NODE(&sp->clist, 689 SYSCTL_CHILDREN(sp->isc->oid), 690 OID_AUTO, 691 sp->dev->si_name+5, // iscsi0 692 CTLFLAG_RD, 693 0, 694 "initiator"); 695 SYSCTL_ADD_PROC(&sp->clist, 696 SYSCTL_CHILDREN(sp->oid), 697 OID_AUTO, 698 "targetname", 699 CTLFLAG_RD, 700 (void *)&sp->opt.targetName, 0, 701 isc_sysctl_targetName, "A", "target name"); 702 703 SYSCTL_ADD_PROC(&sp->clist, 704 SYSCTL_CHILDREN(sp->oid), 705 OID_AUTO, 706 "targeaddress", 707 CTLFLAG_RD, 708 (void *)&sp->opt.targetAddress, 0, 709 isc_sysctl_targetAddress, "A", "target address"); 710 711 SYSCTL_ADD_PROC(&sp->clist, 712 SYSCTL_CHILDREN(sp->oid), 713 OID_AUTO, 714 "stats", 715 CTLFLAG_RD, 716 (void *)sp, 0, 717 isc_dump_stats, "A", "statistics"); 718 719 SYSCTL_ADD_INT(&sp->clist, 720 SYSCTL_CHILDREN(sp->oid), 721 OID_AUTO, 722 "douio", 723 CTLFLAG_RW, 724 &sp->douio, 0, "enable uio on read"); 725} 726 727void 728ism_stop(isc_session_t *sp) 729{ 730 struct isc_softc *sc = sp->isc; 731 int n; 732 733 debug_called(8); 734 sdebug(2, "terminating"); 735 /* 736 | first stop the receiver 737 */ 738 isc_stop_receiver(sp); 739 /* 740 | now stop the xmitter 741 */ 742 n = 5; 743 sp->flags &= ~ISC_SM_RUN; 744 while(n-- && (sp->flags & ISC_SM_RUNNING)) { 745 sdebug(2, "n=%d", n); 746 wakeup(&sp->flags); 747 tsleep(sp, PRIBIO, "-", 5*hz); 748 } 749 sdebug(2, "final n=%d", n); 750 sp->flags &= ~ISC_FFPHASE; 751 752 iscsi_cleanup(sp); 753 754 (void)i_pdu_flush(sp); 755
| 581} 582 583#if 0 584static int 585isc_dump_options(SYSCTL_HANDLER_ARGS) 586{ 587 int error; 588 isc_session_t *sp; 589 char buf[1024], *bp; 590 591 sp = (isc_session_t *)arg1; 592 bp = buf; 593 sprintf(bp, "targetname='%s'", sp->opt.targetName); 594 bp += strlen(bp); 595 sprintf(bp, " targetname='%s'", sp->opt.targetAddress); 596 error = SYSCTL_OUT(req, buf, strlen(buf)); 597 return error; 598} 599#endif 600 601static int 602isc_dump_stats(SYSCTL_HANDLER_ARGS) 603{ 604 isc_session_t *sp; 605 struct isc_softc *sc; 606 char buf[1024], *bp; 607 int error, n; 608 609 sp = (isc_session_t *)arg1; 610 sc = sp->isc; 611 612 bp = buf; 613 n = sizeof(buf); 614 snprintf(bp, n, "recv=%d sent=%d", sp->stats.nrecv, sp->stats.nsent); 615 bp += strlen(bp); 616 n -= strlen(bp); 617 snprintf(bp, n, " flags=0x%08x pdus-alloc=%d pdus-max=%d", 618 sp->flags, sc->npdu_alloc, sc->npdu_max); 619 bp += strlen(bp); 620 n -= strlen(bp); 621 snprintf(bp, n, " cws=%d cmd=%x exp=%x max=%x stat=%x itt=%x", 622 sp->cws, sp->sn.cmd, sp->sn.expCmd, sp->sn.maxCmd, sp->sn.stat, sp->sn.itt); 623 error = SYSCTL_OUT(req, buf, strlen(buf)); 624 return error; 625} 626 627static int 628isc_sysctl_targetName(SYSCTL_HANDLER_ARGS) 629{ 630 char buf[128], **cp; 631 int error; 632 633 cp = (char **)arg1; 634 snprintf(buf, sizeof(buf), "%s", *cp); 635 error = SYSCTL_OUT(req, buf, strlen(buf)); 636 return error; 637} 638 639static int 640isc_sysctl_targetAddress(SYSCTL_HANDLER_ARGS) 641{ 642 char buf[128], **cp; 643 int error; 644 645 cp = (char **)arg1; 646 snprintf(buf, sizeof(buf), "%s", *cp); 647 error = SYSCTL_OUT(req, buf, strlen(buf)); 648 return error; 649} 650 651static void 652isc_add_sysctls(isc_session_t *sp) 653{ 654 debug_called(8); 655 sdebug(6, "sid=%d %s", sp->sid, sp->dev->si_name); 656 657 sysctl_ctx_init(&sp->clist); 658 sp->oid = SYSCTL_ADD_NODE(&sp->clist, 659 SYSCTL_CHILDREN(sp->isc->oid), 660 OID_AUTO, 661 sp->dev->si_name+5, // iscsi0 662 CTLFLAG_RD, 663 0, 664 "initiator"); 665 SYSCTL_ADD_PROC(&sp->clist, 666 SYSCTL_CHILDREN(sp->oid), 667 OID_AUTO, 668 "targetname", 669 CTLFLAG_RD, 670 (void *)&sp->opt.targetName, 0, 671 isc_sysctl_targetName, "A", "target name"); 672 673 SYSCTL_ADD_PROC(&sp->clist, 674 SYSCTL_CHILDREN(sp->oid), 675 OID_AUTO, 676 "targeaddress", 677 CTLFLAG_RD, 678 (void *)&sp->opt.targetAddress, 0, 679 isc_sysctl_targetAddress, "A", "target address"); 680 681 SYSCTL_ADD_PROC(&sp->clist, 682 SYSCTL_CHILDREN(sp->oid), 683 OID_AUTO, 684 "stats", 685 CTLFLAG_RD, 686 (void *)sp, 0, 687 isc_dump_stats, "A", "statistics"); 688 689 SYSCTL_ADD_INT(&sp->clist, 690 SYSCTL_CHILDREN(sp->oid), 691 OID_AUTO, 692 "douio", 693 CTLFLAG_RW, 694 &sp->douio, 0, "enable uio on read"); 695} 696 697void 698ism_stop(isc_session_t *sp) 699{ 700 struct isc_softc *sc = sp->isc; 701 int n; 702 703 debug_called(8); 704 sdebug(2, "terminating"); 705 /* 706 | first stop the receiver 707 */ 708 isc_stop_receiver(sp); 709 /* 710 | now stop the xmitter 711 */ 712 n = 5; 713 sp->flags &= ~ISC_SM_RUN; 714 while(n-- && (sp->flags & ISC_SM_RUNNING)) { 715 sdebug(2, "n=%d", n); 716 wakeup(&sp->flags); 717 tsleep(sp, PRIBIO, "-", 5*hz); 718 } 719 sdebug(2, "final n=%d", n); 720 sp->flags &= ~ISC_FFPHASE; 721 722 iscsi_cleanup(sp); 723 724 (void)i_pdu_flush(sp); 725
|
756 ic_lost_target(sp, sp->sid);
| 726 ic_destroy(sp);
|
757
| 727
|
758 mtx_lock(&sc->mtx);
| 728 sx_xlock(&sc->unit_sx); 729 free_unr(sc->unit, sp->sid); 730 sx_xunlock(&sc->unit_sx); 731 732 mtx_lock(&sc->isc_mtx);
|
759 TAILQ_REMOVE(&sc->isc_sess, sp, sp_link); 760 sc->nsess--;
| 733 TAILQ_REMOVE(&sc->isc_sess, sp, sp_link); 734 sc->nsess--;
|
761 mtx_unlock(&sc->mtx);
| 735 mtx_unlock(&sc->isc_mtx);
|
762 763#if __FreeBSD_version < 700000 764 destroy_dev(sp->dev); 765#endif 766 767 mtx_destroy(&sp->rsp_mtx); 768 mtx_destroy(&sp->rsv_mtx); 769 mtx_destroy(&sp->hld_mtx); 770 mtx_destroy(&sp->snd_mtx); 771 mtx_destroy(&sp->io_mtx); 772 773 i_freeopt(&sp->opt);
| 736 737#if __FreeBSD_version < 700000 738 destroy_dev(sp->dev); 739#endif 740 741 mtx_destroy(&sp->rsp_mtx); 742 mtx_destroy(&sp->rsv_mtx); 743 mtx_destroy(&sp->hld_mtx); 744 mtx_destroy(&sp->snd_mtx); 745 mtx_destroy(&sp->io_mtx); 746 747 i_freeopt(&sp->opt);
|
774 sc->sessions[sp->sid] = NULL;
| |
775 776 if(sysctl_ctx_free(&sp->clist)) 777 xdebug("sysctl_ctx_free failed"); 778 779 free(sp, M_ISCSI); 780} 781 782int 783ism_start(isc_session_t *sp) 784{ 785 debug_called(8); 786 /* 787 | now is a good time to do some initialization 788 */ 789 TAILQ_INIT(&sp->rsp); 790 TAILQ_INIT(&sp->rsv); 791 TAILQ_INIT(&sp->csnd); 792 TAILQ_INIT(&sp->isnd); 793 TAILQ_INIT(&sp->wsnd); 794 TAILQ_INIT(&sp->hld);
| 748 749 if(sysctl_ctx_free(&sp->clist)) 750 xdebug("sysctl_ctx_free failed"); 751 752 free(sp, M_ISCSI); 753} 754 755int 756ism_start(isc_session_t *sp) 757{ 758 debug_called(8); 759 /* 760 | now is a good time to do some initialization 761 */ 762 TAILQ_INIT(&sp->rsp); 763 TAILQ_INIT(&sp->rsv); 764 TAILQ_INIT(&sp->csnd); 765 TAILQ_INIT(&sp->isnd); 766 TAILQ_INIT(&sp->wsnd); 767 TAILQ_INIT(&sp->hld);
|
795#if 1
| 768
|
796 mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_DEF); 797 mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_DEF); 798 mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF); 799 mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF);
| 769 mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_DEF); 770 mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_DEF); 771 mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_DEF); 772 mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_DEF);
|
800#else 801 mtx_init(&sp->rsv_mtx, "iscsi-rsv", NULL, MTX_SPIN); 802 mtx_init(&sp->rsp_mtx, "iscsi-rsp", NULL, MTX_SPIN); 803 mtx_init(&sp->snd_mtx, "iscsi-snd", NULL, MTX_SPIN); 804 mtx_init(&sp->hld_mtx, "iscsi-hld", NULL, MTX_SPIN); 805#endif
| |
806 mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF); 807 808 isc_add_sysctls(sp); 809 810 sp->flags |= ISC_SM_RUN; 811 812 debug(4, "starting ism_proc: sp->sid=%d", sp->sid);
| 773 mtx_init(&sp->io_mtx, "iscsi-io", NULL, MTX_DEF); 774 775 isc_add_sysctls(sp); 776 777 sp->flags |= ISC_SM_RUN; 778 779 debug(4, "starting ism_proc: sp->sid=%d", sp->sid);
|
813 return kproc_create(ism_proc, sp, &sp->stp, 0, 0, "ism_%d", sp->sid);
| 780 781#if __FreeBSD_version >= 800000 782 return kproc_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); 783#else 784 return kthread_create(ism_out, sp, &sp->stp, 0, 0, "isc_out %d", sp->sid); 785#endif
|
814}
| 786}
|