1e25c779eSMatthew Dillon /*-
2e25c779eSMatthew Dillon * Copyright (c) 2005-2008 Daniel Braniss <danny@cs.huji.ac.il>
3e25c779eSMatthew Dillon * All rights reserved.
4e25c779eSMatthew Dillon *
5e25c779eSMatthew Dillon * Redistribution and use in source and binary forms, with or without
6e25c779eSMatthew Dillon * modification, are permitted provided that the following conditions
7e25c779eSMatthew Dillon * are met:
8e25c779eSMatthew Dillon * 1. Redistributions of source code must retain the above copyright
9e25c779eSMatthew Dillon * notice, this list of conditions and the following disclaimer.
10e25c779eSMatthew Dillon * 2. Redistributions in binary form must reproduce the above copyright
11e25c779eSMatthew Dillon * notice, this list of conditions and the following disclaimer in the
12e25c779eSMatthew Dillon * documentation and/or other materials provided with the distribution.
13e25c779eSMatthew Dillon *
14e25c779eSMatthew Dillon * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15e25c779eSMatthew Dillon * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16e25c779eSMatthew Dillon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17e25c779eSMatthew Dillon * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18e25c779eSMatthew Dillon * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19e25c779eSMatthew Dillon * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20e25c779eSMatthew Dillon * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21e25c779eSMatthew Dillon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22e25c779eSMatthew Dillon * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23e25c779eSMatthew Dillon * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24e25c779eSMatthew Dillon * SUCH DAMAGE.
25e25c779eSMatthew Dillon *
26e25c779eSMatthew Dillon * $FreeBSD: src/sys/dev/iscsi/initiator/isc_subr.c,v 1.3 2009/02/14 11:34:57 rrs Exp $
27e25c779eSMatthew Dillon */
28e25c779eSMatthew Dillon /*
29e25c779eSMatthew Dillon | iSCSI
30e25c779eSMatthew Dillon | $Id: isc_subr.c,v 1.20 2006/12/01 09:10:17 danny Exp danny $
31e25c779eSMatthew Dillon */
32e25c779eSMatthew Dillon
33e25c779eSMatthew Dillon #include "opt_iscsi_initiator.h"
34e25c779eSMatthew Dillon
35e25c779eSMatthew Dillon #include <sys/param.h>
36e25c779eSMatthew Dillon #include <sys/kernel.h>
37e25c779eSMatthew Dillon #include <sys/conf.h>
38e25c779eSMatthew Dillon #include <sys/systm.h>
39e25c779eSMatthew Dillon #include <sys/malloc.h>
40e25c779eSMatthew Dillon #include <sys/ctype.h>
41e25c779eSMatthew Dillon #include <sys/errno.h>
42e25c779eSMatthew Dillon #include <sys/sysctl.h>
43e25c779eSMatthew Dillon #include <sys/file.h>
44e25c779eSMatthew Dillon #include <sys/uio.h>
45e25c779eSMatthew Dillon #include <sys/socketvar.h>
46e25c779eSMatthew Dillon #include <sys/socket.h>
47e25c779eSMatthew Dillon #include <sys/protosw.h>
48e25c779eSMatthew Dillon #include <sys/proc.h>
49e25c779eSMatthew Dillon #include <sys/queue.h>
50e25c779eSMatthew Dillon #include <sys/kthread.h>
51e25c779eSMatthew Dillon #include <sys/syslog.h>
52e25c779eSMatthew Dillon #include <sys/mbuf.h>
53e25c779eSMatthew Dillon #include <sys/libkern.h>
54e25c779eSMatthew Dillon #include <sys/eventhandler.h>
55e25c779eSMatthew Dillon
56e25c779eSMatthew Dillon #include <bus/cam/cam.h>
57e25c779eSMatthew Dillon
58e25c779eSMatthew Dillon #include "dev/disk/iscsi/initiator/iscsi.h"
59e25c779eSMatthew Dillon #include "dev/disk/iscsi/initiator/iscsivar.h"
60e25c779eSMatthew Dillon
61e25c779eSMatthew Dillon static char *
i_strdupin(char * s,size_t maxlen)62e25c779eSMatthew Dillon i_strdupin(char *s, size_t maxlen)
63e25c779eSMatthew Dillon {
64e25c779eSMatthew Dillon size_t len;
65e25c779eSMatthew Dillon char *p, *q;
66e25c779eSMatthew Dillon
67e25c779eSMatthew Dillon p = kmalloc(maxlen, M_ISCSI, M_WAITOK);
68e25c779eSMatthew Dillon if(copyinstr(s, p, maxlen, &len)) {
69e25c779eSMatthew Dillon kfree(p, M_ISCSI);
70e25c779eSMatthew Dillon return NULL;
71e25c779eSMatthew Dillon }
72e25c779eSMatthew Dillon q = kmalloc(len, M_ISCSI, M_WAITOK);
73e25c779eSMatthew Dillon bcopy(p, q, len);
74e25c779eSMatthew Dillon kfree(p, M_ISCSI);
75e25c779eSMatthew Dillon
76e25c779eSMatthew Dillon return q;
77e25c779eSMatthew Dillon }
78e25c779eSMatthew Dillon
79e25c779eSMatthew Dillon /*
80e25c779eSMatthew Dillon | XXX: not finished coding
81e25c779eSMatthew Dillon */
82e25c779eSMatthew Dillon int
i_setopt(isc_session_t * sp,isc_opt_t * opt)83e25c779eSMatthew Dillon i_setopt(isc_session_t *sp, isc_opt_t *opt)
84e25c779eSMatthew Dillon {
85e25c779eSMatthew Dillon const int digsize = 6;
86*bfc09ba0SMatthew Dillon size_t len;
87e25c779eSMatthew Dillon char hdigest[digsize], ddigest[digsize];
88e25c779eSMatthew Dillon
89e25c779eSMatthew Dillon debug_called(8);
90e25c779eSMatthew Dillon if(opt->maxRecvDataSegmentLength > 0) {
91e25c779eSMatthew Dillon sp->opt.maxRecvDataSegmentLength = opt->maxRecvDataSegmentLength;
92e25c779eSMatthew Dillon sdebug(2, "maxRecvDataSegmentLength=%d", sp->opt.maxRecvDataSegmentLength);
93e25c779eSMatthew Dillon }
94e25c779eSMatthew Dillon if(opt->maxXmitDataSegmentLength > 0) {
95e25c779eSMatthew Dillon // danny's RFC
96e25c779eSMatthew Dillon sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength;
97e25c779eSMatthew Dillon sdebug(2, "maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength);
98e25c779eSMatthew Dillon }
99e25c779eSMatthew Dillon if(opt->maxBurstLength != 0) {
100e25c779eSMatthew Dillon sp->opt.maxBurstLength = opt->maxBurstLength;
101e25c779eSMatthew Dillon sdebug(2, "maxBurstLength=%d", sp->opt.maxBurstLength);
102e25c779eSMatthew Dillon }
103e25c779eSMatthew Dillon
104e25c779eSMatthew Dillon if(opt->targetAddress != NULL) {
105e25c779eSMatthew Dillon if(sp->opt.targetAddress != NULL)
106e25c779eSMatthew Dillon kfree(sp->opt.targetAddress, M_ISCSI);
107e25c779eSMatthew Dillon sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128);
108e25c779eSMatthew Dillon sdebug(4, "opt.targetAddress='%s'", sp->opt.targetAddress);
109e25c779eSMatthew Dillon }
110e25c779eSMatthew Dillon if(opt->targetName != NULL) {
111e25c779eSMatthew Dillon if(sp->opt.targetName != NULL)
112e25c779eSMatthew Dillon kfree(sp->opt.targetName, M_ISCSI);
113e25c779eSMatthew Dillon sp->opt.targetName = i_strdupin(opt->targetName, 128);
114e25c779eSMatthew Dillon sdebug(4, "opt.targetName='%s'", sp->opt.targetName);
115e25c779eSMatthew Dillon }
116e25c779eSMatthew Dillon if(opt->initiatorName != NULL) {
117e25c779eSMatthew Dillon if(sp->opt.initiatorName != NULL)
118e25c779eSMatthew Dillon kfree(sp->opt.initiatorName, M_ISCSI);
119e25c779eSMatthew Dillon sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128);
120e25c779eSMatthew Dillon sdebug(4, "opt.initiatorName='%s'", sp->opt.initiatorName);
121e25c779eSMatthew Dillon }
122e25c779eSMatthew Dillon
123e25c779eSMatthew Dillon if(opt->maxluns > 0) {
124e25c779eSMatthew Dillon if(opt->maxluns > ISCSI_MAX_LUNS)
125e25c779eSMatthew Dillon sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ...
126e25c779eSMatthew Dillon sp->opt.maxluns = opt->maxluns;
127e25c779eSMatthew Dillon sdebug(4, "opt.maxluns=%d", sp->opt.maxluns);
128e25c779eSMatthew Dillon }
129e25c779eSMatthew Dillon
130e25c779eSMatthew Dillon /* Try to copy the userland pointer containing the header digest */
131e25c779eSMatthew Dillon if(opt->headerDigest != NULL) {
132e25c779eSMatthew Dillon if ((copyinstr(opt->headerDigest, &hdigest, digsize, &len)) != EFAULT) {
133e25c779eSMatthew Dillon sdebug(2, "opt.headerDigest='%s'", hdigest);
134e25c779eSMatthew Dillon if(strcmp(hdigest, "CRC32C") == 0) {
135e25c779eSMatthew Dillon sp->hdrDigest = (digest_t *)crc32_ext;
136e25c779eSMatthew Dillon sdebug(2, "headerDigest set");
137e25c779eSMatthew Dillon }
138e25c779eSMatthew Dillon }
139e25c779eSMatthew Dillon }
140e25c779eSMatthew Dillon /* Try to copy the userland pointer containing the data digest */
141e25c779eSMatthew Dillon if(opt->dataDigest != NULL) {
142e25c779eSMatthew Dillon if ((copyinstr(opt->dataDigest, &ddigest, digsize, &len)) != EFAULT) {
143e25c779eSMatthew Dillon if (strcmp(ddigest, "CRC32C") == 0) {
144e25c779eSMatthew Dillon sp->dataDigest = (digest_t *)crc32_ext;
145e25c779eSMatthew Dillon sdebug(2, "dataDigest set");
146e25c779eSMatthew Dillon }
147e25c779eSMatthew Dillon }
148e25c779eSMatthew Dillon }
149e25c779eSMatthew Dillon
150e25c779eSMatthew Dillon return 0;
151e25c779eSMatthew Dillon }
152e25c779eSMatthew Dillon
153e25c779eSMatthew Dillon void
i_freeopt(isc_opt_t * opt)154e25c779eSMatthew Dillon i_freeopt(isc_opt_t *opt)
155e25c779eSMatthew Dillon {
156e25c779eSMatthew Dillon if(opt->targetAddress != NULL) {
157e25c779eSMatthew Dillon kfree(opt->targetAddress, M_ISCSI);
158e25c779eSMatthew Dillon opt->targetAddress = NULL;
159e25c779eSMatthew Dillon }
160e25c779eSMatthew Dillon if(opt->targetName != NULL) {
161e25c779eSMatthew Dillon kfree(opt->targetName, M_ISCSI);
162e25c779eSMatthew Dillon opt->targetName = NULL;
163e25c779eSMatthew Dillon }
164e25c779eSMatthew Dillon if(opt->initiatorName != NULL) {
165e25c779eSMatthew Dillon kfree(opt->initiatorName, M_ISCSI);
166e25c779eSMatthew Dillon opt->initiatorName = NULL;
167e25c779eSMatthew Dillon }
168e25c779eSMatthew Dillon }
169