Skip to contentSkip to conversation

add scsi helpers to send async requests and map pages

PATCH In review Mike Christie 1 participant 1 message Sep 16, 2005 SCSI

lore
Share & tools
lore
#0 lore raw

PATCH 2/5 add scsi helpers to send async requests and map pages

Add scsi helper scsi_execute_async and convert some functions to user it. This is similar to scsi_execute in that it returns the sense instead of a normalized scsi sense header. I can extract the internals and implement a scsi_execute_async_req that returns a sense header.

Fixed from the review comments:
- Renamed __scsi_request to scsi_io_context.

- Went page based. I used a scatterlist since the bio_vec is only supposed to point to a single page and a scatterlist gives us the structure we are looking for but it does seem odd to go from a scatterlist to a request to a scsi_cmd with a scatterlist again (the difference between the scatterlists is that the one from SG/ST does not always obey queue limits though). We could add some flag on the request and some checks in blk_rq_map_sg() and come up with the same result as we had before, but that would move this odd case back to the block layer. And with this patch at least sg and st cannot go beyond and segment queue limits and use HighMem.

- moved the request mapping function to scsi becuase it has some modificiations that are only useful for SG and ST's large request handling and we may want to modify them further to handle their non sector based commands.

There seems to be a log of arguments to our scsi execute functions. Does this seem strange to anyone else or is it ok?

drivers/scsi/scsi_error.c +9 -38
@@ -1366,23 +1366,6 @@ int scsi_decide_disposition(struct scsi_
 }
 
 /**
- * scsi_eh_lock_done - done function for eh door lock request
- * @scmd:	SCSI command block for the door lock request
- *
- * Notes:
- * 	We completed the asynchronous door lock request, and it has either
- * 	locked the door or failed.  We must free the command structures
- * 	associated with this request.
- **/
-static void scsi_eh_lock_done(struct scsi_cmnd *scmd)
-{
-	struct scsi_request *sreq = scmd->sc_request;
-
-	scsi_release_request(sreq);
-}
-
-
-/**
  * scsi_eh_lock_door - Prevent medium removal for the specified device
  * @sdev:	SCSI device to prevent medium removal
  *
@@ -1404,29 +1387,17 @@ static void scsi_eh_lock_done(struct scs
  **/
 static void scsi_eh_lock_door(struct scsi_device *sdev)
 {
-	struct scsi_request *sreq = scsi_allocate_request(sdev, GFP_KERNEL);
-
-	if (unlikely(!sreq)) {
-		printk(KERN_ERR "%s: request allocate failed,"
-		       "prevent media removal cmd not sent\n", __FUNCTION__);
-		return;
-	}
+	unsigned char cmnd[MAX_COMMAND_SIZE];
 
-	sreq->sr_cmnd[0] = ALLOW_MEDIUM_REMOVAL;
-	sreq->sr_cmnd[1] = 0;
-	sreq->sr_cmnd[2] = 0;
-	sreq->sr_cmnd[3] = 0;
-	sreq->sr_cmnd[4] = SCSI_REMOVAL_PREVENT;
-	sreq->sr_cmnd[5] = 0;
-	sreq->sr_data_direction = DMA_NONE;
-	sreq->sr_bufflen = 0;
-	sreq->sr_buffer = NULL;
-	sreq->sr_allowed = 5;
-	sreq->sr_done = scsi_eh_lock_done;
-	sreq->sr_timeout_per_command = 10 * HZ;
-	sreq->sr_cmd_len = COMMAND_SIZE(sreq->sr_cmnd[0]);
+	cmnd[0] = ALLOW_MEDIUM_REMOVAL;
+	cmnd[1] = 0;
+	cmnd[2] = 0;
+	cmnd[3] = 0;
+	cmnd[4] = SCSI_REMOVAL_PREVENT;
+	cmnd[5] = 0;
 
-	scsi_insert_special_req(sreq, 1);
+	scsi_execute_async(sdev, cmnd, DMA_NONE, NULL, 0, 0, 10 * HZ,
+			   5, NULL, NULL, GFP_KERNEL);
 }
 
 
drivers/scsi/scsi_lib.c +149 -34

202 lines not on this page · raw message

drivers/scsi/scsi_priv.h +0 -1
@@ -41,7 +41,6 @@ extern void scsi_exit_hosts(void);
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
 extern void scsi_destroy_command_freelist(struct Scsi_Host *shost);
-extern int scsi_insert_special_req(struct scsi_request *sreq, int);
 extern void scsi_init_cmd_from_req(struct scsi_cmnd *cmd,
 		struct scsi_request *sreq);
 extern void __scsi_release_request(struct scsi_request *sreq);
include/scsi/scsi_device.h +6 -0
@@ -264,6 +264,12 @@ extern int scsi_execute(struct scsi_devi
 extern int scsi_execute_req(struct scsi_device *sdev, const unsigned char *cmd,
 			    int data_direction, void *buffer, unsigned bufflen,
 			    struct scsi_sense_hdr *, int timeout, int retries);
+extern int scsi_execute_async(struct scsi_device *sdev,
+			      const unsigned char *cmd, int data_direction,
+			      void *buffer, unsigned bufflen, int use_sg,
+			      int timeout, int retries, void *privdata,
+			      void (*done)(void *, char *, int, int),
+			      unsigned int gfp);
 
 static inline int scsi_device_online(struct scsi_device *sdev)
 {