xref: /dflybsd-src/sys/dev/disk/iscsi/initiator/isc_subr.c (revision f354e0e64689159f00d07d7caa59dab0cea92fcb)
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