add scsi helpers
Subsystems (3)
PATCH 2/5 add scsi helpers
Add scsi helpers to create really-large-requests and convert scsi-ml to scsi_execute_async().
Per Jens's previous comments, I placed this function in scsi_lib.c. I made it follow all the queue's limits - I think I did at least :), so I removed the warning on the function header.
I think the scsi_execute_* functions should envtually take a request_queue and be placed some place where the dm-multipath hw_handler can use them if that failover code is going to stay in the kernel. That conversion patch will be sent in another mail though.
Signed-off-by Mike Christie <[email protected]>
drivers/scsi/scsi_error.c +9 -38
@@ -1315,23 +1315,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 *
@@ -1353,29 +1336,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 +196 -34
249 lines not on this page · raw message
drivers/scsi/scsi_priv.h +0 -1
@@ -40,7 +40,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);
fs/bio.c +20 -0
@@ -386,6 +386,25 @@ static int __bio_add_page(request_queue_ }/** +* bio_add_pc_page - attempt to add page to bio +* @bio: destination bio +* @page: page to add +* @len: vec entry length +* @offset: vec entry offset +* +* Attempt to add a page to the bio_vec maplist. This can fail for a +* number of reasons, such as the bio being full or target block +* device limitations. The target block device must allow bio's +* smaller than PAGE_SIZE, so it is always possible to add a single +* page to an empty bio. This should only be used by REQ_PC bios. +*/ +int bio_add_pc_page (request_queue_t *q,struct bio *bio,struct page *page, +unsigned int len,unsigned int offset) +{ +return __bio_add_page (q, bio, page, len, offset); +} + +/** * bio_add_page - attempt to add page to bio * @bio: destination bio * @page: page to add
@@ -1228,6 +1247,7 @@ EXPORT_SYMBOL(bio_clone);EXPORT_SYMBOL (bio_phys_segments);EXPORT_SYMBOL (bio_hw_segments);EXPORT_SYMBOL (bio_add_page); +EXPORT_SYMBOL (bio_add_pc_page);EXPORT_SYMBOL (bio_get_nr_vecs);EXPORT_SYMBOL (bio_map_user);EXPORT_SYMBOL (bio_unmap_user);
include/linux/bio.h +2 -0
@@ -292,6 +292,8 @@ extern struct bio *bio_clone(struct bioextern void bio_init (struct bio *);extern int bio_add_page (struct bio *,struct page *,unsigned int ,unsigned int ); +extern int bio_add_pc_page (struct request_queue *,struct bio *,struct page *, +unsigned int ,unsigned int );extern int bio_get_nr_vecs (struct block_device *);extern struct bio *bio_map_user (struct request_queue *,struct block_device *,unsigned long ,unsigned int ,int );
include/scsi/scsi_device.h +6 -0
@@ -274,6 +274,12 @@ extern int scsi_execute(struct scsi_deviextern 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 ), +gfp_t gfp);static inline unsigned int sdev_channel (struct scsi_device *sdev) {