diff -upr linux-2.6.16.29/drivers/scsi/scsi_lib.c linux-2.6.16.29/drivers/scsi/scsi_lib.c
--- linux-2.6.16.29/drivers/scsi/scsi_lib.c	2006-09-12 22:02:10.000000000 +0400
+++ linux-2.6.16.29/drivers/scsi/scsi_lib.c	2007-07-05 12:59:24.000000000 +0400
@@ -227,6 +227,63 @@ void scsi_do_req(struct scsi_request *sr
 }
 EXPORT_SYMBOL(scsi_do_req);
 
+/*
+ * Function:    scsi_do_req_fifo
+ *
+ * Purpose:     Queue a SCSI request
+ *
+ * Arguments:   sreq      - command descriptor.
+ *              cmnd      - actual SCSI command to be performed.
+ *              buffer    - data buffer.
+ *              bufflen   - size of data buffer.
+ *              done      - completion function to be run.
+ *              timeout   - how long to let it run before timeout.
+ *              retries   - number of retries we allow.
+ *
+ * Lock status: No locks held upon entry.
+ *
+ * Returns:     Nothing.
+ *
+ * Notes:       This function is used for queueing requests in FIFO order.
+ *              It is a copy of scsi_do_req() with only changed the last 
+ *              parameter of scsi_insert_special_req(). Not sure, if it
+ *              breaks quiesce, but, anyway, I don't see another way to 
+ *              queue requests in FIFO order, which is necessary for SCST.
+ */
+void scsi_do_req_fifo(struct scsi_request *sreq, const void *cmnd,
+		      void *buffer, unsigned bufflen,
+		      void (*done)(struct scsi_cmnd *),
+		      int timeout, int retries)
+{
+	/*
+	 * If the upper level driver is reusing these things, then
+	 * we should release the low-level block now.  Another one will
+	 * be allocated later when this request is getting queued.
+	 */
+	__scsi_release_request(sreq);
+ 
+	/*
+	 * Our own function scsi_done (which marks the host as not busy,
+	 * disables the timeout counter, etc) will be called by us or by the
+	 * scsi_hosts[host].queuecommand() function needs to also call
+	 * the completion function for the high level driver.
+	 */
+	memcpy(sreq->sr_cmnd, cmnd, sizeof(sreq->sr_cmnd));
+	sreq->sr_bufflen = bufflen;
+	sreq->sr_buffer = buffer;
+	sreq->sr_allowed = retries;
+	sreq->sr_done = done;
+	sreq->sr_timeout_per_command = timeout;
+ 
+	if (sreq->sr_cmd_len == 0)
+		sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]);
+ 
+	sreq->sr_request->flags &= ~REQ_DONTPREP;
+	blk_insert_request(sreq->sr_device->request_queue, sreq->sr_request,
+			   1, sreq);
+}
+EXPORT_SYMBOL(scsi_do_req_fifo);
+ 
 /**
  * scsi_execute - insert request and wait for the result
  * @sdev:	scsi device
diff -upr linux-2.6.16.29/include/scsi/scsi_request.h linux-2.6.16.29/include/scsi/scsi_request.h
--- linux-2.6.16.29/include/scsi/scsi_request.h	2006-09-12 22:02:10.000000000 +0400
+++ linux-2.6.16.29/include/scsi/scsi_request.h	2007-07-05 13:01:04.000000000 +0400
@@ -51,4 +51,9 @@ extern void scsi_do_req(struct scsi_requ
 			void *buffer, unsigned bufflen,
 			void (*done) (struct scsi_cmnd *),
 			int timeout, int retries);
+#define SCSI_EXEC_REQ_FIFO_DEFINED
+extern void scsi_do_req_fifo(struct scsi_request *, const void *cmnd,
+			     void *buffer, unsigned bufflen,
+			     void (*done) (struct scsi_cmnd *),
+			     int timeout, int retries);
 #endif /* _SCSI_SCSI_REQUEST_H */
