aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_main.c
diff options
context:
space:
mode:
authorJayamohan Kallickal <jayamohank@serverengines.com>2010-01-04 18:40:46 -0500
committerJames Bottomley <James.Bottomley@suse.de>2010-01-18 11:48:23 -0500
commit756d29c8c7ed8887ed7d752371ce2f6d12399267 (patch)
treeeb70b756dc22a798538b306010647b72709a6206 /drivers/scsi/be2iscsi/be_main.c
parent51a462500fbed4a1e8110dc60a421a3f12b9580b (diff)
[SCSI] be2iscsi: Enable async mode for mcc rings
This patches enables async mode for mcc rings so that multiple requests can be queued. Signed-off-by: Jayamohan Kallickal <jayamohank@serverengines.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi/be2iscsi/be_main.c')
-rw-r--r--drivers/scsi/be2iscsi/be_main.c83
1 files changed, 75 insertions, 8 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 6170548a5289..a6a2c6469677 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -442,7 +442,7 @@ static irqreturn_t be_isr(int irq, void *dev_id)
442 if (phba->todo_mcc_cq) 442 if (phba->todo_mcc_cq)
443 queue_work(phba->wq, &phba->work_cqs); 443 queue_work(phba->wq, &phba->work_cqs);
444 444
445 if ((num_mcceq_processed) && (!num_ioeq_processed)) 445 if ((num_mcceq_processed) && (!num_ioeq_processed))
446 hwi_ring_eq_db(phba, eq->id, 0, 446 hwi_ring_eq_db(phba, eq->id, 0,
447 (num_ioeq_processed + 447 (num_ioeq_processed +
448 num_mcceq_processed) , 1, 1); 448 num_mcceq_processed) , 1, 1);
@@ -651,7 +651,6 @@ struct wrb_handle *alloc_wrb_handle(struct beiscsi_hba *phba, unsigned int cid)
651 pwrb_context->alloc_index = 0; 651 pwrb_context->alloc_index = 0;
652 else 652 else
653 pwrb_context->alloc_index++; 653 pwrb_context->alloc_index++;
654
655 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[ 654 pwrb_handle_tmp = pwrb_context->pwrb_handle_base[
656 pwrb_context->alloc_index]; 655 pwrb_context->alloc_index];
657 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index; 656 pwrb_handle->nxt_wrb_index = pwrb_handle_tmp->wrb_index;
@@ -791,6 +790,7 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn,
791 memcpy(task->sc->sense_buffer, sense, 790 memcpy(task->sc->sense_buffer, sense,
792 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE)); 791 min_t(u16, sense_len, SCSI_SENSE_BUFFERSIZE));
793 } 792 }
793
794 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) { 794 if (io_task->cmd_bhs->iscsi_hdr.flags & ISCSI_FLAG_CMD_READ) {
795 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32] 795 if (psol->dw[offsetof(struct amap_sol_cqe, i_res_cnt) / 32]
796 & SOL_RES_CNT_MASK) 796 & SOL_RES_CNT_MASK)
@@ -1432,6 +1432,48 @@ static void hwi_process_default_pdu_ring(struct beiscsi_conn *beiscsi_conn,
1432 hwi_post_async_buffers(phba, pasync_handle->is_header); 1432 hwi_post_async_buffers(phba, pasync_handle->is_header);
1433} 1433}
1434 1434
1435static void beiscsi_process_mcc_isr(struct beiscsi_hba *phba)
1436{
1437 struct be_queue_info *mcc_cq;
1438 struct be_mcc_compl *mcc_compl;
1439 unsigned int num_processed = 0;
1440
1441 mcc_cq = &phba->ctrl.mcc_obj.cq;
1442 mcc_compl = queue_tail_node(mcc_cq);
1443 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1444 while (mcc_compl->flags & CQE_FLAGS_VALID_MASK) {
1445
1446 if (num_processed >= 32) {
1447 hwi_ring_cq_db(phba, mcc_cq->id,
1448 num_processed, 0, 0);
1449 num_processed = 0;
1450 }
1451 if (mcc_compl->flags & CQE_FLAGS_ASYNC_MASK) {
1452 /* Interpret flags as an async trailer */
1453 if (is_link_state_evt(mcc_compl->flags))
1454 /* Interpret compl as a async link evt */
1455 beiscsi_async_link_state_process(phba,
1456 (struct be_async_event_link_state *) mcc_compl);
1457 else
1458 SE_DEBUG(DBG_LVL_1,
1459 " Unsupported Async Event, flags"
1460 " = 0x%08x \n", mcc_compl->flags);
1461 } else if (mcc_compl->flags & CQE_FLAGS_COMPLETED_MASK) {
1462 be_mcc_compl_process_isr(&phba->ctrl, mcc_compl);
1463 atomic_dec(&phba->ctrl.mcc_obj.q.used);
1464 }
1465
1466 mcc_compl->flags = 0;
1467 queue_tail_inc(mcc_cq);
1468 mcc_compl = queue_tail_node(mcc_cq);
1469 mcc_compl->flags = le32_to_cpu(mcc_compl->flags);
1470 num_processed++;
1471 }
1472
1473 if (num_processed > 0)
1474 hwi_ring_cq_db(phba, mcc_cq->id, num_processed, 1, 0);
1475
1476}
1435 1477
1436static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq) 1478static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1437{ 1479{
@@ -1468,6 +1510,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1468 } 1510 }
1469 beiscsi_ep = ep->dd_data; 1511 beiscsi_ep = ep->dd_data;
1470 beiscsi_conn = beiscsi_ep->conn; 1512 beiscsi_conn = beiscsi_ep->conn;
1513
1471 if (num_processed >= 32) { 1514 if (num_processed >= 32) {
1472 hwi_ring_cq_db(phba, cq->id, 1515 hwi_ring_cq_db(phba, cq->id,
1473 num_processed, 0, 0); 1516 num_processed, 0, 0);
@@ -1603,7 +1646,7 @@ static unsigned int beiscsi_process_cq(struct be_eq_obj *pbe_eq)
1603 return tot_nump; 1646 return tot_nump;
1604} 1647}
1605 1648
1606static void beiscsi_process_all_cqs(struct work_struct *work) 1649void beiscsi_process_all_cqs(struct work_struct *work)
1607{ 1650{
1608 unsigned long flags; 1651 unsigned long flags;
1609 struct hwi_controller *phwi_ctrlr; 1652 struct hwi_controller *phwi_ctrlr;
@@ -1623,6 +1666,7 @@ static void beiscsi_process_all_cqs(struct work_struct *work)
1623 spin_lock_irqsave(&phba->isr_lock, flags); 1666 spin_lock_irqsave(&phba->isr_lock, flags);
1624 phba->todo_mcc_cq = 0; 1667 phba->todo_mcc_cq = 0;
1625 spin_unlock_irqrestore(&phba->isr_lock, flags); 1668 spin_unlock_irqrestore(&phba->isr_lock, flags);
1669 beiscsi_process_mcc_isr(phba);
1626 } 1670 }
1627 1671
1628 if (phba->todo_cq) { 1672 if (phba->todo_cq) {
@@ -3160,6 +3204,7 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3160 struct be_queue_info *eq; 3204 struct be_queue_info *eq;
3161 struct be_eq_entry *eqe = NULL; 3205 struct be_eq_entry *eqe = NULL;
3162 int i, eq_msix; 3206 int i, eq_msix;
3207 unsigned int num_processed;
3163 3208
3164 phwi_ctrlr = phba->phwi_ctrlr; 3209 phwi_ctrlr = phba->phwi_ctrlr;
3165 phwi_context = phwi_ctrlr->phwi_ctxt; 3210 phwi_context = phwi_ctrlr->phwi_ctxt;
@@ -3171,13 +3216,17 @@ static void hwi_purge_eq(struct beiscsi_hba *phba)
3171 for (i = 0; i < (phba->num_cpus + eq_msix); i++) { 3216 for (i = 0; i < (phba->num_cpus + eq_msix); i++) {
3172 eq = &phwi_context->be_eq[i].q; 3217 eq = &phwi_context->be_eq[i].q;
3173 eqe = queue_tail_node(eq); 3218 eqe = queue_tail_node(eq);
3174 3219 num_processed = 0;
3175 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32] 3220 while (eqe->dw[offsetof(struct amap_eq_entry, valid) / 32]
3176 & EQE_VALID_MASK) { 3221 & EQE_VALID_MASK) {
3177 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0); 3222 AMAP_SET_BITS(struct amap_eq_entry, valid, eqe, 0);
3178 queue_tail_inc(eq); 3223 queue_tail_inc(eq);
3179 eqe = queue_tail_node(eq); 3224 eqe = queue_tail_node(eq);
3225 num_processed++;
3180 } 3226 }
3227
3228 if (num_processed)
3229 hwi_ring_eq_db(phba, eq->id, 1, num_processed, 1, 1);
3181 } 3230 }
3182} 3231}
3183 3232
@@ -3189,8 +3238,9 @@ static void beiscsi_clean_port(struct beiscsi_hba *phba)
3189 if (mgmt_status) 3238 if (mgmt_status)
3190 shost_printk(KERN_WARNING, phba->shost, 3239 shost_printk(KERN_WARNING, phba->shost,
3191 "mgmt_epfw_cleanup FAILED \n"); 3240 "mgmt_epfw_cleanup FAILED \n");
3192 hwi_cleanup(phba); 3241
3193 hwi_purge_eq(phba); 3242 hwi_purge_eq(phba);
3243 hwi_cleanup(phba);
3194 if (ring_mode) 3244 if (ring_mode)
3195 kfree(phba->sgl_hndl_array); 3245 kfree(phba->sgl_hndl_array);
3196 kfree(phba->io_sgl_hndl_base); 3246 kfree(phba->io_sgl_hndl_base);
@@ -3519,6 +3569,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3519 unsigned int doorbell = 0; 3569 unsigned int doorbell = 0;
3520 unsigned int i, cid; 3570 unsigned int i, cid;
3521 struct iscsi_task *aborted_task; 3571 struct iscsi_task *aborted_task;
3572 unsigned int tag;
3522 3573
3523 cid = beiscsi_conn->beiscsi_conn_cid; 3574 cid = beiscsi_conn->beiscsi_conn_cid;
3524 pwrb = io_task->pwrb_handle->pwrb; 3575 pwrb = io_task->pwrb_handle->pwrb;
@@ -3550,7 +3601,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
3550 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3601 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3551 else 3602 else
3552 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1); 3603 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 1);
3553
3554 hwi_write_buffer(pwrb, task); 3604 hwi_write_buffer(pwrb, task);
3555 break; 3605 break;
3556 case ISCSI_OP_TEXT: 3606 case ISCSI_OP_TEXT:
@@ -3579,9 +3629,18 @@ static int beiscsi_mtask(struct iscsi_task *task)
3579 if (!aborted_io_task->scsi_cmnd) 3629 if (!aborted_io_task->scsi_cmnd)
3580 return 0; 3630 return 0;
3581 3631
3582 mgmt_invalidate_icds(phba, 3632 tag = mgmt_invalidate_icds(phba,
3583 aborted_io_task->psgl_handle->sgl_index, 3633 aborted_io_task->psgl_handle->sgl_index,
3584 cid); 3634 cid);
3635 if (!tag) {
3636 shost_printk(KERN_WARNING, phba->shost,
3637 "mgmt_invalidate_icds could not be"
3638 " submitted\n");
3639 } else {
3640 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
3641 phba->ctrl.mcc_numtag[tag]);
3642 free_mcc_tag(&phba->ctrl, tag);
3643 }
3585 if (ring_mode) 3644 if (ring_mode)
3586 io_task->psgl_handle->type = INI_TMF_CMD; 3645 io_task->psgl_handle->type = INI_TMF_CMD;
3587 else 3646 else
@@ -3656,7 +3715,6 @@ static int beiscsi_task_xmit(struct iscsi_task *task)
3656 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir); 3715 return beiscsi_iotask(task, sg, num_sg, xferlen, writedir);
3657} 3716}
3658 3717
3659
3660static void beiscsi_remove(struct pci_dev *pcidev) 3718static void beiscsi_remove(struct pci_dev *pcidev)
3661{ 3719{
3662 struct beiscsi_hba *phba = NULL; 3720 struct beiscsi_hba *phba = NULL;
@@ -3776,6 +3834,15 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3776 goto free_port; 3834 goto free_port;
3777 } 3835 }
3778 3836
3837 for (i = 0; i < MAX_MCC_CMD ; i++) {
3838 init_waitqueue_head(&phba->ctrl.mcc_wait[i + 1]);
3839 phba->ctrl.mcc_tag[i] = i + 1;
3840 phba->ctrl.mcc_numtag[i + 1] = 0;
3841 phba->ctrl.mcc_tag_available++;
3842 }
3843
3844 phba->ctrl.mcc_alloc_index = phba->ctrl.mcc_free_index = 0;
3845
3779 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u", 3846 snprintf(phba->wq_name, sizeof(phba->wq_name), "beiscsi_q_irq%u",
3780 phba->shost->host_no); 3847 phba->shost->host_no);
3781 phba->wq = create_workqueue(phba->wq_name); 3848 phba->wq = create_workqueue(phba->wq_name);