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.c134
1 files changed, 127 insertions, 7 deletions
diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c
index 4d269b434a78..eab31a515de3 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,11 +191,11 @@ 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,
198 .eh_device_reset_handler = beiscsi_eh_device_reset,
82 .eh_target_reset_handler = iscsi_eh_session_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,
@@ -3486,9 +3603,9 @@ static int beiscsi_mtask(struct iscsi_task *task)
3486 struct hwi_wrb_context *pwrb_context; 3603 struct hwi_wrb_context *pwrb_context;
3487 struct wrb_handle *pwrb_handle; 3604 struct wrb_handle *pwrb_handle;
3488 unsigned int doorbell = 0; 3605 unsigned int doorbell = 0;
3489 unsigned int i, cid; 3606 struct invalidate_command_table *inv_tbl;
3490 struct iscsi_task *aborted_task; 3607 struct iscsi_task *aborted_task;
3491 unsigned int tag; 3608 unsigned int i, cid, tag, num_invalidate;
3492 3609
3493 cid = beiscsi_conn->beiscsi_conn_cid; 3610 cid = beiscsi_conn->beiscsi_conn_cid;
3494 pwrb = io_task->pwrb_handle->pwrb; 3611 pwrb = io_task->pwrb_handle->pwrb;
@@ -3538,9 +3655,12 @@ static int beiscsi_mtask(struct iscsi_task *task)
3538 if (!aborted_io_task->scsi_cmnd) 3655 if (!aborted_io_task->scsi_cmnd)
3539 return 0; 3656 return 0;
3540 3657
3541 tag = mgmt_invalidate_icds(phba, 3658 inv_tbl = phba->inv_tbl;
3542 aborted_io_task->psgl_handle->sgl_index, 3659 memset(inv_tbl, 0x0, sizeof(*inv_tbl));
3543 cid); 3660 inv_tbl->cid = cid;
3661 inv_tbl->icd = aborted_io_task->psgl_handle->sgl_index;
3662 num_invalidate = 1;
3663 tag = mgmt_invalidate_icds(phba, inv_tbl, num_invalidate, cid);
3544 if (!tag) { 3664 if (!tag) {
3545 shost_printk(KERN_WARNING, phba->shost, 3665 shost_printk(KERN_WARNING, phba->shost,
3546 "mgmt_invalidate_icds could not be" 3666 "mgmt_invalidate_icds could not be"