]> Git Repo - linux.git/commitdiff
Merge branch 'fixes' into misc
authorJames Bottomley <[email protected]>
Tue, 15 Mar 2016 22:24:44 +0000 (15:24 -0700)
committerJames Bottomley <[email protected]>
Tue, 15 Mar 2016 22:24:44 +0000 (15:24 -0700)
1  2 
drivers/scsi/be2iscsi/be_main.c
drivers/scsi/scsi_lib.c

index e89a0f8d2c6e9a9b650cc1ca3d30609a475991db,069e5c50abd02b25b090c56b275390df44660dcf..f05e7737107d2a0fced40581b7f34bad70ca2820
@@@ -29,7 -29,6 +29,7 @@@
  #include <linux/iscsi_boot_sysfs.h>
  #include <linux/module.h>
  #include <linux/bsg-lib.h>
 +#include <linux/irq_poll.h>
  
  #include <scsi/libiscsi.h>
  #include <scsi/scsi_bsg_iscsi.h>
@@@ -286,7 -285,7 +286,7 @@@ static int beiscsi_eh_abort(struct scsi
                return FAILED;
        }
  
 -      rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
 +      rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
        if (rc != -EBUSY)
                pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
                                    nonemb_cmd.va, nonemb_cmd.dma);
@@@ -367,7 -366,7 +367,7 @@@ static int beiscsi_eh_device_reset(stru
                return FAILED;
        }
  
 -      rc = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
 +      rc = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
        if (rc != -EBUSY)
                pci_free_consistent(phba->ctrl.pdev, nonemb_cmd.size,
                                    nonemb_cmd.va, nonemb_cmd.dma);
@@@ -728,8 -727,9 +728,8 @@@ static int be_ctrl_init(struct beiscsi_
        mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
        mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
        memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
 -      spin_lock_init(&ctrl->mbox_lock);
 +      mutex_init(&ctrl->mbox_lock);
        spin_lock_init(&phba->ctrl.mcc_lock);
 -      spin_lock_init(&phba->ctrl.mcc_cq_lock);
  
        return status;
  }
@@@ -895,17 -895,31 +895,17 @@@ static irqreturn_t be_isr_mcc(int irq, 
  static irqreturn_t be_isr_msix(int irq, void *dev_id)
  {
        struct beiscsi_hba *phba;
 -      struct be_eq_entry *eqe = NULL;
        struct be_queue_info *eq;
 -      struct be_queue_info *cq;
 -      unsigned int num_eq_processed;
        struct be_eq_obj *pbe_eq;
  
        pbe_eq = dev_id;
        eq = &pbe_eq->q;
 -      cq = pbe_eq->cq;
 -      eqe = queue_tail_node(eq);
  
        phba = pbe_eq->phba;
 -      num_eq_processed = 0;
 -      while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
 -                              & EQE_VALID_MASK) {
 -              irq_poll_sched(&pbe_eq->iopoll);
  
 -              AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 -              queue_tail_inc(eq);
 -              eqe = queue_tail_node(eq);
 -              num_eq_processed++;
 -      }
 -
 -      if (num_eq_processed)
 -              hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
 +      /* disable interrupt till iopoll completes */
 +      hwi_ring_eq_db(phba, eq->id, 1, 0, 0, 1);
 +      irq_poll_sched(&pbe_eq->iopoll);
  
        return IRQ_HANDLED;
  }
