aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/be2iscsi/be_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/be2iscsi/be_main.c')
-rw-r--r--drivers/scsi/be2iscsi/be_main.c201
1 files changed, 142 insertions, 59 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 7c22616ab141..fcfb29e02d8a 100644
--- a/drivers/scsi/be2iscsi/be_main.c
+++ b/drivers/scsi/be2iscsi/be_main.c
@@ -58,6 +58,123 @@ static int beiscsi_slave_configure(struct scsi_device *sdev)
58 return 0; 58 return 0;
59} 59}
60 60
61static int beiscsi_eh_abort(struct scsi_cmnd *sc)
62{
63 struct iscsi_cls_session *cls_session;
64 struct iscsi_task *aborted_task = (struct iscsi_task *)sc->SCp.ptr;
65 struct beiscsi_io_task *aborted_io_task;
66 struct iscsi_conn *conn;
67 struct beiscsi_conn *beiscsi_conn;
68 struct beiscsi_hba *phba;
69 struct iscsi_session *session;
70 struct invalidate_command_table *inv_tbl;
71 unsigned int cid, tag, num_invalidate;
72
73 cls_session = starget_to_session(scsi_target(sc->device));
74 session = cls_session->dd_data;
75
76 spin_lock_bh(&session->lock);
77 if (!aborted_task || !aborted_task->sc) {
78 /* we raced */
79 spin_unlock_bh(&session->lock);
80 return SUCCESS;
81 }
82
83 aborted_io_task = aborted_task->dd_data;
84 if (!aborted_io_task->scsi_cmnd) {
85 /* raced or invalid command */
86 spin_unlock_bh(&session->lock);
87 return SUCCESS;
88 }
89 spin_unlock_bh(&session->lock);
90 conn = aborted_task->conn;
91 beiscsi_conn = conn->dd_data;
92 phba = beiscsi_conn->phba;
93
94 /* invalidate iocb */
95 cid = beiscsi_conn->beiscsi_conn_cid;
96 inv_tbl = phba->inv_tbl;
97 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
98 inv_tbl->cid = cid;
99 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
100 num_invalidate = 1;
101 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
102 if (!tag) {
103 shost_printk(KERN_WARNING, phba->shost,
104 "mgmt_invalidate_icds could not be"
105 " submitted\n");
106 return FAILED;
107 } else {
108 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
109 phba->ctrl.mcc_numtag[tag]);
110 free_mcc_tag(&phba->ctrl, tag);
111 }
112
113 return iscsi_eh_abort(sc);
114}
115
116static int beiscsi_eh_device_reset(struct scsi_cmnd *sc)
117{
118 struct iscsi_task *abrt_task;
119 struct beiscsi_io_task *abrt_io_task;
120 struct iscsi_conn *conn;
121 struct beiscsi_conn *beiscsi_conn;
122 struct beiscsi_hba *phba;
123 struct iscsi_session *session;
124 struct iscsi_cls_session *cls_session;
125 struct invalidate_command_table *inv_tbl;
126 unsigned int cid, tag, i, num_invalidate;
127 int rc = FAILED;
128
129 /* invalidate iocbs */
130 cls_session = starget_to_session(scsi_target(sc->device));
131 session = cls_session->dd_data;
132 spin_lock_bh(&session->lock);
133 if (!session->leadconn || session->state != ISCSI_STATE_LOGGED_IN)
134 goto unlock;
135
136 conn = session->leadconn;
137 beiscsi_conn = conn->dd_data;
138 phba = beiscsi_conn->phba;
139 cid = beiscsi_conn->beiscsi_conn_cid;
140 inv_tbl = phba->inv_tbl;
141 memset(inv_tbl, 0x0, sizeof(*inv_tbl) * BE2_CMDS_PER_CXN);
142 num_invalidate = 0;
143 for (i = 0; i < conn->session->cmds_max; i++) {
144 abrt_task = conn->session->cmds[i];
145 abrt_io_task = abrt_task->dd_data;
146 if (!abrt_task->sc || abrt_task->state == ISCSI_TASK_FREE)
147 continue;
148
149 if (abrt_task->sc->device->lun != abrt_task->sc->device->lun)
150 continue;
151
152 inv_tbl->cid = cid;
153 inv_tbl->icd = abrt_io_task->psgl_handle->sgl_index;
154 num_invalidate++;
155 inv_tbl++;
156 }
157 spin_unlock_bh(&session->lock);
158 inv_tbl = phba->inv_tbl;
159
160 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
161 if (!tag) {
162 shost_printk(KERN_WARNING, phba->shost,
163 "mgmt_invalidate_icds could not be"
164 " submitted\n");
165 return FAILED;
166 } else {
167 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
168 phba->ctrl.mcc_numtag[tag]);
169 free_mcc_tag(&phba->ctrl, tag);
170 }
171
172 return iscsi_eh_device_reset(sc);
173unlock:
174 spin_unlock_bh(&session->lock);
175 return rc;
176}
177
61/*------------------- PCI Driver operations and data ----------------- */ 178/*------------------- PCI Driver operations and data ----------------- */
62static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = { 179static DEFINE_PCI_DEVICE_TABLE(beiscsi_pci_id_table) = {
63 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) }, 180 { PCI_DEVICE(BE_VENDOR_ID, BE_DEVICE_ID1) },
@@ -74,12 +191,12 @@ static struct scsi_host_template beiscsi_sht = {
74 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver", 191 .name = "ServerEngines 10Gbe open-iscsi Initiator Driver",
75 .proc_name = DRV_NAME, 192 .proc_name = DRV_NAME,
76 .queuecommand = iscsi_queuecommand, 193 .queuecommand = iscsi_queuecommand,
77 .eh_abort_handler = iscsi_eh_abort,
78 .change_queue_depth = iscsi_change_queue_depth, 194 .change_queue_depth = iscsi_change_queue_depth,
79 .slave_configure = beiscsi_slave_configure, 195 .slave_configure = beiscsi_slave_configure,
80 .target_alloc = iscsi_target_alloc, 196 .target_alloc = iscsi_target_alloc,
81 .eh_device_reset_handler = iscsi_eh_device_reset, 197 .eh_abort_handler = beiscsi_eh_abort,
82 .eh_target_reset_handler = iscsi_eh_target_reset, 198 .eh_device_reset_handler = beiscsi_eh_device_reset,
199 .eh_target_reset_handler = iscsi_eh_session_reset,
83 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS, 200 .sg_tablesize = BEISCSI_SGLIST_ELEMENTS,
84 .can_queue = BE2_IO_DEPTH, 201 .can_queue = BE2_IO_DEPTH,
85 .this_id = -1, 202 .this_id = -1,
@@ -242,7 +359,7 @@ static void beiscsi_get_params(struct beiscsi_hba *phba)
242 + BE2_TMFS 359 + BE2_TMFS
243 + BE2_NOPOUT_REQ)); 360 + BE2_NOPOUT_REQ));
244 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count; 361 phba->params.cxns_per_ctrl = phba->fw_config.iscsi_cid_count;
245 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count;; 362 phba->params.asyncpdus_per_ctrl = phba->fw_config.iscsi_cid_count * 2;
246 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;; 363 phba->params.icds_per_ctrl = phba->fw_config.iscsi_icd_count;;
247 phba->params.num_sge_per_io = BE2_SGE; 364 phba->params.num_sge_per_io = BE2_SGE;
248 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ; 365 phba->params.defpdu_hdr_sz = BE2_DEFPDU_HDR_SZ;
@@ -946,14 +1063,18 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
946 case HWH_TYPE_IO: 1063 case HWH_TYPE_IO:
947 case HWH_TYPE_IO_RD: 1064 case HWH_TYPE_IO_RD:
948 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == 1065 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) ==
949 ISCSI_OP_NOOP_OUT) { 1066 ISCSI_OP_NOOP_OUT)
950 be_complete_nopin_resp(beiscsi_conn, task, psol); 1067 be_complete_nopin_resp(beiscsi_conn, task, psol);
951 } else 1068 else
952 be_complete_io(beiscsi_conn, task, psol); 1069 be_complete_io(beiscsi_conn, task, psol);
953 break; 1070 break;
954 1071
955 case HWH_TYPE_LOGOUT: 1072 case HWH_TYPE_LOGOUT:
956 be_complete_logout(beiscsi_conn, task, psol); 1073 if ((task->hdr->opcode & ISCSI_OPCODE_MASK) == ISCSI_OP_LOGOUT)
1074 be_complete_logout(beiscsi_conn, task, psol);
1075 else
1076 be_complete_tmf(beiscsi_conn, task, psol);
1077
957 break; 1078 break;
958 1079
959 case HWH_TYPE_LOGIN: 1080 case HWH_TYPE_LOGIN:
@@ -962,10 +1083,6 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn,
962 "- Solicited path \n"); 1083 "- Solicited path \n");
963 break; 1084 break;
964 1085
965 case HWH_TYPE_TMF:
966 be_complete_tmf(beiscsi_conn, task, psol);
967 break;
968
969 case HWH_TYPE_NOP: 1086 case HWH_TYPE_NOP:
970 be_complete_nopin_resp(beiscsi_conn, task, psol); 1087 be_complete_nopin_resp(beiscsi_conn, task, psol);
971 break; 1088 break;
@@ -2052,7 +2169,7 @@ static void beiscsi_init_wrb_handle(struct beiscsi_hba *phba)
2052 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) / 2169 num_cxn_wrb = (mem_descr_wrb->mem_array[idx].size) /
2053 ((sizeof(struct iscsi_wrb) * 2170 ((sizeof(struct iscsi_wrb) *
2054 phba->params.wrbs_per_cxn)); 2171 phba->params.wrbs_per_cxn));
2055 for (index = 0; index < phba->params.cxns_per_ctrl; index += 2) { 2172 for (index = 0; index < phba->params.cxns_per_ctrl * 2; index += 2) {
2056 pwrb_context = &phwi_ctrlr->wrb_context[index]; 2173 pwrb_context = &phwi_ctrlr->wrb_context[index];
2057 if (num_cxn_wrb) { 2174 if (num_cxn_wrb) {
2058 for (j = 0; j < phba->params.wrbs_per_cxn; j++) { 2175 for (j = 0; j < phba->params.wrbs_per_cxn; j++) {
@@ -3073,14 +3190,18 @@ static unsigned char hwi_enable_intr(struct beiscsi_hba *phba)
3073 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK; 3190 reg |= MEMBAR_CTRL_INT_CTRL_HOSTINTR_MASK;
3074 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr); 3191 SE_DEBUG(DBG_LVL_8, "reg =x%08x addr=%p \n", reg, addr);
3075 iowrite32(reg, addr); 3192 iowrite32(reg, addr);
3076 for (i = 0; i <= phba->num_cpus; i++) { 3193 if (!phba->msix_enabled) {
3077 eq = &phwi_context->be_eq[i].q; 3194 eq = &phwi_context->be_eq[0].q;
3078 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id); 3195 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
3079 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1); 3196 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
3197 } else {
3198 for (i = 0; i <= phba->num_cpus; i++) {
3199 eq = &phwi_context->be_eq[i].q;
3200 SE_DEBUG(DBG_LVL_8, "eq->id=%d \n", eq->id);
3201 hwi_ring_eq_db(phba, eq->id, 0, 0, 1, 1);
3202 }
3080 } 3203 }
3081 } else 3204 }
3082 shost_printk(KERN_WARNING, phba->shost,
3083 "In hwi_enable_intr, Not Enabled \n");
3084 return true; 3205 return true;
3085} 3206}
3086 3207
@@ -3476,19 +3597,13 @@ static int beiscsi_iotask(struct iscsi_task *task, struct scatterlist *sg,
3476 3597
3477static int beiscsi_mtask(struct iscsi_task *task) 3598static int beiscsi_mtask(struct iscsi_task *task)
3478{ 3599{
3479 struct beiscsi_io_task *aborted_io_task, *io_task = task->dd_data; 3600 struct beiscsi_io_task *io_task = task->dd_data;
3480 struct iscsi_conn *conn = task->conn; 3601 struct iscsi_conn *conn = task->conn;
3481 struct beiscsi_conn *beiscsi_conn = conn->dd_data; 3602 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3482 struct beiscsi_hba *phba = beiscsi_conn->phba; 3603 struct beiscsi_hba *phba = beiscsi_conn->phba;
3483 struct iscsi_session *session;
3484 struct iscsi_wrb *pwrb = NULL; 3604 struct iscsi_wrb *pwrb = NULL;
3485 struct hwi_controller *phwi_ctrlr;
3486 struct hwi_wrb_context *pwrb_context;
3487 struct wrb_handle *pwrb_handle;
3488 unsigned int doorbell = 0; 3605 unsigned int doorbell = 0;
3489 unsigned int i, cid; 3606 unsigned int cid;
3490 struct iscsi_task *aborted_task;
3491 unsigned int tag;
3492 3607
3493 cid = beiscsi_conn->beiscsi_conn_cid; 3608 cid = beiscsi_conn->beiscsi_conn_cid;
3494 pwrb = io_task->pwrb_handle->pwrb; 3609 pwrb = io_task->pwrb_handle->pwrb;
@@ -3499,6 +3614,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3499 io_task->pwrb_handle->wrb_index); 3614 io_task->pwrb_handle->wrb_index);
3500 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb, 3615 AMAP_SET_BITS(struct amap_iscsi_wrb, sgl_icd_idx, pwrb,
3501 io_task->psgl_handle->sgl_index); 3616 io_task->psgl_handle->sgl_index);
3617
3502 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) { 3618 switch (task->hdr->opcode & ISCSI_OPCODE_MASK) {
3503 case ISCSI_OP_LOGIN: 3619 case ISCSI_OP_LOGIN:
3504 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3620 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
@@ -3523,33 +3639,6 @@ static int beiscsi_mtask(struct iscsi_task *task)
3523 hwi_write_buffer(pwrb, task); 3639 hwi_write_buffer(pwrb, task);
3524 break; 3640 break;
3525 case ISCSI_OP_SCSI_TMFUNC: 3641 case ISCSI_OP_SCSI_TMFUNC:
3526 session = conn->session;
3527 i = ((struct iscsi_tm *)task->hdr)->rtt;
3528 phwi_ctrlr = phba->phwi_ctrlr;
3529 pwrb_context = &phwi_ctrlr->wrb_context[cid -
3530 phba->fw_config.iscsi_cid_start];
3531 pwrb_handle = pwrb_context->pwrb_handle_basestd[be32_to_cpu(i)
3532 >> 16];
3533 aborted_task = pwrb_handle->pio_handle;
3534 if (!aborted_task)
3535 return 0;
3536
3537 aborted_io_task = aborted_task->dd_data;
3538 if (!aborted_io_task->scsi_cmnd)
3539 return 0;
3540
3541 tag = mgmt_invalidate_icds(phba,
3542 aborted_io_task->psgl_handle->sgl_index,
3543 cid);
3544 if (!tag) {
3545 shost_printk(KERN_WARNING, phba->shost,
3546 "mgmt_invalidate_icds could not be"
3547 " submitted\n");
3548 } else {
3549 wait_event_interruptible(phba->ctrl.mcc_wait[tag],
3550 phba->ctrl.mcc_numtag[tag]);
3551 free_mcc_tag(&phba->ctrl, tag);
3552 }
3553 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3642 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3554 INI_TMF_CMD); 3643 INI_TMF_CMD);
3555 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3644 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
@@ -3558,7 +3647,7 @@ static int beiscsi_mtask(struct iscsi_task *task)
3558 case ISCSI_OP_LOGOUT: 3647 case ISCSI_OP_LOGOUT:
3559 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0); 3648 AMAP_SET_BITS(struct amap_iscsi_wrb, dmsg, pwrb, 0);
3560 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb, 3649 AMAP_SET_BITS(struct amap_iscsi_wrb, type, pwrb,
3561 HWH_TYPE_LOGOUT); 3650 HWH_TYPE_LOGOUT);
3562 hwi_write_buffer(pwrb, task); 3651 hwi_write_buffer(pwrb, task);
3563 break; 3652 break;
3564 3653
@@ -3584,17 +3673,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3584 3673
3585static int beiscsi_task_xmit(struct iscsi_task *task) 3674static int beiscsi_task_xmit(struct iscsi_task *task)
3586{ 3675{
3587 struct iscsi_conn *conn = task->conn;
3588 struct beiscsi_io_task *io_task = task->dd_data; 3676 struct beiscsi_io_task *io_task = task->dd_data;
3589 struct scsi_cmnd *sc = task->sc; 3677 struct scsi_cmnd *sc = task->sc;
3590 struct beiscsi_conn *beiscsi_conn = conn->dd_data;
3591 struct scatterlist *sg; 3678 struct scatterlist *sg;
3592 int num_sg; 3679 int num_sg;
3593 unsigned int writedir = 0, xferlen = 0; 3680 unsigned int writedir = 0, xferlen = 0;
3594 3681
3595 SE_DEBUG(DBG_LVL_4, "\n cid=%d In beiscsi_task_xmit task=%p conn=%p \t"
3596 "beiscsi_conn=%p \n", beiscsi_conn->beiscsi_conn_cid,
3597 task, conn, beiscsi_conn);
3598 if (!sc) 3682 if (!sc)
3599 return beiscsi_mtask(task); 3683 return beiscsi_mtask(task);
3600 3684
@@ -3699,7 +3783,6 @@ static int __devinit beiscsi_dev_probe(struct pci_dev *pcidev,
3699 " Failed in beiscsi_hba_alloc \n"); 3783 " Failed in beiscsi_hba_alloc \n");
3700 goto disable_pci; 3784 goto disable_pci;
3701 } 3785 }
3702 SE_DEBUG(DBG_LVL_8, " phba = %p \n", phba);
3703 3786
3704 switch (pcidev->device) { 3787 switch (pcidev->device) {
3705 case BE_DEVICE_ID1: 3788 case BE_DEVICE_ID1: