GNU Linux-libre 4.4.284-gnu1
[releases.git] / drivers / scsi / qla2xxx / qla_bsg.c
1 /*
2  * QLogic Fibre Channel HBA Driver
3  * Copyright (c)  2003-2014 QLogic Corporation
4  *
5  * See LICENSE.qla2xxx for copyright and licensing details.
6  */
7 #include "qla_def.h"
8
9 #include <linux/kthread.h>
10 #include <linux/vmalloc.h>
11 #include <linux/delay.h>
12
13 /* BSG support for ELS/CT pass through */
14 void
15 qla2x00_bsg_job_done(void *data, void *ptr, int res)
16 {
17         srb_t *sp = (srb_t *)ptr;
18         struct scsi_qla_host *vha = (scsi_qla_host_t *)data;
19         struct fc_bsg_job *bsg_job = sp->u.bsg_job;
20
21         bsg_job->reply->result = res;
22         bsg_job->job_done(bsg_job);
23         sp->free(vha, sp);
24 }
25
26 void
27 qla2x00_bsg_sp_free(void *data, void *ptr)
28 {
29         srb_t *sp = (srb_t *)ptr;
30         struct scsi_qla_host *vha = sp->fcport->vha;
31         struct fc_bsg_job *bsg_job = sp->u.bsg_job;
32         struct qla_hw_data *ha = vha->hw;
33         struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
34
35         if (sp->type == SRB_FXIOCB_BCMD) {
36                 piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
37                     &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
38
39                 if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
40                         dma_unmap_sg(&ha->pdev->dev,
41                             bsg_job->request_payload.sg_list,
42                             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
43
44                 if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
45                         dma_unmap_sg(&ha->pdev->dev,
46                             bsg_job->reply_payload.sg_list,
47                             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
48         } else {
49                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
50                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
51
52                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
53                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
54         }
55
56         if (sp->type == SRB_CT_CMD ||
57             sp->type == SRB_FXIOCB_BCMD ||
58             sp->type == SRB_ELS_CMD_HST)
59                 kfree(sp->fcport);
60         qla2x00_rel_sp(vha, sp);
61 }
62
63 int
64 qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
65         struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
66 {
67         int i, ret, num_valid;
68         uint8_t *bcode;
69         struct qla_fcp_prio_entry *pri_entry;
70         uint32_t *bcode_val_ptr, bcode_val;
71
72         ret = 1;
73         num_valid = 0;
74         bcode = (uint8_t *)pri_cfg;
75         bcode_val_ptr = (uint32_t *)pri_cfg;
76         bcode_val = (uint32_t)(*bcode_val_ptr);
77
78         if (bcode_val == 0xFFFFFFFF) {
79                 /* No FCP Priority config data in flash */
80                 ql_dbg(ql_dbg_user, vha, 0x7051,
81                     "No FCP Priority config data.\n");
82                 return 0;
83         }
84
85         if (bcode[0] != 'H' || bcode[1] != 'Q' || bcode[2] != 'O' ||
86                         bcode[3] != 'S') {
87                 /* Invalid FCP priority data header*/
88                 ql_dbg(ql_dbg_user, vha, 0x7052,
89                     "Invalid FCP Priority data header. bcode=0x%x.\n",
90                     bcode_val);
91                 return 0;
92         }
93         if (flag != 1)
94                 return ret;
95
96         pri_entry = &pri_cfg->entry[0];
97         for (i = 0; i < pri_cfg->num_entries; i++) {
98                 if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
99                         num_valid++;
100                 pri_entry++;
101         }
102
103         if (num_valid == 0) {
104                 /* No valid FCP priority data entries */
105                 ql_dbg(ql_dbg_user, vha, 0x7053,
106                     "No valid FCP Priority data entries.\n");
107                 ret = 0;
108         } else {
109                 /* FCP priority data is valid */
110                 ql_dbg(ql_dbg_user, vha, 0x7054,
111                     "Valid FCP priority data. num entries = %d.\n",
112                     num_valid);
113         }
114
115         return ret;
116 }
117
118 static int
119 qla24xx_proc_fcp_prio_cfg_cmd(struct fc_bsg_job *bsg_job)
120 {
121         struct Scsi_Host *host = bsg_job->shost;
122         scsi_qla_host_t *vha = shost_priv(host);
123         struct qla_hw_data *ha = vha->hw;
124         int ret = 0;
125         uint32_t len;
126         uint32_t oper;
127
128         if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
129                 ret = -EINVAL;
130                 goto exit_fcp_prio_cfg;
131         }
132
133         /* Get the sub command */
134         oper = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
135
136         /* Only set config is allowed if config memory is not allocated */
137         if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
138                 ret = -EINVAL;
139                 goto exit_fcp_prio_cfg;
140         }
141         switch (oper) {
142         case QLFC_FCP_PRIO_DISABLE:
143                 if (ha->flags.fcp_prio_enabled) {
144                         ha->flags.fcp_prio_enabled = 0;
145                         ha->fcp_prio_cfg->attributes &=
146                                 ~FCP_PRIO_ATTR_ENABLE;
147                         qla24xx_update_all_fcp_prio(vha);
148                         bsg_job->reply->result = DID_OK;
149                 } else {
150                         ret = -EINVAL;
151                         bsg_job->reply->result = (DID_ERROR << 16);
152                         goto exit_fcp_prio_cfg;
153                 }
154                 break;
155
156         case QLFC_FCP_PRIO_ENABLE:
157                 if (!ha->flags.fcp_prio_enabled) {
158                         if (ha->fcp_prio_cfg) {
159                                 ha->flags.fcp_prio_enabled = 1;
160                                 ha->fcp_prio_cfg->attributes |=
161                                     FCP_PRIO_ATTR_ENABLE;
162                                 qla24xx_update_all_fcp_prio(vha);
163                                 bsg_job->reply->result = DID_OK;
164                         } else {
165                                 ret = -EINVAL;
166                                 bsg_job->reply->result = (DID_ERROR << 16);
167                                 goto exit_fcp_prio_cfg;
168                         }
169                 }
170                 break;
171
172         case QLFC_FCP_PRIO_GET_CONFIG:
173                 len = bsg_job->reply_payload.payload_len;
174                 if (!len || len > FCP_PRIO_CFG_SIZE) {
175                         ret = -EINVAL;
176                         bsg_job->reply->result = (DID_ERROR << 16);
177                         goto exit_fcp_prio_cfg;
178                 }
179
180                 bsg_job->reply->result = DID_OK;
181                 bsg_job->reply->reply_payload_rcv_len =
182                         sg_copy_from_buffer(
183                         bsg_job->reply_payload.sg_list,
184                         bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
185                         len);
186
187                 break;
188
189         case QLFC_FCP_PRIO_SET_CONFIG:
190                 len = bsg_job->request_payload.payload_len;
191                 if (!len || len > FCP_PRIO_CFG_SIZE) {
192                         bsg_job->reply->result = (DID_ERROR << 16);
193                         ret = -EINVAL;
194                         goto exit_fcp_prio_cfg;
195                 }
196
197                 if (!ha->fcp_prio_cfg) {
198                         ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
199                         if (!ha->fcp_prio_cfg) {
200                                 ql_log(ql_log_warn, vha, 0x7050,
201                                     "Unable to allocate memory for fcp prio "
202                                     "config data (%x).\n", FCP_PRIO_CFG_SIZE);
203                                 bsg_job->reply->result = (DID_ERROR << 16);
204                                 ret = -ENOMEM;
205                                 goto exit_fcp_prio_cfg;
206                         }
207                 }
208
209                 memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
210                 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
211                 bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
212                         FCP_PRIO_CFG_SIZE);
213
214                 /* validate fcp priority data */
215
216                 if (!qla24xx_fcp_prio_cfg_valid(vha,
217                     (struct qla_fcp_prio_cfg *) ha->fcp_prio_cfg, 1)) {
218                         bsg_job->reply->result = (DID_ERROR << 16);
219                         ret = -EINVAL;
220                         /* If buffer was invalidatic int
221                          * fcp_prio_cfg is of no use
222                          */
223                         vfree(ha->fcp_prio_cfg);
224                         ha->fcp_prio_cfg = NULL;
225                         goto exit_fcp_prio_cfg;
226                 }
227
228                 ha->flags.fcp_prio_enabled = 0;
229                 if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
230                         ha->flags.fcp_prio_enabled = 1;
231                 qla24xx_update_all_fcp_prio(vha);
232                 bsg_job->reply->result = DID_OK;
233                 break;
234         default:
235                 ret = -EINVAL;
236                 break;
237         }
238 exit_fcp_prio_cfg:
239         if (!ret)
240                 bsg_job->job_done(bsg_job);
241         return ret;
242 }
243
244 static int
245 qla2x00_process_els(struct fc_bsg_job *bsg_job)
246 {
247         struct fc_rport *rport;
248         fc_port_t *fcport = NULL;
249         struct Scsi_Host *host;
250         scsi_qla_host_t *vha;
251         struct qla_hw_data *ha;
252         srb_t *sp;
253         const char *type;
254         int req_sg_cnt, rsp_sg_cnt;
255         int rval =  (DID_ERROR << 16);
256         uint16_t nextlid = 0;
257
258         if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
259                 rport = bsg_job->rport;
260                 fcport = *(fc_port_t **) rport->dd_data;
261                 host = rport_to_shost(rport);
262                 vha = shost_priv(host);
263                 ha = vha->hw;
264                 type = "FC_BSG_RPT_ELS";
265         } else {
266                 host = bsg_job->shost;
267                 vha = shost_priv(host);
268                 ha = vha->hw;
269                 type = "FC_BSG_HST_ELS_NOLOGIN";
270         }
271
272         if (!vha->flags.online) {
273                 ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
274                 rval = -EIO;
275                 goto done;
276         }
277
278         /* pass through is supported only for ISP 4Gb or higher */
279         if (!IS_FWI2_CAPABLE(ha)) {
280                 ql_dbg(ql_dbg_user, vha, 0x7001,
281                     "ELS passthru not supported for ISP23xx based adapters.\n");
282                 rval = -EPERM;
283                 goto done;
284         }
285
286         /*  Multiple SG's are not supported for ELS requests */
287         if (bsg_job->request_payload.sg_cnt > 1 ||
288                 bsg_job->reply_payload.sg_cnt > 1) {
289                 ql_dbg(ql_dbg_user, vha, 0x7002,
290                     "Multiple SG's are not suppored for ELS requests, "
291                     "request_sg_cnt=%x reply_sg_cnt=%x.\n",
292                     bsg_job->request_payload.sg_cnt,
293                     bsg_job->reply_payload.sg_cnt);
294                 rval = -EPERM;
295                 goto done;
296         }
297
298         /* ELS request for rport */
299         if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
300                 /* make sure the rport is logged in,
301                  * if not perform fabric login
302                  */
303                 if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
304                         ql_dbg(ql_dbg_user, vha, 0x7003,
305                             "Failed to login port %06X for ELS passthru.\n",
306                             fcport->d_id.b24);
307                         rval = -EIO;
308                         goto done;
309                 }
310         } else {
311                 /* Allocate a dummy fcport structure, since functions
312                  * preparing the IOCB and mailbox command retrieves port
313                  * specific information from fcport structure. For Host based
314                  * ELS commands there will be no fcport structure allocated
315                  */
316                 fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
317                 if (!fcport) {
318                         rval = -ENOMEM;
319                         goto done;
320                 }
321
322                 /* Initialize all required  fields of fcport */
323                 fcport->vha = vha;
324                 fcport->d_id.b.al_pa =
325                         bsg_job->request->rqst_data.h_els.port_id[0];
326                 fcport->d_id.b.area =
327                         bsg_job->request->rqst_data.h_els.port_id[1];
328                 fcport->d_id.b.domain =
329                         bsg_job->request->rqst_data.h_els.port_id[2];
330                 fcport->loop_id =
331                         (fcport->d_id.b.al_pa == 0xFD) ?
332                         NPH_FABRIC_CONTROLLER : NPH_F_PORT;
333         }
334
335         req_sg_cnt =
336                 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
337                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
338         if (!req_sg_cnt) {
339                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
340                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
341                 rval = -ENOMEM;
342                 goto done_free_fcport;
343         }
344
345         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
346                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
347         if (!rsp_sg_cnt) {
348                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
349                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
350                 rval = -ENOMEM;
351                 goto done_free_fcport;
352         }
353
354         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
355                 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
356                 ql_log(ql_log_warn, vha, 0x7008,
357                     "dma mapping resulted in different sg counts, "
358                     "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
359                     "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
360                     req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
361                 rval = -EAGAIN;
362                 goto done_unmap_sg;
363         }
364
365         /* Alloc SRB structure */
366         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
367         if (!sp) {
368                 rval = -ENOMEM;
369                 goto done_unmap_sg;
370         }
371
372         sp->type =
373                 (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
374                 SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
375         sp->name =
376                 (bsg_job->request->msgcode == FC_BSG_RPT_ELS ?
377                 "bsg_els_rpt" : "bsg_els_hst");
378         sp->u.bsg_job = bsg_job;
379         sp->free = qla2x00_bsg_sp_free;
380         sp->done = qla2x00_bsg_job_done;
381
382         ql_dbg(ql_dbg_user, vha, 0x700a,
383             "bsg rqst type: %s els type: %x - loop-id=%x "
384             "portid=%-2x%02x%02x.\n", type,
385             bsg_job->request->rqst_data.h_els.command_code, fcport->loop_id,
386             fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
387
388         rval = qla2x00_start_sp(sp);
389         if (rval != QLA_SUCCESS) {
390                 ql_log(ql_log_warn, vha, 0x700e,
391                     "qla2x00_start_sp failed = %d\n", rval);
392                 qla2x00_rel_sp(vha, sp);
393                 rval = -EIO;
394                 goto done_unmap_sg;
395         }
396         return rval;
397
398 done_unmap_sg:
399         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
400                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
401         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
402                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
403         goto done_free_fcport;
404
405 done_free_fcport:
406         if (bsg_job->request->msgcode == FC_BSG_RPT_ELS)
407                 kfree(fcport);
408 done:
409         return rval;
410 }
411
412 static inline uint16_t
413 qla24xx_calc_ct_iocbs(uint16_t dsds)
414 {
415         uint16_t iocbs;
416
417         iocbs = 1;
418         if (dsds > 2) {
419                 iocbs += (dsds - 2) / 5;
420                 if ((dsds - 2) % 5)
421                         iocbs++;
422         }
423         return iocbs;
424 }
425
426 static int
427 qla2x00_process_ct(struct fc_bsg_job *bsg_job)
428 {
429         srb_t *sp;
430         struct Scsi_Host *host = bsg_job->shost;
431         scsi_qla_host_t *vha = shost_priv(host);
432         struct qla_hw_data *ha = vha->hw;
433         int rval = (DID_ERROR << 16);
434         int req_sg_cnt, rsp_sg_cnt;
435         uint16_t loop_id;
436         struct fc_port *fcport;
437         char  *type = "FC_BSG_HST_CT";
438
439         req_sg_cnt =
440                 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
441                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
442         if (!req_sg_cnt) {
443                 ql_log(ql_log_warn, vha, 0x700f,
444                     "dma_map_sg return %d for request\n", req_sg_cnt);
445                 rval = -ENOMEM;
446                 goto done;
447         }
448
449         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
450                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
451         if (!rsp_sg_cnt) {
452                 ql_log(ql_log_warn, vha, 0x7010,
453                     "dma_map_sg return %d for reply\n", rsp_sg_cnt);
454                 rval = -ENOMEM;
455                 goto done;
456         }
457
458         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
459             (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
460                 ql_log(ql_log_warn, vha, 0x7011,
461                     "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
462                     "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
463                     req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
464                 rval = -EAGAIN;
465                 goto done_unmap_sg;
466         }
467
468         if (!vha->flags.online) {
469                 ql_log(ql_log_warn, vha, 0x7012,
470                     "Host is not online.\n");
471                 rval = -EIO;
472                 goto done_unmap_sg;
473         }
474
475         loop_id =
476                 (bsg_job->request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
477                         >> 24;
478         switch (loop_id) {
479         case 0xFC:
480                 loop_id = cpu_to_le16(NPH_SNS);
481                 break;
482         case 0xFA:
483                 loop_id = vha->mgmt_svr_loop_id;
484                 break;
485         default:
486                 ql_dbg(ql_dbg_user, vha, 0x7013,
487                     "Unknown loop id: %x.\n", loop_id);
488                 rval = -EINVAL;
489                 goto done_unmap_sg;
490         }
491
492         /* Allocate a dummy fcport structure, since functions preparing the
493          * IOCB and mailbox command retrieves port specific information
494          * from fcport structure. For Host based ELS commands there will be
495          * no fcport structure allocated
496          */
497         fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
498         if (!fcport) {
499                 ql_log(ql_log_warn, vha, 0x7014,
500                     "Failed to allocate fcport.\n");
501                 rval = -ENOMEM;
502                 goto done_unmap_sg;
503         }
504
505         /* Initialize all required  fields of fcport */
506         fcport->vha = vha;
507         fcport->d_id.b.al_pa = bsg_job->request->rqst_data.h_ct.port_id[0];
508         fcport->d_id.b.area = bsg_job->request->rqst_data.h_ct.port_id[1];
509         fcport->d_id.b.domain = bsg_job->request->rqst_data.h_ct.port_id[2];
510         fcport->loop_id = loop_id;
511
512         /* Alloc SRB structure */
513         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
514         if (!sp) {
515                 ql_log(ql_log_warn, vha, 0x7015,
516                     "qla2x00_get_sp failed.\n");
517                 rval = -ENOMEM;
518                 goto done_free_fcport;
519         }
520
521         sp->type = SRB_CT_CMD;
522         sp->name = "bsg_ct";
523         sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
524         sp->u.bsg_job = bsg_job;
525         sp->free = qla2x00_bsg_sp_free;
526         sp->done = qla2x00_bsg_job_done;
527
528         ql_dbg(ql_dbg_user, vha, 0x7016,
529             "bsg rqst type: %s else type: %x - "
530             "loop-id=%x portid=%02x%02x%02x.\n", type,
531             (bsg_job->request->rqst_data.h_ct.preamble_word2 >> 16),
532             fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
533             fcport->d_id.b.al_pa);
534
535         rval = qla2x00_start_sp(sp);
536         if (rval != QLA_SUCCESS) {
537                 ql_log(ql_log_warn, vha, 0x7017,
538                     "qla2x00_start_sp failed=%d.\n", rval);
539                 qla2x00_rel_sp(vha, sp);
540                 rval = -EIO;
541                 goto done_free_fcport;
542         }
543         return rval;
544
545 done_free_fcport:
546         kfree(fcport);
547 done_unmap_sg:
548         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
549                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
550         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
551                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
552 done:
553         return rval;
554 }
555
556 /* Disable loopback mode */
557 static inline int
558 qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
559                             int wait, int wait2)
560 {
561         int ret = 0;
562         int rval = 0;
563         uint16_t new_config[4];
564         struct qla_hw_data *ha = vha->hw;
565
566         if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
567                 goto done_reset_internal;
568
569         memset(new_config, 0 , sizeof(new_config));
570         if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
571             ENABLE_INTERNAL_LOOPBACK ||
572             (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
573             ENABLE_EXTERNAL_LOOPBACK) {
574                 new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
575                 ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
576                     (new_config[0] & INTERNAL_LOOPBACK_MASK));
577                 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
578
579                 ha->notify_dcbx_comp = wait;
580                 ha->notify_lb_portup_comp = wait2;
581
582                 ret = qla81xx_set_port_config(vha, new_config);
583                 if (ret != QLA_SUCCESS) {
584                         ql_log(ql_log_warn, vha, 0x7025,
585                             "Set port config failed.\n");
586                         ha->notify_dcbx_comp = 0;
587                         ha->notify_lb_portup_comp = 0;
588                         rval = -EINVAL;
589                         goto done_reset_internal;
590                 }
591
592                 /* Wait for DCBX complete event */
593                 if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
594                         (DCBX_COMP_TIMEOUT * HZ))) {
595                         ql_dbg(ql_dbg_user, vha, 0x7026,
596                             "DCBX completion not received.\n");
597                         ha->notify_dcbx_comp = 0;
598                         ha->notify_lb_portup_comp = 0;
599                         rval = -EINVAL;
600                         goto done_reset_internal;
601                 } else
602                         ql_dbg(ql_dbg_user, vha, 0x7027,
603                             "DCBX completion received.\n");
604
605                 if (wait2 &&
606                     !wait_for_completion_timeout(&ha->lb_portup_comp,
607                     (LB_PORTUP_COMP_TIMEOUT * HZ))) {
608                         ql_dbg(ql_dbg_user, vha, 0x70c5,
609                             "Port up completion not received.\n");
610                         ha->notify_lb_portup_comp = 0;
611                         rval = -EINVAL;
612                         goto done_reset_internal;
613                 } else
614                         ql_dbg(ql_dbg_user, vha, 0x70c6,
615                             "Port up completion received.\n");
616
617                 ha->notify_dcbx_comp = 0;
618                 ha->notify_lb_portup_comp = 0;
619         }
620 done_reset_internal:
621         return rval;
622 }
623
624 /*
625  * Set the port configuration to enable the internal or external loopback
626  * depending on the loopback mode.
627  */
628 static inline int
629 qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
630         uint16_t *new_config, uint16_t mode)
631 {
632         int ret = 0;
633         int rval = 0;
634         unsigned long rem_tmo = 0, current_tmo = 0;
635         struct qla_hw_data *ha = vha->hw;
636
637         if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
638                 goto done_set_internal;
639
640         if (mode == INTERNAL_LOOPBACK)
641                 new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
642         else if (mode == EXTERNAL_LOOPBACK)
643                 new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
644         ql_dbg(ql_dbg_user, vha, 0x70be,
645              "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
646
647         memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
648
649         ha->notify_dcbx_comp = 1;
650         ret = qla81xx_set_port_config(vha, new_config);
651         if (ret != QLA_SUCCESS) {
652                 ql_log(ql_log_warn, vha, 0x7021,
653                     "set port config failed.\n");
654                 ha->notify_dcbx_comp = 0;
655                 rval = -EINVAL;
656                 goto done_set_internal;
657         }
658
659         /* Wait for DCBX complete event */
660         current_tmo = DCBX_COMP_TIMEOUT * HZ;
661         while (1) {
662                 rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
663                     current_tmo);
664                 if (!ha->idc_extend_tmo || rem_tmo) {
665                         ha->idc_extend_tmo = 0;
666                         break;
667                 }
668                 current_tmo = ha->idc_extend_tmo * HZ;
669                 ha->idc_extend_tmo = 0;
670         }
671
672         if (!rem_tmo) {
673                 ql_dbg(ql_dbg_user, vha, 0x7022,
674                     "DCBX completion not received.\n");
675                 ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
676                 /*
677                  * If the reset of the loopback mode doesn't work take a FCoE
678                  * dump and reset the chip.
679                  */
680                 if (ret) {
681                         ha->isp_ops->fw_dump(vha, 0);
682                         set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
683                 }
684                 rval = -EINVAL;
685         } else {
686                 if (ha->flags.idc_compl_status) {
687                         ql_dbg(ql_dbg_user, vha, 0x70c3,
688                             "Bad status in IDC Completion AEN\n");
689                         rval = -EINVAL;
690                         ha->flags.idc_compl_status = 0;
691                 } else
692                         ql_dbg(ql_dbg_user, vha, 0x7023,
693                             "DCBX completion received.\n");
694         }
695
696         ha->notify_dcbx_comp = 0;
697         ha->idc_extend_tmo = 0;
698
699 done_set_internal:
700         return rval;
701 }
702
703 static int
704 qla2x00_process_loopback(struct fc_bsg_job *bsg_job)
705 {
706         struct Scsi_Host *host = bsg_job->shost;
707         scsi_qla_host_t *vha = shost_priv(host);
708         struct qla_hw_data *ha = vha->hw;
709         int rval;
710         uint8_t command_sent;
711         char *type;
712         struct msg_echo_lb elreq;
713         uint16_t response[MAILBOX_REGISTER_COUNT];
714         uint16_t config[4], new_config[4];
715         uint8_t *fw_sts_ptr;
716         uint8_t *req_data = NULL;
717         dma_addr_t req_data_dma;
718         uint32_t req_data_len;
719         uint8_t *rsp_data = NULL;
720         dma_addr_t rsp_data_dma;
721         uint32_t rsp_data_len;
722
723         if (!vha->flags.online) {
724                 ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
725                 return -EIO;
726         }
727
728         elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
729                 bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
730                 DMA_TO_DEVICE);
731
732         if (!elreq.req_sg_cnt) {
733                 ql_log(ql_log_warn, vha, 0x701a,
734                     "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
735                 return -ENOMEM;
736         }
737
738         elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
739                 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
740                 DMA_FROM_DEVICE);
741
742         if (!elreq.rsp_sg_cnt) {
743                 ql_log(ql_log_warn, vha, 0x701b,
744                     "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
745                 rval = -ENOMEM;
746                 goto done_unmap_req_sg;
747         }
748
749         if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
750                 (elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
751                 ql_log(ql_log_warn, vha, 0x701c,
752                     "dma mapping resulted in different sg counts, "
753                     "request_sg_cnt: %x dma_request_sg_cnt: %x "
754                     "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
755                     bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
756                     bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
757                 rval = -EAGAIN;
758                 goto done_unmap_sg;
759         }
760         req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
761         req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
762                 &req_data_dma, GFP_KERNEL);
763         if (!req_data) {
764                 ql_log(ql_log_warn, vha, 0x701d,
765                     "dma alloc failed for req_data.\n");
766                 rval = -ENOMEM;
767                 goto done_unmap_sg;
768         }
769
770         rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
771                 &rsp_data_dma, GFP_KERNEL);
772         if (!rsp_data) {
773                 ql_log(ql_log_warn, vha, 0x7004,
774                     "dma alloc failed for rsp_data.\n");
775                 rval = -ENOMEM;
776                 goto done_free_dma_req;
777         }
778
779         /* Copy the request buffer in req_data now */
780         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
781                 bsg_job->request_payload.sg_cnt, req_data, req_data_len);
782
783         elreq.send_dma = req_data_dma;
784         elreq.rcv_dma = rsp_data_dma;
785         elreq.transfer_size = req_data_len;
786
787         elreq.options = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
788         elreq.iteration_count =
789             bsg_job->request->rqst_data.h_vendor.vendor_cmd[2];
790
791         if (atomic_read(&vha->loop_state) == LOOP_READY &&
792             (ha->current_topology == ISP_CFG_F ||
793             ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
794             le32_to_cpu(*(uint32_t *)req_data) == ELS_OPCODE_BYTE
795             && req_data_len == MAX_ELS_FRAME_PAYLOAD)) &&
796                 elreq.options == EXTERNAL_LOOPBACK) {
797                 type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
798                 ql_dbg(ql_dbg_user, vha, 0x701e,
799                     "BSG request type: %s.\n", type);
800                 command_sent = INT_DEF_LB_ECHO_CMD;
801                 rval = qla2x00_echo_test(vha, &elreq, response);
802         } else {
803                 if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
804                         memset(config, 0, sizeof(config));
805                         memset(new_config, 0, sizeof(new_config));
806
807                         if (qla81xx_get_port_config(vha, config)) {
808                                 ql_log(ql_log_warn, vha, 0x701f,
809                                     "Get port config failed.\n");
810                                 rval = -EPERM;
811                                 goto done_free_dma_rsp;
812                         }
813
814                         if ((config[0] & INTERNAL_LOOPBACK_MASK) != 0) {
815                                 ql_dbg(ql_dbg_user, vha, 0x70c4,
816                                     "Loopback operation already in "
817                                     "progress.\n");
818                                 rval = -EAGAIN;
819                                 goto done_free_dma_rsp;
820                         }
821
822                         ql_dbg(ql_dbg_user, vha, 0x70c0,
823                             "elreq.options=%04x\n", elreq.options);
824
825                         if (elreq.options == EXTERNAL_LOOPBACK)
826                                 if (IS_QLA8031(ha) || IS_QLA8044(ha))
827                                         rval = qla81xx_set_loopback_mode(vha,
828                                             config, new_config, elreq.options);
829                                 else
830                                         rval = qla81xx_reset_loopback_mode(vha,
831                                             config, 1, 0);
832                         else
833                                 rval = qla81xx_set_loopback_mode(vha, config,
834                                     new_config, elreq.options);
835
836                         if (rval) {
837                                 rval = -EPERM;
838                                 goto done_free_dma_rsp;
839                         }
840
841                         type = "FC_BSG_HST_VENDOR_LOOPBACK";
842                         ql_dbg(ql_dbg_user, vha, 0x7028,
843                             "BSG request type: %s.\n", type);
844
845                         command_sent = INT_DEF_LB_LOOPBACK_CMD;
846                         rval = qla2x00_loopback_test(vha, &elreq, response);
847
848                         if (response[0] == MBS_COMMAND_ERROR &&
849                                         response[1] == MBS_LB_RESET) {
850                                 ql_log(ql_log_warn, vha, 0x7029,
851                                     "MBX command error, Aborting ISP.\n");
852                                 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
853                                 qla2xxx_wake_dpc(vha);
854                                 qla2x00_wait_for_chip_reset(vha);
855                                 /* Also reset the MPI */
856                                 if (IS_QLA81XX(ha)) {
857                                         if (qla81xx_restart_mpi_firmware(vha) !=
858                                             QLA_SUCCESS) {
859                                                 ql_log(ql_log_warn, vha, 0x702a,
860                                                     "MPI reset failed.\n");
861                                         }
862                                 }
863
864                                 rval = -EIO;
865                                 goto done_free_dma_rsp;
866                         }
867
868                         if (new_config[0]) {
869                                 int ret;
870
871                                 /* Revert back to original port config
872                                  * Also clear internal loopback
873                                  */
874                                 ret = qla81xx_reset_loopback_mode(vha,
875                                     new_config, 0, 1);
876                                 if (ret) {
877                                         /*
878                                          * If the reset of the loopback mode
879                                          * doesn't work take FCoE dump and then
880                                          * reset the chip.
881                                          */
882                                         ha->isp_ops->fw_dump(vha, 0);
883                                         set_bit(ISP_ABORT_NEEDED,
884                                             &vha->dpc_flags);
885                                 }
886
887                         }
888
889                 } else {
890                         type = "FC_BSG_HST_VENDOR_LOOPBACK";
891                         ql_dbg(ql_dbg_user, vha, 0x702b,
892                             "BSG request type: %s.\n", type);
893                         command_sent = INT_DEF_LB_LOOPBACK_CMD;
894                         rval = qla2x00_loopback_test(vha, &elreq, response);
895                 }
896         }
897
898         if (rval) {
899                 ql_log(ql_log_warn, vha, 0x702c,
900                     "Vendor request %s failed.\n", type);
901
902                 rval = 0;
903                 bsg_job->reply->result = (DID_ERROR << 16);
904                 bsg_job->reply->reply_payload_rcv_len = 0;
905         } else {
906                 ql_dbg(ql_dbg_user, vha, 0x702d,
907                     "Vendor request %s completed.\n", type);
908                 bsg_job->reply->result = (DID_OK << 16);
909                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
910                         bsg_job->reply_payload.sg_cnt, rsp_data,
911                         rsp_data_len);
912         }
913
914         bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
915             sizeof(response) + sizeof(uint8_t);
916         fw_sts_ptr = ((uint8_t *)bsg_job->req->sense) +
917             sizeof(struct fc_bsg_reply);
918         memcpy(fw_sts_ptr, response, sizeof(response));
919         fw_sts_ptr += sizeof(response);
920         *fw_sts_ptr = command_sent;
921
922 done_free_dma_rsp:
923         dma_free_coherent(&ha->pdev->dev, rsp_data_len,
924                 rsp_data, rsp_data_dma);
925 done_free_dma_req:
926         dma_free_coherent(&ha->pdev->dev, req_data_len,
927                 req_data, req_data_dma);
928 done_unmap_sg:
929         dma_unmap_sg(&ha->pdev->dev,
930             bsg_job->reply_payload.sg_list,
931             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
932 done_unmap_req_sg:
933         dma_unmap_sg(&ha->pdev->dev,
934             bsg_job->request_payload.sg_list,
935             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
936         if (!rval)
937                 bsg_job->job_done(bsg_job);
938         return rval;
939 }
940
941 static int
942 qla84xx_reset(struct fc_bsg_job *bsg_job)
943 {
944         struct Scsi_Host *host = bsg_job->shost;
945         scsi_qla_host_t *vha = shost_priv(host);
946         struct qla_hw_data *ha = vha->hw;
947         int rval = 0;
948         uint32_t flag;
949
950         if (!IS_QLA84XX(ha)) {
951                 ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
952                 return -EINVAL;
953         }
954
955         flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
956
957         rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
958
959         if (rval) {
960                 ql_log(ql_log_warn, vha, 0x7030,
961                     "Vendor request 84xx reset failed.\n");
962                 rval = (DID_ERROR << 16);
963
964         } else {
965                 ql_dbg(ql_dbg_user, vha, 0x7031,
966                     "Vendor request 84xx reset completed.\n");
967                 bsg_job->reply->result = DID_OK;
968                 bsg_job->job_done(bsg_job);
969         }
970
971         return rval;
972 }
973
974 static int
975 qla84xx_updatefw(struct fc_bsg_job *bsg_job)
976 {
977         struct Scsi_Host *host = bsg_job->shost;
978         scsi_qla_host_t *vha = shost_priv(host);
979         struct qla_hw_data *ha = vha->hw;
980         struct verify_chip_entry_84xx *mn = NULL;
981         dma_addr_t mn_dma, fw_dma;
982         void *fw_buf = NULL;
983         int rval = 0;
984         uint32_t sg_cnt;
985         uint32_t data_len;
986         uint16_t options;
987         uint32_t flag;
988         uint32_t fw_ver;
989
990         if (!IS_QLA84XX(ha)) {
991                 ql_dbg(ql_dbg_user, vha, 0x7032,
992                     "Not 84xx, exiting.\n");
993                 return -EINVAL;
994         }
995
996         sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
997                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
998         if (!sg_cnt) {
999                 ql_log(ql_log_warn, vha, 0x7033,
1000                     "dma_map_sg returned %d for request.\n", sg_cnt);
1001                 return -ENOMEM;
1002         }
1003
1004         if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1005                 ql_log(ql_log_warn, vha, 0x7034,
1006                     "DMA mapping resulted in different sg counts, "
1007                     "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1008                     bsg_job->request_payload.sg_cnt, sg_cnt);
1009                 rval = -EAGAIN;
1010                 goto done_unmap_sg;
1011         }
1012
1013         data_len = bsg_job->request_payload.payload_len;
1014         fw_buf = dma_alloc_coherent(&ha->pdev->dev, data_len,
1015                 &fw_dma, GFP_KERNEL);
1016         if (!fw_buf) {
1017                 ql_log(ql_log_warn, vha, 0x7035,
1018                     "DMA alloc failed for fw_buf.\n");
1019                 rval = -ENOMEM;
1020                 goto done_unmap_sg;
1021         }
1022
1023         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1024                 bsg_job->request_payload.sg_cnt, fw_buf, data_len);
1025
1026         mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1027         if (!mn) {
1028                 ql_log(ql_log_warn, vha, 0x7036,
1029                     "DMA alloc failed for fw buffer.\n");
1030                 rval = -ENOMEM;
1031                 goto done_free_fw_buf;
1032         }
1033
1034         flag = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1035         fw_ver = le32_to_cpu(*((uint32_t *)((uint32_t *)fw_buf + 2)));
1036
1037         memset(mn, 0, sizeof(struct access_chip_84xx));
1038         mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
1039         mn->entry_count = 1;
1040
1041         options = VCO_FORCE_UPDATE | VCO_END_OF_DATA;
1042         if (flag == A84_ISSUE_UPDATE_DIAGFW_CMD)
1043                 options |= VCO_DIAG_FW;
1044
1045         mn->options = cpu_to_le16(options);
1046         mn->fw_ver =  cpu_to_le32(fw_ver);
1047         mn->fw_size =  cpu_to_le32(data_len);
1048         mn->fw_seq_size =  cpu_to_le32(data_len);
1049         mn->dseg_address[0] = cpu_to_le32(LSD(fw_dma));
1050         mn->dseg_address[1] = cpu_to_le32(MSD(fw_dma));
1051         mn->dseg_length = cpu_to_le32(data_len);
1052         mn->data_seg_cnt = cpu_to_le16(1);
1053
1054         rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
1055
1056         if (rval) {
1057                 ql_log(ql_log_warn, vha, 0x7037,
1058                     "Vendor request 84xx updatefw failed.\n");
1059
1060                 rval = (DID_ERROR << 16);
1061         } else {
1062                 ql_dbg(ql_dbg_user, vha, 0x7038,
1063                     "Vendor request 84xx updatefw completed.\n");
1064
1065                 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1066                 bsg_job->reply->result = DID_OK;
1067         }
1068
1069         dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1070
1071 done_free_fw_buf:
1072         dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
1073
1074 done_unmap_sg:
1075         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1076                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1077
1078         if (!rval)
1079                 bsg_job->job_done(bsg_job);
1080         return rval;
1081 }
1082
1083 static int
1084 qla84xx_mgmt_cmd(struct fc_bsg_job *bsg_job)
1085 {
1086         struct Scsi_Host *host = bsg_job->shost;
1087         scsi_qla_host_t *vha = shost_priv(host);
1088         struct qla_hw_data *ha = vha->hw;
1089         struct access_chip_84xx *mn = NULL;
1090         dma_addr_t mn_dma, mgmt_dma;
1091         void *mgmt_b = NULL;
1092         int rval = 0;
1093         struct qla_bsg_a84_mgmt *ql84_mgmt;
1094         uint32_t sg_cnt;
1095         uint32_t data_len = 0;
1096         uint32_t dma_direction = DMA_NONE;
1097
1098         if (!IS_QLA84XX(ha)) {
1099                 ql_log(ql_log_warn, vha, 0x703a,
1100                     "Not 84xx, exiting.\n");
1101                 return -EINVAL;
1102         }
1103
1104         mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1105         if (!mn) {
1106                 ql_log(ql_log_warn, vha, 0x703c,
1107                     "DMA alloc failed for fw buffer.\n");
1108                 return -ENOMEM;
1109         }
1110
1111         memset(mn, 0, sizeof(struct access_chip_84xx));
1112         mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
1113         mn->entry_count = 1;
1114         ql84_mgmt = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
1115         switch (ql84_mgmt->mgmt.cmd) {
1116         case QLA84_MGMT_READ_MEM:
1117         case QLA84_MGMT_GET_INFO:
1118                 sg_cnt = dma_map_sg(&ha->pdev->dev,
1119                         bsg_job->reply_payload.sg_list,
1120                         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1121                 if (!sg_cnt) {
1122                         ql_log(ql_log_warn, vha, 0x703d,
1123                             "dma_map_sg returned %d for reply.\n", sg_cnt);
1124                         rval = -ENOMEM;
1125                         goto exit_mgmt;
1126                 }
1127
1128                 dma_direction = DMA_FROM_DEVICE;
1129
1130                 if (sg_cnt != bsg_job->reply_payload.sg_cnt) {
1131                         ql_log(ql_log_warn, vha, 0x703e,
1132                             "DMA mapping resulted in different sg counts, "
1133                             "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
1134                             bsg_job->reply_payload.sg_cnt, sg_cnt);
1135                         rval = -EAGAIN;
1136                         goto done_unmap_sg;
1137                 }
1138
1139                 data_len = bsg_job->reply_payload.payload_len;
1140
1141                 mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1142                     &mgmt_dma, GFP_KERNEL);
1143                 if (!mgmt_b) {
1144                         ql_log(ql_log_warn, vha, 0x703f,
1145                             "DMA alloc failed for mgmt_b.\n");
1146                         rval = -ENOMEM;
1147                         goto done_unmap_sg;
1148                 }
1149
1150                 if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) {
1151                         mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
1152                         mn->parameter1 =
1153                                 cpu_to_le32(
1154                                 ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1155
1156                 } else if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO) {
1157                         mn->options = cpu_to_le16(ACO_REQUEST_INFO);
1158                         mn->parameter1 =
1159                                 cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.info.type);
1160
1161                         mn->parameter2 =
1162                                 cpu_to_le32(
1163                                 ql84_mgmt->mgmt.mgmtp.u.info.context);
1164                 }
1165                 break;
1166
1167         case QLA84_MGMT_WRITE_MEM:
1168                 sg_cnt = dma_map_sg(&ha->pdev->dev,
1169                         bsg_job->request_payload.sg_list,
1170                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1171
1172                 if (!sg_cnt) {
1173                         ql_log(ql_log_warn, vha, 0x7040,
1174                             "dma_map_sg returned %d.\n", sg_cnt);
1175                         rval = -ENOMEM;
1176                         goto exit_mgmt;
1177                 }
1178
1179                 dma_direction = DMA_TO_DEVICE;
1180
1181                 if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1182                         ql_log(ql_log_warn, vha, 0x7041,
1183                             "DMA mapping resulted in different sg counts, "
1184                             "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1185                             bsg_job->request_payload.sg_cnt, sg_cnt);
1186                         rval = -EAGAIN;
1187                         goto done_unmap_sg;
1188                 }
1189
1190                 data_len = bsg_job->request_payload.payload_len;
1191                 mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1192                         &mgmt_dma, GFP_KERNEL);
1193                 if (!mgmt_b) {
1194                         ql_log(ql_log_warn, vha, 0x7042,
1195                             "DMA alloc failed for mgmt_b.\n");
1196                         rval = -ENOMEM;
1197                         goto done_unmap_sg;
1198                 }
1199
1200                 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1201                         bsg_job->request_payload.sg_cnt, mgmt_b, data_len);
1202
1203                 mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
1204                 mn->parameter1 =
1205                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1206                 break;
1207
1208         case QLA84_MGMT_CHNG_CONFIG:
1209                 mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
1210                 mn->parameter1 =
1211                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.id);
1212
1213                 mn->parameter2 =
1214                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param0);
1215
1216                 mn->parameter3 =
1217                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param1);
1218                 break;
1219
1220         default:
1221                 rval = -EIO;
1222                 goto exit_mgmt;
1223         }
1224
1225         if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
1226                 mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
1227                 mn->dseg_count = cpu_to_le16(1);
1228                 mn->dseg_address[0] = cpu_to_le32(LSD(mgmt_dma));
1229                 mn->dseg_address[1] = cpu_to_le32(MSD(mgmt_dma));
1230                 mn->dseg_length = cpu_to_le32(ql84_mgmt->mgmt.len);
1231         }
1232
1233         rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
1234
1235         if (rval) {
1236                 ql_log(ql_log_warn, vha, 0x7043,
1237                     "Vendor request 84xx mgmt failed.\n");
1238
1239                 rval = (DID_ERROR << 16);
1240
1241         } else {
1242                 ql_dbg(ql_dbg_user, vha, 0x7044,
1243                     "Vendor request 84xx mgmt completed.\n");
1244
1245                 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1246                 bsg_job->reply->result = DID_OK;
1247
1248                 if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
1249                         (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
1250                         bsg_job->reply->reply_payload_rcv_len =
1251                                 bsg_job->reply_payload.payload_len;
1252
1253                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1254                                 bsg_job->reply_payload.sg_cnt, mgmt_b,
1255                                 data_len);
1256                 }
1257         }
1258
1259 done_unmap_sg:
1260         if (mgmt_b)
1261                 dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
1262
1263         if (dma_direction == DMA_TO_DEVICE)
1264                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1265                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1266         else if (dma_direction == DMA_FROM_DEVICE)
1267                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1268                         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1269
1270 exit_mgmt:
1271         dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1272
1273         if (!rval)
1274                 bsg_job->job_done(bsg_job);
1275         return rval;
1276 }
1277
1278 static int
1279 qla24xx_iidma(struct fc_bsg_job *bsg_job)
1280 {
1281         struct Scsi_Host *host = bsg_job->shost;
1282         scsi_qla_host_t *vha = shost_priv(host);
1283         int rval = 0;
1284         struct qla_port_param *port_param = NULL;
1285         fc_port_t *fcport = NULL;
1286         int found = 0;
1287         uint16_t mb[MAILBOX_REGISTER_COUNT];
1288         uint8_t *rsp_ptr = NULL;
1289
1290         if (!IS_IIDMA_CAPABLE(vha->hw)) {
1291                 ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
1292                 return -EINVAL;
1293         }
1294
1295         port_param = (void *)bsg_job->request + sizeof(struct fc_bsg_request);
1296         if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
1297                 ql_log(ql_log_warn, vha, 0x7048,
1298                     "Invalid destination type.\n");
1299                 return -EINVAL;
1300         }
1301
1302         list_for_each_entry(fcport, &vha->vp_fcports, list) {
1303                 if (fcport->port_type != FCT_TARGET)
1304                         continue;
1305
1306                 if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
1307                         fcport->port_name, sizeof(fcport->port_name)))
1308                         continue;
1309
1310                 found = 1;
1311                 break;
1312         }
1313
1314         if (!found) {
1315                 ql_log(ql_log_warn, vha, 0x7049,
1316                     "Failed to find port.\n");
1317                 return -EINVAL;
1318         }
1319
1320         if (atomic_read(&fcport->state) != FCS_ONLINE) {
1321                 ql_log(ql_log_warn, vha, 0x704a,
1322                     "Port is not online.\n");
1323                 return -EINVAL;
1324         }
1325
1326         if (fcport->flags & FCF_LOGIN_NEEDED) {
1327                 ql_log(ql_log_warn, vha, 0x704b,
1328                     "Remote port not logged in flags = 0x%x.\n", fcport->flags);
1329                 return -EINVAL;
1330         }
1331
1332         if (port_param->mode)
1333                 rval = qla2x00_set_idma_speed(vha, fcport->loop_id,
1334                         port_param->speed, mb);
1335         else
1336                 rval = qla2x00_get_idma_speed(vha, fcport->loop_id,
1337                         &port_param->speed, mb);
1338
1339         if (rval) {
1340                 ql_log(ql_log_warn, vha, 0x704c,
1341                     "iIDMA cmd failed for %8phN -- "
1342                     "%04x %x %04x %04x.\n", fcport->port_name,
1343                     rval, fcport->fp_speed, mb[0], mb[1]);
1344                 rval = (DID_ERROR << 16);
1345         } else {
1346                 if (!port_param->mode) {
1347                         bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
1348                                 sizeof(struct qla_port_param);
1349
1350                         rsp_ptr = ((uint8_t *)bsg_job->reply) +
1351                                 sizeof(struct fc_bsg_reply);
1352
1353                         memcpy(rsp_ptr, port_param,
1354                                 sizeof(struct qla_port_param));
1355                 }
1356
1357                 bsg_job->reply->result = DID_OK;
1358                 bsg_job->job_done(bsg_job);
1359         }
1360
1361         return rval;
1362 }
1363
1364 static int
1365 qla2x00_optrom_setup(struct fc_bsg_job *bsg_job, scsi_qla_host_t *vha,
1366         uint8_t is_update)
1367 {
1368         uint32_t start = 0;
1369         int valid = 0;
1370         struct qla_hw_data *ha = vha->hw;
1371
1372         if (unlikely(pci_channel_offline(ha->pdev)))
1373                 return -EINVAL;
1374
1375         start = bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1376         if (start > ha->optrom_size) {
1377                 ql_log(ql_log_warn, vha, 0x7055,
1378                     "start %d > optrom_size %d.\n", start, ha->optrom_size);
1379                 return -EINVAL;
1380         }
1381
1382         if (ha->optrom_state != QLA_SWAITING) {
1383                 ql_log(ql_log_info, vha, 0x7056,
1384                     "optrom_state %d.\n", ha->optrom_state);
1385                 return -EBUSY;
1386         }
1387
1388         ha->optrom_region_start = start;
1389         ql_dbg(ql_dbg_user, vha, 0x7057, "is_update=%d.\n", is_update);
1390         if (is_update) {
1391                 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
1392                         valid = 1;
1393                 else if (start == (ha->flt_region_boot * 4) ||
1394                     start == (ha->flt_region_fw * 4))
1395                         valid = 1;
1396                 else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
1397                     IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha))
1398                         valid = 1;
1399                 if (!valid) {
1400                         ql_log(ql_log_warn, vha, 0x7058,
1401                             "Invalid start region 0x%x/0x%x.\n", start,
1402                             bsg_job->request_payload.payload_len);
1403                         return -EINVAL;
1404                 }
1405
1406                 ha->optrom_region_size = start +
1407                     bsg_job->request_payload.payload_len > ha->optrom_size ?
1408                     ha->optrom_size - start :
1409                     bsg_job->request_payload.payload_len;
1410                 ha->optrom_state = QLA_SWRITING;
1411         } else {
1412                 ha->optrom_region_size = start +
1413                     bsg_job->reply_payload.payload_len > ha->optrom_size ?
1414                     ha->optrom_size - start :
1415                     bsg_job->reply_payload.payload_len;
1416                 ha->optrom_state = QLA_SREADING;
1417         }
1418
1419         ha->optrom_buffer = vmalloc(ha->optrom_region_size);
1420         if (!ha->optrom_buffer) {
1421                 ql_log(ql_log_warn, vha, 0x7059,
1422                     "Read: Unable to allocate memory for optrom retrieval "
1423                     "(%x)\n", ha->optrom_region_size);
1424
1425                 ha->optrom_state = QLA_SWAITING;
1426                 return -ENOMEM;
1427         }
1428
1429         memset(ha->optrom_buffer, 0, ha->optrom_region_size);
1430         return 0;
1431 }
1432
1433 static int
1434 qla2x00_read_optrom(struct fc_bsg_job *bsg_job)
1435 {
1436         struct Scsi_Host *host = bsg_job->shost;
1437         scsi_qla_host_t *vha = shost_priv(host);
1438         struct qla_hw_data *ha = vha->hw;
1439         int rval = 0;
1440
1441         if (ha->flags.nic_core_reset_hdlr_active)
1442                 return -EBUSY;
1443
1444         mutex_lock(&ha->optrom_mutex);
1445         rval = qla2x00_optrom_setup(bsg_job, vha, 0);
1446         if (rval) {
1447                 mutex_unlock(&ha->optrom_mutex);
1448                 return rval;
1449         }
1450
1451         ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
1452             ha->optrom_region_start, ha->optrom_region_size);
1453
1454         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1455             bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
1456             ha->optrom_region_size);
1457
1458         bsg_job->reply->reply_payload_rcv_len = ha->optrom_region_size;
1459         bsg_job->reply->result = DID_OK;
1460         vfree(ha->optrom_buffer);
1461         ha->optrom_buffer = NULL;
1462         ha->optrom_state = QLA_SWAITING;
1463         mutex_unlock(&ha->optrom_mutex);
1464         bsg_job->job_done(bsg_job);
1465         return rval;
1466 }
1467
1468 static int
1469 qla2x00_update_optrom(struct fc_bsg_job *bsg_job)
1470 {
1471         struct Scsi_Host *host = bsg_job->shost;
1472         scsi_qla_host_t *vha = shost_priv(host);
1473         struct qla_hw_data *ha = vha->hw;
1474         int rval = 0;
1475
1476         mutex_lock(&ha->optrom_mutex);
1477         rval = qla2x00_optrom_setup(bsg_job, vha, 1);
1478         if (rval) {
1479                 mutex_unlock(&ha->optrom_mutex);
1480                 return rval;
1481         }
1482
1483         /* Set the isp82xx_no_md_cap not to capture minidump */
1484         ha->flags.isp82xx_no_md_cap = 1;
1485
1486         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1487             bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
1488             ha->optrom_region_size);
1489
1490         ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
1491             ha->optrom_region_start, ha->optrom_region_size);
1492
1493         bsg_job->reply->result = DID_OK;
1494         vfree(ha->optrom_buffer);
1495         ha->optrom_buffer = NULL;
1496         ha->optrom_state = QLA_SWAITING;
1497         mutex_unlock(&ha->optrom_mutex);
1498         bsg_job->job_done(bsg_job);
1499         return rval;
1500 }
1501
1502 static int
1503 qla2x00_update_fru_versions(struct fc_bsg_job *bsg_job)
1504 {
1505         struct Scsi_Host *host = bsg_job->shost;
1506         scsi_qla_host_t *vha = shost_priv(host);
1507         struct qla_hw_data *ha = vha->hw;
1508         int rval = 0;
1509         uint8_t bsg[DMA_POOL_SIZE];
1510         struct qla_image_version_list *list = (void *)bsg;
1511         struct qla_image_version *image;
1512         uint32_t count;
1513         dma_addr_t sfp_dma;
1514         void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1515         if (!sfp) {
1516                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1517                     EXT_STATUS_NO_MEMORY;
1518                 goto done;
1519         }
1520
1521         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1522             bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
1523
1524         image = list->version;
1525         count = list->count;
1526         while (count--) {
1527                 memcpy(sfp, &image->field_info, sizeof(image->field_info));
1528                 rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1529                     image->field_address.device, image->field_address.offset,
1530                     sizeof(image->field_info), image->field_address.option);
1531                 if (rval) {
1532                         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1533                             EXT_STATUS_MAILBOX;
1534                         goto dealloc;
1535                 }
1536                 image++;
1537         }
1538
1539         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1540
1541 dealloc:
1542         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1543
1544 done:
1545         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1546         bsg_job->reply->result = DID_OK << 16;
1547         bsg_job->job_done(bsg_job);
1548
1549         return 0;
1550 }
1551
1552 static int
1553 qla2x00_read_fru_status(struct fc_bsg_job *bsg_job)
1554 {
1555         struct Scsi_Host *host = bsg_job->shost;
1556         scsi_qla_host_t *vha = shost_priv(host);
1557         struct qla_hw_data *ha = vha->hw;
1558         int rval = 0;
1559         uint8_t bsg[DMA_POOL_SIZE];
1560         struct qla_status_reg *sr = (void *)bsg;
1561         dma_addr_t sfp_dma;
1562         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1563         if (!sfp) {
1564                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1565                     EXT_STATUS_NO_MEMORY;
1566                 goto done;
1567         }
1568
1569         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1570             bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1571
1572         rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1573             sr->field_address.device, sr->field_address.offset,
1574             sizeof(sr->status_reg), sr->field_address.option);
1575         sr->status_reg = *sfp;
1576
1577         if (rval) {
1578                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1579                     EXT_STATUS_MAILBOX;
1580                 goto dealloc;
1581         }
1582
1583         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1584             bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
1585
1586         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1587
1588 dealloc:
1589         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1590
1591 done:
1592         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1593         bsg_job->reply->reply_payload_rcv_len = sizeof(*sr);
1594         bsg_job->reply->result = DID_OK << 16;
1595         bsg_job->job_done(bsg_job);
1596
1597         return 0;
1598 }
1599
1600 static int
1601 qla2x00_write_fru_status(struct fc_bsg_job *bsg_job)
1602 {
1603         struct Scsi_Host *host = bsg_job->shost;
1604         scsi_qla_host_t *vha = shost_priv(host);
1605         struct qla_hw_data *ha = vha->hw;
1606         int rval = 0;
1607         uint8_t bsg[DMA_POOL_SIZE];
1608         struct qla_status_reg *sr = (void *)bsg;
1609         dma_addr_t sfp_dma;
1610         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1611         if (!sfp) {
1612                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1613                     EXT_STATUS_NO_MEMORY;
1614                 goto done;
1615         }
1616
1617         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1618             bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1619
1620         *sfp = sr->status_reg;
1621         rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1622             sr->field_address.device, sr->field_address.offset,
1623             sizeof(sr->status_reg), sr->field_address.option);
1624
1625         if (rval) {
1626                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1627                     EXT_STATUS_MAILBOX;
1628                 goto dealloc;
1629         }
1630
1631         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1632
1633 dealloc:
1634         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1635
1636 done:
1637         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1638         bsg_job->reply->result = DID_OK << 16;
1639         bsg_job->job_done(bsg_job);
1640
1641         return 0;
1642 }
1643
1644 static int
1645 qla2x00_write_i2c(struct fc_bsg_job *bsg_job)
1646 {
1647         struct Scsi_Host *host = bsg_job->shost;
1648         scsi_qla_host_t *vha = shost_priv(host);
1649         struct qla_hw_data *ha = vha->hw;
1650         int rval = 0;
1651         uint8_t bsg[DMA_POOL_SIZE];
1652         struct qla_i2c_access *i2c = (void *)bsg;
1653         dma_addr_t sfp_dma;
1654         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1655         if (!sfp) {
1656                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1657                     EXT_STATUS_NO_MEMORY;
1658                 goto done;
1659         }
1660
1661         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1662             bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1663
1664         memcpy(sfp, i2c->buffer, i2c->length);
1665         rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1666             i2c->device, i2c->offset, i2c->length, i2c->option);
1667
1668         if (rval) {
1669                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1670                     EXT_STATUS_MAILBOX;
1671                 goto dealloc;
1672         }
1673
1674         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1675
1676 dealloc:
1677         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1678
1679 done:
1680         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1681         bsg_job->reply->result = DID_OK << 16;
1682         bsg_job->job_done(bsg_job);
1683
1684         return 0;
1685 }
1686
1687 static int
1688 qla2x00_read_i2c(struct fc_bsg_job *bsg_job)
1689 {
1690         struct Scsi_Host *host = bsg_job->shost;
1691         scsi_qla_host_t *vha = shost_priv(host);
1692         struct qla_hw_data *ha = vha->hw;
1693         int rval = 0;
1694         uint8_t bsg[DMA_POOL_SIZE];
1695         struct qla_i2c_access *i2c = (void *)bsg;
1696         dma_addr_t sfp_dma;
1697         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1698         if (!sfp) {
1699                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1700                     EXT_STATUS_NO_MEMORY;
1701                 goto done;
1702         }
1703
1704         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1705             bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1706
1707         rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1708                 i2c->device, i2c->offset, i2c->length, i2c->option);
1709
1710         if (rval) {
1711                 bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
1712                     EXT_STATUS_MAILBOX;
1713                 goto dealloc;
1714         }
1715
1716         memcpy(i2c->buffer, sfp, i2c->length);
1717         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1718             bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
1719
1720         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1721
1722 dealloc:
1723         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1724
1725 done:
1726         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1727         bsg_job->reply->reply_payload_rcv_len = sizeof(*i2c);
1728         bsg_job->reply->result = DID_OK << 16;
1729         bsg_job->job_done(bsg_job);
1730
1731         return 0;
1732 }
1733
1734 static int
1735 qla24xx_process_bidir_cmd(struct fc_bsg_job *bsg_job)
1736 {
1737         struct Scsi_Host *host = bsg_job->shost;
1738         scsi_qla_host_t *vha = shost_priv(host);
1739         struct qla_hw_data *ha = vha->hw;
1740         uint32_t rval = EXT_STATUS_OK;
1741         uint16_t req_sg_cnt = 0;
1742         uint16_t rsp_sg_cnt = 0;
1743         uint16_t nextlid = 0;
1744         uint32_t tot_dsds;
1745         srb_t *sp = NULL;
1746         uint32_t req_data_len;
1747         uint32_t rsp_data_len;
1748
1749         /* Check the type of the adapter */
1750         if (!IS_BIDI_CAPABLE(ha)) {
1751                 ql_log(ql_log_warn, vha, 0x70a0,
1752                         "This adapter is not supported\n");
1753                 rval = EXT_STATUS_NOT_SUPPORTED;
1754                 goto done;
1755         }
1756
1757         if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1758                 test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1759                 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1760                 rval =  EXT_STATUS_BUSY;
1761                 goto done;
1762         }
1763
1764         /* Check if host is online */
1765         if (!vha->flags.online) {
1766                 ql_log(ql_log_warn, vha, 0x70a1,
1767                         "Host is not online\n");
1768                 rval = EXT_STATUS_DEVICE_OFFLINE;
1769                 goto done;
1770         }
1771
1772         /* Check if cable is plugged in or not */
1773         if (vha->device_flags & DFLG_NO_CABLE) {
1774                 ql_log(ql_log_warn, vha, 0x70a2,
1775                         "Cable is unplugged...\n");
1776                 rval = EXT_STATUS_INVALID_CFG;
1777                 goto done;
1778         }
1779
1780         /* Check if the switch is connected or not */
1781         if (ha->current_topology != ISP_CFG_F) {
1782                 ql_log(ql_log_warn, vha, 0x70a3,
1783                         "Host is not connected to the switch\n");
1784                 rval = EXT_STATUS_INVALID_CFG;
1785                 goto done;
1786         }
1787
1788         /* Check if operating mode is P2P */
1789         if (ha->operating_mode != P2P) {
1790                 ql_log(ql_log_warn, vha, 0x70a4,
1791                     "Host is operating mode is not P2p\n");
1792                 rval = EXT_STATUS_INVALID_CFG;
1793                 goto done;
1794         }
1795
1796         mutex_lock(&ha->selflogin_lock);
1797         if (vha->self_login_loop_id == 0) {
1798                 /* Initialize all required  fields of fcport */
1799                 vha->bidir_fcport.vha = vha;
1800                 vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1801                 vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1802                 vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1803                 vha->bidir_fcport.loop_id = vha->loop_id;
1804
1805                 if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1806                         ql_log(ql_log_warn, vha, 0x70a7,
1807                             "Failed to login port %06X for bidirectional IOCB\n",
1808                             vha->bidir_fcport.d_id.b24);
1809                         mutex_unlock(&ha->selflogin_lock);
1810                         rval = EXT_STATUS_MAILBOX;
1811                         goto done;
1812                 }
1813                 vha->self_login_loop_id = nextlid - 1;
1814
1815         }
1816         /* Assign the self login loop id to fcport */
1817         mutex_unlock(&ha->selflogin_lock);
1818
1819         vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1820
1821         req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1822                 bsg_job->request_payload.sg_list,
1823                 bsg_job->request_payload.sg_cnt,
1824                 DMA_TO_DEVICE);
1825
1826         if (!req_sg_cnt) {
1827                 rval = EXT_STATUS_NO_MEMORY;
1828                 goto done;
1829         }
1830
1831         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1832                 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1833                 DMA_FROM_DEVICE);
1834
1835         if (!rsp_sg_cnt) {
1836                 rval = EXT_STATUS_NO_MEMORY;
1837                 goto done_unmap_req_sg;
1838         }
1839
1840         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
1841                 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1842                 ql_dbg(ql_dbg_user, vha, 0x70a9,
1843                     "Dma mapping resulted in different sg counts "
1844                     "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1845                     "%x dma_reply_sg_cnt: %x]\n",
1846                     bsg_job->request_payload.sg_cnt, req_sg_cnt,
1847                     bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1848                 rval = EXT_STATUS_NO_MEMORY;
1849                 goto done_unmap_sg;
1850         }
1851
1852         req_data_len = bsg_job->request_payload.payload_len;
1853         rsp_data_len = bsg_job->reply_payload.payload_len;
1854
1855         if (req_data_len != rsp_data_len) {
1856                 rval = EXT_STATUS_BUSY;
1857                 ql_log(ql_log_warn, vha, 0x70aa,
1858                     "req_data_len != rsp_data_len\n");
1859                 goto done_unmap_sg;
1860         }
1861
1862         /* Alloc SRB structure */
1863         sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1864         if (!sp) {
1865                 ql_dbg(ql_dbg_user, vha, 0x70ac,
1866                     "Alloc SRB structure failed\n");
1867                 rval = EXT_STATUS_NO_MEMORY;
1868                 goto done_unmap_sg;
1869         }
1870
1871         /*Populate srb->ctx with bidir ctx*/
1872         sp->u.bsg_job = bsg_job;
1873         sp->free = qla2x00_bsg_sp_free;
1874         sp->type = SRB_BIDI_CMD;
1875         sp->done = qla2x00_bsg_job_done;
1876
1877         /* Add the read and write sg count */
1878         tot_dsds = rsp_sg_cnt + req_sg_cnt;
1879
1880         rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1881         if (rval != EXT_STATUS_OK)
1882                 goto done_free_srb;
1883         /* the bsg request  will be completed in the interrupt handler */
1884         return rval;
1885
1886 done_free_srb:
1887         mempool_free(sp, ha->srb_mempool);
1888 done_unmap_sg:
1889         dma_unmap_sg(&ha->pdev->dev,
1890             bsg_job->reply_payload.sg_list,
1891             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1892 done_unmap_req_sg:
1893         dma_unmap_sg(&ha->pdev->dev,
1894             bsg_job->request_payload.sg_list,
1895             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1896 done:
1897
1898         /* Return an error vendor specific response
1899          * and complete the bsg request
1900          */
1901         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1902         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1903         bsg_job->reply->reply_payload_rcv_len = 0;
1904         bsg_job->reply->result = (DID_OK) << 16;
1905         bsg_job->job_done(bsg_job);
1906         /* Always return success, vendor rsp carries correct status */
1907         return 0;
1908 }
1909
1910 static int
1911 qlafx00_mgmt_cmd(struct fc_bsg_job *bsg_job)
1912 {
1913         struct Scsi_Host *host = bsg_job->shost;
1914         scsi_qla_host_t *vha = shost_priv(host);
1915         struct qla_hw_data *ha = vha->hw;
1916         int rval = (DID_ERROR << 16);
1917         struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
1918         srb_t *sp;
1919         int req_sg_cnt = 0, rsp_sg_cnt = 0;
1920         struct fc_port *fcport;
1921         char  *type = "FC_BSG_HST_FX_MGMT";
1922
1923         /* Copy the IOCB specific information */
1924         piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
1925             &bsg_job->request->rqst_data.h_vendor.vendor_cmd[1];
1926
1927         /* Dump the vendor information */
1928         ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
1929             (uint8_t *)piocb_rqst, sizeof(struct qla_mt_iocb_rqst_fx00));
1930
1931         if (!vha->flags.online) {
1932                 ql_log(ql_log_warn, vha, 0x70d0,
1933                     "Host is not online.\n");
1934                 rval = -EIO;
1935                 goto done;
1936         }
1937
1938         if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
1939                 req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1940                     bsg_job->request_payload.sg_list,
1941                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1942                 if (!req_sg_cnt) {
1943                         ql_log(ql_log_warn, vha, 0x70c7,
1944                             "dma_map_sg return %d for request\n", req_sg_cnt);
1945                         rval = -ENOMEM;
1946                         goto done;
1947                 }
1948         }
1949
1950         if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) {
1951                 rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1952                     bsg_job->reply_payload.sg_list,
1953                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1954                 if (!rsp_sg_cnt) {
1955                         ql_log(ql_log_warn, vha, 0x70c8,
1956                             "dma_map_sg return %d for reply\n", rsp_sg_cnt);
1957                         rval = -ENOMEM;
1958                         goto done_unmap_req_sg;
1959                 }
1960         }
1961
1962         ql_dbg(ql_dbg_user, vha, 0x70c9,
1963             "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
1964             "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
1965             req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1966
1967         /* Allocate a dummy fcport structure, since functions preparing the
1968          * IOCB and mailbox command retrieves port specific information
1969          * from fcport structure. For Host based ELS commands there will be
1970          * no fcport structure allocated
1971          */
1972         fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
1973         if (!fcport) {
1974                 ql_log(ql_log_warn, vha, 0x70ca,
1975                     "Failed to allocate fcport.\n");
1976                 rval = -ENOMEM;
1977                 goto done_unmap_rsp_sg;
1978         }
1979
1980         /* Alloc SRB structure */
1981         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
1982         if (!sp) {
1983                 ql_log(ql_log_warn, vha, 0x70cb,
1984                     "qla2x00_get_sp failed.\n");
1985                 rval = -ENOMEM;
1986                 goto done_free_fcport;
1987         }
1988
1989         /* Initialize all required  fields of fcport */
1990         fcport->vha = vha;
1991         fcport->loop_id = piocb_rqst->dataword;
1992
1993         sp->type = SRB_FXIOCB_BCMD;
1994         sp->name = "bsg_fx_mgmt";
1995         sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
1996         sp->u.bsg_job = bsg_job;
1997         sp->free = qla2x00_bsg_sp_free;
1998         sp->done = qla2x00_bsg_job_done;
1999
2000         ql_dbg(ql_dbg_user, vha, 0x70cc,
2001             "bsg rqst type: %s fx_mgmt_type: %x id=%x\n",
2002             type, piocb_rqst->func_type, fcport->loop_id);
2003
2004         rval = qla2x00_start_sp(sp);
2005         if (rval != QLA_SUCCESS) {
2006                 ql_log(ql_log_warn, vha, 0x70cd,
2007                     "qla2x00_start_sp failed=%d.\n", rval);
2008                 mempool_free(sp, ha->srb_mempool);
2009                 rval = -EIO;
2010                 goto done_free_fcport;
2011         }
2012         return rval;
2013
2014 done_free_fcport:
2015         kfree(fcport);
2016
2017 done_unmap_rsp_sg:
2018         if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
2019                 dma_unmap_sg(&ha->pdev->dev,
2020                     bsg_job->reply_payload.sg_list,
2021                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2022 done_unmap_req_sg:
2023         if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
2024                 dma_unmap_sg(&ha->pdev->dev,
2025                     bsg_job->request_payload.sg_list,
2026                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
2027
2028 done:
2029         return rval;
2030 }
2031
2032 static int
2033 qla26xx_serdes_op(struct fc_bsg_job *bsg_job)
2034 {
2035         struct Scsi_Host *host = bsg_job->shost;
2036         scsi_qla_host_t *vha = shost_priv(host);
2037         int rval = 0;
2038         struct qla_serdes_reg sr;
2039
2040         memset(&sr, 0, sizeof(sr));
2041
2042         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2043             bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2044
2045         switch (sr.cmd) {
2046         case INT_SC_SERDES_WRITE_REG:
2047                 rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
2048                 bsg_job->reply->reply_payload_rcv_len = 0;
2049                 break;
2050         case INT_SC_SERDES_READ_REG:
2051                 rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
2052                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2053                     bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2054                 bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
2055                 break;
2056         default:
2057                 ql_dbg(ql_dbg_user, vha, 0x708c,
2058                     "Unknown serdes cmd %x.\n", sr.cmd);
2059                 rval = -EINVAL;
2060                 break;
2061         }
2062
2063         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
2064             rval ? EXT_STATUS_MAILBOX : 0;
2065
2066         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2067         bsg_job->reply->result = DID_OK << 16;
2068         bsg_job->job_done(bsg_job);
2069         return 0;
2070 }
2071
2072 static int
2073 qla8044_serdes_op(struct fc_bsg_job *bsg_job)
2074 {
2075         struct Scsi_Host *host = bsg_job->shost;
2076         scsi_qla_host_t *vha = shost_priv(host);
2077         int rval = 0;
2078         struct qla_serdes_reg_ex sr;
2079
2080         memset(&sr, 0, sizeof(sr));
2081
2082         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2083             bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2084
2085         switch (sr.cmd) {
2086         case INT_SC_SERDES_WRITE_REG:
2087                 rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
2088                 bsg_job->reply->reply_payload_rcv_len = 0;
2089                 break;
2090         case INT_SC_SERDES_READ_REG:
2091                 rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
2092                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2093                     bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2094                 bsg_job->reply->reply_payload_rcv_len = sizeof(sr);
2095                 break;
2096         default:
2097                 ql_dbg(ql_dbg_user, vha, 0x70cf,
2098                     "Unknown serdes cmd %x.\n", sr.cmd);
2099                 rval = -EINVAL;
2100                 break;
2101         }
2102
2103         bsg_job->reply->reply_data.vendor_reply.vendor_rsp[0] =
2104             rval ? EXT_STATUS_MAILBOX : 0;
2105
2106         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2107         bsg_job->reply->result = DID_OK << 16;
2108         bsg_job->job_done(bsg_job);
2109         return 0;
2110 }
2111
2112 static int
2113 qla2x00_process_vendor_specific(struct fc_bsg_job *bsg_job)
2114 {
2115         switch (bsg_job->request->rqst_data.h_vendor.vendor_cmd[0]) {
2116         case QL_VND_LOOPBACK:
2117                 return qla2x00_process_loopback(bsg_job);
2118
2119         case QL_VND_A84_RESET:
2120                 return qla84xx_reset(bsg_job);
2121
2122         case QL_VND_A84_UPDATE_FW:
2123                 return qla84xx_updatefw(bsg_job);
2124
2125         case QL_VND_A84_MGMT_CMD:
2126                 return qla84xx_mgmt_cmd(bsg_job);
2127
2128         case QL_VND_IIDMA:
2129                 return qla24xx_iidma(bsg_job);
2130
2131         case QL_VND_FCP_PRIO_CFG_CMD:
2132                 return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
2133
2134         case QL_VND_READ_FLASH:
2135                 return qla2x00_read_optrom(bsg_job);
2136
2137         case QL_VND_UPDATE_FLASH:
2138                 return qla2x00_update_optrom(bsg_job);
2139
2140         case QL_VND_SET_FRU_VERSION:
2141                 return qla2x00_update_fru_versions(bsg_job);
2142
2143         case QL_VND_READ_FRU_STATUS:
2144                 return qla2x00_read_fru_status(bsg_job);
2145
2146         case QL_VND_WRITE_FRU_STATUS:
2147                 return qla2x00_write_fru_status(bsg_job);
2148
2149         case QL_VND_WRITE_I2C:
2150                 return qla2x00_write_i2c(bsg_job);
2151
2152         case QL_VND_READ_I2C:
2153                 return qla2x00_read_i2c(bsg_job);
2154
2155         case QL_VND_DIAG_IO_CMD:
2156                 return qla24xx_process_bidir_cmd(bsg_job);
2157
2158         case QL_VND_FX00_MGMT_CMD:
2159                 return qlafx00_mgmt_cmd(bsg_job);
2160
2161         case QL_VND_SERDES_OP:
2162                 return qla26xx_serdes_op(bsg_job);
2163
2164         case QL_VND_SERDES_OP_EX:
2165                 return qla8044_serdes_op(bsg_job);
2166
2167         default:
2168                 return -ENOSYS;
2169         }
2170 }
2171
2172 int
2173 qla24xx_bsg_request(struct fc_bsg_job *bsg_job)
2174 {
2175         int ret = -EINVAL;
2176         struct fc_rport *rport;
2177         struct Scsi_Host *host;
2178         scsi_qla_host_t *vha;
2179
2180         /* In case no data transferred. */
2181         bsg_job->reply->reply_payload_rcv_len = 0;
2182
2183         if (bsg_job->request->msgcode == FC_BSG_RPT_ELS) {
2184                 rport = bsg_job->rport;
2185                 host = rport_to_shost(rport);
2186                 vha = shost_priv(host);
2187         } else {
2188                 host = bsg_job->shost;
2189                 vha = shost_priv(host);
2190         }
2191
2192         if (qla2x00_reset_active(vha)) {
2193                 ql_dbg(ql_dbg_user, vha, 0x709f,
2194                     "BSG: ISP abort active/needed -- cmd=%d.\n",
2195                     bsg_job->request->msgcode);
2196                 return -EBUSY;
2197         }
2198
2199         ql_dbg(ql_dbg_user, vha, 0x7000,
2200             "Entered %s msgcode=0x%x.\n", __func__, bsg_job->request->msgcode);
2201
2202         switch (bsg_job->request->msgcode) {
2203         case FC_BSG_RPT_ELS:
2204         case FC_BSG_HST_ELS_NOLOGIN:
2205                 ret = qla2x00_process_els(bsg_job);
2206                 break;
2207         case FC_BSG_HST_CT:
2208                 ret = qla2x00_process_ct(bsg_job);
2209                 break;
2210         case FC_BSG_HST_VENDOR:
2211                 ret = qla2x00_process_vendor_specific(bsg_job);
2212                 break;
2213         case FC_BSG_HST_ADD_RPORT:
2214         case FC_BSG_HST_DEL_RPORT:
2215         case FC_BSG_RPT_CT:
2216         default:
2217                 ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
2218                 break;
2219         }
2220         return ret;
2221 }
2222
2223 int
2224 qla24xx_bsg_timeout(struct fc_bsg_job *bsg_job)
2225 {
2226         scsi_qla_host_t *vha = shost_priv(bsg_job->shost);
2227         struct qla_hw_data *ha = vha->hw;
2228         srb_t *sp;
2229         int cnt, que;
2230         unsigned long flags;
2231         struct req_que *req;
2232
2233         /* find the bsg job from the active list of commands */
2234         spin_lock_irqsave(&ha->hardware_lock, flags);
2235         for (que = 0; que < ha->max_req_queues; que++) {
2236                 req = ha->req_q_map[que];
2237                 if (!req)
2238                         continue;
2239
2240                 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
2241                         sp = req->outstanding_cmds[cnt];
2242                         if (sp) {
2243                                 if (((sp->type == SRB_CT_CMD) ||
2244                                         (sp->type == SRB_ELS_CMD_HST) ||
2245                                         (sp->type == SRB_FXIOCB_BCMD))
2246                                         && (sp->u.bsg_job == bsg_job)) {
2247                                         req->outstanding_cmds[cnt] = NULL;
2248                                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2249                                         if (ha->isp_ops->abort_command(sp)) {
2250                                                 ql_log(ql_log_warn, vha, 0x7089,
2251                                                     "mbx abort_command "
2252                                                     "failed.\n");
2253                                                 bsg_job->req->errors =
2254                                                 bsg_job->reply->result = -EIO;
2255                                         } else {
2256                                                 ql_dbg(ql_dbg_user, vha, 0x708a,
2257                                                     "mbx abort_command "
2258                                                     "success.\n");
2259                                                 bsg_job->req->errors =
2260                                                 bsg_job->reply->result = 0;
2261                                         }
2262                                         spin_lock_irqsave(&ha->hardware_lock, flags);
2263                                         goto done;
2264                                 }
2265                         }
2266                 }
2267         }
2268         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2269         ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
2270         bsg_job->req->errors = bsg_job->reply->result = -ENXIO;
2271         return 0;
2272
2273 done:
2274         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2275         sp->free(vha, sp);
2276         return 0;
2277 }