@@@ -982,7 -996,6 +982,7 @@@ static irqreturn_t be_isr(int irq, voi
                return IRQ_NONE;
  }
  
 +
  static int beiscsi_init_irqs(struct beiscsi_hba *phba)
  {
        struct pci_dev *pcidev = phba->pcidev;
@@@ -1057,7 -1070,7 +1057,7 @@@ free_msix_irqs
  
  void hwi_ring_cq_db(struct beiscsi_hba *phba,
                           unsigned int id, unsigned int num_processed,
 -                         unsigned char rearm, unsigned char event)
 +                         unsigned char rearm)
  {
        u32 val = 0;
  
@@@ -1132,7 -1145,6 +1132,7 @@@ static struct sgl_handle *alloc_io_sgl_
  {
        struct sgl_handle *psgl_handle;
  
 +      spin_lock_bh(&phba->io_sgl_lock);
        if (phba->io_sgl_hndl_avbl) {
                beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
                            "BM_%d : In alloc_io_sgl_handle,"
                        phba->io_sgl_alloc_index++;
        } else
                psgl_handle = NULL;
 +      spin_unlock_bh(&phba->io_sgl_lock);
        return psgl_handle;
  }
  
  static void
  free_io_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
  {
 +      spin_lock_bh(&phba->io_sgl_lock);
        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_IO,
                    "BM_%d : In free_,io_sgl_free_index=%d\n",
                    phba->io_sgl_free_index);
                             "value there=%p\n", phba->io_sgl_free_index,
                             phba->io_sgl_hndl_base
                             [phba->io_sgl_free_index]);
 +               spin_unlock_bh(&phba->io_sgl_lock);
                return;
        }
        phba->io_sgl_hndl_base[phba->io_sgl_free_index] = psgl_handle;
                phba->io_sgl_free_index = 0;
        else
                phba->io_sgl_free_index++;
 +      spin_unlock_bh(&phba->io_sgl_lock);
 +}
 +
 +static inline struct wrb_handle *
 +beiscsi_get_wrb_handle(struct hwi_wrb_context *pwrb_context,
 +                     unsigned int wrbs_per_cxn)
 +{
 +      struct wrb_handle *pwrb_handle;
 +
 +      spin_lock_bh(&pwrb_context->wrb_lock);
 +      pwrb_handle = pwrb_context->pwrb_handle_base[pwrb_context->alloc_index];
 +      pwrb_context->wrb_handles_available--;
 +      if (pwrb_context->alloc_index == (wrbs_per_cxn - 1))
 +              pwrb_context->alloc_index = 0;
 +      else
 +              pwrb_context->alloc_index++;
 +      spin_unlock_bh(&pwrb_context->wrb_lock);
 +
 +      return pwrb_handle;
  }
  
  /**
   * This happens under session_lock until submission to chip
   */
  struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid,
 -                                   struct hwi_wrb_context **pcontext)
 +                                  struct hwi_wrb_context **pcontext)
  {
        struct hwi_wrb_context *pwrb_context;
        struct hwi_controller *phwi_ctrlr;
 -      struct wrb_handle *pwrb_handle;
        uint16_t cri_index = BE_GET_CRI_FROM_CID(cid);
  
        phwi_ctrlr = phba->phwi_ctrlr;
        pwrb_context = &phwi_ctrlr->wrb_context[cri_index];
 -      if (pwrb_context->wrb_handles_available >= 2) {
 -              pwrb_handle = pwrb_context->pwrb_handle_base[
 -                                          pwrb_context->alloc_index];
 -              pwrb_context->wrb_handles_available--;
 -              if (pwrb_context->alloc_index ==
 -                                              (phba->params.wrbs_per_cxn - 1))
 -                      pwrb_context->alloc_index = 0;
 -              else
 -                      pwrb_context->alloc_index++;
 +      /* return the context address */
 +      *pcontext = pwrb_context;
 +      return beiscsi_get_wrb_handle(pwrb_context, phba->params.wrbs_per_cxn);
 +}
  
 -              /* Return the context address */
 -              *pcontext = pwrb_context;
 -      } else
 -              pwrb_handle = NULL;
 -      return pwrb_handle;
 +static inline void
 +beiscsi_put_wrb_handle(struct hwi_wrb_context *pwrb_context,
 +                     struct wrb_handle *pwrb_handle,
 +                     unsigned int wrbs_per_cxn)
 +{
 +      spin_lock_bh(&pwrb_context->wrb_lock);
 +      pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
 +      pwrb_context->wrb_handles_available++;
 +      if (pwrb_context->free_index == (wrbs_per_cxn - 1))
 +              pwrb_context->free_index = 0;
 +      else
 +              pwrb_context->free_index++;
 +      spin_unlock_bh(&pwrb_context->wrb_lock);
  }
  
  /**
@@@ -1251,9 -1239,13 +1251,9 @@@ static voi
  free_wrb_handle(struct beiscsi_hba *phba, struct hwi_wrb_context *pwrb_context,
                struct wrb_handle *pwrb_handle)
  {
 -      pwrb_context->pwrb_handle_base[pwrb_context->free_index] = pwrb_handle;
 -      pwrb_context->wrb_handles_available++;
 -      if (pwrb_context->free_index == (phba->params.wrbs_per_cxn - 1))
 -              pwrb_context->free_index = 0;
 -      else
 -              pwrb_context->free_index++;
 -
 +      beiscsi_put_wrb_handle(pwrb_context,
 +                             pwrb_handle,
 +                             phba->params.wrbs_per_cxn);
        beiscsi_log(phba, KERN_INFO,
                    BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
                    "BM_%d : FREE WRB: pwrb_handle=%p free_index=0x%x"
@@@ -1266,7 -1258,6 +1266,7 @@@ static struct sgl_handle *alloc_mgmt_sg
  {
        struct sgl_handle *psgl_handle;
  
 +      spin_lock_bh(&phba->mgmt_sgl_lock);
        if (phba->eh_sgl_hndl_avbl) {
                psgl_handle = phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index];
                phba->eh_sgl_hndl_base[phba->eh_sgl_alloc_index] = NULL;
                        phba->eh_sgl_alloc_index++;
        } else
                psgl_handle = NULL;
 +      spin_unlock_bh(&phba->mgmt_sgl_lock);
        return psgl_handle;
  }
  
  void
  free_mgmt_sgl_handle(struct beiscsi_hba *phba, struct sgl_handle *psgl_handle)
  {
 -
 +      spin_lock_bh(&phba->mgmt_sgl_lock);
        beiscsi_log(phba, KERN_INFO, BEISCSI_LOG_CONFIG,
                    "BM_%d : In  free_mgmt_sgl_handle,"
                    "eh_sgl_free_index=%d\n",
                            "BM_%d : Double Free in eh SGL ,"
                            "eh_sgl_free_index=%d\n",
                            phba->eh_sgl_free_index);
 +              spin_unlock_bh(&phba->mgmt_sgl_lock);
                return;
        }
        phba->eh_sgl_hndl_base[phba->eh_sgl_free_index] = psgl_handle;
                phba->eh_sgl_free_index = 0;
        else
                phba->eh_sgl_free_index++;
 +      spin_unlock_bh(&phba->mgmt_sgl_lock);
  }
  
  static void
@@@ -2041,7 -2029,7 +2041,7 @@@ static void hwi_process_default_pdu_rin
                               phwi_ctrlr, cri_index));
  }
  
 -static void  beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
 +void beiscsi_process_mcc_cq(struct beiscsi_hba *phba)
  {
        struct be_queue_info *mcc_cq;
        struct  be_mcc_compl *mcc_compl;
        mcc_compl = queue_tail_node(mcc_cq);
        mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
        while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
 -
                if (num_processed >= 32) {
                        hwi_ring_cq_db(phba, mcc_cq->id,
 -                                      num_processed, 0, 0);
 +                                      num_processed, 0);
                        num_processed = 0;
                }
                if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
 -                      /* Interpret flags as an async trailer */
 -                      if (is_link_state_evt(mcc_compl->flags))
 -                              /* Interpret compl as a async link evt */
 -                              beiscsi_async_link_state_process(phba,
 -                              (struct be_async_event_link_state *) mcc_compl);
 -                      else {
 -                              beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_MBOX,
 -                                          "BM_%d :  Unsupported Async Event, flags"
 -                                          " = 0x%08x\n",
 -                                          mcc_compl->flags);
 -                              if (phba->state & BE_ADAPTER_LINK_UP) {
 -                                      phba->state |= BE_ADAPTER_CHECK_BOOT;
 -                                      phba->get_boot = BE_GET_BOOT_RETRIES;
 -                              }
 -                      }
 +                      beiscsi_process_async_event(phba, mcc_compl);
                } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
 -                      be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
 -                      atomic_dec(&phba->ctrl.mcc_obj.q.used);
 +                      beiscsi_process_mcc_compl(&phba->ctrl, mcc_compl);
                }
  
                mcc_compl->flags = 0;
        }
  
        if (num_processed > 0)
 -              hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
 -
 +              hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1);
  }
  
  /**
   * beiscsi_process_cq()- Process the Completion Queue
   * @pbe_eq: Event Q on which the Completion has come
 + * @budget: Max number of events to processed
   *
   * return
   *     Number of Completion Entries processed.
   **/
 -unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
 +unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq, int budget)
  {
        struct be_queue_info *cq;
        struct sol_cqe *sol;
        struct dmsg_cqe *dmsg;
 +      unsigned int total = 0;
        unsigned int num_processed = 0;
 -      unsigned int tot_nump = 0;
        unsigned short code = 0, cid = 0;
        uint16_t cri_index = 0;
        struct beiscsi_conn *beiscsi_conn;
                beiscsi_ep = ep->dd_data;
                beiscsi_conn = beiscsi_ep->conn;
  
 -              if (num_processed >= 32) {
 -                      hwi_ring_cq_db(phba, cq->id,
 -                                      num_processed, 0, 0);
 -                      tot_nump += num_processed;
 +              /* replenish cq */
 +              if (num_processed == 32) {
 +                      hwi_ring_cq_db(phba, cq->id, 32, 0);
                        num_processed = 0;
                }
 +              total++;
  
                switch (code) {
                case SOL_CMD_COMPLETE:
                                    "BM_%d : Ignoring %s[%d] on CID : %d\n",
                                    cqe_desc[code], code, cid);
                        break;
 +              case CXN_KILLED_HDR_DIGEST_ERR:
                case SOL_CMD_KILLED_DATA_DIGEST_ERR:
 +                      beiscsi_log(phba, KERN_ERR,
 +                                  BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
 +                                  "BM_%d : Cmd Notification %s[%d] on CID : %d\n",
 +                                  cqe_desc[code], code,  cid);
 +                      break;
                case CMD_KILLED_INVALID_STATSN_RCVD:
                case CMD_KILLED_INVALID_R2T_RCVD:
                case CMD_CXN_KILLED_LUN_INVALID:
                case CXN_KILLED_PDU_SIZE_EXCEEDS_DSL:
                case CXN_KILLED_BURST_LEN_MISMATCH:
                case CXN_KILLED_AHS_RCVD:
 -              case CXN_KILLED_HDR_DIGEST_ERR:
                case CXN_KILLED_UNKNOWN_HDR:
                case CXN_KILLED_STALE_ITT_TTT_RCVD:
                case CXN_KILLED_INVALID_ITT_TTT_RCVD:
@@@ -2254,12 -2253,13 +2254,12 @@@ proc_next_cqe
                queue_tail_inc(cq);
                sol = queue_tail_node(cq);
                num_processed++;
 +              if (total == budget)
 +                      break;
        }
  
 -      if (num_processed > 0) {
 -              tot_nump += num_processed;
 -              hwi_ring_cq_db(phba, cq->id, num_processed, 1, 0);
 -      }
 -      return tot_nump;
 +      hwi_ring_cq_db(phba, cq->id, num_processed, 1);
 +      return total;
  }
  
  void beiscsi_process_all_cqs(struct work_struct *work)
                spin_lock_irqsave(&phba->isr_lock, flags);
                pbe_eq->todo_mcc_cq = false;
                spin_unlock_irqrestore(&phba->isr_lock, flags);
 -              beiscsi_process_mcc_isr(phba);
 +              beiscsi_process_mcc_cq(phba);
        }
  
        if (pbe_eq->todo_cq) {
                spin_lock_irqsave(&phba->isr_lock, flags);
                pbe_eq->todo_cq = false;
                spin_unlock_irqrestore(&phba->isr_lock, flags);
 -              beiscsi_process_cq(pbe_eq);
 +              beiscsi_process_cq(pbe_eq, BE2_MAX_NUM_CQ_PROC);
        }
  
        /* rearm EQ for further interrupts */
  
  static int be_iopoll(struct irq_poll *iop, int budget)
  {
 -      unsigned int ret;
 +      unsigned int ret, num_eq_processed;
        struct beiscsi_hba *phba;
        struct be_eq_obj *pbe_eq;
 +      struct be_eq_entry *eqe = NULL;
 +      struct be_queue_info *eq;
  
 +      num_eq_processed = 0;
        pbe_eq = container_of(iop, struct be_eq_obj, iopoll);
 -      ret = beiscsi_process_cq(pbe_eq);
 +      phba = pbe_eq->phba;
 +      eq = &pbe_eq->q;
 +      eqe = queue_tail_node(eq);
 +
 +      while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] &
 +                      EQE_VALID_MASK) {
 +              AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
 +              queue_tail_inc(eq);
 +              eqe = queue_tail_node(eq);
 +              num_eq_processed++;
 +      }
 +
 +      hwi_ring_eq_db(phba, eq->id, 1, num_eq_processed, 0, 1);
 +
 +      ret = beiscsi_process_cq(pbe_eq, budget);
        pbe_eq->cq_count += ret;
        if (ret < budget) {
 -              phba = pbe_eq->phba;
                irq_poll_complete(iop);
                beiscsi_log(phba, KERN_INFO,
                            BEISCSI_LOG_CONFIG | BEISCSI_LOG_IO,
 -                          "BM_%d : rearm pbe_eq->q.id =%d\n",
 -                          pbe_eq->q.id);
 +                          "BM_%d : rearm pbe_eq->q.id =%d ret %d\n",
 +                          pbe_eq->q.id, ret);
                hwi_ring_eq_db(phba, pbe_eq->q.id, 0, 0, 1, 1);
        }
        return ret;
