On 30/10/18 09:45, Christoph Hellwig wrote:
> On Mon, Oct 29, 2018 at 02:42:12PM -0600, Jens Axboe wrote:
>> LGTM, for both:
> 
> I also have this one on top as requested by Martin.  The core block
> bidi support is unfortunately also used by bsg-lib, although it is
> not anywhere near as invasive.  But that is another argument for
> looking into moving bsg-lib away from using block queues..
> 

BUT this patch is very very wrong.

Totally apart from T10-OSD and its use in the field. Support for scsi BIDI
commands is not exclusive to T10-OSD at all. Even the simple scsi-array
command-set has BIDI operations defined. for example the write-return-xor
and so on.

Also some private administrative CDBs of some vendor devices uses SCSI-BIDI.
So this patch just broke some drivers. (User-mode apps use bsg pass through)

Also you might (try hard and) remove all usage of scsi-bidi as an initiator
from the Linux Kernel. But what about target mode. As a target we have supported
on the wire bidi protocols like write-return-xor and others for a long time.
Are you willing to silently break all these setups in the field on the next 
update?
Are you so sure these are never used?

PLEASE, I beg of you guys. Do not remove SCSI-BIDI. It is a cry of generations.

And I think by the rules of Linus, as far as target mode. You are not allowed
to break users in this way.

Thanks
Boaz

