Ignore:
Timestamp:
Apr 21, 2017, 4:28:29 AM (2 months ago)
Author:
brainslayer
Message:

update

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-4.9/drivers/target/target_core_user.c

    r31574 r31885  
    307307}
    308308
    309 static void gather_data_area(struct tcmu_dev *udev, unsigned long *cmd_bitmap,
    310                 struct scatterlist *data_sg, unsigned int data_nents)
    311 {
     309static void gather_data_area(struct tcmu_dev *udev, struct tcmu_cmd *cmd,
     310                             bool bidi)
     311{
     312        struct se_cmd *se_cmd = cmd->se_cmd;
    312313        int i, block;
    313314        int block_remaining = 0;
    314315        void *from, *to;
    315316        size_t copy_bytes, from_offset;
    316         struct scatterlist *sg;
     317        struct scatterlist *sg, *data_sg;
     318        unsigned int data_nents;
     319        DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
     320
     321        bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
     322
     323        if (!bidi) {
     324                data_sg = se_cmd->t_data_sg;
     325                data_nents = se_cmd->t_data_nents;
     326        } else {
     327                uint32_t count;
     328
     329                /*
     330                 * For bidi case, the first count blocks are for Data-Out
     331                 * buffer blocks, and before gathering the Data-In buffer
     332                 * the Data-Out buffer blocks should be discarded.
     333                 */
     334                count = DIV_ROUND_UP(se_cmd->data_length, DATA_BLOCK_SIZE);
     335                while (count--) {
     336                        block = find_first_bit(bitmap, DATA_BLOCK_BITS);
     337                        clear_bit(block, bitmap);
     338                }
     339
     340                data_sg = se_cmd->t_bidi_data_sg;
     341                data_nents = se_cmd->t_bidi_data_nents;
     342        }
    317343
    318344        for_each_sg(data_sg, sg, data_nents, i) {
     
    321347                while (sg_remaining > 0) {
    322348                        if (block_remaining == 0) {
    323                                 block = find_first_bit(cmd_bitmap,
     349                                block = find_first_bit(bitmap,
    324350                                                DATA_BLOCK_BITS);
    325351                                block_remaining = DATA_BLOCK_SIZE;
    326                                 clear_bit(block, cmd_bitmap);
     352                                clear_bit(block, bitmap);
    327353                        }
    328354                        copy_bytes = min_t(size_t, sg_remaining,
     
    388414
    389415        return true;
     416}
     417
     418static inline size_t tcmu_cmd_get_data_length(struct tcmu_cmd *tcmu_cmd)
     419{
     420        struct se_cmd *se_cmd = tcmu_cmd->se_cmd;
     421        size_t data_length = round_up(se_cmd->data_length, DATA_BLOCK_SIZE);
     422
     423        if (se_cmd->se_cmd_flags & SCF_BIDI) {
     424                BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents));
     425                data_length += round_up(se_cmd->t_bidi_data_sg->length,
     426                                DATA_BLOCK_SIZE);
     427        }
     428
     429        return data_length;
     430}
     431
     432static inline uint32_t tcmu_cmd_get_block_cnt(struct tcmu_cmd *tcmu_cmd)
     433{
     434        size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd);
     435
     436        return data_length / DATA_BLOCK_SIZE;
    390437}
    391438
     
    403450        uint64_t cdb_off;
    404451        bool copy_to_data_area;
    405         size_t data_length;
     452        size_t data_length = tcmu_cmd_get_data_length(tcmu_cmd);
    406453        DECLARE_BITMAP(old_bitmap, DATA_BLOCK_BITS);
    407454
     
    417464        */
    418465        base_command_size = max(offsetof(struct tcmu_cmd_entry,
    419                                 req.iov[se_cmd->t_bidi_data_nents +
    420                                         se_cmd->t_data_nents]),
     466                                req.iov[tcmu_cmd_get_block_cnt(tcmu_cmd)]),
    421467                                sizeof(struct tcmu_cmd_entry));
    422468        command_size = base_command_size
     
    429475        mb = udev->mb_addr;
    430476        cmd_head = mb->cmd_head % udev->cmdr_size; /* UAM */
    431         data_length = se_cmd->data_length;
    432         if (se_cmd->se_cmd_flags & SCF_BIDI) {
    433                 BUG_ON(!(se_cmd->t_bidi_data_sg && se_cmd->t_bidi_data_nents));
    434                 data_length += se_cmd->t_bidi_data_sg->length;
    435         }
    436477        if ((command_size > (udev->cmdr_size / 2)) ||
    437478            data_length > udev->data_size) {
     
    503544
    504545        /* Handle BIDI commands */
    505         iov_cnt = 0;
    506         alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
    507                 se_cmd->t_bidi_data_nents, &iov, &iov_cnt, false);
    508         entry->req.iov_bidi_cnt = iov_cnt;
    509 
     546        if (se_cmd->se_cmd_flags & SCF_BIDI) {
     547                iov_cnt = 0;
     548                iov++;
     549                alloc_and_scatter_data_area(udev, se_cmd->t_bidi_data_sg,
     550                                se_cmd->t_bidi_data_nents, &iov, &iov_cnt,
     551                                false);
     552                entry->req.iov_bidi_cnt = iov_cnt;
     553        }
    510554        /* cmd's data_bitmap is what changed in process */
    511555        bitmap_xor(tcmu_cmd->data_bitmap, old_bitmap, udev->data_bitmap,
     
    583627                free_data_area(udev, cmd);
    584628        } else if (se_cmd->se_cmd_flags & SCF_BIDI) {
    585                 DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
    586 
    587629                /* Get Data-In buffer before clean up */
    588                 bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
    589                 gather_data_area(udev, bitmap,
    590                         se_cmd->t_bidi_data_sg, se_cmd->t_bidi_data_nents);
     630                gather_data_area(udev, cmd, true);
    591631                free_data_area(udev, cmd);
    592632        } else if (se_cmd->data_direction == DMA_FROM_DEVICE) {
    593                 DECLARE_BITMAP(bitmap, DATA_BLOCK_BITS);
    594 
    595                 bitmap_copy(bitmap, cmd->data_bitmap, DATA_BLOCK_BITS);
    596                 gather_data_area(udev, bitmap,
    597                         se_cmd->t_data_sg, se_cmd->t_data_nents);
     633                gather_data_area(udev, cmd, false);
    598634                free_data_area(udev, cmd);
    599635        } else if (se_cmd->data_direction == DMA_TO_DEVICE) {
Note: See TracChangeset for help on using the changeset viewer.