]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/iscsi_initiator/isc_subr.c
MFV r298178:
[FreeBSD/FreeBSD.git] / sys / dev / iscsi_initiator / isc_subr.c
1 /*-
2  * Copyright (c) 2005-2011 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
29  | $Id: isc_subr.c 560 2009-05-07 07:37:49Z danny $
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
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/libkern.h>
57 #include <vm/uma.h>
58
59 #include <dev/iscsi_initiator/iscsi.h>
60 #include <dev/iscsi_initiator/iscsivar.h>
61
62 static MALLOC_DEFINE(M_ISC, "iSC", "iSCSI driver options");
63
64 static char *
65 i_strdupin(char *s, size_t maxlen)
66 {
67      size_t     len;
68      char       *p, *q;
69
70      p = malloc(maxlen, M_ISC, M_WAITOK);
71      if(copyinstr(s, p, maxlen, &len)) {
72           free(p, M_ISC);
73           return NULL;
74      }
75      q = malloc(len, M_ISC, M_WAITOK);
76      bcopy(p, q, len);
77      free(p, M_ISC);
78
79      return q;
80 }
81 #if __FreeBSD_version < 800000
82 /*****************************************************************/
83 /*                                                               */
84 /* CRC LOOKUP TABLE                                              */
85 /* ================                                              */
86 /* The following CRC lookup table was generated automagically    */
87 /* by the Rocksoft^tm Model CRC Algorithm Table Generation       */
88 /* Program V1.0 using the following model parameters:            */
89 /*                                                               */
90 /*    Width   : 4 bytes.                                         */
91 /*    Poly    : 0x1EDC6F41L                                      */
92 /*    Reverse : TRUE.                                            */
93 /*                                                               */
94 /* For more information on the Rocksoft^tm Model CRC Algorithm,  */
95 /* see the document titled "A Painless Guide to CRC Error        */
96 /* Detection Algorithms" by Ross Williams                        */
97 /* (ross@guest.adelaide.edu.au.). This document is likely to be  */
98 /* in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft".        */
99 /*                                                               */
100 /*****************************************************************/
101
102 static uint32_t crc32Table[256] = {
103     0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L,
104     0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL,
105     0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL,
106     0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L,
107     0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL,
108     0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L,
109     0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L,
110     0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL,
111     0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL,
112     0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L,
113     0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L,
114     0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL,
115     0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L,
116     0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL,
117     0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL,
118     0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L,
119     0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L,
120     0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L,
121     0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L,
122     0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L,
123     0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L,
124     0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L,
125     0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L,
126     0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L,
127     0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L,
128     0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L,
129     0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L,
130     0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L,
131     0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L,
132     0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L,
133     0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L,
134     0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L,
135     0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL,
136     0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L,
137     0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L,
138     0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL,
139     0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L,
140     0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL,
141     0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL,
142     0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L,
143     0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L,
144     0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL,
145     0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL,
146     0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L,
147     0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL,
148     0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L,
149     0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L,
150     0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL,
151     0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L,
152     0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL,
153     0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL,
154     0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L,
155     0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL,
156     0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L,
157     0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L,
158     0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL,
159     0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL,
160     0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L,
161     0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L,
162     0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL,
163     0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L,
164     0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL,
165     0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL,
166     0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L
167 };
168
169 static __inline int
170 calculate_crc32c(uint32_t crc, const void *buf, size_t size)
171 {
172      const uint8_t *p = buf;
173
174      while (size--)
175           crc = crc32Table[(crc ^ *p++) & 0xff] ^ (crc >> 8);
176      return crc;
177 }
178 #endif
179
180 static uint32_t
181 i_crc32c(const void *buf, size_t size, uint32_t crc)
182 {
183      crc = crc ^ 0xffffffff;
184      crc = calculate_crc32c(crc, buf, size);
185      crc = crc ^ 0xffffffff;
186      return crc;
187 }
188
189 /*
190  | XXX: not finished coding
191  */
192 int
193 i_setopt(isc_session_t *sp, isc_opt_t *opt)
194 {
195      if(opt->maxRecvDataSegmentLength > 0) {
196           sp->opt.maxRecvDataSegmentLength = opt->maxRecvDataSegmentLength;
197           sdebug(2, "maxRecvDataSegmentLength=%d", sp->opt.maxRecvDataSegmentLength);
198      }
199      if(opt->maxXmitDataSegmentLength > 0) {
200           // danny's RFC
201           sp->opt.maxXmitDataSegmentLength = opt->maxXmitDataSegmentLength;
202           sdebug(2, "opt.maXmitDataSegmentLength=%d", sp->opt.maxXmitDataSegmentLength);
203      }
204      if(opt->maxBurstLength != 0) {
205           sp->opt.maxBurstLength = opt->maxBurstLength;
206           sdebug(2, "opt.maxBurstLength=%d", sp->opt.maxBurstLength);
207      }
208
209      if(opt->targetAddress != NULL) {
210           if(sp->opt.targetAddress != NULL)
211                free(sp->opt.targetAddress, M_ISC);
212           sp->opt.targetAddress = i_strdupin(opt->targetAddress, 128);
213           sdebug(2, "opt.targetAddress='%s'", sp->opt.targetAddress);
214      }
215      if(opt->targetName != NULL) {
216           if(sp->opt.targetName != NULL)
217                free(sp->opt.targetName, M_ISC);
218           sp->opt.targetName = i_strdupin(opt->targetName, 128);
219           sdebug(2, "opt.targetName='%s'", sp->opt.targetName);
220      }
221      if(opt->initiatorName != NULL) {
222           if(sp->opt.initiatorName != NULL)
223                free(sp->opt.initiatorName, M_ISC);
224           sp->opt.initiatorName = i_strdupin(opt->initiatorName, 128);
225           sdebug(2, "opt.initiatorName='%s'", sp->opt.initiatorName);
226      }
227
228      if(opt->maxluns > 0) {
229           if(opt->maxluns > ISCSI_MAX_LUNS)
230                sp->opt.maxluns = ISCSI_MAX_LUNS; // silently chop it down ...
231           sp->opt.maxluns = opt->maxluns;
232           sdebug(2, "opt.maxluns=%d", sp->opt.maxluns);
233      }
234
235      if(opt->headerDigest != NULL) {
236           sdebug(2, "opt.headerDigest='%s'", opt->headerDigest);
237           if(strcmp(opt->headerDigest, "CRC32C") == 0) {
238                sp->hdrDigest = (digest_t *)i_crc32c;
239                sdebug(2, "opt.headerDigest set");
240           }
241      }
242      if(opt->dataDigest != NULL) {
243           sdebug(2, "opt.dataDigest='%s'", opt->headerDigest);
244           if(strcmp(opt->dataDigest, "CRC32C") == 0) {
245                sp->dataDigest = (digest_t *)i_crc32c;
246                sdebug(2, "opt.dataDigest set");
247           }
248      }
249
250      return 0;
251 }
252
253 void
254 i_freeopt(isc_opt_t *opt)
255 {
256      debug_called(8);
257
258      if(opt->targetAddress != NULL) {
259           free(opt->targetAddress, M_ISC);
260           opt->targetAddress = NULL;
261      }
262      if(opt->targetName != NULL) {
263           free(opt->targetName, M_ISC);
264           opt->targetName = NULL;
265      }
266      if(opt->initiatorName != NULL) {
267           free(opt->initiatorName, M_ISC);
268           opt->initiatorName = NULL;
269      }
270 }