> ---
>>From d6dd4f32798edd425a4df72f6125dba03e19d8c7 Mon Sep 17 00:00:00 2001
> From: Christoph Hellwig <[email protected]>
> Date: Sat, 27 Oct 2018 15:49:13 +0200
> Subject: scsi: remove bidirectional command support
> 
> Signed-off-by: Christoph Hellwig <[email protected]>
> ---
>  drivers/scsi/cxgbi/libcxgbi.c      | 13 ++---
>  drivers/scsi/iscsi_tcp.c           |  9 +---
>  drivers/scsi/libiscsi.c            | 64 +++---------------------
>  drivers/scsi/libiscsi_tcp.c        |  8 +--
>  drivers/scsi/scsi_debug.c          | 51 ++++---------------
>  drivers/scsi/scsi_error.c          |  3 --
>  drivers/scsi/scsi_lib.c            | 80 ++----------------------------
>  drivers/scsi/virtio_scsi.c         | 14 ++----
>  drivers/target/loopback/tcm_loop.c | 15 ------
>  drivers/usb/storage/uas.c          | 11 +---
>  include/scsi/scsi_cmnd.h           | 19 +------
>  include/scsi/scsi_eh.h             |  1 -
>  12 files changed, 35 insertions(+), 253 deletions(-)
> 
> diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c
> index 75f876409fb9..4466ae5c9a74 100644
> --- a/drivers/scsi/cxgbi/libcxgbi.c
> +++ b/drivers/scsi/cxgbi/libcxgbi.c
> @@ -1211,7 +1211,7 @@ scmd_get_params(struct scsi_cmnd *sc, struct 
> scatterlist **sgl,
>               unsigned int *sgcnt, unsigned int *dlen,
>               unsigned int prot)
>  {
> -     struct scsi_data_buffer *sdb = prot ? scsi_prot(sc) : scsi_out(sc);
> +     struct scsi_data_buffer *sdb = prot ? scsi_prot(sc) : &sc->sdb;
>  
>       *sgl = sdb->table.sgl;
>       *sgcnt = sdb->table.nents;
> @@ -1427,8 +1427,7 @@ static void task_release_itt(struct iscsi_task *task, 
> itt_t hdr_itt)
>       log_debug(1 << CXGBI_DBG_DDP,
>                 "cdev 0x%p, task 0x%p, release tag 0x%x.\n",
>                 cdev, task, tag);
> -     if (sc &&
> -         (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE) &&
> +     if (sc && sc->sc_data_direction == DMA_FROM_DEVICE &&
>           cxgbi_ppm_is_ddp_tag(ppm, tag)) {
>               struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
>               struct cxgbi_task_tag_info *ttinfo = &tdata->ttinfo;
> @@ -1460,9 +1459,7 @@ static int task_reserve_itt(struct iscsi_task *task, 
> itt_t *hdr_itt)
>       u32 tag = 0;
>       int err = -EINVAL;
>  
> -     if (sc &&
> -         (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_FROM_DEVICE)
> -     ) {
> +     if (sc && sc->sc_data_direction == DMA_FROM_DEVICE) {
>               struct cxgbi_task_data *tdata = iscsi_task_cxgbi_data(task);
>               struct cxgbi_task_tag_info *ttinfo = &tdata->ttinfo;
>  
> @@ -1896,7 +1893,7 @@ int cxgbi_conn_alloc_pdu(struct iscsi_task *task, u8 
> opcode)
>       if (SKB_MAX_HEAD(cdev->skb_tx_rsvd) > (512 * MAX_SKB_FRAGS) &&
>           (opcode == ISCSI_OP_SCSI_DATA_OUT ||
>            (opcode == ISCSI_OP_SCSI_CMD &&
> -           (scsi_bidi_cmnd(sc) || sc->sc_data_direction == DMA_TO_DEVICE))))
> +           sc->sc_data_direction == DMA_TO_DEVICE)))
>               /* data could goes into skb head */
>               headroom += min_t(unsigned int,
>                               SKB_MAX_HEAD(cdev->skb_tx_rsvd),
> @@ -1971,7 +1968,7 @@ int cxgbi_conn_init_pdu(struct iscsi_task *task, 
> unsigned int offset,
>               return 0;
>  
>       if (task->sc) {
> -             struct scsi_data_buffer *sdb = scsi_out(task->sc);
> +             struct scsi_data_buffer *sdb = &task->sc->sdb;
>               struct scatterlist *sg = NULL;
>               int err;
>  
> diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c
> index 23354f206533..a78b46bb2b71 100644
> --- a/drivers/scsi/iscsi_tcp.c
> +++ b/drivers/scsi/iscsi_tcp.c
> @@ -514,7 +514,7 @@ static int iscsi_sw_tcp_pdu_init(struct iscsi_task *task,
>       if (!task->sc)
>               iscsi_sw_tcp_send_linear_data_prep(conn, task->data, count);
>       else {
> -             struct scsi_data_buffer *sdb = scsi_out(task->sc);
> +             struct scsi_data_buffer *sdb = &task->sc->sdb;
>  
>               err = iscsi_sw_tcp_send_data_prep(conn, sdb->table.sgl,
>                                                 sdb->table.nents, offset,
> @@ -948,12 +948,6 @@ static umode_t iscsi_sw_tcp_attr_is_visible(int 
> param_type, int param)
>       return 0;
>  }
>  
> -static int iscsi_sw_tcp_slave_alloc(struct scsi_device *sdev)
> -{
> -     blk_queue_flag_set(QUEUE_FLAG_BIDI, sdev->request_queue);
> -     return 0;
> -}
> -
>  static int iscsi_sw_tcp_slave_configure(struct scsi_device *sdev)
>  {
>       struct iscsi_sw_tcp_host *tcp_sw_host = iscsi_host_priv(sdev->host);
> @@ -981,7 +975,6 @@ static struct scsi_host_template iscsi_sw_tcp_sht = {
>       .eh_device_reset_handler= iscsi_eh_device_reset,
>       .eh_target_reset_handler = iscsi_eh_recover_target,
>       .use_clustering         = DISABLE_CLUSTERING,
> -     .slave_alloc            = iscsi_sw_tcp_slave_alloc,
>       .slave_configure        = iscsi_sw_tcp_slave_configure,
>       .target_alloc           = iscsi_target_alloc,
>       .proc_name              = "iscsi_tcp",
> diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
> index 93c66ebad907..a6dec983c30e 100644
> --- a/drivers/scsi/libiscsi.c
> +++ b/drivers/scsi/libiscsi.c
> @@ -218,32 +218,6 @@ static int iscsi_prep_ecdb_ahs(struct iscsi_task *task)
>       return 0;
>  }
>  
> -static int iscsi_prep_bidi_ahs(struct iscsi_task *task)
> -{
> -     struct scsi_cmnd *sc = task->sc;
> -     struct iscsi_rlength_ahdr *rlen_ahdr;
> -     int rc;
> -
> -     rlen_ahdr = iscsi_next_hdr(task);
> -     rc = iscsi_add_hdr(task, sizeof(*rlen_ahdr));
> -     if (rc)
> -             return rc;
> -
> -     rlen_ahdr->ahslength =
> -             cpu_to_be16(sizeof(rlen_ahdr->read_length) +
> -                                               sizeof(rlen_ahdr->reserved));
> -     rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
> -     rlen_ahdr->reserved = 0;
> -     rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
> -
> -     ISCSI_DBG_SESSION(task->conn->session,
> -                       "bidi-in rlen_ahdr->read_length(%d) "
> -                       "rlen_ahdr->ahslength(%d)\n",
> -                       be32_to_cpu(rlen_ahdr->read_length),
> -                       be16_to_cpu(rlen_ahdr->ahslength));
> -     return 0;
> -}
> -
>  /**
>   * iscsi_check_tmf_restrictions - check if a task is affected by TMF
>   * @task: iscsi task
> @@ -382,13 +356,6 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task 
> *task)
>       memcpy(hdr->cdb, sc->cmnd, cmd_len);
>  
>       task->imm_count = 0;
> -     if (scsi_bidi_cmnd(sc)) {
> -             hdr->flags |= ISCSI_FLAG_CMD_READ;
> -             rc = iscsi_prep_bidi_ahs(task);
> -             if (rc)
> -                     return rc;
> -     }
> -
>       if (scsi_get_prot_op(sc) != SCSI_PROT_NORMAL)
>               task->protected = true;
>  
> @@ -463,12 +430,10 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task 
> *task)
>  
>       conn->scsicmd_pdus_cnt++;
>       ISCSI_DBG_SESSION(session, "iscsi prep [%s cid %d sc %p cdb 0x%x "
> -                       "itt 0x%x len %d bidi_len %d cmdsn %d win %d]\n",
> -                       scsi_bidi_cmnd(sc) ? "bidirectional" :
> +                       "itt 0x%x len %d cmdsn %d win %d]\n",
>                         sc->sc_data_direction == DMA_TO_DEVICE ?
>                         "write" : "read", conn->id, sc, sc->cmnd[0],
>                         task->itt, transfer_length,
> -                       scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
>                         session->cmdsn,
>                         session->max_cmdsn - session->exp_cmdsn + 1);
>       return 0;
> @@ -637,12 +602,7 @@ static void fail_scsi_task(struct iscsi_task *task, int 
> err)
>               state = ISCSI_TASK_ABRT_TMF;
>  
>       sc->result = err << 16;
> -     if (!scsi_bidi_cmnd(sc))
> -             scsi_set_resid(sc, scsi_bufflen(sc));
> -     else {
> -             scsi_out(sc)->resid = scsi_out(sc)->length;
> -             scsi_in(sc)->resid = scsi_in(sc)->length;
> -     }
> +     scsi_set_resid(sc, scsi_bufflen(sc));
>  
>       /* regular RX path uses back_lock */
>       spin_lock_bh(&conn->session->back_lock);
> @@ -897,14 +857,7 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, 
> struct iscsi_hdr *hdr,
>  
>       if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
>                          ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
> -             int res_count = be32_to_cpu(rhdr->bi_residual_count);
> -
> -             if (scsi_bidi_cmnd(sc) && res_count > 0 &&
> -                             (rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
> -                              res_count <= scsi_in(sc)->length))
> -                     scsi_in(sc)->resid = res_count;
> -             else
> -                     sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
> +             sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
>       }
>  
>       if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
> @@ -951,8 +904,8 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct 
> iscsi_hdr *hdr,
>  
>               if (res_count > 0 &&
>                   (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
> -                  res_count <= scsi_in(sc)->length))
> -                     scsi_in(sc)->resid = res_count;
> +                  res_count <= sc->sdb.length))
> +                     sc->sdb.resid = res_count;
>               else
>                       sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
>       }
> @@ -1794,12 +1747,7 @@ int iscsi_queuecommand(struct Scsi_Host *host, struct 
> scsi_cmnd *sc)
>       spin_unlock_bh(&session->frwd_lock);
>       ISCSI_DBG_SESSION(session, "iscsi: cmd 0x%x is not queued (%d)\n",
>                         sc->cmnd[0], reason);
> -     if (!scsi_bidi_cmnd(sc))
> -             scsi_set_resid(sc, scsi_bufflen(sc));
> -     else {
> -             scsi_out(sc)->resid = scsi_out(sc)->length;
> -             scsi_in(sc)->resid = scsi_in(sc)->length;
> -     }
> +     scsi_set_resid(sc, scsi_bufflen(sc));
>       sc->scsi_done(sc);
>       return 0;
>  }
> diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c
> index 4fcb9e65be57..1ec8332df515 100644
> --- a/drivers/scsi/libiscsi_tcp.c
> +++ b/drivers/scsi/libiscsi_tcp.c
> @@ -491,7 +491,7 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, 
> struct iscsi_task *task)
>       struct iscsi_tcp_task *tcp_task = task->dd_data;
>       struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)tcp_conn->in.hdr;
>       int datasn = be32_to_cpu(rhdr->datasn);
> -     unsigned total_in_length = scsi_in(task->sc)->length;
> +     unsigned total_in_length = task->sc->sdb.length;
>  
>       /*
>        * lib iscsi will update this in the completion handling if there
> @@ -576,11 +576,11 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, 
> struct iscsi_task *task)
>                             data_length, session->max_burst);
>  
>       data_offset = be32_to_cpu(rhdr->data_offset);
> -     if (data_offset + data_length > scsi_out(task->sc)->length) {
> +     if (data_offset + data_length > task->sc->sdb.length) {
>               iscsi_conn_printk(KERN_ERR, conn,
>                                 "invalid R2T with data len %u at offset %u "
>                                 "and total length %d\n", data_length,
> -                               data_offset, scsi_out(task->sc)->length);
> +                               data_offset, task->sc->sdb.length);
>               return ISCSI_ERR_DATALEN;
>       }
>  
> @@ -692,7 +692,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct 
> iscsi_hdr *hdr)
>               if (tcp_conn->in.datalen) {
>                       struct iscsi_tcp_task *tcp_task = task->dd_data;
>                       struct ahash_request *rx_hash = NULL;
> -                     struct scsi_data_buffer *sdb = scsi_in(task->sc);
> +                     struct scsi_data_buffer *sdb = &task->sc->sdb;
>  
>                       /*
>                        * Setup copy of Data-In into the struct scsi_cmnd
> diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
> index 60bcc6df97a9..98b212ec6240 100644
> --- a/drivers/scsi/scsi_debug.c
> +++ b/drivers/scsi/scsi_debug.c
> @@ -430,7 +430,6 @@ static int resp_rsup_opcodes(struct scsi_cmnd *, struct 
> sdebug_dev_info *);
>  static int resp_rsup_tmfs(struct scsi_cmnd *, struct sdebug_dev_info *);
>  static int resp_write_same_10(struct scsi_cmnd *, struct sdebug_dev_info *);
>  static int resp_write_same_16(struct scsi_cmnd *, struct sdebug_dev_info *);
> -static int resp_xdwriteread_10(struct scsi_cmnd *, struct sdebug_dev_info *);
>  static int resp_comp_write(struct scsi_cmnd *, struct sdebug_dev_info *);
>  static int resp_write_buffer(struct scsi_cmnd *, struct sdebug_dev_info *);
>  static int resp_sync_cache(struct scsi_cmnd *, struct sdebug_dev_info *);
> @@ -600,9 +599,6 @@ static const struct opcode_info_t 
> opcode_info_arr[SDEB_I_LAST_ELEMENT + 1] = {
>       {0, 0x42, 0, F_D_OUT | FF_MEDIA_IO, resp_unmap, NULL, /* UNMAP */
>           {10,  0x1, 0, 0, 0, 0, 0x3f, 0xff, 0xff, 0xc7, 0, 0, 0, 0, 0, 0} },
>  /* 25 */
> -     {0, 0x53, 0, F_D_IN | F_D_OUT | FF_MEDIA_IO, resp_xdwriteread_10,
> -         NULL, {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xc7,
> -                0, 0, 0, 0, 0, 0} },         /* XDWRITEREAD(10) */
>       {0, 0x3b, 0, F_D_OUT_MAYBE, resp_write_buffer, NULL,
>           {10,  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc7, 0, 0,
>            0, 0, 0, 0} },                     /* WRITE_BUFFER */
> @@ -1010,11 +1006,11 @@ static int fill_from_dev_buffer(struct scsi_cmnd 
> *scp, unsigned char *arr,
>                               int arr_len)
>  {
>       int act_len;
> -     struct scsi_data_buffer *sdb = scsi_in(scp);
> +     struct scsi_data_buffer *sdb = &scp->sdb;
>  
>       if (!sdb->length)
>               return 0;
> -     if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
> +     if (scp->sc_data_direction != DMA_FROM_DEVICE)
>               return DID_ERROR << 16;
>  
>       act_len = sg_copy_from_buffer(sdb->table.sgl, sdb->table.nents,
> @@ -1033,12 +1029,12 @@ static int p_fill_from_dev_buffer(struct scsi_cmnd 
> *scp, const void *arr,
>                                 int arr_len, unsigned int off_dst)
>  {
>       int act_len, n;
> -     struct scsi_data_buffer *sdb = scsi_in(scp);
> +     struct scsi_data_buffer *sdb = &scp->sdb;
>       off_t skip = off_dst;
>  
>       if (sdb->length <= off_dst)
>               return 0;
> -     if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_FROM_DEVICE))
> +     if (scp->sc_data_direction != DMA_FROM_DEVICE)
>               return DID_ERROR << 16;
>  
>       act_len = sg_pcopy_from_buffer(sdb->table.sgl, sdb->table.nents,
> @@ -1058,7 +1054,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *scp, 
> unsigned char *arr,
>  {
>       if (!scsi_bufflen(scp))
>               return 0;
> -     if (!(scsi_bidi_cmnd(scp) || scp->sc_data_direction == DMA_TO_DEVICE))
> +     if (scp->sc_data_direction != DMA_TO_DEVICE)
>               return -1;
>  
>       return scsi_sg_copy_to_buffer(scp, arr, arr_len);
> @@ -2477,21 +2473,19 @@ static int do_device_access(struct scsi_cmnd *scmd, 
> u32 sg_skip, u64 lba,
>  {
>       int ret;
>       u64 block, rest = 0;
> -     struct scsi_data_buffer *sdb;
> +     struct scsi_data_buffer *sdb = &scmd->sdb;
>       enum dma_data_direction dir;
>  
>       if (do_write) {
> -             sdb = scsi_out(scmd);
>               dir = DMA_TO_DEVICE;
>               write_since_sync = true;
>       } else {
> -             sdb = scsi_in(scmd);
>               dir = DMA_FROM_DEVICE;
>       }
>  
>       if (!sdb->length)
>               return 0;
> -     if (!(scsi_bidi_cmnd(scmd) || scmd->sc_data_direction == dir))
> +     if (scmd->sc_data_direction != dir)
>               return -1;
>  
>       block = do_div(lba, sdebug_store_sectors);
> @@ -2774,7 +2768,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct 
> sdebug_dev_info *devip)
>       if (unlikely(ret == -1))
>               return DID_ERROR << 16;
>  
> -     scsi_in(scp)->resid = scsi_bufflen(scp) - ret;
> +     scp->sdb.resid = scsi_bufflen(scp) - ret;
>  
>       if (unlikely(sqcp)) {
>               if (sqcp->inj_recovered) {
> @@ -3724,7 +3718,7 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, 
> unsigned long long lba,
>       int j;
>       unsigned char *kaddr, *buf;
>       unsigned int offset;
> -     struct scsi_data_buffer *sdb = scsi_in(scp);
> +     struct scsi_data_buffer *sdb = &scp->sdb;
>       struct sg_mapping_iter miter;
>  
>       /* better not to use temporary buffer. */
> @@ -3754,32 +3748,6 @@ static int resp_xdwriteread(struct scsi_cmnd *scp, 
> unsigned long long lba,
>       return 0;
>  }
>  
> -static int resp_xdwriteread_10(struct scsi_cmnd *scp,
> -                            struct sdebug_dev_info *devip)
> -{
> -     u8 *cmd = scp->cmnd;
> -     u64 lba;
> -     u32 num;
> -     int errsts;
> -
> -     if (!scsi_bidi_cmnd(scp)) {
> -             mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC,
> -                             INSUFF_RES_ASCQ);
> -             return check_condition_result;
> -     }
> -     errsts = resp_read_dt0(scp, devip);
> -     if (errsts)
> -             return errsts;
> -     if (!(cmd[1] & 0x4)) {          /* DISABLE_WRITE is not set */
> -             errsts = resp_write_dt0(scp, devip);
> -             if (errsts)
> -                     return errsts;
> -     }
> -     lba = get_unaligned_be32(cmd + 2);
> -     num = get_unaligned_be16(cmd + 7);
> -     return resp_xdwriteread(scp, lba, num, devip);
> -}
> -
>  static struct sdebug_queue *get_queue(struct scsi_cmnd *cmnd)
>  {
>       u32 tag = blk_mq_unique_tag(cmnd->request);
> @@ -3953,7 +3921,6 @@ static int scsi_debug_slave_alloc(struct scsi_device 
> *sdp)
>       if (sdebug_verbose)
>               pr_info("slave_alloc <%u %u %u %llu>\n",
>                      sdp->host->host_no, sdp->channel, sdp->id, sdp->lun);
> -     blk_queue_flag_set(QUEUE_FLAG_BIDI, sdp->request_queue);
>       return 0;
>  }
>  
> diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
> index c736d61b1648..42dd49961ca5 100644
> --- a/drivers/scsi/scsi_error.c
> +++ b/drivers/scsi/scsi_error.c
> @@ -965,7 +965,6 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct 
> scsi_eh_save *ses,
>       ses->cmnd = scmd->cmnd;
>       ses->data_direction = scmd->sc_data_direction;
>       ses->sdb = scmd->sdb;
> -     ses->next_rq = scmd->request->next_rq;
>       ses->result = scmd->result;
>       ses->underflow = scmd->underflow;
>       ses->prot_op = scmd->prot_op;
> @@ -976,7 +975,6 @@ void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct 
> scsi_eh_save *ses,
>       scmd->cmnd = ses->eh_cmnd;
>       memset(scmd->cmnd, 0, BLK_MAX_CDB);
>       memset(&scmd->sdb, 0, sizeof(scmd->sdb));
> -     scmd->request->next_rq = NULL;
>       scmd->result = 0;
>  
>       if (sense_bytes) {
> @@ -1029,7 +1027,6 @@ void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, 
> struct scsi_eh_save *ses)
>       scmd->cmnd = ses->cmnd;
>       scmd->sc_data_direction = ses->data_direction;
>       scmd->sdb = ses->sdb;
> -     scmd->request->next_rq = ses->next_rq;
>       scmd->result = ses->result;
>       scmd->underflow = ses->underflow;
>       scmd->prot_op = ses->prot_op;
> diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
> index c7fccbb8f554..cae0a5f7539d 100644
> --- a/drivers/scsi/scsi_lib.c
> +++ b/drivers/scsi/scsi_lib.c
> @@ -610,11 +610,6 @@ static void scsi_mq_free_sgtables(struct scsi_cmnd *cmd)
>  
>       if (cmd->sdb.table.nents)
>               sg_free_table_chained(&cmd->sdb.table, true);
> -     if (cmd->request->next_rq) {
> -             sdb = cmd->request->next_rq->special;
> -             if (sdb)
> -                     sg_free_table_chained(&sdb->table, true);
> -     }
>       if (scsi_prot_sg_count(cmd))
>               sg_free_table_chained(&cmd->prot_sdb->table, true);
>  }
> @@ -653,18 +648,9 @@ static void scsi_release_buffers(struct scsi_cmnd *cmd)
>               sg_free_table_chained(&cmd->prot_sdb->table, false);
>  }
>  
> -static void scsi_release_bidi_buffers(struct scsi_cmnd *cmd)
> -{
> -     struct scsi_data_buffer *bidi_sdb = cmd->request->next_rq->special;
> -
> -     sg_free_table_chained(&bidi_sdb->table, false);
> -     kmem_cache_free(scsi_sdb_cache, bidi_sdb);
> -     cmd->request->next_rq->special = NULL;
> -}
> -
>  /* Returns false when no more bytes to process, true if there are more */
>  static bool scsi_end_request(struct request *req, blk_status_t error,
> -             unsigned int bytes, unsigned int bidi_bytes)
> +             unsigned int bytes)
>  {
>       struct scsi_cmnd *cmd = blk_mq_rq_to_pdu(req);
>       struct scsi_device *sdev = cmd->device;
> @@ -673,11 +659,6 @@ static bool scsi_end_request(struct request *req, 
> blk_status_t error,
>       if (blk_update_request(req, error, bytes))
>               return true;
>  
> -     /* Bidi request must be completed as a whole */
> -     if (unlikely(bidi_bytes) &&
> -         blk_update_request(req->next_rq, error, bidi_bytes))
> -             return true;
> -
>       if (blk_queue_add_random(q))
>               add_disk_randomness(req->rq_disk);
>  
> @@ -707,8 +688,6 @@ static bool scsi_end_request(struct request *req, 
> blk_status_t error,
>       } else {
>               unsigned long flags;
>  
> -             if (bidi_bytes)
> -                     scsi_release_bidi_buffers(cmd);
>               scsi_release_buffers(cmd);
>               scsi_put_command(cmd);
>  
> @@ -916,7 +895,7 @@ static void scsi_io_completion_action(struct scsi_cmnd 
> *cmd, int result)
>                               scsi_print_command(cmd);
>                       }
>               }
> -             if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req), 0))
> +             if (!scsi_end_request(req, blk_stat, blk_rq_err_bytes(req)))
>                       return;
>               /*FALLTHRU*/
>       case ACTION_REPREP:
> @@ -1051,29 +1030,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, 
> unsigned int good_bytes)
>                */
>               scsi_req(req)->result = cmd->result;
>               scsi_req(req)->resid_len = scsi_get_resid(cmd);
> -
> -             if (unlikely(scsi_bidi_cmnd(cmd))) {
> -                     /*
> -                      * Bidi commands Must be complete as a whole,
> -                      * both sides at once.
> -                      */
> -                     scsi_req(req->next_rq)->resid_len = scsi_in(cmd)->resid;
> -                     if (scsi_end_request(req, BLK_STS_OK, blk_rq_bytes(req),
> -                                     blk_rq_bytes(req->next_rq)))
> -                             WARN_ONCE(true,
> -                                       "Bidi command with remaining bytes");
> -                     return;
> -             }
> -     }
> -
> -     /* no bidi support yet, other than in pass-through */
> -     if (unlikely(blk_bidi_rq(req))) {
> -             WARN_ONCE(true, "Only support bidi command in passthrough");
> -             scmd_printk(KERN_ERR, cmd, "Killing bidi command\n");
> -             if (scsi_end_request(req, BLK_STS_IOERR, blk_rq_bytes(req),
> -                                  blk_rq_bytes(req->next_rq)))
> -                     WARN_ONCE(true, "Bidi command with remaining bytes");
> -             return;
>       }
>  
>       /*
> @@ -1090,13 +1046,13 @@ void scsi_io_completion(struct scsi_cmnd *cmd, 
> unsigned int good_bytes)
>        * to retry code. Fast path should return in this block.
>        */
>       if (likely(blk_rq_bytes(req) > 0 || blk_stat == BLK_STS_OK)) {
> -             if (likely(!scsi_end_request(req, blk_stat, good_bytes, 0)))
> +             if (likely(!scsi_end_request(req, blk_stat, good_bytes)))
>                       return; /* no bytes remaining */
>       }
>  
>       /* Kill remainder if no retries. */
>       if (unlikely(blk_stat && scsi_noretry_cmd(cmd))) {
> -             if (scsi_end_request(req, blk_stat, blk_rq_bytes(req), 0))
> +             if (scsi_end_request(req, blk_stat, blk_rq_bytes(req)))
>                       WARN_ONCE(true,
>                           "Bytes remaining after failed, no-retry command");
>               return;
> @@ -1159,23 +1115,6 @@ int scsi_init_io(struct scsi_cmnd *cmd)
>       if (error)
>               goto err_exit;
>  
> -     if (blk_bidi_rq(rq)) {
> -             if (!rq->q->mq_ops) {
> -                     struct scsi_data_buffer *bidi_sdb =
> -                             kmem_cache_zalloc(scsi_sdb_cache, GFP_ATOMIC);
> -                     if (!bidi_sdb) {
> -                             error = BLKPREP_DEFER;
> -                             goto err_exit;
> -                     }
> -
> -                     rq->next_rq->special = bidi_sdb;
> -             }
> -
> -             error = scsi_init_sgtable(rq->next_rq, rq->next_rq->special);
> -             if (error)
> -                     goto err_exit;
> -     }
> -
>       if (blk_integrity_rq(rq)) {
>               struct scsi_data_buffer *prot_sdb = cmd->prot_sdb;
>               int ivecs, count;
> @@ -2026,17 +1965,6 @@ static int scsi_mq_prep_fn(struct request *req)
>                       (struct scatterlist *)(cmd->prot_sdb + 1);
>       }
>  
> -     if (blk_bidi_rq(req)) {
> -             struct request *next_rq = req->next_rq;
> -             struct scsi_data_buffer *bidi_sdb = blk_mq_rq_to_pdu(next_rq);
> -
> -             memset(bidi_sdb, 0, sizeof(struct scsi_data_buffer));
> -             bidi_sdb->table.sgl =
> -                     (struct scatterlist *)(bidi_sdb + 1);
> -
> -             next_rq->special = bidi_sdb;
> -     }
> -
>       blk_mq_start_request(req);
>  
>       return scsi_setup_cmnd(sdev, req);
> diff --git a/drivers/scsi/virtio_scsi.c b/drivers/scsi/virtio_scsi.c
> index 1c72db94270e..fd54c12a5ed3 100644
> --- a/drivers/scsi/virtio_scsi.c
> +++ b/drivers/scsi/virtio_scsi.c
> @@ -127,16 +127,8 @@ static inline struct Scsi_Host *virtio_scsi_host(struct 
> virtio_device *vdev)
>  
>  static void virtscsi_compute_resid(struct scsi_cmnd *sc, u32 resid)
>  {
> -     if (!resid)
> -             return;
> -
> -     if (!scsi_bidi_cmnd(sc)) {
> +     if (resid)
>               scsi_set_resid(sc, resid);
> -             return;
> -     }
> -
> -     scsi_in(sc)->resid = min(resid, scsi_in(sc)->length);
> -     scsi_out(sc)->resid = resid - scsi_in(sc)->resid;
>  }
>  
>  /**
> @@ -430,9 +422,9 @@ static int virtscsi_add_cmd(struct virtqueue *vq,
>  
>       if (sc && sc->sc_data_direction != DMA_NONE) {
>               if (sc->sc_data_direction != DMA_FROM_DEVICE)
> -                     out = &scsi_out(sc)->table;
> +                     out = &sc->sdb.table;
>               if (sc->sc_data_direction != DMA_TO_DEVICE)
> -                     in = &scsi_in(sc)->table;
> +                     in = &sc->sdb.table;
>       }
>  
>       /* Request header.  */
> diff --git a/drivers/target/loopback/tcm_loop.c 
> b/drivers/target/loopback/tcm_loop.c
> index bc8918f382e4..a43bb76cccf6 100644
> --- a/drivers/target/loopback/tcm_loop.c
> +++ b/drivers/target/loopback/tcm_loop.c
> @@ -128,14 +128,6 @@ static void tcm_loop_submission_work(struct work_struct 
> *work)
>               set_host_byte(sc, DID_ERROR);
>               goto out_done;
>       }
> -     if (scsi_bidi_cmnd(sc)) {
> -             struct scsi_data_buffer *sdb = scsi_in(sc);
> -
> -             sgl_bidi = sdb->table.sgl;
> -             sgl_bidi_count = sdb->table.nents;
> -             se_cmd->se_cmd_flags |= SCF_BIDI;
> -
> -     }
>  
>       transfer_length = scsi_transfer_length(sc);
>       if (!scsi_prot_sg_count(sc) &&
> @@ -304,12 +296,6 @@ static int tcm_loop_target_reset(struct scsi_cmnd *sc)
>       return FAILED;
>  }
>  
> -static int tcm_loop_slave_alloc(struct scsi_device *sd)
> -{
> -     blk_queue_flag_set(QUEUE_FLAG_BIDI, sd->request_queue);
> -     return 0;
> -}
> -
>  static struct scsi_host_template tcm_loop_driver_template = {
>       .show_info              = tcm_loop_show_info,
>       .proc_name              = "tcm_loopback",
> @@ -325,7 +311,6 @@ static struct scsi_host_template tcm_loop_driver_template 
> = {
>       .cmd_per_lun            = 1024,
>       .max_sectors            = 0xFFFF,
>       .use_clustering         = DISABLE_CLUSTERING,
> -     .slave_alloc            = tcm_loop_slave_alloc,
>       .module                 = THIS_MODULE,
>       .track_queue_depth      = 1,
>  };
> diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
> index 1f7b401c4d04..1c3bff3d57b0 100644
> --- a/drivers/usb/storage/uas.c
> +++ b/drivers/usb/storage/uas.c
> @@ -368,25 +368,19 @@ static void uas_data_cmplt(struct urb *urb)
>       struct scsi_cmnd *cmnd = urb->context;
>       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>       struct uas_dev_info *devinfo = (void *)cmnd->device->hostdata;
> -     struct scsi_data_buffer *sdb = NULL;
> +     struct scsi_data_buffer *sdb = &cmnd->sdb;
>       unsigned long flags;
>       int status = urb->status;
>  
>       spin_lock_irqsave(&devinfo->lock, flags);
>  
>       if (cmdinfo->data_in_urb == urb) {
> -             sdb = scsi_in(cmnd);
>               cmdinfo->state &= ~DATA_IN_URB_INFLIGHT;
>               cmdinfo->data_in_urb = NULL;
>       } else if (cmdinfo->data_out_urb == urb) {
> -             sdb = scsi_out(cmnd);
>               cmdinfo->state &= ~DATA_OUT_URB_INFLIGHT;
>               cmdinfo->data_out_urb = NULL;
>       }
> -     if (sdb == NULL) {
> -             WARN_ON_ONCE(1);
> -             goto out;
> -     }
>  
>       if (devinfo->resetting)
>               goto out;
> @@ -426,8 +420,7 @@ static struct urb *uas_alloc_data_urb(struct uas_dev_info 
> *devinfo, gfp_t gfp,
>       struct usb_device *udev = devinfo->udev;
>       struct uas_cmd_info *cmdinfo = (void *)&cmnd->SCp;
>       struct urb *urb = usb_alloc_urb(0, gfp);
> -     struct scsi_data_buffer *sdb = (dir == DMA_FROM_DEVICE)
> -             ? scsi_in(cmnd) : scsi_out(cmnd);
> +     struct scsi_data_buffer *sdb = &cmnd->sdb;
>       unsigned int pipe = (dir == DMA_FROM_DEVICE)
>               ? devinfo->data_in_pipe : devinfo->data_out_pipe;
>  
> diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
> index c891ada3c5c2..681f0ca808d7 100644
> --- a/include/scsi/scsi_cmnd.h
> +++ b/include/scsi/scsi_cmnd.h
> @@ -209,23 +209,6 @@ 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)
> -{
> -     return scsi_bidi_cmnd(cmd) ?
> -             cmd->request->next_rq->special : &cmd->sdb;
> -}
> -
> -static inline struct scsi_data_buffer *scsi_out(struct scsi_cmnd *cmd)
> -{
> -     return &cmd->sdb;
> -}
> -
>  static inline int scsi_sg_copy_from_buffer(struct scsi_cmnd *cmd,
>                                          void *buf, int buflen)
>  {
> @@ -347,7 +330,7 @@ static inline void set_driver_byte(struct scsi_cmnd *cmd, 
> char status)
>  
>  static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd)
>  {
> -     unsigned int xfer_len = scsi_out(scmd)->length;
> +     unsigned int xfer_len = scmd->sdb.length;
>       unsigned int prot_interval = scsi_prot_interval(scmd);
>  
>       if (scmd->prot_flags & SCSI_PROT_TRANSFER_PI)
> diff --git a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
> index 2b7e227960e1..3810b340551c 100644
> --- a/include/scsi/scsi_eh.h
> +++ b/include/scsi/scsi_eh.h
> @@ -39,7 +39,6 @@ struct scsi_eh_save {
>       unsigned char prot_op;
>       unsigned char *cmnd;
>       struct scsi_data_buffer sdb;
> -     struct request *next_rq;
>       /* new command support */
>       unsigned char eh_cmnd[BLK_MAX_CDB];
>       struct scatterlist sense_sgl;
> 

Reply via email to