Last 3 patches for bidi support
Subsystems (3)
cover Last 3 patches for bidi support
James hi.
Bidi patches just broke again, by a patch that fixes some to-be-dead code. (scsi: BUG_ON() impossible condition)
Could it not just be accepted into the tree now. It sat in -mm tree with no reports of breakage or complains. What are we waiting for? the way I see it there is nothing holding it back, it's not even dangerous anymore.
You need Arm's accessors patch from scsi-pending Russell King <[email protected]>
Please send an Acked-by for this patch
and the patch that removes the old esp drivers
(http://www.spinics.net/lists/linux-scsi/msg20914.html)
Christoph Hellwig <[email protected]>
David S. Miller <[email protected]>
Maciej W. Rozycki <[email protected]>
Please send an Ack-by or Recommended-by to the removal of these old esp drivers.
And the 3 patches (based on scsi-misc)
[1] tgt: Use scsi_init_io instead of scsi_alloc_sgtable Was Ack-by the maintainer of tgt. Please accept independent of the other 2.
[2] scsi: scsi_data_buffer
The move to scsi_data_buffer. From here on any unconverted driver will not compile.
[3] scsi: bidi support
Actual very simple really.
All parties involved, send your reservations if any NOW. Else James please put it in.
Andrew could they be included back into -mm tree?
Boaz
PATCH 1/1 tgt: Use scsi_init_io instead of scsi_alloc_sgtable
- If we export scsi_init_io()/scsi_release_buffers() instead of scsi_{alloc,free}_sgtable() from scsi_lib than tgt code is much more insulated from scsi_lib changes. As a bonus it will also gain bidi capability when it comes.
--- drivers/scsi/scsi_lib.c | 21 ++++++++++----------- drivers/scsi/scsi_tgt_lib.c | 29 +++++------------------------ include/scsi/scsi_cmnd.h | 4 ++-- 3 files changed, 17 insertions(+), 37 deletions(-)
drivers/scsi/scsi_lib.c +10 -11
@@ -739,7 +739,8 @@ static inline unsigned int scsi_sgtable_index(unsigned short nents)return index; } -struct scatterlist *scsi_alloc_sgtable (struct scsi_cmnd *cmd,gfp_t gfp_mask) +static struct scatterlist *scsi_alloc_sgtable (struct scsi_cmnd *cmd, +gfp_t gfp_mask) {struct scsi_host_sg_pool *sgp;struct scatterlist *sgl, *prev, *ret;
@@ -825,9 +826,7 @@ enomem:return NULL ; } -EXPORT_SYMBOL (scsi_alloc_sgtable); - -void scsi_free_sgtable (struct scsi_cmnd *cmd) +static void scsi_free_sgtable (struct scsi_cmnd *cmd) {struct scatterlist *sgl = cmd->request_buffer;struct scsi_host_sg_pool *sgp;
@@ -873,8 +872,6 @@ void scsi_free_sgtable(struct scsi_cmnd *cmd)mempool_free (sgl, sgp->pool); } -EXPORT_SYMBOL (scsi_free_sgtable); -/* * Function: scsi_release_buffers() *
@@ -892,7 +889,7 @@ EXPORT_SYMBOL(scsi_free_sgtable);* the scatter-gather table, and potentially any bounce * buffers. */ -static void scsi_release_buffers (struct scsi_cmnd *cmd) +void scsi_release_buffers (struct scsi_cmnd *cmd) {if (cmd->use_sg)scsi_free_sgtable (cmd);
@@ -904,6 +901,7 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd) cmd->request_buffer =NULL ; cmd->request_bufflen =0 ; } +EXPORT_SYMBOL (scsi_release_buffers);/* * Function: scsi_io_completion()
@@ -1105,7 +1103,7 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)* Returns: 0 on success * BLKPREP_DEFER if the failure is retryable */ -static int scsi_init_io (struct scsi_cmnd *cmd) +int scsi_init_io (struct scsi_cmnd *cmd,gfp_t gfp_mask) {struct request *req = cmd->request;int count;
@@ -1120,7 +1118,7 @@ static int scsi_init_io(struct scsi_cmnd *cmd)/* * If sg table allocation fails, requeue request later. */ - cmd->request_buffer =scsi_alloc_sgtable (cmd,GFP_ATOMIC ); + cmd->request_buffer =scsi_alloc_sgtable (cmd, gfp_mask);if (unlikely (!cmd->request_buffer)) {scsi_unprep_request (req);return BLKPREP_DEFER ;
@@ -1141,6 +1139,7 @@ static int scsi_init_io(struct scsi_cmnd *cmd) cmd->use_sg = count;return BLKPREP_OK ; } +EXPORT_SYMBOL (scsi_init_io);static struct scsi_cmnd *scsi_get_cmd_from_req (struct scsi_device *sdev,struct request *req)
@@ -1186,7 +1185,7 @@ int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req)BUG_ON (!req->nr_phys_segments); - ret =scsi_init_io (cmd); + ret =scsi_init_io (cmd,GFP_ATOMIC );if (unlikely (ret))return ret; }else {
@@ -1237,7 +1236,7 @@ int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req)if (unlikely (!cmd))return BLKPREP_DEFER ; -return scsi_init_io (cmd); +return scsi_init_io (cmd,GFP_ATOMIC ); }EXPORT_SYMBOL (scsi_setup_fs_cmnd);
drivers/scsi/scsi_tgt_lib.c +5 -24
@@ -331,8 +331,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)scsi_tgt_uspace_send_status (cmd, tcmd->itn_id, tcmd->tag); -if (scsi_sglist (cmd)) -scsi_free_sgtable (cmd); +scsi_release_buffers (cmd);queue_work (scsi_tgtd, &tcmd->work); }
@@ -353,26 +352,6 @@ static int scsi_tgt_transfer_response(struct scsi_cmnd *cmd)return 0 ; } -static int scsi_tgt_init_cmd (struct scsi_cmnd *cmd,gfp_t gfp_mask) -{ -struct request *rq = cmd->request; -int count; - - cmd->use_sg = rq->nr_phys_segments; - cmd->request_buffer =scsi_alloc_sgtable (cmd, gfp_mask); -if (!cmd->request_buffer) -return -ENOMEM ; - - cmd->request_bufflen = rq->data_len; - -dprintk ("cmd %p cnt %d %lu\n" , cmd,scsi_sg_count (cmd), -rq_data_dir (rq)); - count =blk_rq_map_sg (rq->q, rq,scsi_sglist (cmd)); -BUG_ON (count > cmd->use_sg); - cmd->use_sg = count; -return 0 ; -} -/* TODO: test this crap and replace bio_map_user with new interface maybe */ static int scsi_map_user_pages (struct scsi_tgt_cmd *tcmd,struct scsi_cmnd *cmd,unsigned long uaddr,unsigned int len,int rw)
@@ -398,9 +377,11 @@ static int scsi_map_user_pages(struct scsi_tgt_cmd *tcmd, struct scsi_cmnd *cmd, } tcmd->bio = rq->bio; - err =scsi_tgt_init_cmd (cmd,GFP_KERNEL ); -if (err) + err =scsi_init_io (cmd,GFP_KERNEL ); +if (err) { +scsi_release_buffers (cmd); goto unmap_rq; + }return 0 ;
include/scsi/scsi_cmnd.h +2 -2
@@ -128,8 +128,8 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, size_t *offset, size_t *len);extern void scsi_kunmap_atomic_sg (void *virt); -extern struct scatterlist *scsi_alloc_sgtable (struct scsi_cmnd *,gfp_t ); -extern void scsi_free_sgtable (struct scsi_cmnd *); +extern int scsi_init_io (struct scsi_cmnd *cmd,gfp_t gfp_mask); +extern void scsi_release_buffers (struct scsi_cmnd *cmd);extern int scsi_dma_map (struct scsi_cmnd *cmd);extern void scsi_dma_unmap (struct scsi_cmnd *cmd);
Signature · 1 line
1.5.3.3
James Bottomley
maintainerRe: [PATCH] tgt: Use scsi_init_io instead of scsi_alloc_sgtable
Quoted 7 lines · Boaz Harrosh
- If we export scsi_init_io()/scsi_release_buffers() instead of scsi_{alloc,free}_sgtable() from
scsi_libthan tgt code is much more insulated fromscsi_libchanges. As a bonus it will also gain bidi capability when it comes.Signed-off-by Boaz Harrosh <[email protected]>Acked-by FUJITA Tomonori <[email protected]>
I'm afraid the reversion of ->done removal broke the application of this yet again ... could you respin.
Thanks,
James
Re: [PATCH] tgt: Use scsi_init_io instead of scsi_alloc_sgtable
Quoted 9 lines · James Bottomley
Quoted 7 lines · Boaz Harrosh
- If we export scsi_init_io()/scsi_release_buffers() instead of scsi_{alloc,free}_sgtable() from
scsi_libthan tgt code is much more insulated fromscsi_libchanges. As a bonus it will also gain bidi capability when it comes.Signed-off-by Boaz Harrosh <[email protected]>Acked-by FUJITA Tomonori <[email protected]>
Quoted 7 lines
I'm afraid the reversion of ->done removal broke the application of this yet again ... could you respin.
Thanks,
James
It looks like the revert is to be reverted ;)
I have rebased, but should I wait a while to
see if they're needed?
Boaz
James Bottomley
maintainerRe: [PATCH] tgt: Use scsi_init_io instead of scsi_alloc_sgtable
Quoted 13 lines · Boaz Harrosh
Quoted 12 lines · James Bottomley
Quoted 7 lines · Boaz Harrosh
- If we export scsi_init_io()/scsi_release_buffers() instead of scsi_{alloc,free}_sgtable() from
scsi_libthan tgt code is much more insulated fromscsi_libchanges. As a bonus it will also gain bidi capability when it comes.Signed-off-by Boaz Harrosh <[email protected]>Acked-by FUJITA Tomonori <[email protected]>I'm afraid the reversion of ->done removal broke the application of this yet again ... could you respin.
Quoted 7 lines
Quoted 4 lines
Thanks,
James
It looks like the revert is to be reverted ;)
I have rebased, but should I wait a while to
see if they're needed?
Yes, let's just wait a while to see what the outcome is ...
James
PATCH 1/1 scsi: scsi_data_buffer
In reply to Boaz Harrosh In preparation for bidi we abstract all IO members of scsi_cmnd, that will need to duplicate, into a substructure.
- Group all IO members of scsi_cmnd into a scsi_data_buffer structure.
- Adjust accessors to new members.
- scsi_{alloc,free}_sgtable receive a scsi_data_buffer instead of scsi_cmnd. And work on it.
- Adjust scsi_init_io() and scsi_release_buffers() for above change.
- Fix other parts of scsi_lib/scsi.c to members migration. Use accessors where appropriate.
- fix Documentation about scsi_cmnd in scsi_host.h
- scsi_error.c
* Changed needed members of struct scsi_eh_save.
* Careful considerations in scsi_eh_prep/restore_cmnd.
- sd.c and sr.c
* sd and sr would adjust IO size to align on device's block size so code needs to change once we move to scsi_data_buff implementation.
* Convert code to use scsi_for_each_sg
* Use data accessors where appropriate.
- tgt: convert libsrp to use scsi_data_buffer
- isd200: This driver still bangs on scsi_cmnd IO members, so need changing
--- drivers/scsi/libsrp.c | 4 +- drivers/scsi/scsi.c | 2 +- drivers/scsi/scsi_error.c | 28 +++++---------- drivers/scsi/scsi_lib.c | 77 ++++++++++++++++-------------------------- drivers/scsi/sd.c | 4 +- drivers/scsi/sr.c | 25 +++++++------ drivers/usb/storage/isd200.c | 8 ++-- include/scsi/scsi_cmnd.h | 39 +++++++++++++-------- include/scsi/scsi_eh.h | 8 ++--- include/scsi/scsi_host.h | 4 +- 10 files changed, 91 insertions(+), 108 deletions(-)
drivers/scsi/libsrp.c +2 -2
@@ -426,8 +426,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, sc->SCp.ptr = info;memcpy (sc->cmnd, cmd->cdb,MAX_COMMAND_SIZE ); - sc->request_bufflen = len; - sc->request_buffer = (void *) (unsigned long ) addr; + sc->sdb.length = len; + sc->sdb.sglist = (void *) (unsigned long ) addr; sc->tag = tag; err =scsi_tgt_queue_command (sc, itn_id, (struct scsi_lun *)&cmd->lun, cmd->tag);
drivers/scsi/scsi.c +1 -1
@@ -712,7 +712,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)"Notifying upper driver of completion " "(result %x)\n", cmd->result)); - good_bytes = cmd->request_bufflen; + good_bytes =scsi_bufflen (cmd);if (cmd->request->cmd_type !=REQ_TYPE_BLOCK_PC ) { drv =scsi_cmd_to_driver (cmd);if (drv->done)
drivers/scsi/scsi_error.c +10 -18
@@ -617,29 +617,25 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, ses->cmd_len = scmd->cmd_len;memcpy (ses->cmnd, scmd->cmnd,sizeof (scmd->cmnd)); ses->data_direction = scmd->sc_data_direction; - ses->bufflen = scmd->request_bufflen; - ses->buffer = scmd->request_buffer; - ses->use_sg = scmd->use_sg; - ses->resid = scmd->resid; + ses->sdb = scmd->sdb; ses->result = scmd->result; +memset (&scmd->sdb,0 ,sizeof (scmd->sdb)); +if (sense_bytes) { - scmd->request_bufflen =min_t (unsigned, + scmd->sdb.length =min_t (unsigned,sizeof (scmd->sense_buffer), sense_bytes);sg_init_one (&ses->sense_sgl, scmd->sense_buffer, - scmd->request_bufflen); - scmd->request_buffer = &ses->sense_sgl; + scmd->sdb.length); + scmd->sdb.sglist = &ses->sense_sgl; scmd->sc_data_direction =DMA_FROM_DEVICE ; - scmd->use_sg =1 ; + scmd->sdb.sg_count =1 ;memset (scmd->cmnd,0 ,sizeof (scmd->cmnd)); scmd->cmnd[0 ] =REQUEST_SENSE ; - scmd->cmnd[4 ] = scmd->request_bufflen; + scmd->cmnd[4 ] = scmd->sdb.length; scmd->cmd_len =COMMAND_SIZE (scmd->cmnd[0 ]); }else { - scmd->request_buffer =NULL ; - scmd->request_bufflen =0 ; scmd->sc_data_direction =DMA_NONE ; - scmd->use_sg =0 ;if (cmnd) {memset (scmd->cmnd,0 ,sizeof (scmd->cmnd));memcpy (scmd->cmnd, cmnd, cmnd_size);
@@ -676,10 +672,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) scmd->cmd_len = ses->cmd_len;memcpy (scmd->cmnd, ses->cmnd,sizeof (scmd->cmnd)); scmd->sc_data_direction = ses->data_direction; - scmd->request_bufflen = ses->bufflen; - scmd->request_buffer = ses->buffer; - scmd->use_sg = ses->use_sg; - scmd->resid = ses->resid; + scmd->sdb = ses->sdb; scmd->result = ses->result; }EXPORT_SYMBOL (scsi_eh_restore_cmnd);
@@ -1700,8 +1693,7 @@ scsi_reset_provider(struct scsi_device *dev, int flag)memset (&scmd->cmnd,'\0' ,sizeof (scmd->cmnd)); scmd->scsi_done = scsi_reset_provider_done_command; - scmd->request_buffer =NULL ; - scmd->request_bufflen =0 ; +memset (&scmd->sdb,0 ,sizeof (scmd->sdb)); scmd->cmd_len =0 ;
drivers/scsi/scsi_lib.c +29 -48
186 lines not on this page · raw message
drivers/scsi/sd.c +2 -2
@@ -507,7 +507,7 @@ static int sd_prep_fn(struct request_queue *q, struct request *rq) SCpnt->cmnd[4 ] = (unsigned char ) this_count; SCpnt->cmnd[5 ] =0 ; } - SCpnt->request_bufflen = this_count * sdp->sector_size; + SCpnt->sdb.length = this_count * sdp->sector_size;/* * We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -914,7 +914,7 @@ static struct block_device_operations sd_fops = {static int sd_done (struct scsi_cmnd *SCpnt) {int result = SCpnt->result; -unsigned int xfer_size = SCpnt->request_bufflen; +unsigned int xfer_size =scsi_bufflen (SCpnt);unsigned int good_bytes = result ?0 : xfer_size;u64 start_lba = SCpnt->request->sector;u64 bad_lba;
drivers/scsi/sr.c +13 -12
@@ -233,7 +233,7 @@ out:static int sr_done (struct scsi_cmnd *SCpnt) {int result = SCpnt->result; -int this_count = SCpnt->request_bufflen; +int this_count =scsi_bufflen (SCpnt);int good_bytes = (result ==0 ? this_count :0 );int block_sectors =0 ;long error_sector;
@@ -378,17 +378,18 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq) } { -struct scatterlist *sg = SCpnt->request_buffer; -int i, size =0 ; -for (i =0 ; i < SCpnt->use_sg; i++) - size += sg[i].length; +struct scatterlist *sg; +int i, size =0 , sg_count =scsi_sg_count (SCpnt); -if (size != SCpnt->request_bufflen && SCpnt->use_sg) { +scsi_for_each_sg (SCpnt, sg, sg_count, i) + size += sg->length; + +if (size !=scsi_bufflen (SCpnt)) {scmd_printk (KERN_ERR , SCpnt,"mismatch count %d, bytes %d\n" , - size, SCpnt->request_bufflen); -if (SCpnt->request_bufflen > size) - SCpnt->request_bufflen = size; + size,scsi_bufflen (SCpnt)); +if (scsi_bufflen (SCpnt) > size) + SCpnt->sdb.length = size; } }
@@ -396,12 +397,12 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)* request doesn't start on hw block boundary, add scatter pads */ if (((unsigned int )rq->sector % (s_size >>9 )) || - (SCpnt->request_bufflen % s_size)) { + (scsi_bufflen (SCpnt) % s_size)) {scmd_printk (KERN_NOTICE , SCpnt,"unaligned transfer\n" ); goto out; } - this_count = (SCpnt->request_bufflen >>9 ) / (s_size >>9 ); + this_count = (scsi_bufflen (SCpnt) >>9 ) / (s_size >>9 ); SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n",
@@ -415,7 +416,7 @@ static int sr_prep_fn(struct request_queue *q, struct request *rq)if (this_count >0xffff ) { this_count =0xffff ; - SCpnt->request_bufflen = this_count * s_size; + SCpnt->sdb.length = this_count * s_size; } SCpnt->cmnd[2 ] = (unsigned char ) (block >>24 ) &0xff ;
drivers/usb/storage/isd200.c +4 -4
@@ -415,14 +415,14 @@ static void isd200_set_srb(struct isd200_info *info,sg_init_one (&info->sg, buff, bufflen); srb->sc_data_direction = dir; - srb->request_buffer = buff ? &info->sg :NULL ; - srb->request_bufflen = bufflen; - srb->use_sg = buff ?1 :0 ; + srb->sdb.sglist = buff ? &info->sg :NULL ; + srb->sdb.length = bufflen; + srb->sdb.sg_count = buff ?1 :0 ; }static void isd200_srb_set_bufflen (struct scsi_cmnd *srb,unsigned bufflen) { - srb->request_bufflen = bufflen; + srb->sdb.length = bufflen; }
include/scsi/scsi_cmnd.h +25 -14
@@ -12,6 +12,13 @@ struct scatterlist;struct Scsi_Host ;struct scsi_device ; +struct scsi_data_buffer { +struct scatterlist *sglist; +unsigned length; +int resid; +unsigned short sg_count; +unsigned short alloc_sg_count;/* private to scsi_lib */ +};/* embedded in scsi_cmnd */ struct scsi_pointer {
@@ -62,15 +69,10 @@ struct scsi_cmnd {/* These elements define the operation we are about to perform */ #define MAX_COMMAND_SIZE 16unsigned char cmnd[MAX_COMMAND_SIZE ]; -unsigned request_bufflen;/* Actual request size */ struct timer_list eh_timeout;/* Used to time out the command. */ -void *request_buffer;/* Actual requested buffer */ /* These elements define the operation we ultimately want to perform */ -unsigned short use_sg;/* Number of pieces of scatter-gather */ -unsigned short __use_sg; -unsigned underflow;/* Return error if less than this amount is transferred */
@@ -80,10 +82,6 @@ struct scsi_cmnd {reconnects. Probably == sector size */ -int resid;/* Number of bytes requested to be -transferred less actual number -transferred (0 if not supported) */ -struct request *request;/* The command we are working on */
@@ -114,6 +112,8 @@ struct scsi_cmnd {int result;/* Status code from lower level driver */ unsigned char tag;/* SCSI-II queued command tag */ + +struct scsi_data_buffer sdb; };extern struct scsi_cmnd *scsi_get_command (struct scsi_device *,gfp_t );
@@ -134,18 +134,29 @@ extern void scsi_release_buffers(struct scsi_cmnd *cmd);extern int scsi_dma_map (struct scsi_cmnd *cmd);extern void scsi_dma_unmap (struct scsi_cmnd *cmd); -#define scsi_sg_count (cmd) ((cmd)->use_sg) -#define scsi_sglist (cmd) ((struct scatterlist *)(cmd)->request_buffer) -#define scsi_bufflen (cmd) ((cmd)->request_bufflen) +static inline unsigned scsi_sg_count (struct scsi_cmnd *cmd) +{ +return cmd->sdb.sg_count; +} + +static inline struct scatterlist *scsi_sglist (struct scsi_cmnd *cmd) +{ +return cmd->sdb.sglist; +} + +static inline unsigned scsi_bufflen (struct scsi_cmnd *cmd) +{ +return cmd->sdb.length; +}static inline void scsi_set_resid (struct scsi_cmnd *cmd,int resid) { - cmd->resid = resid; + cmd->sdb.resid = resid; }static inline int scsi_get_resid (struct scsi_cmnd *cmd) { -return cmd->resid; +return cmd->sdb.resid; }#define scsi_for_each_sg (cmd, sg, nseg, __i) \
include/scsi/scsi_eh.h +3 -5
@@ -68,16 +68,14 @@ extern int scsi_get_sense_info_fld(const u8 * sense_buffer, int sb_len,extern int scsi_reset_provider (struct scsi_device *,int );struct scsi_eh_save { +/* saved state */ int result;enum dma_data_direction data_direction;unsigned char cmd_len;unsigned char cmnd[MAX_COMMAND_SIZE ]; +struct scsi_data_buffer sdb; -void *buffer; -unsigned bufflen; -unsigned short use_sg; -int resid; - +/* new command support */ struct scatterlist sense_sgl; };
include/scsi/scsi_host.h +2 -2
@@ -136,9 +136,9 @@ struct scsi_host_template {* the done callback is invoked. * * This is called to inform the LLD to transfer -* cmd->request_bufflen bytes. The cmd->use_sg speciefies the +* scsi_bufflen(cmd) bytes. scsi_sg_count(cmd) speciefies the * number of scatterlist entried in the command and -* cmd->request_buffer contains the scatterlist. +* scsi_sglist(cmd) returns the scatterlist. * * return values: see queuecommand *
Signature · 1 line
1.5.3.3
PATCH 1/1 scsi: bidi support
In reply to Boaz Harrosh At the block level bidi request uses req->next_rq pointer for a second bidi_read request.
At Scsi-midlayer a second scsi_data_buffer structure is used for the bidi_read part. This bidi scsi_data_buffer is put on request->next_rq->special. Struct scsi_cmnd is not changed.
- Define scsi_bidi_cmnd() to return true if it is a bidi request and a second sgtable was allocated.
- Define scsi_in()/scsi_out() to return the in or out scsi_data_buffer from this command This API is to isolate users from the mechanics of bidi.
- Define scsi_end_bidi_request() to do what scsi_end_request() does but for a bidi request. This is necessary because bidi commands are a bit tricky here. (See comments in body)
- scsi_release_buffers() will also release the bidi_read scsi_data_buffer
- scsi_io_completion() on bidi commands will now call scsi_end_bidi_request() and return.
- The previous work done in scsi_init_io() is now done in a new scsi_init_sgtable() (which is 99% identical to old scsi_init_io()) The new scsi_init_io() will call the above twice if needed also for the bidi_read command. Only at this point is a command bidi.
- In scsi_error.c at scsi_eh_prep/restore_cmnd() make sure bidi-lld is not confused by a get-sense command that looks like bidi. This is done by puting NULL at request->next_rq, and restoring.
--- drivers/scsi/scsi_error.c | 3 + drivers/scsi/scsi_lib.c | 144 ++++++++++++++++++++++++++++++++++++--------- include/scsi/scsi_cmnd.h | 23 +++++++- include/scsi/scsi_eh.h | 1 + 4 files changed, 141 insertions(+), 30 deletions(-)
drivers/scsi/scsi_error.c +3 -0
@@ -618,9 +618,11 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses,memcpy (ses->cmnd, scmd->cmnd,sizeof (scmd->cmnd)); ses->data_direction = scmd->sc_data_direction; ses->sdb = scmd->sdb; + ses->next_rq = scmd->request->next_rq; ses->result = scmd->result;memset (&scmd->sdb,0 ,sizeof (scmd->sdb)); + scmd->request->next_rq =NULL ;if (sense_bytes) { scmd->sdb.length = min_t(unsigned,
@@ -673,6 +675,7 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses)memcpy (scmd->cmnd, ses->cmnd,sizeof (scmd->cmnd)); scmd->sc_data_direction = ses->data_direction; scmd->sdb = ses->sdb; + scmd->request->next_rq = ses->next_rq; scmd->result = ses->result; }EXPORT_SYMBOL (scsi_eh_restore_cmnd);
drivers/scsi/scsi_lib.c +115 -29
208 lines not on this page · raw message
include/scsi/scsi_cmnd.h +22 -1
@@ -2,12 +2,12 @@#define _SCSI_SCSI_CMND_H#include <linux/dma-mapping.h> +#include <linux/blkdev.h> #include <linux/list.h> #include <linux/types.h> #include <linux/timer.h> #include <linux/scatterlist.h> -struct request ;struct scatterlist ;struct Scsi_Host ;struct scsi_device ;
@@ -162,4 +162,25 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd)#define scsi_for_each_sg (cmd, sg, nseg, __i) \ for_each_sg(scsi_sglist(cmd), sg, nseg, __i) +static inline int scsi_bidi_cmnd (struct scsi_cmnd *cmd) +{ +return blk_bidi_rq (cmd->request) && + (cmd->request->next_rq->special !=NULL ); +} + +static inline struct scsi_data_buffer *scsi_in (struct scsi_cmnd *cmd) +{ +WARN_ON ((cmd->sc_data_direction !=DMA_FROM_DEVICE ) && + !scsi_bidi_cmnd (cmd)); +return scsi_bidi_cmnd (cmd) ? + cmd->request->next_rq->special : &cmd->sdb; +} + +static inline struct scsi_data_buffer *scsi_out (struct scsi_cmnd *cmd) +{ +WARN_ON ((cmd->sc_data_direction !=DMA_TO_DEVICE ) && + !scsi_bidi_cmnd (cmd)); +return &cmd->sdb; +} +#endif /* _SCSI_SCSI_CMND_H */
include/scsi/scsi_eh.h +1 -0
@@ -74,6 +74,7 @@ struct scsi_eh_save {unsigned char cmd_len;unsigned char cmnd[MAX_COMMAND_SIZE ];struct scsi_data_buffer sdb; +struct request *next_rq;/* new command support */ struct scatterlist sense_sgl;
Signature · 1 line
1.5.3.3