@@@ -2518,7 -2502,7 +2518,7 @@@ hwi_write_sgl(struct iscsi_wrb *pwrb, s
   * @pwrb: ptr to the WRB entry
   * @task: iscsi task which is to be executed
   **/
 -static void hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
 +static int hwi_write_buffer(struct iscsi_wrb *pwrb, struct iscsi_task *task)
  {
        struct iscsi_sge *psgl;
        struct beiscsi_io_task *io_task = task->dd_data;
                                                             task->data,
                                                             task->data_count,
                                                             PCI_DMA_TODEVICE);
 +                      if (pci_dma_mapping_error(phba->pcidev,
 +                                                io_task->mtask_addr))
 +                              return -ENOMEM;
                        io_task->mtask_data_count = task->data_count;
                } else
                        io_task->mtask_addr = 0;
                AMAP_SET_BITS(struct amap_iscsi_sge, len, psgl, 0x106);
        }
        AMAP_SET_BITS(struct amap_iscsi_sge, last_sge, psgl, 1);
 +      return 0;
  }
  
  /**
@@@ -2726,10 -2706,8 +2726,10 @@@ static int beiscsi_alloc_mem(struct bei
        phwi_ctrlr->wrb_context = kzalloc(sizeof(struct hwi_wrb_context) *
                                          phba->params.cxns_per_ctrl,
                                          GFP_KERNEL);
 -      if (!phwi_ctrlr->wrb_context)
 +      if (!phwi_ctrlr->wrb_context) {
 +              kfree(phba->phwi_ctrlr);
                return -ENOMEM;
 +      }
  
        phba->init_mem = kcalloc(SE_MEM_MAX, sizeof(*mem_descr),
                                 GFP_KERNEL);
@@@ -2926,7 -2904,6 +2926,7 @@@ static int beiscsi_init_wrb_handle(stru
                        }
                        num_cxn_wrbh--;
                }
 +              spin_lock_init(&pwrb_context->wrb_lock);
        }
        idx = 0;
        for (index = 0; index < phba->params.cxns_per_ctrl; index++) {
@@@ -3889,8 -3866,6 +3889,8 @@@ static int hwi_init_port(struct beiscsi
        phwi_context->min_eqd = 0;
        phwi_context->cur_eqd = 0;
        be_cmd_fw_initialize(&phba->ctrl);
 +      /* set optic state to unknown */
 +      phba->optic_state = 0xff;
  
        status = beiscsi_create_eqs(phba, phwi_context);
        if (status != 0) {
@@@ -4409,7 -4384,7 +4409,7 @@@ static int beiscsi_get_boot_info(struc
                goto boot_freemem;
        }
  
 -      ret = beiscsi_mccq_compl(phba, tag, NULL, &nonemb_cmd);
 +      ret = beiscsi_mccq_compl_wait(phba, tag, NULL, &nonemb_cmd);
        if (ret) {
                beiscsi_log(phba, KERN_ERR,
                            BEISCSI_LOG_INIT | BEISCSI_LOG_CONFIG,
@@@ -4493,6 -4468,7 +4493,7 @@@ put_shost
        scsi_host_put(phba->shost);
  free_kset:
        iscsi_boot_destroy_kset(phba->boot_kset);
+       phba->boot_kset = NULL;
        return -ENOMEM;
  }
  
@@@ -4632,9 -4608,11 +4633,9 @@@ beiscsi_free_mgmt_task_handles(struct b
        }
  
        if (io_task->psgl_handle) {
 -              spin_lock_bh(&phba->mgmt_sgl_lock);
                free_mgmt_sgl_handle(phba,
                                     io_task->psgl_handle);
                io_task->psgl_handle = NULL;
 -              spin_unlock_bh(&phba->mgmt_sgl_lock);
        }
  
        if (io_task->mtask_addr) {
@@@ -4680,7 -4658,9 +4681,7 @@@ static void beiscsi_cleanup_task(struc
                }
  
                if (io_task->psgl_handle) {
 -                      spin_lock(&phba->io_sgl_lock);
                        free_io_sgl_handle(phba, io_task->psgl_handle);
 -                      spin_unlock(&phba->io_sgl_lock);
                        io_task->psgl_handle = NULL;
                }
  
@@@ -4735,20 -4715,6 +4736,20 @@@ beiscsi_offload_connection(struct beisc
        doorbell |= 1 << DB_DEF_PDU_NUM_POSTED_SHIFT;
        iowrite32(doorbell, phba->db_va +
                  beiscsi_conn->doorbell_offset);
 +
 +      /*
 +       * There is no completion for CONTEXT_UPDATE. The completion of next
 +       * WRB posted guarantees FW's processing and DMA'ing of it.
 +       * Use beiscsi_put_wrb_handle to put it back in the pool which makes
 +       * sure zero'ing or reuse of the WRB only after wrbs_per_cxn.
 +       */
 +      beiscsi_put_wrb_handle(pwrb_context, pwrb_handle,
 +                             phba->params.wrbs_per_cxn);
 +      beiscsi_log(phba, KERN_INFO,
 +                  BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
 +                  "BM_%d : put CONTEXT_UPDATE pwrb_handle=%p free_index=0x%x wrb_handles_available=%d\n",
 +                  pwrb_handle, pwrb_context->free_index,
 +                  pwrb_context->wrb_handles_available);
  }
  
  static void beiscsi_parse_pdu(struct iscsi_conn *conn, itt_t itt,
@@@ -4796,7 -4762,9 +4797,7 @@@ static int beiscsi_alloc_pdu(struct isc
        io_task->pwrb_handle = NULL;
  
        if (task->sc) {
 -              spin_lock(&phba->io_sgl_lock);
                io_task->psgl_handle = alloc_io_sgl_handle(phba);
 -              spin_unlock(&phba->io_sgl_lock);
                if (!io_task->psgl_handle) {
                        beiscsi_log(phba, KERN_ERR,
                                    BEISCSI_LOG_IO | BEISCSI_LOG_CONFIG,
                if ((opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGIN) {
                        beiscsi_conn->task = task;
                        if (!beiscsi_conn->login_in_progress) {
 -                              spin_lock(&phba->mgmt_sgl_lock);
                                io_task->psgl_handle = (struct sgl_handle *)
                                                alloc_mgmt_sgl_handle(phba);
 -                              spin_unlock(&phba->mgmt_sgl_lock);
                                if (!io_task->psgl_handle) {
                                        beiscsi_log(phba, KERN_ERR,
                                                    BEISCSI_LOG_IO |
                                                beiscsi_conn->plogin_wrb_handle;
                        }
                } else {
 -                      spin_lock(&phba->mgmt_sgl_lock);
                        io_task->psgl_handle = alloc_mgmt_sgl_handle(phba);
 -                      spin_unlock(&phba->mgmt_sgl_lock);
                        if (!io_task->psgl_handle) {
                                beiscsi_log(phba, KERN_ERR,
                                            BEISCSI_LOG_IO |
        return 0;
  
  free_io_hndls:
 -      spin_lock(&phba->io_sgl_lock);
        free_io_sgl_handle(phba, io_task->psgl_handle);
 -      spin_unlock(&phba->io_sgl_lock);
        goto free_hndls;
  free_mgmt_hndls:
 -      spin_lock(&phba->mgmt_sgl_lock);
        free_mgmt_sgl_handle(phba, io_task->psgl_handle);
        io_task->psgl_handle = NULL;
 -      spin_unlock(&phba->mgmt_sgl_lock);
  free_hndls:
        phwi_ctrlr = phba->phwi_ctrlr;
        cri_index = BE_GET_CRI_FROM_CID(
@@@ -4928,6 -4904,7 +4929,6 @@@ int beiscsi_iotask_v2(struct iscsi_tas
  
        pwrb = io_task->pwrb_handle->pwrb;
  
 -      io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
        io_task->bhs_len = sizeof(struct be_cmd_bhs);
  
        if (writedir) {
@@@ -4988,6 -4965,7 +4989,6 @@@ static int beiscsi_iotask(struct iscsi_
        unsigned int doorbell = 0;
  
        pwrb = io_task->pwrb_handle->pwrb;
 -      io_task->cmd_bhs->iscsi_hdr.exp_statsn = 0;
        io_task->bhs_len = sizeof(struct be_cmd_bhs);
  
        if (writedir) {
@@@ -5046,7 -5024,6 +5047,7 @@@ static int beiscsi_mtask(struct iscsi_t
        unsigned int doorbell = 0;
        unsigned int cid;
        unsigned int pwrb_typeoffset = 0;
 +      int ret = 0;
  
        cid = beiscsi_conn->beiscsi_conn_cid;
        pwrb = io_task->pwrb_handle->pwrb;
        case ISCSI_OP_LOGIN:
                AMAP_SET_BITS(struct amap_iscsi_wrb, cmdsn_itt, pwrb, 1);
                ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset);
 -              hwi_write_buffer(pwrb, task);
 +              ret = hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_NOOP_OUT:
                if (task->hdr->ttt != ISCSI_RESERVED_TAG) {
                                AMAP_SET_BITS(struct amap_iscsi_wrb_v2,
                                              dmsg, pwrb, 0);
                }
 -              hwi_write_buffer(pwrb, task);
 +              ret = hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_TEXT:
                ADAPTER_SET_WRB_TYPE(pwrb, TGT_DM_CMD, pwrb_typeoffset);
 -              hwi_write_buffer(pwrb, task);
 +              ret = hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_SCSI_TMFUNC:
                ADAPTER_SET_WRB_TYPE(pwrb, INI_TMF_CMD, pwrb_typeoffset);
 -              hwi_write_buffer(pwrb, task);
 +              ret = hwi_write_buffer(pwrb, task);
                break;
        case ISCSI_OP_LOGOUT:
                ADAPTER_SET_WRB_TYPE(pwrb, HWH_TYPE_LOGOUT, pwrb_typeoffset);
 -              hwi_write_buffer(pwrb, task);
 +              ret = hwi_write_buffer(pwrb, task);
                break;
  
        default:
                return -EINVAL;
        }
  
 +      if (ret)
 +              return ret;
 +
        /* Set the task type */
        io_task->wrb_type = (is_chip_be2_be3r(phba)) ?
                AMAP_GET_BITS(struct amap_iscsi_wrb, type, pwrb) :
@@@ -5159,21 -5133,23 +5160,21 @@@ static int beiscsi_task_xmit(struct isc
  {
        struct beiscsi_io_task *io_task = task->dd_data;
        struct scsi_cmnd *sc = task->sc;
 -      struct beiscsi_hba *phba = NULL;
 +      struct beiscsi_hba *phba;
        struct scatterlist *sg;
        int num_sg;
        unsigned int  writedir = 0, xferlen = 0;
  
 -      phba = ((struct beiscsi_conn *)task->conn->dd_data)->phba;
 +      if (!io_task->conn->login_in_progress)
 +              task->hdr->exp_statsn = 0;
  
        if (!sc)
                return beiscsi_mtask(task);
  
        io_task->scsi_cmnd = sc;
        num_sg = scsi_dma_map(sc);
 +      phba = io_task->conn->phba;
        if (num_sg < 0) {
 -              struct iscsi_conn *conn = task->conn;
 -              struct beiscsi_hba *phba = NULL;
 -
 -              phba = ((struct beiscsi_conn *)conn->dd_data)->phba;
                beiscsi_log(phba, KERN_ERR,
                            BEISCSI_LOG_IO | BEISCSI_LOG_ISCSI,
                            "BM_%d : scsi_dma_map Failed "
@@@ -5236,13 -5212,12 +5237,13 @@@ static int beiscsi_bsg_request(struct b
  
                rc = wait_event_interruptible_timeout(
                                        phba->ctrl.mcc_wait[tag],
 -                                      phba->ctrl.mcc_numtag[tag],
 +                                      phba->ctrl.mcc_tag_status[tag],
                                        msecs_to_jiffies(
                                        BEISCSI_HOST_MBX_TIMEOUT));
 -              extd_status = (phba->ctrl.mcc_numtag[tag] & 0x0000FF00) >> 8;
 -              status = phba->ctrl.mcc_numtag[tag] & 0x000000FF;
 -              free_mcc_tag(&phba->ctrl, tag);
 +              extd_status = (phba->ctrl.mcc_tag_status[tag] &
 +                             CQE_STATUS_ADDL_MASK) >> CQE_STATUS_ADDL_SHIFT;
 +              status = phba->ctrl.mcc_tag_status[tag] & CQE_STATUS_MASK;
 +              free_mcc_wrb(&phba->ctrl, tag);
                resp = (struct be_cmd_resp_hdr *)nonemb_cmd.va;
                sg_copy_from_buffer(job->reply_payload.sg_list,
                                    job->reply_payload.sg_cnt,
@@@ -5303,12 -5278,15 +5304,12 @@@ static void beiscsi_quiesce(struct beis
        if (phba->msix_enabled) {
                for (i = 0; i <= phba->num_cpus; i++) {
                        msix_vec = phba->msix_entries[i].vector;
 -                      synchronize_irq(msix_vec);
                        free_irq(msix_vec, &phwi_context->be_eq[i]);
                        kfree(phba->msi_name[i]);
                }
        } else
 -              if (phba->pcidev->irq) {
 -                      synchronize_irq(phba->pcidev->irq);
 +              if (phba->pcidev->irq)
                        free_irq(phba->pcidev->irq, phba);
 -              }
        pci_disable_msix(phba->pcidev);
        cancel_delayed_work_sync(&phba->beiscsi_hw_check_task);
  
  
  static void beiscsi_remove(struct pci_dev *pcidev)
  {
 -
        struct beiscsi_hba *phba = NULL;
  
        phba = pci_get_drvdata(pcidev);
        }
  
        beiscsi_destroy_def_ifaces(phba);
 -      beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
        iscsi_boot_destroy_kset(phba->boot_kset);
        iscsi_host_remove(phba->shost);
 +      beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
        pci_dev_put(phba->pcidev);
        iscsi_host_free(phba->shost);
        pci_disable_pcie_error_reporting(pcidev);
        pci_disable_device(pcidev);
  }
  
 -static void beiscsi_shutdown(struct pci_dev *pcidev)
 -{
 -
 -      struct beiscsi_hba *phba = NULL;
 -
 -      phba = (struct beiscsi_hba *)pci_get_drvdata(pcidev);
 -      if (!phba) {
 -              dev_err(&pcidev->dev, "beiscsi_shutdown called with no phba\n");
 -              return;
 -      }
 -
 -      phba->state = BE_ADAPTER_STATE_SHUTDOWN;
 -      iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session);
 -      beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD);
 -      pci_disable_device(pcidev);
 -}
 -
  static void beiscsi_msix_enable(struct beiscsi_hba *phba)
  {
        int i, status;
@@@ -5418,7 -5414,7 +5419,7 @@@ static void be_eqd_update(struct beiscs
        if (num) {
                tag = be_cmd_modify_eq_delay(phba, set_eqd, num);
                if (tag)
 -                      beiscsi_mccq_compl(phba, tag, NULL, NULL);
 +                      beiscsi_mccq_compl_wait(phba, tag, NULL, NULL);
        }
  }
  
@@@ -5569,17 -5565,11 +5570,17 @@@ static void beiscsi_eeh_resume(struct p
        phba->shost->max_id = phba->params.cxns_per_ctrl;
        phba->shost->can_queue = phba->params.ios_per_ctrl;
        ret = hwi_init_controller(phba);
 +      if (ret) {
 +              beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
 +                          "BM_%d : beiscsi_eeh_resume -"
 +                           "Failed to initialize beiscsi_hba.\n");
 +              goto ret_err;
 +      }
  
        for (i = 0; i < MAX_MCC_CMD; i++) {
                init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
                phba->ctrl.mcc_tag[i] = i + 1;
 -              phba->ctrl.mcc_numtag[i + 1] = 0;
 +              phba->ctrl.mcc_tag_status[i + 1] = 0;
                phba->ctrl.mcc_tag_available++;
        }
  
@@@ -5681,9 -5671,6 +5682,9 @@@ static int beiscsi_dev_probe(struct pci
                goto hba_free;
        }
  
 +      /*
 +       * FUNCTION_RESET should clean up any stale info in FW for this fn
 +       */
        ret = beiscsi_cmd_reset_function(phba);
        if (ret) {
                beiscsi_log(phba, KERN_ERR, BEISCSI_LOG_INIT,
                            "BM_%d : Error getting fw config\n");
                goto free_port;
        }
 +      mgmt_get_port_name(&phba->ctrl, phba);
 +      beiscsi_get_params(phba);
  
        if (enable_msix)
                find_num_cpus(phba);
        }
  
        phba->shost->max_id = phba->params.cxns_per_ctrl;
 -      beiscsi_get_params(phba);
        phba->shost->can_queue = phba->params.ios_per_ctrl;
        ret = beiscsi_init_port(phba);
        if (ret < 0) {
        for (i = 0; i < MAX_MCC_CMD; i++) {
                init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
                phba->ctrl.mcc_tag[i] = i + 1;
 -              phba->ctrl.mcc_numtag[i + 1] = 0;
 +              phba->ctrl.mcc_tag_status[i + 1] = 0;
                phba->ctrl.mcc_tag_available++;
                memset(&phba->ctrl.ptag_state[i].tag_mem_state, 0,
                       sizeof(struct be_dma_mem));
@@@ -5872,6 -5858,7 +5873,6 @@@ static struct pci_driver beiscsi_pci_dr
        .name = DRV_NAME,
        .probe = beiscsi_dev_probe,
        .remove = beiscsi_remove,
 -      .shutdown = beiscsi_shutdown,
        .id_table = beiscsi_pci_id_table,
        .err_handler = &beiscsi_eeh_handlers
  };
diff --combined drivers/scsi/scsi_lib.c
index d46193a5e24651e63cad394e378995b10facf034,8c6e31874171b47459232d74f882328cdb967efb..8106515d1df8c048174b0a7fdc239eedc265f6fa
@@@ -1344,6 -1344,7 +1344,7 @@@ scsi_prep_return(struct request_queue *
  
        switch (ret) {
        case BLKPREP_KILL:
+       case BLKPREP_INVALID:
                req->errors = DID_NO_CONNECT << 16;
                /* release the command and kill it */
                if (req->special) {
@@@ -2699,7 -2700,6 +2700,7 @@@ static void scsi_evt_emit(struct scsi_d
                envp[idx++] = "SDEV_MEDIA_CHANGE=1";
                break;
        case SDEV_EVT_INQUIRY_CHANGE_REPORTED:
 +              scsi_rescan_device(&sdev->sdev_gendev);
                envp[idx++] = "SDEV_UA=INQUIRY_DATA_HAS_CHANGED";
                break;
        case SDEV_EVT_CAPACITY_CHANGE_REPORTED:
This page took 0.093315 seconds and 4 git commands to generate.