|
@@ -222,24 +222,27 @@ static void iscsi_data_out_done ( struct iscsi_session *iscsi ) {
|
222
|
222
|
* Send iSCSI data-out data segment
|
223
|
223
|
*
|
224
|
224
|
* @v iscsi iSCSI session
|
|
225
|
+ * @v buf Temporary data buffer
|
|
226
|
+ * @v len Length of temporary data buffer
|
225
|
227
|
*/
|
226
|
|
-static void iscsi_tx_data_out ( struct iscsi_session *iscsi ) {
|
|
228
|
+static void iscsi_tx_data_out ( struct iscsi_session *iscsi,
|
|
229
|
+ void *buf, size_t len ) {
|
227
|
230
|
struct iscsi_bhs_data_out *data_out = &iscsi->tx_bhs.data_out;
|
228
|
231
|
unsigned long offset;
|
229
|
|
- unsigned long len;
|
|
232
|
+ unsigned long remaining;
|
230
|
233
|
|
231
|
234
|
offset = ( iscsi->transfer_offset + ntohl ( data_out->offset ) +
|
232
|
235
|
iscsi->tx_offset );
|
233
|
|
- len = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset );
|
|
236
|
+ remaining = ( ISCSI_DATA_LEN ( data_out->lengths ) - iscsi->tx_offset);
|
234
|
237
|
assert ( iscsi->command != NULL );
|
235
|
238
|
assert ( iscsi->command->data_out != NULL );
|
236
|
239
|
assert ( ( offset + len ) <= iscsi->command->data_out_len );
|
237
|
240
|
|
238
|
|
- if ( len > tcp_buflen )
|
239
|
|
- len = tcp_buflen;
|
240
|
|
- copy_from_user ( tcp_buffer, iscsi->command->data_out, offset, len );
|
|
241
|
+ if ( remaining < len )
|
|
242
|
+ len = remaining;
|
|
243
|
+ copy_from_user ( buf, iscsi->command->data_out, offset, len );
|
241
|
244
|
|
242
|
|
- tcp_send ( &iscsi->tcp, tcp_buffer, len );
|
|
245
|
+ tcp_send ( &iscsi->tcp, buf, len );
|
243
|
246
|
}
|
244
|
247
|
|
245
|
248
|
/****************************************************************************
|
|
@@ -336,15 +339,15 @@ static void iscsi_start_login ( struct iscsi_session *iscsi, int first ) {
|
336
|
339
|
* Transmit data segment of an iSCSI login request PDU
|
337
|
340
|
*
|
338
|
341
|
* @v iscsi iSCSI session
|
|
342
|
+ * @v buf Temporary data buffer
|
|
343
|
+ * @v len Length of temporary data buffer
|
339
|
344
|
*
|
340
|
345
|
* For login requests, the data segment consists of the login strings.
|
341
|
346
|
*/
|
342
|
|
-static void iscsi_tx_login_request ( struct iscsi_session *iscsi ) {
|
343
|
|
- int len;
|
344
|
|
-
|
345
|
|
- len = iscsi_build_login_request_strings ( iscsi, tcp_buffer,
|
346
|
|
- tcp_buflen );
|
347
|
|
- tcp_send ( &iscsi->tcp, tcp_buffer + iscsi->tx_offset,
|
|
347
|
+static void iscsi_tx_login_request ( struct iscsi_session *iscsi,
|
|
348
|
+ void *buf, size_t len ) {
|
|
349
|
+ len = iscsi_build_login_request_strings ( iscsi, buf, len );
|
|
350
|
+ tcp_send ( &iscsi->tcp, buf + iscsi->tx_offset,
|
348
|
351
|
len - iscsi->tx_offset );
|
349
|
352
|
}
|
350
|
353
|
|
|
@@ -422,19 +425,22 @@ static void iscsi_start_tx ( struct iscsi_session *iscsi ) {
|
422
|
425
|
* Transmit data segment of an iSCSI PDU
|
423
|
426
|
*
|
424
|
427
|
* @v iscsi iSCSI session
|
|
428
|
+ * @v buf Temporary data buffer
|
|
429
|
+ * @v len Length of temporary data buffer
|
425
|
430
|
*
|
426
|
431
|
* Handle transmission of part of a PDU data segment. iscsi::tx_bhs
|
427
|
432
|
* will be valid when this is called.
|
428
|
433
|
*/
|
429
|
|
-static void iscsi_tx_data ( struct iscsi_session *iscsi ) {
|
|
434
|
+static void iscsi_tx_data ( struct iscsi_session *iscsi,
|
|
435
|
+ void *buf, size_t len ) {
|
430
|
436
|
struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
|
431
|
437
|
|
432
|
438
|
switch ( common->opcode & ISCSI_OPCODE_MASK ) {
|
433
|
439
|
case ISCSI_OPCODE_DATA_OUT:
|
434
|
|
- iscsi_tx_data_out ( iscsi );
|
|
440
|
+ iscsi_tx_data_out ( iscsi, buf, len );
|
435
|
441
|
break;
|
436
|
442
|
case ISCSI_OPCODE_LOGIN_REQUEST:
|
437
|
|
- iscsi_tx_login_request ( iscsi );
|
|
443
|
+ iscsi_tx_login_request ( iscsi, buf, len );
|
438
|
444
|
break;
|
439
|
445
|
default:
|
440
|
446
|
assert ( 0 );
|
|
@@ -524,10 +530,13 @@ static void iscsi_acked ( struct tcp_connection *conn, size_t len ) {
|
524
|
530
|
* Transmit iSCSI PDU
|
525
|
531
|
*
|
526
|
532
|
* @v iscsi iSCSI session
|
|
533
|
+ * @v buf Temporary data buffer
|
|
534
|
+ * @v len Length of temporary data buffer
|
527
|
535
|
*
|
528
|
536
|
* Constructs data to be sent for the current TX state
|
529
|
537
|
*/
|
530
|
|
-static void iscsi_senddata ( struct tcp_connection *conn ) {
|
|
538
|
+static void iscsi_senddata ( struct tcp_connection *conn,
|
|
539
|
+ void *buf, size_t len ) {
|
531
|
540
|
struct iscsi_session *iscsi = tcp_to_iscsi ( conn );
|
532
|
541
|
struct iscsi_bhs_common *common = &iscsi->tx_bhs.common;
|
533
|
542
|
static const char pad[] = { '\0', '\0', '\0' };
|
|
@@ -545,7 +554,7 @@ static void iscsi_senddata ( struct tcp_connection *conn ) {
|
545
|
554
|
assert ( 0 );
|
546
|
555
|
break;
|
547
|
556
|
case ISCSI_TX_DATA:
|
548
|
|
- iscsi_tx_data ( iscsi );
|
|
557
|
+ iscsi_tx_data ( iscsi, buf, len );
|
549
|
558
|
break;
|
550
|
559
|
case ISCSI_TX_DATA_PADDING:
|
551
|
560
|
tcp_send ( conn, pad, ( ISCSI_DATA_PAD_LEN ( common->lengths )
|