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