Index: external/bsd/iscsi/dist/include/iscsiutil.h =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/include/iscsiutil.h,v retrieving revision 1.7 diff -p -u -r1.7 iscsiutil.h --- external/bsd/iscsi/dist/include/iscsiutil.h 13 Jan 2017 19:11:16 -0000 1.7 +++ external/bsd/iscsi/dist/include/iscsiutil.h 19 Apr 2025 13:38:54 -0000 @@ -284,10 +284,11 @@ int iscsi_sock_connect(int , int iscsi_sock_accept(int , int *); int iscsi_sock_shutdown(int , int); int iscsi_sock_close(int); -int iscsi_sock_msg(int , int , unsigned , void *, int); +int iscsi_sock_msg(int , int , unsigned , void *, int, int); int iscsi_sock_send_header_and_data(int , void *, unsigned , - const void *, unsigned , int); + const void *, unsigned , int, + int, int); int iscsi_sock_getsockname(int , struct sockaddr * , unsigned *); int iscsi_sock_getpeername(int , struct sockaddr * , unsigned *); int modify_iov(struct iovec ** , int *, uint32_t , uint32_t); @@ -445,6 +446,8 @@ uint32_t iscsi_atoi(char *); int HexTextToData(const char *, uint32_t , uint8_t *, uint32_t); int HexDataToText(uint8_t *, uint32_t , char *, uint32_t); void GenRandomData(uint8_t *, uint32_t); +uint32_t gen_digest(const void *, int, uint32_t); + /* this is the maximum number of iovecs which we can use in * iscsi_sock_send_header_and_data */ Index: external/bsd/iscsi/dist/include/scsi_cmd_codes.h =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/include/scsi_cmd_codes.h,v retrieving revision 1.3 diff -p -u -r1.3 scsi_cmd_codes.h --- external/bsd/iscsi/dist/include/scsi_cmd_codes.h 30 Jun 2009 02:44:52 -0000 1.3 +++ external/bsd/iscsi/dist/include/scsi_cmd_codes.h 19 Apr 2025 13:38:54 -0000 @@ -43,9 +43,13 @@ enum { MODE_SENSE_6 = 0x1a, STOP_START_UNIT = 0x1b, READ_CAPACITY = 0x25, + READ_CAPACITY_16 = 0x9e, READ_10 = 0x28, WRITE_10 = 0x2a, WRITE_VERIFY = 0x2e, + READ_16 = 0x88, + WRITE_16 = 0x8a, + WRITE_VERIFY_16 = 0x8e, VERIFY = 0x2f, SYNC_CACHE = 0x35, LOG_SENSE = 0x4d, Index: external/bsd/iscsi/dist/src/lib/crc32.c =================================================================== RCS file: external/bsd/iscsi/dist/src/lib/crc32.c diff -N external/bsd/iscsi/dist/src/lib/crc32.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ external/bsd/iscsi/dist/src/lib/crc32.c 19 Apr 2025 13:38:54 -0000 @@ -0,0 +1,145 @@ +/*- + * Copyright (c) 2004,2005,2006,2008 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Wasabi Systems, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +uint32_t gen_digest(const void *, int, uint32_t); + +/***************************************************************** + * + * CRC LOOKUP TABLE + * ================ + * The following CRC lookup table was generated automagically + * by the Rocksoft^tm Model CRC Algorithm Table Generation + * Program V1.0 using the following model parameters: + * + * Width : 4 bytes. + * Poly : 0x1EDC6F41L + * Reverse : TRUE. + * + * For more information on the Rocksoft^tm Model CRC Algorithm, + * see the document titled "A Painless Guide to CRC Error + * Detection Algorithms" by Ross Williams + * (ross@guest.adelaide.edu.au.). This document is likely to be + * in the FTP archive "ftp.adelaide.edu.au/pub/rocksoft". + * + *****************************************************************/ + +static uint32_t crc_table[256] = { + 0x00000000L, 0xF26B8303L, 0xE13B70F7L, 0x1350F3F4L, + 0xC79A971FL, 0x35F1141CL, 0x26A1E7E8L, 0xD4CA64EBL, + 0x8AD958CFL, 0x78B2DBCCL, 0x6BE22838L, 0x9989AB3BL, + 0x4D43CFD0L, 0xBF284CD3L, 0xAC78BF27L, 0x5E133C24L, + 0x105EC76FL, 0xE235446CL, 0xF165B798L, 0x030E349BL, + 0xD7C45070L, 0x25AFD373L, 0x36FF2087L, 0xC494A384L, + 0x9A879FA0L, 0x68EC1CA3L, 0x7BBCEF57L, 0x89D76C54L, + 0x5D1D08BFL, 0xAF768BBCL, 0xBC267848L, 0x4E4DFB4BL, + 0x20BD8EDEL, 0xD2D60DDDL, 0xC186FE29L, 0x33ED7D2AL, + 0xE72719C1L, 0x154C9AC2L, 0x061C6936L, 0xF477EA35L, + 0xAA64D611L, 0x580F5512L, 0x4B5FA6E6L, 0xB93425E5L, + 0x6DFE410EL, 0x9F95C20DL, 0x8CC531F9L, 0x7EAEB2FAL, + 0x30E349B1L, 0xC288CAB2L, 0xD1D83946L, 0x23B3BA45L, + 0xF779DEAEL, 0x05125DADL, 0x1642AE59L, 0xE4292D5AL, + 0xBA3A117EL, 0x4851927DL, 0x5B016189L, 0xA96AE28AL, + 0x7DA08661L, 0x8FCB0562L, 0x9C9BF696L, 0x6EF07595L, + 0x417B1DBCL, 0xB3109EBFL, 0xA0406D4BL, 0x522BEE48L, + 0x86E18AA3L, 0x748A09A0L, 0x67DAFA54L, 0x95B17957L, + 0xCBA24573L, 0x39C9C670L, 0x2A993584L, 0xD8F2B687L, + 0x0C38D26CL, 0xFE53516FL, 0xED03A29BL, 0x1F682198L, + 0x5125DAD3L, 0xA34E59D0L, 0xB01EAA24L, 0x42752927L, + 0x96BF4DCCL, 0x64D4CECFL, 0x77843D3BL, 0x85EFBE38L, + 0xDBFC821CL, 0x2997011FL, 0x3AC7F2EBL, 0xC8AC71E8L, + 0x1C661503L, 0xEE0D9600L, 0xFD5D65F4L, 0x0F36E6F7L, + 0x61C69362L, 0x93AD1061L, 0x80FDE395L, 0x72966096L, + 0xA65C047DL, 0x5437877EL, 0x4767748AL, 0xB50CF789L, + 0xEB1FCBADL, 0x197448AEL, 0x0A24BB5AL, 0xF84F3859L, + 0x2C855CB2L, 0xDEEEDFB1L, 0xCDBE2C45L, 0x3FD5AF46L, + 0x7198540DL, 0x83F3D70EL, 0x90A324FAL, 0x62C8A7F9L, + 0xB602C312L, 0x44694011L, 0x5739B3E5L, 0xA55230E6L, + 0xFB410CC2L, 0x092A8FC1L, 0x1A7A7C35L, 0xE811FF36L, + 0x3CDB9BDDL, 0xCEB018DEL, 0xDDE0EB2AL, 0x2F8B6829L, + 0x82F63B78L, 0x709DB87BL, 0x63CD4B8FL, 0x91A6C88CL, + 0x456CAC67L, 0xB7072F64L, 0xA457DC90L, 0x563C5F93L, + 0x082F63B7L, 0xFA44E0B4L, 0xE9141340L, 0x1B7F9043L, + 0xCFB5F4A8L, 0x3DDE77ABL, 0x2E8E845FL, 0xDCE5075CL, + 0x92A8FC17L, 0x60C37F14L, 0x73938CE0L, 0x81F80FE3L, + 0x55326B08L, 0xA759E80BL, 0xB4091BFFL, 0x466298FCL, + 0x1871A4D8L, 0xEA1A27DBL, 0xF94AD42FL, 0x0B21572CL, + 0xDFEB33C7L, 0x2D80B0C4L, 0x3ED04330L, 0xCCBBC033L, + 0xA24BB5A6L, 0x502036A5L, 0x4370C551L, 0xB11B4652L, + 0x65D122B9L, 0x97BAA1BAL, 0x84EA524EL, 0x7681D14DL, + 0x2892ED69L, 0xDAF96E6AL, 0xC9A99D9EL, 0x3BC21E9DL, + 0xEF087A76L, 0x1D63F975L, 0x0E330A81L, 0xFC588982L, + 0xB21572C9L, 0x407EF1CAL, 0x532E023EL, 0xA145813DL, + 0x758FE5D6L, 0x87E466D5L, 0x94B49521L, 0x66DF1622L, + 0x38CC2A06L, 0xCAA7A905L, 0xD9F75AF1L, 0x2B9CD9F2L, + 0xFF56BD19L, 0x0D3D3E1AL, 0x1E6DCDEEL, 0xEC064EEDL, + 0xC38D26C4L, 0x31E6A5C7L, 0x22B65633L, 0xD0DDD530L, + 0x0417B1DBL, 0xF67C32D8L, 0xE52CC12CL, 0x1747422FL, + 0x49547E0BL, 0xBB3FFD08L, 0xA86F0EFCL, 0x5A048DFFL, + 0x8ECEE914L, 0x7CA56A17L, 0x6FF599E3L, 0x9D9E1AE0L, + 0xD3D3E1ABL, 0x21B862A8L, 0x32E8915CL, 0xC083125FL, + 0x144976B4L, 0xE622F5B7L, 0xF5720643L, 0x07198540L, + 0x590AB964L, 0xAB613A67L, 0xB831C993L, 0x4A5A4A90L, + 0x9E902E7BL, 0x6CFBAD78L, 0x7FAB5E8CL, 0x8DC0DD8FL, + 0xE330A81AL, 0x115B2B19L, 0x020BD8EDL, 0xF0605BEEL, + 0x24AA3F05L, 0xD6C1BC06L, 0xC5914FF2L, 0x37FACCF1L, + 0x69E9F0D5L, 0x9B8273D6L, 0x88D28022L, 0x7AB90321L, + 0xAE7367CAL, 0x5C18E4C9L, 0x4F48173DL, 0xBD23943EL, + 0xF36E6F75L, 0x0105EC76L, 0x12551F82L, 0xE03E9C81L, + 0x34F4F86AL, 0xC69F7B69L, 0xD5CF889DL, 0x27A40B9EL, + 0x79B737BAL, 0x8BDCB4B9L, 0x988C474DL, 0x6AE7C44EL, + 0xBE2DA0A5L, 0x4C4623A6L, 0x5F16D052L, 0xAD7D5351L +}; + + +/* + * gen_digest: + * Generate an iSCSI CRC32C digest over the given data. + * + * Parameters: + * buff The data + * len The length of the data in bytes + * crc The digest of a previous buffer or 0 + * + * Returns: The digest + */ + +uint32_t +gen_digest(const void *buff, int len, uint32_t crc) +{ + const uint8_t *bp = (const uint8_t *) buff; + + crc = crc ^ 0xffffffff; + while (len--) { + crc = ((crc >> 8) & 0x00ffffff) ^ crc_table[(crc ^ *bp++) & 0xff]; + } + return crc ^ 0xffffffff; +} + Index: external/bsd/iscsi/dist/src/lib/disk.c =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/src/lib/disk.c,v retrieving revision 1.9 diff -p -u -r1.9 disk.c --- external/bsd/iscsi/dist/src/lib/disk.c 30 Sep 2014 15:25:18 -0000 1.9 +++ external/bsd/iscsi/dist/src/lib/disk.c 19 Apr 2025 13:38:54 -0000 @@ -180,9 +180,9 @@ disk/extent code * Private Interface */ static int disk_read(target_session_t *, iscsi_scsi_cmd_args_t *, - uint32_t, uint16_t, uint8_t); + uint64_t, uint32_t, uint8_t); static int disk_write(target_session_t *, iscsi_scsi_cmd_args_t *, - uint8_t, uint32_t, uint32_t); + uint8_t, uint64_t, uint32_t); /* return the de index and offset within the device for RAID0 */ static int @@ -897,27 +897,15 @@ device_init(iscsi_target_t *tgt, targv_t static void cdb2lba(uint32_t *lba, uint16_t *len, uint8_t *cdb) { - /* Some platforms (like strongarm) aligns on */ - /* word boundaries. So HTONL and NTOHL won't */ - /* work here. */ - int little_endian = 1; - - if (*(char *) (void *) &little_endian) { - /* little endian */ - ((uint8_t *) (void *) lba)[0] = cdb[5]; - ((uint8_t *) (void *) lba)[1] = cdb[4]; - ((uint8_t *) (void *) lba)[2] = cdb[3]; - ((uint8_t *) (void *) lba)[3] = cdb[2]; - ((uint8_t *) (void *) len)[0] = cdb[8]; - ((uint8_t *) (void *) len)[1] = cdb[7]; - } else { - ((uint8_t *) (void *) lba)[0] = cdb[2]; - ((uint8_t *) (void *) lba)[1] = cdb[3]; - ((uint8_t *) (void *) lba)[2] = cdb[4]; - ((uint8_t *) (void *) lba)[3] = cdb[5]; - ((uint8_t *) (void *) len)[0] = cdb[7]; - ((uint8_t *) (void *) len)[1] = cdb[8]; - } + *lba = be32dec(&cdb[2]); + *len = be16dec(&cdb[7]); +} + +static void +cdb2lba64(uint64_t *lba64, uint32_t *len32, uint8_t *cdb) +{ + *lba64 = be64dec(&cdb[2]); + *len32 = be32dec(&cdb[10]); } /* handle MODE_SENSE_6 and MODE_SENSE_10 commands */ @@ -1095,7 +1083,9 @@ device_command(target_session_t *sess, t iscsi_scsi_cmd_args_t *args = cmd->scsi_cmd; uint32_t status; uint32_t lba; + uint64_t lba64; uint16_t len; + uint32_t len32; uint8_t *cdbsize; uint8_t *rspc; uint8_t *data; @@ -1209,17 +1199,27 @@ device_command(target_session_t *sess, t case READ_CAPACITY: iscsi_trace(TRACE_SCSI_CMD, "READ_CAPACITY\n"); data = args->send_data; - *((uint32_t *)(void *)data) = (uint32_t) ISCSI_HTONL( - (uint32_t) disks.v[sess->d].blockc - 1); - /* Max LBA */ - *((uint32_t *)(void *)(data + 4)) = (uint32_t) ISCSI_HTONL( - (uint32_t) disks.v[sess->d].blocklen); - /* Block len */ + /* Max LBA */ + be32enc(data, disks.v[sess->d].blockc - 1); + /* Block len */ + be32enc(data + 4, disks.v[sess->d].blocklen); args->input = 8; args->length = 8; args->status = SCSI_SUCCESS; break; + case READ_CAPACITY_16: + iscsi_trace(TRACE_SCSI_CMD, "READ_CAPACITY_16\n"); + data = args->send_data; + /* Max LBA */ + be64enc(data, disks.v[sess->d].blockc - 1); + /* Block len */ + be32enc(data + 8, disks.v[sess->d].blocklen); + args->input = 12; + args->length = 12; + args->status = SCSI_SUCCESS; + break; + case WRITE_6: lba = ISCSI_NTOHL(*((uint32_t *) (void *)cdb)) & 0x001fffff; if ((len = *cdbsize) == 0) { @@ -1282,6 +1282,34 @@ device_command(target_session_t *sess, t args->input = 1; break; + case WRITE_16: + case WRITE_VERIFY_16: + cdb2lba64(&lba64, &len32, cdb); + + iscsi_trace(TRACE_SCSI_CMD, + "WRITE_16 | WRITE_VERIFY_16(lba %" PRIu64 ", len %u blocks)\n", + lba64, len32); + if (disk_write(sess, args, lun, lba64, (unsigned) len32) != 0) { + iscsi_err(__FILE__, __LINE__, + "disk_write() failed\n"); + args->status = SCSI_CHECK_CONDITION; + } + args->length = 0; + break; + + case READ_16: + cdb2lba64(&lba64, &len32, cdb); + iscsi_trace(TRACE_SCSI_CMD, + "READ_16(lba %" PRIu64 ", len %u blocks)\n", + lba64, len32); + if (disk_read(sess, args, lba64, len32, lun) != 0) { + iscsi_err(__FILE__, __LINE__, + "disk_read() failed\n"); + args->status = SCSI_CHECK_CONDITION; + } + args->input = 1; + break; + case VERIFY: /* For now just set the status to success. */ args->status = SCSI_SUCCESS; @@ -1385,7 +1413,7 @@ device_shutdown(target_session_t *sess) static int disk_write(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint8_t lun, - uint32_t lba, uint32_t len) + uint64_t lba, uint32_t len) { struct iovec sg; uint64_t byte_offset; @@ -1456,8 +1484,8 @@ out: } static int -disk_read(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint32_t lba, - uint16_t len, uint8_t lun) +disk_read(target_session_t *sess, iscsi_scsi_cmd_args_t *args, uint64_t lba, + uint32_t len, uint8_t lun) { uint64_t byte_offset; uint64_t bytec; @@ -1480,7 +1508,7 @@ disk_read(target_session_t *sess, iscsi_ (lba + len) > disks.v[sess->d].blockc) { iscsi_err(__FILE__, __LINE__, "attempt to read beyond end of media\n" - "max_lba = %" PRIu64 ", requested lba = %u, len = %u\n", + "max_lba = %" PRIu64 ", requested lba = %" PRIu64 ", len = %u\n", disks.v[sess->d].blockc - 1, lba, len); return -1; } Index: external/bsd/iscsi/dist/src/lib/initiator.c =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/src/lib/initiator.c,v retrieving revision 1.12 diff -p -u -r1.12 initiator.c --- external/bsd/iscsi/dist/src/lib/initiator.c 17 Jan 2021 00:13:49 -0000 1.12 +++ external/bsd/iscsi/dist/src/lib/initiator.c 19 Apr 2025 13:38:54 -0000 @@ -266,8 +266,8 @@ session_init_i(initiator_session_t ** se PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_DECLARATIVE, "CHAP_C", "", "", return -1); /* CHAP Support Parameters */ - PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_LIST, "HeaderDigest", "None", "None", return -1); - PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_LIST, "DataDigest", "None", "None", return -1); + PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_LIST, "HeaderDigest", "None", "CR32C,None", return -1); + PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_LIST, "DataDigest", "None", "CR32C,None", return -1); PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_NUMERICAL, "MaxConnections", "1", "1", return -1); PARAM_LIST_ADD(l, ISCSI_PARAM_TYPE_DECLARATIVE, "SendTargets", "", "", return -1); @@ -1644,7 +1644,7 @@ rx_worker_proc_i(void *arg) for (;;) { iscsi_trace(TRACE_ISCSI_DEBUG, "rx_worker[%d]: reading iscsi header (sock %#x) \n", me->id, (int) sess->sock); - if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_trace(TRACE_ISCSI_DEBUG, "rx_worker[%d]: iscsi_sock_msg() failed\n", me->id); goto done; } @@ -1805,7 +1805,7 @@ text_command_i(initiator_cmd_t * cmd) iscsi_err(__FILE__, __LINE__, "(iscsi_text_cmd_encap() failed\n"); return -1; } - if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, text_cmd->text, text_cmd->length, 0) + if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, text_cmd->text, text_cmd->length, 0, sess->sess_params.header_digest, sess->sess_params.data_digest) != ISCSI_HEADER_LEN + text_cmd->length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed.\n"); return -1; @@ -1841,7 +1841,7 @@ login_command_i(initiator_cmd_t * cmd) iscsi_err(__FILE__, __LINE__, "(iscsi_login_cmd_encap() failed\n"); return -1; } - if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, login_cmd->text, login_cmd->length, 0) + if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, login_cmd->text, login_cmd->length, 0, sess->sess_params.header_digest, sess->sess_params.data_digest) != ISCSI_HEADER_LEN + login_cmd->length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed.\n"); return -1; @@ -2123,7 +2123,7 @@ text_response_i(initiator_session_t * se iscsi_free_atomic(text_in); TI_ERROR; } - if (iscsi_sock_msg(sess->sock, 0, (unsigned)len_in, text_in, 0) != len_in) { + if (iscsi_sock_msg(sess->sock, 0, (unsigned)len_in, text_in, 0, sess->sess_params.header_digest) != len_in) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); TI_ERROR; } @@ -2228,7 +2228,7 @@ login_response_i(initiator_session_t * s iscsi_err(__FILE__, __LINE__, "iscsi_malloc_atomic() failed\n"); LIR_ERROR; } - if (iscsi_sock_msg(sess->sock, 0, (unsigned)len_in, text_in, 0) != len_in) { + if (iscsi_sock_msg(sess->sock, 0, (unsigned)len_in, text_in, 0, sess->sess_params.header_digest) != len_in) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); LIR_ERROR; } @@ -2393,7 +2393,7 @@ logout_command_i(initiator_cmd_t * cmd) iscsi_err(__FILE__, __LINE__, "iscsi_logout_cmd_encap() failed\n"); return -1; } - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed.\n"); return -1; } @@ -2517,7 +2517,7 @@ nop_out_i(initiator_cmd_t * cmd) if ((rc = iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, nop_out->data, (unsigned)length, - 0)) != ISCSI_HEADER_LEN + length) { + 0, sess->sess_params.header_digest, sess->sess_params.data_digest)) != ISCSI_HEADER_LEN + length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed: got %d expected %d\n", rc, ISCSI_HEADER_LEN + length); return -1; } @@ -2631,20 +2631,20 @@ scsi_command_i(initiator_cmd_t * cmd) goto error; } if (scsi_cmd->ahs) { - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); goto error; } - if (iscsi_sock_msg(sess->sock, 1, (unsigned)scsi_cmd->ahs_len, scsi_cmd->ahs, 0) != scsi_cmd->ahs_len) { + if (iscsi_sock_msg(sess->sock, 1, (unsigned)scsi_cmd->ahs_len, scsi_cmd->ahs, 0, sess->sess_params.header_digest) != scsi_cmd->ahs_len) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); goto error; } - if ((unsigned)iscsi_sock_msg(sess->sock, 1, scsi_cmd->length, sg_copy, sg_len_copy) != scsi_cmd->length) { + if ((unsigned)iscsi_sock_msg(sess->sock, 1, scsi_cmd->length, sg_copy, sg_len_copy, sess->sess_params.header_digest) != scsi_cmd->length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); goto error; } } else { - if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_copy, scsi_cmd->length, sg_len_copy) + if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_copy, scsi_cmd->length, sg_len_copy, sess->sess_params.header_digest, sess->sess_params.data_digest) != ISCSI_HEADER_LEN + scsi_cmd->length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); goto error; @@ -2652,12 +2652,12 @@ scsi_command_i(initiator_cmd_t * cmd) } scsi_cmd->bytes_sent += scsi_cmd->length; } else { - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); goto error; } if (scsi_cmd->ahs_len) { - if (iscsi_sock_msg(sess->sock, 1, (unsigned)scsi_cmd->ahs_len, scsi_cmd->ahs, 0) != scsi_cmd->ahs_len) { + if (iscsi_sock_msg(sess->sock, 1, (unsigned)scsi_cmd->ahs_len, scsi_cmd->ahs, 0, sess->sess_params.header_digest) != scsi_cmd->ahs_len) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); goto error; } @@ -2769,7 +2769,7 @@ scsi_command_i(initiator_cmd_t * cmd) iscsi_trace(TRACE_ISCSI_DEBUG, "sending write data PDU (offset %u, len %u, sg_len %u)\n", data.offset, data.length, sg_len_which); - if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_which, data.length, sg_len_which) + if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_which, data.length, sg_len_which, sess->sess_params.header_digest, sess->sess_params.data_digest) != ISCSI_HEADER_LEN + data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); goto error; @@ -2822,7 +2822,7 @@ reject_i(initiator_session_t * sess, uin /* Read bad header, extract tag, and get cmd from hash table */ - if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, bad_header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, bad_header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); return -1; } @@ -2882,7 +2882,7 @@ async_msg_i(initiator_session_t * sess, return -1; } iscsi_trace(TRACE_ISCSI_DEBUG, "reading %d bytes sense data \n", msg.length); - if ((unsigned)iscsi_sock_msg(sess->sock, 0, msg.length, sense_data, 0) != msg.length) { + if ((unsigned)iscsi_sock_msg(sess->sock, 0, msg.length, sense_data, 0, sess->sess_params.header_digest) != msg.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); if (sense_data != NULL) iscsi_free(sense_data); @@ -2970,7 +2970,7 @@ nop_in_i(initiator_session_t * sess, ini #define NOI_CLEANUP {if (ping_data) iscsi_free_atomic(ping_data);} #define NOI_ERROR {NOI_CLEANUP; return -1;} if ((unsigned)iscsi_sock_msg(sess->sock, 0, nop_in.length, - ping_data, 0) != nop_in.length) { + ping_data, 0, sess->sess_params.header_digest) != nop_in.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); NOI_ERROR; @@ -3014,7 +3014,7 @@ nop_in_i(initiator_session_t * sess, ini } if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, nop_header, nop_out_args.length, ping_data, - nop_in.length, 0) != nop_in.length) { + nop_in.length, 0, sess->sess_params.header_digest, sess->sess_params.data_digest) != nop_in.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); NOI_ERROR; @@ -3203,7 +3203,7 @@ scsi_r2t_i(initiator_session_t * sess, i } iscsi_trace(TRACE_ISCSI_DEBUG, "sending R2T write data PDU (offset %u, len %u, sg_len %u)\n", data.offset, data.length, sg_len_which); - if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_which, data.length, sg_len_which) + if ((unsigned)iscsi_sock_send_header_and_data(sess->sock, header, ISCSI_HEADER_LEN, sg_which, data.length, sg_len_which, sess->sess_params.header_digest, sess->sess_params.data_digest) != ISCSI_HEADER_LEN + data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); FF_CLEANUP; @@ -3344,7 +3344,7 @@ scsi_response_i(initiator_session_t * se "reading %d bytes sense data (recv_sg_len %u)\n", scsi_rsp.length, scsi_cmd->recv_sg_len); if ((unsigned)iscsi_sock_msg(sess->sock, 0, scsi_rsp.length, - sense_data, 0) != scsi_rsp.length) { + sense_data, 0, sess->sess_params.header_digest) != scsi_rsp.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); if (sense_data != NULL) { @@ -3535,7 +3535,7 @@ scsi_read_data_i(initiator_session_t * s sg = (struct iovec *)(void *)scsi_cmd->recv_data; } iscsi_trace(TRACE_ISCSI_DEBUG, "reading %d bytes into sg buffer (total offset %u)\n", data.length, data.offset); - if ((rc = iscsi_sock_msg(sess->sock, 0, data.length, (uint8_t *)(void *) sg, sg_len)) != (int)data.length) { + if ((rc = iscsi_sock_msg(sess->sock, 0, data.length, (uint8_t *)(void *) sg, sg_len, sess->sess_params.header_digest)) != (int)data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed: got %u, expected %u\n", rc, data.length); if (sg_orig) iscsi_free_atomic(sg_orig); @@ -3547,7 +3547,7 @@ scsi_read_data_i(initiator_session_t * s } else { if (data.length) { iscsi_trace(TRACE_ISCSI_DEBUG, "reading %d bytes into dest buffer (offset %u)\n", data.length, data.offset); - if (iscsi_sock_msg(sess->sock, 0, data.length, scsi_cmd->recv_data + data.offset, 0) != (int)data.length) { + if (iscsi_sock_msg(sess->sock, 0, data.length, scsi_cmd->recv_data + data.offset, 0, sess->sess_params.header_digest) != (int)data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); return -1; } Index: external/bsd/iscsi/dist/src/lib/parameters.c =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/src/lib/parameters.c,v retrieving revision 1.4 diff -p -u -r1.4 parameters.c --- external/bsd/iscsi/dist/src/lib/parameters.c 15 Nov 2014 01:15:45 -0000 1.4 +++ external/bsd/iscsi/dist/src/lib/parameters.c 19 Apr 2025 13:38:54 -0000 @@ -1292,8 +1292,8 @@ set_session_parameters(iscsi_parameter_t sess_params->first_burst_length = param_atoi(head, "FirstBurstLength"); sess_params->max_dataseg_len = param_atoi(head, "MaxRecvDataSegmentLength"); - sess_params->header_digest = (param_equiv(head, "HeaderDigest", "Yes")) ? 1 : 0; - sess_params->data_digest = (param_equiv(head, "DataDigest", "Yes")) ? 1 : 0; + sess_params->header_digest = (param_equiv(head, "HeaderDigest", "CRC32C")) ? 1 : 0; + sess_params->data_digest = (param_equiv(head, "DataDigest", "CRC32C")) ? 1 : 0; sess_params->initial_r2t = (param_equiv(head, "InitialR2T", "Yes")); sess_params->immediate_data = (param_equiv(head, "ImmediateData", "Yes")); } Index: external/bsd/iscsi/dist/src/lib/target.c =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/src/lib/target.c,v retrieving revision 1.10 diff -p -u -r1.10 target.c --- external/bsd/iscsi/dist/src/lib/target.c 8 Oct 2019 20:02:44 -0000 1.10 +++ external/bsd/iscsi/dist/src/lib/target.c 19 Apr 2025 13:38:54 -0000 @@ -155,7 +155,7 @@ reject_t(target_session_t * sess, uint8_ return -1; } if (iscsi_sock_send_header_and_data(sess->sock, rsp_header, - ISCSI_HEADER_LEN, header, ISCSI_HEADER_LEN, 0) != + ISCSI_HEADER_LEN, header, ISCSI_HEADER_LEN, 0, sess->sess_params.header_digest, sess->sess_params.data_digest) != 2 * ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); @@ -264,7 +264,7 @@ scsi_command_t(target_session_t *sess, u goto out; } if (iscsi_sock_msg(sess->sock, 0, (unsigned)scsi_cmd.ahs_len, - scsi_cmd.ahs, 0) != scsi_cmd.ahs_len) { + scsi_cmd.ahs, 0, sess->sess_params.header_digest) != scsi_cmd.ahs_len) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); result = -1; @@ -421,8 +421,11 @@ scsi_command_t(target_session_t *sess, u result = -1; goto out; } - if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, rsp_header, ISCSI_HEADER_LEN, sg, data.length, sg_len) - != ISCSI_HEADER_LEN + data.length) { + if ((uint32_t)iscsi_sock_send_header_and_data( + sess->sock, rsp_header, ISCSI_HEADER_LEN, + sg, data.length, sg_len, + sess->sess_params.header_digest, + sess->sess_params.data_digest) != ISCSI_HEADER_LEN + data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); result = -1; goto out; @@ -460,9 +463,11 @@ response: result = -1; goto out; } - if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, rsp_header, ISCSI_HEADER_LEN, - scsi_cmd.send_data, scsi_rsp.length, scsi_cmd.send_sg_len) - != ISCSI_HEADER_LEN + scsi_rsp.length) { + if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, + rsp_header, ISCSI_HEADER_LEN, scsi_cmd.send_data, + scsi_rsp.length, 0, + sess->sess_params.header_digest, + sess->sess_params.data_digest) != ISCSI_HEADER_LEN + scsi_rsp.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); result = -1; @@ -585,7 +590,7 @@ task_command_t(target_session_t * sess, iscsi_err(__FILE__, __LINE__, "iscsi_task_cmd_decap() failed\n"); return -1; } - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0) != ISCSI_HEADER_LEN) { + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); return -1; @@ -618,7 +623,7 @@ nop_out_t(target_session_t * sess, uint8 iscsi_err(__FILE__, __LINE__, "iscsi_malloc() failed\n"); return -1; } - if ((uint32_t)iscsi_sock_msg(sess->sock, 0, nop_out.length, ping_data, 0) != nop_out.length) { + if ((uint32_t)iscsi_sock_msg(sess->sock, 0, nop_out.length, ping_data, 0, sess->sess_params.header_digest) != nop_out.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); if (ping_data) { iscsi_free(ping_data); @@ -649,8 +654,11 @@ nop_out_t(target_session_t * sess, uint8 } return -1; } - if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, rsp_header, ISCSI_HEADER_LEN, - ping_data, nop_in.length, 0) != ISCSI_HEADER_LEN + nop_in.length) { + if ((uint32_t)iscsi_sock_send_header_and_data( + sess->sock, rsp_header, ISCSI_HEADER_LEN, + ping_data, nop_in.length, 0, + sess->sess_params.header_digest, + sess->sess_params.data_digest) != ISCSI_HEADER_LEN + nop_in.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); if (ping_data) { iscsi_free(ping_data); @@ -740,7 +748,7 @@ text_command_t(target_session_t * sess, iscsi_trace(TRACE_ISCSI_DEBUG, "reading %u bytes text parameters\n", len_in); if ((unsigned)iscsi_sock_msg(sess->sock, 0, len_in, text_in, - 0) != len_in) { + 0, sess->sess_params.header_digest) != len_in) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); TC_CLEANUP; @@ -832,7 +840,7 @@ text_command_t(target_session_t * sess, TC_CLEANUP; return -1; } - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0) != + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); @@ -840,7 +848,7 @@ text_command_t(target_session_t * sess, return -1; } if (len_out && iscsi_sock_msg(sess->sock, 1, (unsigned) len_out, - text_out, 0) != len_out) { + text_out, 0, sess->sess_params.header_digest) != len_out) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); TC_CLEANUP; @@ -971,7 +979,7 @@ login_command_t(target_session_t * sess, return -1; } if (iscsi_sock_msg(sess->sock, 0, (unsigned) len_in, text_in, - 0) != len_in) { + 0, sess->sess_params.header_digest) != len_in) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); LC_CLEANUP; @@ -1140,8 +1148,9 @@ response: } iscsi_trace(TRACE_ISCSI_DEBUG, "sending login response\n"); if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, rsp_header, - ISCSI_HEADER_LEN, text_out, rsp.length, 0) != - ISCSI_HEADER_LEN + rsp.length) { + ISCSI_HEADER_LEN, text_out, rsp.length, 0, + sess->sess_params.header_digest, + sess->sess_params.data_digest) != ISCSI_HEADER_LEN + rsp.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); LC_CLEANUP; @@ -1240,7 +1249,7 @@ logout_command_t(target_session_t * sess "iscsi_logout_rsp_encap() failed\n"); return -1; } - if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0) != + if (iscsi_sock_msg(sess->sock, 1, ISCSI_HEADER_LEN, rsp_header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); @@ -1317,7 +1326,9 @@ verify_cmd_t(target_session_t * sess, ui } iscsi_trace(TRACE_ISCSI_DEBUG, "sending login response\n"); if ((uint32_t)iscsi_sock_send_header_and_data(sess->sock, - rsp_header, ISCSI_HEADER_LEN, NULL, 0, 0) != + rsp_header, ISCSI_HEADER_LEN, NULL, 0, 0, + sess->sess_params.header_digest, + sess->sess_params.data_digest) != ISCSI_HEADER_LEN + rsp.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_send_header_and_data() failed\n"); @@ -1488,7 +1499,7 @@ worker_proc_t(void *arg) while (sess->target->state != TARGET_SHUT_DOWN) { iscsi_trace(TRACE_ISCSI_DEBUG, "session %d: reading header\n", sess->id); - if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0) + if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_trace(TRACE_ISCSI_DEBUG, "session %d: iscsi_sock_msg() failed\n", @@ -1552,7 +1563,7 @@ read_data_pdu(target_session_t * sess, uint8_t header[ISCSI_HEADER_LEN]; int ret_val = -1; - if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0) != + if (iscsi_sock_msg(sess->sock, 0, ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); @@ -1653,7 +1664,7 @@ target_transfer_data(target_session_t * "reading %u bytes immediate write data\n", args->length); if ((uint32_t)iscsi_sock_msg(sess->sock, 0, args->length, iov, - iov_len) != args->length) { + iov_len, sess->sess_params.header_digest) != args->length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); TTD_CLEANUP; @@ -1718,7 +1729,7 @@ target_transfer_data(target_session_t * r2t.tag, r2t.transfer_tag, r2t.length, r2t.offset); if (iscsi_sock_msg(sess->sock, 1, - ISCSI_HEADER_LEN, header, 0) != + ISCSI_HEADER_LEN, header, 0, sess->sess_params.header_digest) != ISCSI_HEADER_LEN) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); @@ -1771,7 +1782,7 @@ target_transfer_data(target_session_t * /* Scatter into destination buffers */ if ((uint32_t)iscsi_sock_msg(sess->sock, 0, - data.length, iov, iov_len) != data.length) { + data.length, iov, iov_len, sess->sess_params.header_digest) != data.length) { iscsi_err(__FILE__, __LINE__, "iscsi_sock_msg() failed\n"); TTD_CLEANUP; Index: external/bsd/iscsi/dist/src/lib/util.c =================================================================== RCS file: /cvsroot/src/external/bsd/iscsi/dist/src/lib/util.c,v retrieving revision 1.5 diff -p -u -r1.5 util.c --- external/bsd/iscsi/dist/src/lib/util.c 3 Aug 2023 08:00:10 -0000 1.5 +++ external/bsd/iscsi/dist/src/lib/util.c 19 Apr 2025 13:38:54 -0000 @@ -892,7 +892,8 @@ iscsi_sock_connect(int sock, char *hostn */ int -iscsi_sock_msg(int sock, int xmit, unsigned len, void *data, int iovc) +iscsi_sock_msg(int sock, int xmit, unsigned len, void *data, int iovc, + int hdigest) { struct iovec singleton; struct iovec *iov; @@ -1025,64 +1026,80 @@ iscsi_sock_msg(int sock, int xmit, unsig return n - padding_len; } -/* - * Temporary Hack: - * - * TCP's Nagle algorithm and delayed-ack lead to poor performance when we send - * two small messages back to back (i.e., header+data). The TCP_NODELAY option - * is supposed to turn off Nagle, but it doesn't seem to work on Linux 2.4. - * Because of this, if our data payload is small, we'll combine the header and - * data, else send as two separate messages. - */ - int iscsi_sock_send_header_and_data(int sock, void *header, unsigned header_len, - const void *data, unsigned data_len, int iovc) + const void *data, unsigned data_len, int iovc, + int hdigest, int ddigest) { - struct iovec iov[ISCSI_MAX_IOVECS]; + struct iovec iov[ISCSI_MAX_IOVECS+2]; + const struct iovec *diov; + uint32_t digest; + int i; + size_t total_len; - if (data_len && data_len <= ISCSI_SOCK_HACK_CROSSOVER) { - /* combine header and data into one iovec */ - if (iovc >= ISCSI_MAX_IOVECS) { - iscsi_err(__FILE__, __LINE__, - "iscsi_sock_msg() failed\n"); - return -1; - } - if (iovc == 0) { - iov[0].iov_base = header; - iov[0].iov_len = header_len; + /* combine header and data into one iovec */ + if (iovc + 1 + (ddigest != 0) > ISCSI_MAX_IOVECS) { + iscsi_err(__FILE__, __LINE__, + "iscsi_sock_msg() failed, iovc %d >= %d\n", + iovc, ISCSI_MAX_IOVECS); + return -1; + } + if (iovc == 0) { + iscsi_trace(TRACE_NET_IOV, + "combining header %u and data %u into iovec\n", + header_len, data_len); + iov[0].iov_base = header; + iov[0].iov_len = header_len; + iovc = 1; + if (data_len > 0) { iov[1].iov_base = __UNCONST((const char *)data); iov[1].iov_len = data_len; - iovc = 2; - } else { - iov[0].iov_base = header; - iov[0].iov_len = header_len; - (void) memcpy(&iov[1], data, sizeof(struct iovec) * - iovc); iovc += 1; } - if ((unsigned)iscsi_sock_msg(sock, Transmit, - header_len + data_len, iov, iovc) != - header_len + data_len) { - iscsi_err(__FILE__, __LINE__, - "iscsi_sock_msg() failed\n"); - return -1; - } } else { - if ((unsigned)iscsi_sock_msg(sock, Transmit, header_len, - header, 0) != header_len) { - iscsi_err(__FILE__, __LINE__, - "iscsi_sock_msg() failed\n"); - return -1; - } - if (data_len != 0 && - (unsigned)iscsi_sock_msg(sock, Transmit, data_len, - __UNCONST((const char *) data), iovc) != data_len) { - iscsi_err(__FILE__, __LINE__, - "iscsi_sock_msg() failed\n"); - return -1; + iscsi_trace(TRACE_NET_IOV, + "prepending header %u to iovec %u\n", + header_len, iovc); + iov[0].iov_base = header; + iov[0].iov_len = header_len; + + diov = (const struct iovec *)data; + total_len = 0; + for (i=0; i data_len) { + total_len -= diov[i].iov_len; + iov[1+i].iov_len = data_len - total_len; + iovc = 1+i; + break; + } } + iovc += 1; + } + if (ddigest) { + iscsi_trace(TRACE_NET_IOV, + "appending data digest to iovec %u\n", + iovc); + + digest = 0; + for (i=1; i