Parcourir la source

[scsi] Make SCSI command issuing partially asynchronous

Move the icky call to step() from iscsi.c to scsi.c; this takes it at
least one step further away from where it really doesn't belong.
tags/v0.9.8
Michael Brown il y a 15 ans
Parent
révision
1d8d8ef2c8
4 fichiers modifiés avec 33 ajouts et 30 suppressions
  1. 15
    3
      src/drivers/block/scsi.c
  2. 0
    5
      src/include/gpxe/iscsi.h
  3. 7
    4
      src/include/gpxe/scsi.h
  4. 11
    18
      src/net/tcp/iscsi.c

+ 15
- 3
src/drivers/block/scsi.c Voir le fichier

@@ -23,6 +23,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
23 23
 #include <byteswap.h>
24 24
 #include <errno.h>
25 25
 #include <gpxe/blockdev.h>
26
+#include <gpxe/process.h>
26 27
 #include <gpxe/scsi.h>
27 28
 
28 29
 /** @file
@@ -57,11 +58,22 @@ static int scsi_command ( struct scsi_device *scsi,
57 58
 	/* Clear sense response code before issuing command */
58 59
 	command->sense_response = 0;
59 60
 
61
+	/* Flag command as in-progress */
62
+	command->rc = -EINPROGRESS;
63
+
60 64
 	/* Issue SCSI command */
61 65
 	if ( ( rc = scsi->command ( scsi, command ) ) != 0 ) {
62
-		/* Something went wrong with the issuing mechanism,
63
-		 * (rather than with the command itself)
64
-		 */
66
+		/* Something went wrong with the issuing mechanism */
67
+		DBG ( "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
68
+		      scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
69
+		return rc;
70
+	}
71
+
72
+	/* Wait for command to complete */
73
+	while ( command->rc == -EINPROGRESS )
74
+		step();
75
+	if ( ( rc = command->rc ) != 0 ) {
76
+		/* Something went wrong with the command execution */
65 77
 		DBG ( "SCSI %p " SCSI_CDB_FORMAT " err %s\n",
66 78
 		      scsi, SCSI_CDB_DATA ( command->cdb ), strerror ( rc ) );
67 79
 		return rc;

+ 0
- 5
src/include/gpxe/iscsi.h Voir le fichier

@@ -614,11 +614,6 @@ struct iscsi_session {
614 614
 	 * Set to NULL when command is complete.
615 615
 	 */
616 616
 	struct scsi_command *command;
617
-	/** SCSI command return code
618
-	 *
619
-	 * Set to -EINPROGRESS while command is processing.
620
-	 */
621
-	int rc;
622 617
 	/** Instant return code
623 618
 	 *
624 619
 	 * Set to a non-zero value if all requests should return

+ 7
- 4
src/include/gpxe/scsi.h Voir le fichier

@@ -236,6 +236,8 @@ struct scsi_command {
236 236
 	uint8_t status;
237 237
 	/** SCSI sense response code */
238 238
 	uint8_t sense_response;
239
+	/** Command status code */
240
+	int rc;
239 241
 };
240 242
 
241 243
 /** A SCSI device */
@@ -256,10 +258,11 @@ struct scsi_device {
256 258
 	 * @ret rc		Return status code
257 259
 	 *
258 260
 	 * Note that a successful return status code indicates only
259
-	 * that the SCSI command completed.  The caller must check the
260
-	 * status field in the command structure to see if, for
261
-	 * example, the device returned CHECK CONDITION or some other
262
-	 * non-success status code.
261
+	 * that the SCSI command was issued.  The caller must check
262
+	 * the status field in the command structure to see when the
263
+	 * command completes and whether, for example, the device
264
+	 * returned CHECK CONDITION or some other non-success status
265
+	 * code.
263 266
 	 */
264 267
 	int ( * command ) ( struct scsi_device *scsi,
265 268
 			    struct scsi_command *command );

+ 11
- 18
src/net/tcp/iscsi.c Voir le fichier

@@ -182,9 +182,10 @@ static void iscsi_close_connection ( struct iscsi_session *iscsi, int rc ) {
182 182
 static void iscsi_scsi_done ( struct iscsi_session *iscsi, int rc ) {
183 183
 
184 184
 	assert ( iscsi->tx_state == ISCSI_TX_IDLE );
185
+	assert ( iscsi->command != NULL );
185 186
 
187
+	iscsi->command->rc = rc;
186 188
 	iscsi->command = NULL;
187
-	iscsi->rc = rc;
188 189
 }
189 190
 
190 191
 /****************************************************************************
@@ -1550,32 +1551,24 @@ static int iscsi_command ( struct scsi_device *scsi,
1550 1551
 		container_of ( scsi->backend, struct iscsi_session, refcnt );
1551 1552
 	int rc;
1552 1553
 
1554
+	/* Abort immediately if we have a recorded permanent failure */
1555
+	if ( iscsi->instant_rc )
1556
+		return iscsi->instant_rc;
1557
+
1553 1558
 	/* Record SCSI command */
1554 1559
 	iscsi->command = command;
1555 1560
 
1556
-	/* Abort immediately if we have a recorded permanent failure */
1557
-	if ( iscsi->instant_rc ) {
1558
-		rc = iscsi->instant_rc;
1559
-		goto done;
1560
-	}
1561
-
1562 1561
 	/* Issue command or open connection as appropriate */
1563 1562
 	if ( iscsi->status ) {
1564 1563
 		iscsi_start_command ( iscsi );
1565 1564
 	} else {
1566
-		if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 )
1567
-			goto done;
1565
+		if ( ( rc = iscsi_open_connection ( iscsi ) ) != 0 ) {
1566
+			iscsi->command = NULL;
1567
+			return rc;
1568
+		}
1568 1569
 	}
1569 1570
 
1570
-	/* Wait for command to complete */
1571
-	iscsi->rc = -EINPROGRESS;
1572
-	while ( iscsi->rc == -EINPROGRESS )
1573
-		step();
1574
-	rc = iscsi->rc;
1575
-
1576
- done:
1577
-	iscsi->command = NULL;
1578
-	return rc;
1571
+	return 0;
1579 1572
 }
1580 1573
 
1581 1574
 static int iscsi_detached_command ( struct scsi_device *scsi __unused,

Chargement…
Annuler
Enregistrer