Merge tag 'x86-entry-2021-02-24' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / scsi / qla2xxx / qla_bsg.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * QLogic Fibre Channel HBA Driver
4  * Copyright (c)  2003-2014 QLogic Corporation
5  */
6 #include "qla_def.h"
7 #include "qla_gbl.h"
8
9 #include <linux/kthread.h>
10 #include <linux/vmalloc.h>
11 #include <linux/delay.h>
12 #include <linux/bsg-lib.h>
13
14 static void qla2xxx_free_fcport_work(struct work_struct *work)
15 {
16         struct fc_port *fcport = container_of(work, typeof(*fcport),
17             free_work);
18
19         qla2x00_free_fcport(fcport);
20 }
21
22 /* BSG support for ELS/CT pass through */
23 void qla2x00_bsg_job_done(srb_t *sp, int res)
24 {
25         struct bsg_job *bsg_job = sp->u.bsg_job;
26         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
27
28         bsg_reply->result = res;
29         bsg_job_done(bsg_job, bsg_reply->result,
30                        bsg_reply->reply_payload_rcv_len);
31         sp->free(sp);
32 }
33
34 void qla2x00_bsg_sp_free(srb_t *sp)
35 {
36         struct qla_hw_data *ha = sp->vha->hw;
37         struct bsg_job *bsg_job = sp->u.bsg_job;
38         struct fc_bsg_request *bsg_request = bsg_job->request;
39         struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
40
41         if (sp->type == SRB_FXIOCB_BCMD) {
42                 piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
43                     &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
44
45                 if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
46                         dma_unmap_sg(&ha->pdev->dev,
47                             bsg_job->request_payload.sg_list,
48                             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
49
50                 if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
51                         dma_unmap_sg(&ha->pdev->dev,
52                             bsg_job->reply_payload.sg_list,
53                             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
54         } else {
55                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
56                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
57
58                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
59                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
60         }
61
62         if (sp->type == SRB_CT_CMD ||
63             sp->type == SRB_FXIOCB_BCMD ||
64             sp->type == SRB_ELS_CMD_HST) {
65                 INIT_WORK(&sp->fcport->free_work, qla2xxx_free_fcport_work);
66                 queue_work(ha->wq, &sp->fcport->free_work);
67         }
68
69         qla2x00_rel_sp(sp);
70 }
71
72 int
73 qla24xx_fcp_prio_cfg_valid(scsi_qla_host_t *vha,
74         struct qla_fcp_prio_cfg *pri_cfg, uint8_t flag)
75 {
76         int i, ret, num_valid;
77         uint8_t *bcode;
78         struct qla_fcp_prio_entry *pri_entry;
79         uint32_t *bcode_val_ptr, bcode_val;
80
81         ret = 1;
82         num_valid = 0;
83         bcode = (uint8_t *)pri_cfg;
84         bcode_val_ptr = (uint32_t *)pri_cfg;
85         bcode_val = (uint32_t)(*bcode_val_ptr);
86
87         if (bcode_val == 0xFFFFFFFF) {
88                 /* No FCP Priority config data in flash */
89                 ql_dbg(ql_dbg_user, vha, 0x7051,
90                     "No FCP Priority config data.\n");
91                 return 0;
92         }
93
94         if (memcmp(bcode, "HQOS", 4)) {
95                 /* Invalid FCP priority data header*/
96                 ql_dbg(ql_dbg_user, vha, 0x7052,
97                     "Invalid FCP Priority data header. bcode=0x%x.\n",
98                     bcode_val);
99                 return 0;
100         }
101         if (flag != 1)
102                 return ret;
103
104         pri_entry = &pri_cfg->entry[0];
105         for (i = 0; i < pri_cfg->num_entries; i++) {
106                 if (pri_entry->flags & FCP_PRIO_ENTRY_TAG_VALID)
107                         num_valid++;
108                 pri_entry++;
109         }
110
111         if (num_valid == 0) {
112                 /* No valid FCP priority data entries */
113                 ql_dbg(ql_dbg_user, vha, 0x7053,
114                     "No valid FCP Priority data entries.\n");
115                 ret = 0;
116         } else {
117                 /* FCP priority data is valid */
118                 ql_dbg(ql_dbg_user, vha, 0x7054,
119                     "Valid FCP priority data. num entries = %d.\n",
120                     num_valid);
121         }
122
123         return ret;
124 }
125
126 static int
127 qla24xx_proc_fcp_prio_cfg_cmd(struct bsg_job *bsg_job)
128 {
129         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
130         struct fc_bsg_request *bsg_request = bsg_job->request;
131         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
132         scsi_qla_host_t *vha = shost_priv(host);
133         struct qla_hw_data *ha = vha->hw;
134         int ret = 0;
135         uint32_t len;
136         uint32_t oper;
137
138         if (!(IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) || IS_P3P_TYPE(ha))) {
139                 ret = -EINVAL;
140                 goto exit_fcp_prio_cfg;
141         }
142
143         /* Get the sub command */
144         oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
145
146         /* Only set config is allowed if config memory is not allocated */
147         if (!ha->fcp_prio_cfg && (oper != QLFC_FCP_PRIO_SET_CONFIG)) {
148                 ret = -EINVAL;
149                 goto exit_fcp_prio_cfg;
150         }
151         switch (oper) {
152         case QLFC_FCP_PRIO_DISABLE:
153                 if (ha->flags.fcp_prio_enabled) {
154                         ha->flags.fcp_prio_enabled = 0;
155                         ha->fcp_prio_cfg->attributes &=
156                                 ~FCP_PRIO_ATTR_ENABLE;
157                         qla24xx_update_all_fcp_prio(vha);
158                         bsg_reply->result = DID_OK;
159                 } else {
160                         ret = -EINVAL;
161                         bsg_reply->result = (DID_ERROR << 16);
162                         goto exit_fcp_prio_cfg;
163                 }
164                 break;
165
166         case QLFC_FCP_PRIO_ENABLE:
167                 if (!ha->flags.fcp_prio_enabled) {
168                         if (ha->fcp_prio_cfg) {
169                                 ha->flags.fcp_prio_enabled = 1;
170                                 ha->fcp_prio_cfg->attributes |=
171                                     FCP_PRIO_ATTR_ENABLE;
172                                 qla24xx_update_all_fcp_prio(vha);
173                                 bsg_reply->result = DID_OK;
174                         } else {
175                                 ret = -EINVAL;
176                                 bsg_reply->result = (DID_ERROR << 16);
177                                 goto exit_fcp_prio_cfg;
178                         }
179                 }
180                 break;
181
182         case QLFC_FCP_PRIO_GET_CONFIG:
183                 len = bsg_job->reply_payload.payload_len;
184                 if (!len || len > FCP_PRIO_CFG_SIZE) {
185                         ret = -EINVAL;
186                         bsg_reply->result = (DID_ERROR << 16);
187                         goto exit_fcp_prio_cfg;
188                 }
189
190                 bsg_reply->result = DID_OK;
191                 bsg_reply->reply_payload_rcv_len =
192                         sg_copy_from_buffer(
193                         bsg_job->reply_payload.sg_list,
194                         bsg_job->reply_payload.sg_cnt, ha->fcp_prio_cfg,
195                         len);
196
197                 break;
198
199         case QLFC_FCP_PRIO_SET_CONFIG:
200                 len = bsg_job->request_payload.payload_len;
201                 if (!len || len > FCP_PRIO_CFG_SIZE) {
202                         bsg_reply->result = (DID_ERROR << 16);
203                         ret = -EINVAL;
204                         goto exit_fcp_prio_cfg;
205                 }
206
207                 if (!ha->fcp_prio_cfg) {
208                         ha->fcp_prio_cfg = vmalloc(FCP_PRIO_CFG_SIZE);
209                         if (!ha->fcp_prio_cfg) {
210                                 ql_log(ql_log_warn, vha, 0x7050,
211                                     "Unable to allocate memory for fcp prio "
212                                     "config data (%x).\n", FCP_PRIO_CFG_SIZE);
213                                 bsg_reply->result = (DID_ERROR << 16);
214                                 ret = -ENOMEM;
215                                 goto exit_fcp_prio_cfg;
216                         }
217                 }
218
219                 memset(ha->fcp_prio_cfg, 0, FCP_PRIO_CFG_SIZE);
220                 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
221                 bsg_job->request_payload.sg_cnt, ha->fcp_prio_cfg,
222                         FCP_PRIO_CFG_SIZE);
223
224                 /* validate fcp priority data */
225
226                 if (!qla24xx_fcp_prio_cfg_valid(vha, ha->fcp_prio_cfg, 1)) {
227                         bsg_reply->result = (DID_ERROR << 16);
228                         ret = -EINVAL;
229                         /* If buffer was invalidatic int
230                          * fcp_prio_cfg is of no use
231                          */
232                         vfree(ha->fcp_prio_cfg);
233                         ha->fcp_prio_cfg = NULL;
234                         goto exit_fcp_prio_cfg;
235                 }
236
237                 ha->flags.fcp_prio_enabled = 0;
238                 if (ha->fcp_prio_cfg->attributes & FCP_PRIO_ATTR_ENABLE)
239                         ha->flags.fcp_prio_enabled = 1;
240                 qla24xx_update_all_fcp_prio(vha);
241                 bsg_reply->result = DID_OK;
242                 break;
243         default:
244                 ret = -EINVAL;
245                 break;
246         }
247 exit_fcp_prio_cfg:
248         if (!ret)
249                 bsg_job_done(bsg_job, bsg_reply->result,
250                                bsg_reply->reply_payload_rcv_len);
251         return ret;
252 }
253
254 static int
255 qla2x00_process_els(struct bsg_job *bsg_job)
256 {
257         struct fc_bsg_request *bsg_request = bsg_job->request;
258         struct fc_rport *rport;
259         fc_port_t *fcport = NULL;
260         struct Scsi_Host *host;
261         scsi_qla_host_t *vha;
262         struct qla_hw_data *ha;
263         srb_t *sp;
264         const char *type;
265         int req_sg_cnt, rsp_sg_cnt;
266         int rval =  (DID_ERROR << 16);
267         uint16_t nextlid = 0;
268
269         if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
270                 rport = fc_bsg_to_rport(bsg_job);
271                 fcport = *(fc_port_t **) rport->dd_data;
272                 host = rport_to_shost(rport);
273                 vha = shost_priv(host);
274                 ha = vha->hw;
275                 type = "FC_BSG_RPT_ELS";
276         } else {
277                 host = fc_bsg_to_shost(bsg_job);
278                 vha = shost_priv(host);
279                 ha = vha->hw;
280                 type = "FC_BSG_HST_ELS_NOLOGIN";
281         }
282
283         if (!vha->flags.online) {
284                 ql_log(ql_log_warn, vha, 0x7005, "Host not online.\n");
285                 rval = -EIO;
286                 goto done;
287         }
288
289         /* pass through is supported only for ISP 4Gb or higher */
290         if (!IS_FWI2_CAPABLE(ha)) {
291                 ql_dbg(ql_dbg_user, vha, 0x7001,
292                     "ELS passthru not supported for ISP23xx based adapters.\n");
293                 rval = -EPERM;
294                 goto done;
295         }
296
297         /*  Multiple SG's are not supported for ELS requests */
298         if (bsg_job->request_payload.sg_cnt > 1 ||
299                 bsg_job->reply_payload.sg_cnt > 1) {
300                 ql_dbg(ql_dbg_user, vha, 0x7002,
301                     "Multiple SG's are not supported for ELS requests, "
302                     "request_sg_cnt=%x reply_sg_cnt=%x.\n",
303                     bsg_job->request_payload.sg_cnt,
304                     bsg_job->reply_payload.sg_cnt);
305                 rval = -EPERM;
306                 goto done;
307         }
308
309         /* ELS request for rport */
310         if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
311                 /* make sure the rport is logged in,
312                  * if not perform fabric login
313                  */
314                 if (qla2x00_fabric_login(vha, fcport, &nextlid)) {
315                         ql_dbg(ql_dbg_user, vha, 0x7003,
316                             "Failed to login port %06X for ELS passthru.\n",
317                             fcport->d_id.b24);
318                         rval = -EIO;
319                         goto done;
320                 }
321         } else {
322                 /* Allocate a dummy fcport structure, since functions
323                  * preparing the IOCB and mailbox command retrieves port
324                  * specific information from fcport structure. For Host based
325                  * ELS commands there will be no fcport structure allocated
326                  */
327                 fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
328                 if (!fcport) {
329                         rval = -ENOMEM;
330                         goto done;
331                 }
332
333                 /* Initialize all required  fields of fcport */
334                 fcport->vha = vha;
335                 fcport->d_id.b.al_pa =
336                         bsg_request->rqst_data.h_els.port_id[0];
337                 fcport->d_id.b.area =
338                         bsg_request->rqst_data.h_els.port_id[1];
339                 fcport->d_id.b.domain =
340                         bsg_request->rqst_data.h_els.port_id[2];
341                 fcport->loop_id =
342                         (fcport->d_id.b.al_pa == 0xFD) ?
343                         NPH_FABRIC_CONTROLLER : NPH_F_PORT;
344         }
345
346         req_sg_cnt =
347                 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
348                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
349         if (!req_sg_cnt) {
350                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
351                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
352                 rval = -ENOMEM;
353                 goto done_free_fcport;
354         }
355
356         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
357                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
358         if (!rsp_sg_cnt) {
359                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
360                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
361                 rval = -ENOMEM;
362                 goto done_free_fcport;
363         }
364
365         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
366                 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
367                 ql_log(ql_log_warn, vha, 0x7008,
368                     "dma mapping resulted in different sg counts, "
369                     "request_sg_cnt: %x dma_request_sg_cnt:%x reply_sg_cnt:%x "
370                     "dma_reply_sg_cnt:%x.\n", bsg_job->request_payload.sg_cnt,
371                     req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
372                 rval = -EAGAIN;
373                 goto done_unmap_sg;
374         }
375
376         /* Alloc SRB structure */
377         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
378         if (!sp) {
379                 rval = -ENOMEM;
380                 goto done_unmap_sg;
381         }
382
383         sp->type =
384                 (bsg_request->msgcode == FC_BSG_RPT_ELS ?
385                  SRB_ELS_CMD_RPT : SRB_ELS_CMD_HST);
386         sp->name =
387                 (bsg_request->msgcode == FC_BSG_RPT_ELS ?
388                  "bsg_els_rpt" : "bsg_els_hst");
389         sp->u.bsg_job = bsg_job;
390         sp->free = qla2x00_bsg_sp_free;
391         sp->done = qla2x00_bsg_job_done;
392
393         ql_dbg(ql_dbg_user, vha, 0x700a,
394             "bsg rqst type: %s els type: %x - loop-id=%x "
395             "portid=%-2x%02x%02x.\n", type,
396             bsg_request->rqst_data.h_els.command_code, fcport->loop_id,
397             fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa);
398
399         rval = qla2x00_start_sp(sp);
400         if (rval != QLA_SUCCESS) {
401                 ql_log(ql_log_warn, vha, 0x700e,
402                     "qla2x00_start_sp failed = %d\n", rval);
403                 qla2x00_rel_sp(sp);
404                 rval = -EIO;
405                 goto done_unmap_sg;
406         }
407         return rval;
408
409 done_unmap_sg:
410         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
411                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
412         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
413                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
414         goto done_free_fcport;
415
416 done_free_fcport:
417         if (bsg_request->msgcode == FC_BSG_RPT_ELS)
418                 qla2x00_free_fcport(fcport);
419 done:
420         return rval;
421 }
422
423 static inline uint16_t
424 qla24xx_calc_ct_iocbs(uint16_t dsds)
425 {
426         uint16_t iocbs;
427
428         iocbs = 1;
429         if (dsds > 2) {
430                 iocbs += (dsds - 2) / 5;
431                 if ((dsds - 2) % 5)
432                         iocbs++;
433         }
434         return iocbs;
435 }
436
437 static int
438 qla2x00_process_ct(struct bsg_job *bsg_job)
439 {
440         srb_t *sp;
441         struct fc_bsg_request *bsg_request = bsg_job->request;
442         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
443         scsi_qla_host_t *vha = shost_priv(host);
444         struct qla_hw_data *ha = vha->hw;
445         int rval = (DID_ERROR << 16);
446         int req_sg_cnt, rsp_sg_cnt;
447         uint16_t loop_id;
448         struct fc_port *fcport;
449         char  *type = "FC_BSG_HST_CT";
450
451         req_sg_cnt =
452                 dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
453                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
454         if (!req_sg_cnt) {
455                 ql_log(ql_log_warn, vha, 0x700f,
456                     "dma_map_sg return %d for request\n", req_sg_cnt);
457                 rval = -ENOMEM;
458                 goto done;
459         }
460
461         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
462                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
463         if (!rsp_sg_cnt) {
464                 ql_log(ql_log_warn, vha, 0x7010,
465                     "dma_map_sg return %d for reply\n", rsp_sg_cnt);
466                 rval = -ENOMEM;
467                 goto done;
468         }
469
470         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
471             (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
472                 ql_log(ql_log_warn, vha, 0x7011,
473                     "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
474                     "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
475                     req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
476                 rval = -EAGAIN;
477                 goto done_unmap_sg;
478         }
479
480         if (!vha->flags.online) {
481                 ql_log(ql_log_warn, vha, 0x7012,
482                     "Host is not online.\n");
483                 rval = -EIO;
484                 goto done_unmap_sg;
485         }
486
487         loop_id =
488                 (bsg_request->rqst_data.h_ct.preamble_word1 & 0xFF000000)
489                         >> 24;
490         switch (loop_id) {
491         case 0xFC:
492                 loop_id = NPH_SNS;
493                 break;
494         case 0xFA:
495                 loop_id = vha->mgmt_svr_loop_id;
496                 break;
497         default:
498                 ql_dbg(ql_dbg_user, vha, 0x7013,
499                     "Unknown loop id: %x.\n", loop_id);
500                 rval = -EINVAL;
501                 goto done_unmap_sg;
502         }
503
504         /* Allocate a dummy fcport structure, since functions preparing the
505          * IOCB and mailbox command retrieves port specific information
506          * from fcport structure. For Host based ELS commands there will be
507          * no fcport structure allocated
508          */
509         fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
510         if (!fcport) {
511                 ql_log(ql_log_warn, vha, 0x7014,
512                     "Failed to allocate fcport.\n");
513                 rval = -ENOMEM;
514                 goto done_unmap_sg;
515         }
516
517         /* Initialize all required  fields of fcport */
518         fcport->vha = vha;
519         fcport->d_id.b.al_pa = bsg_request->rqst_data.h_ct.port_id[0];
520         fcport->d_id.b.area = bsg_request->rqst_data.h_ct.port_id[1];
521         fcport->d_id.b.domain = bsg_request->rqst_data.h_ct.port_id[2];
522         fcport->loop_id = loop_id;
523
524         /* Alloc SRB structure */
525         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
526         if (!sp) {
527                 ql_log(ql_log_warn, vha, 0x7015,
528                     "qla2x00_get_sp failed.\n");
529                 rval = -ENOMEM;
530                 goto done_free_fcport;
531         }
532
533         sp->type = SRB_CT_CMD;
534         sp->name = "bsg_ct";
535         sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
536         sp->u.bsg_job = bsg_job;
537         sp->free = qla2x00_bsg_sp_free;
538         sp->done = qla2x00_bsg_job_done;
539
540         ql_dbg(ql_dbg_user, vha, 0x7016,
541             "bsg rqst type: %s else type: %x - "
542             "loop-id=%x portid=%02x%02x%02x.\n", type,
543             (bsg_request->rqst_data.h_ct.preamble_word2 >> 16),
544             fcport->loop_id, fcport->d_id.b.domain, fcport->d_id.b.area,
545             fcport->d_id.b.al_pa);
546
547         rval = qla2x00_start_sp(sp);
548         if (rval != QLA_SUCCESS) {
549                 ql_log(ql_log_warn, vha, 0x7017,
550                     "qla2x00_start_sp failed=%d.\n", rval);
551                 qla2x00_rel_sp(sp);
552                 rval = -EIO;
553                 goto done_free_fcport;
554         }
555         return rval;
556
557 done_free_fcport:
558         qla2x00_free_fcport(fcport);
559 done_unmap_sg:
560         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
561                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
562         dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
563                 bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
564 done:
565         return rval;
566 }
567
568 /* Disable loopback mode */
569 static inline int
570 qla81xx_reset_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
571                             int wait, int wait2)
572 {
573         int ret = 0;
574         int rval = 0;
575         uint16_t new_config[4];
576         struct qla_hw_data *ha = vha->hw;
577
578         if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
579                 goto done_reset_internal;
580
581         memset(new_config, 0 , sizeof(new_config));
582         if ((config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
583             ENABLE_INTERNAL_LOOPBACK ||
584             (config[0] & INTERNAL_LOOPBACK_MASK) >> 1 ==
585             ENABLE_EXTERNAL_LOOPBACK) {
586                 new_config[0] = config[0] & ~INTERNAL_LOOPBACK_MASK;
587                 ql_dbg(ql_dbg_user, vha, 0x70bf, "new_config[0]=%02x\n",
588                     (new_config[0] & INTERNAL_LOOPBACK_MASK));
589                 memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3) ;
590
591                 ha->notify_dcbx_comp = wait;
592                 ha->notify_lb_portup_comp = wait2;
593
594                 ret = qla81xx_set_port_config(vha, new_config);
595                 if (ret != QLA_SUCCESS) {
596                         ql_log(ql_log_warn, vha, 0x7025,
597                             "Set port config failed.\n");
598                         ha->notify_dcbx_comp = 0;
599                         ha->notify_lb_portup_comp = 0;
600                         rval = -EINVAL;
601                         goto done_reset_internal;
602                 }
603
604                 /* Wait for DCBX complete event */
605                 if (wait && !wait_for_completion_timeout(&ha->dcbx_comp,
606                         (DCBX_COMP_TIMEOUT * HZ))) {
607                         ql_dbg(ql_dbg_user, vha, 0x7026,
608                             "DCBX completion not received.\n");
609                         ha->notify_dcbx_comp = 0;
610                         ha->notify_lb_portup_comp = 0;
611                         rval = -EINVAL;
612                         goto done_reset_internal;
613                 } else
614                         ql_dbg(ql_dbg_user, vha, 0x7027,
615                             "DCBX completion received.\n");
616
617                 if (wait2 &&
618                     !wait_for_completion_timeout(&ha->lb_portup_comp,
619                     (LB_PORTUP_COMP_TIMEOUT * HZ))) {
620                         ql_dbg(ql_dbg_user, vha, 0x70c5,
621                             "Port up completion not received.\n");
622                         ha->notify_lb_portup_comp = 0;
623                         rval = -EINVAL;
624                         goto done_reset_internal;
625                 } else
626                         ql_dbg(ql_dbg_user, vha, 0x70c6,
627                             "Port up completion received.\n");
628
629                 ha->notify_dcbx_comp = 0;
630                 ha->notify_lb_portup_comp = 0;
631         }
632 done_reset_internal:
633         return rval;
634 }
635
636 /*
637  * Set the port configuration to enable the internal or external loopback
638  * depending on the loopback mode.
639  */
640 static inline int
641 qla81xx_set_loopback_mode(scsi_qla_host_t *vha, uint16_t *config,
642         uint16_t *new_config, uint16_t mode)
643 {
644         int ret = 0;
645         int rval = 0;
646         unsigned long rem_tmo = 0, current_tmo = 0;
647         struct qla_hw_data *ha = vha->hw;
648
649         if (!IS_QLA81XX(ha) && !IS_QLA8031(ha) && !IS_QLA8044(ha))
650                 goto done_set_internal;
651
652         if (mode == INTERNAL_LOOPBACK)
653                 new_config[0] = config[0] | (ENABLE_INTERNAL_LOOPBACK << 1);
654         else if (mode == EXTERNAL_LOOPBACK)
655                 new_config[0] = config[0] | (ENABLE_EXTERNAL_LOOPBACK << 1);
656         ql_dbg(ql_dbg_user, vha, 0x70be,
657              "new_config[0]=%02x\n", (new_config[0] & INTERNAL_LOOPBACK_MASK));
658
659         memcpy(&new_config[1], &config[1], sizeof(uint16_t) * 3);
660
661         ha->notify_dcbx_comp = 1;
662         ret = qla81xx_set_port_config(vha, new_config);
663         if (ret != QLA_SUCCESS) {
664                 ql_log(ql_log_warn, vha, 0x7021,
665                     "set port config failed.\n");
666                 ha->notify_dcbx_comp = 0;
667                 rval = -EINVAL;
668                 goto done_set_internal;
669         }
670
671         /* Wait for DCBX complete event */
672         current_tmo = DCBX_COMP_TIMEOUT * HZ;
673         while (1) {
674                 rem_tmo = wait_for_completion_timeout(&ha->dcbx_comp,
675                     current_tmo);
676                 if (!ha->idc_extend_tmo || rem_tmo) {
677                         ha->idc_extend_tmo = 0;
678                         break;
679                 }
680                 current_tmo = ha->idc_extend_tmo * HZ;
681                 ha->idc_extend_tmo = 0;
682         }
683
684         if (!rem_tmo) {
685                 ql_dbg(ql_dbg_user, vha, 0x7022,
686                     "DCBX completion not received.\n");
687                 ret = qla81xx_reset_loopback_mode(vha, new_config, 0, 0);
688                 /*
689                  * If the reset of the loopback mode doesn't work take a FCoE
690                  * dump and reset the chip.
691                  */
692                 if (ret) {
693                         qla2xxx_dump_fw(vha);
694                         set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
695                 }
696                 rval = -EINVAL;
697         } else {
698                 if (ha->flags.idc_compl_status) {
699                         ql_dbg(ql_dbg_user, vha, 0x70c3,
700                             "Bad status in IDC Completion AEN\n");
701                         rval = -EINVAL;
702                         ha->flags.idc_compl_status = 0;
703                 } else
704                         ql_dbg(ql_dbg_user, vha, 0x7023,
705                             "DCBX completion received.\n");
706         }
707
708         ha->notify_dcbx_comp = 0;
709         ha->idc_extend_tmo = 0;
710
711 done_set_internal:
712         return rval;
713 }
714
715 static int
716 qla2x00_process_loopback(struct bsg_job *bsg_job)
717 {
718         struct fc_bsg_request *bsg_request = bsg_job->request;
719         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
720         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
721         scsi_qla_host_t *vha = shost_priv(host);
722         struct qla_hw_data *ha = vha->hw;
723         int rval;
724         uint8_t command_sent;
725         char *type;
726         struct msg_echo_lb elreq;
727         uint16_t response[MAILBOX_REGISTER_COUNT];
728         uint16_t config[4], new_config[4];
729         uint8_t *fw_sts_ptr;
730         void *req_data = NULL;
731         dma_addr_t req_data_dma;
732         uint32_t req_data_len;
733         uint8_t *rsp_data = NULL;
734         dma_addr_t rsp_data_dma;
735         uint32_t rsp_data_len;
736
737         if (!vha->flags.online) {
738                 ql_log(ql_log_warn, vha, 0x7019, "Host is not online.\n");
739                 return -EIO;
740         }
741
742         memset(&elreq, 0, sizeof(elreq));
743
744         elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
745                 bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt,
746                 DMA_TO_DEVICE);
747
748         if (!elreq.req_sg_cnt) {
749                 ql_log(ql_log_warn, vha, 0x701a,
750                     "dma_map_sg returned %d for request.\n", elreq.req_sg_cnt);
751                 return -ENOMEM;
752         }
753
754         elreq.rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
755                 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
756                 DMA_FROM_DEVICE);
757
758         if (!elreq.rsp_sg_cnt) {
759                 ql_log(ql_log_warn, vha, 0x701b,
760                     "dma_map_sg returned %d for reply.\n", elreq.rsp_sg_cnt);
761                 rval = -ENOMEM;
762                 goto done_unmap_req_sg;
763         }
764
765         if ((elreq.req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
766                 (elreq.rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
767                 ql_log(ql_log_warn, vha, 0x701c,
768                     "dma mapping resulted in different sg counts, "
769                     "request_sg_cnt: %x dma_request_sg_cnt: %x "
770                     "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
771                     bsg_job->request_payload.sg_cnt, elreq.req_sg_cnt,
772                     bsg_job->reply_payload.sg_cnt, elreq.rsp_sg_cnt);
773                 rval = -EAGAIN;
774                 goto done_unmap_sg;
775         }
776         req_data_len = rsp_data_len = bsg_job->request_payload.payload_len;
777         req_data = dma_alloc_coherent(&ha->pdev->dev, req_data_len,
778                 &req_data_dma, GFP_KERNEL);
779         if (!req_data) {
780                 ql_log(ql_log_warn, vha, 0x701d,
781                     "dma alloc failed for req_data.\n");
782                 rval = -ENOMEM;
783                 goto done_unmap_sg;
784         }
785
786         rsp_data = dma_alloc_coherent(&ha->pdev->dev, rsp_data_len,
787                 &rsp_data_dma, GFP_KERNEL);
788         if (!rsp_data) {
789                 ql_log(ql_log_warn, vha, 0x7004,
790                     "dma alloc failed for rsp_data.\n");
791                 rval = -ENOMEM;
792                 goto done_free_dma_req;
793         }
794
795         /* Copy the request buffer in req_data now */
796         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
797                 bsg_job->request_payload.sg_cnt, req_data, req_data_len);
798
799         elreq.send_dma = req_data_dma;
800         elreq.rcv_dma = rsp_data_dma;
801         elreq.transfer_size = req_data_len;
802
803         elreq.options = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
804         elreq.iteration_count =
805             bsg_request->rqst_data.h_vendor.vendor_cmd[2];
806
807         if (atomic_read(&vha->loop_state) == LOOP_READY &&
808             ((ha->current_topology == ISP_CFG_F && (elreq.options & 7) >= 2) ||
809             ((IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) &&
810             get_unaligned_le32(req_data) == ELS_OPCODE_BYTE &&
811             req_data_len == MAX_ELS_FRAME_PAYLOAD &&
812             elreq.options == EXTERNAL_LOOPBACK))) {
813                 type = "FC_BSG_HST_VENDOR_ECHO_DIAG";
814                 ql_dbg(ql_dbg_user, vha, 0x701e,
815                     "BSG request type: %s.\n", type);
816                 command_sent = INT_DEF_LB_ECHO_CMD;
817                 rval = qla2x00_echo_test(vha, &elreq, response);
818         } else {
819                 if (IS_QLA81XX(ha) || IS_QLA8031(ha) || IS_QLA8044(ha)) {
820                         memset(config, 0, sizeof(config));
821                         memset(new_config, 0, sizeof(new_config));
822
823                         if (qla81xx_get_port_config(vha, config)) {
824                                 ql_log(ql_log_warn, vha, 0x701f,
825                                     "Get port config failed.\n");
826                                 rval = -EPERM;
827                                 goto done_free_dma_rsp;
828                         }
829
830                         if ((config[0] & INTERNAL_LOOPBACK_MASK) != 0) {
831                                 ql_dbg(ql_dbg_user, vha, 0x70c4,
832                                     "Loopback operation already in "
833                                     "progress.\n");
834                                 rval = -EAGAIN;
835                                 goto done_free_dma_rsp;
836                         }
837
838                         ql_dbg(ql_dbg_user, vha, 0x70c0,
839                             "elreq.options=%04x\n", elreq.options);
840
841                         if (elreq.options == EXTERNAL_LOOPBACK)
842                                 if (IS_QLA8031(ha) || IS_QLA8044(ha))
843                                         rval = qla81xx_set_loopback_mode(vha,
844                                             config, new_config, elreq.options);
845                                 else
846                                         rval = qla81xx_reset_loopback_mode(vha,
847                                             config, 1, 0);
848                         else
849                                 rval = qla81xx_set_loopback_mode(vha, config,
850                                     new_config, elreq.options);
851
852                         if (rval) {
853                                 rval = -EPERM;
854                                 goto done_free_dma_rsp;
855                         }
856
857                         type = "FC_BSG_HST_VENDOR_LOOPBACK";
858                         ql_dbg(ql_dbg_user, vha, 0x7028,
859                             "BSG request type: %s.\n", type);
860
861                         command_sent = INT_DEF_LB_LOOPBACK_CMD;
862                         rval = qla2x00_loopback_test(vha, &elreq, response);
863
864                         if (response[0] == MBS_COMMAND_ERROR &&
865                                         response[1] == MBS_LB_RESET) {
866                                 ql_log(ql_log_warn, vha, 0x7029,
867                                     "MBX command error, Aborting ISP.\n");
868                                 set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
869                                 qla2xxx_wake_dpc(vha);
870                                 qla2x00_wait_for_chip_reset(vha);
871                                 /* Also reset the MPI */
872                                 if (IS_QLA81XX(ha)) {
873                                         if (qla81xx_restart_mpi_firmware(vha) !=
874                                             QLA_SUCCESS) {
875                                                 ql_log(ql_log_warn, vha, 0x702a,
876                                                     "MPI reset failed.\n");
877                                         }
878                                 }
879
880                                 rval = -EIO;
881                                 goto done_free_dma_rsp;
882                         }
883
884                         if (new_config[0]) {
885                                 int ret;
886
887                                 /* Revert back to original port config
888                                  * Also clear internal loopback
889                                  */
890                                 ret = qla81xx_reset_loopback_mode(vha,
891                                     new_config, 0, 1);
892                                 if (ret) {
893                                         /*
894                                          * If the reset of the loopback mode
895                                          * doesn't work take FCoE dump and then
896                                          * reset the chip.
897                                          */
898                                         qla2xxx_dump_fw(vha);
899                                         set_bit(ISP_ABORT_NEEDED,
900                                             &vha->dpc_flags);
901                                 }
902
903                         }
904
905                 } else {
906                         type = "FC_BSG_HST_VENDOR_LOOPBACK";
907                         ql_dbg(ql_dbg_user, vha, 0x702b,
908                             "BSG request type: %s.\n", type);
909                         command_sent = INT_DEF_LB_LOOPBACK_CMD;
910                         rval = qla2x00_loopback_test(vha, &elreq, response);
911                 }
912         }
913
914         if (rval) {
915                 ql_log(ql_log_warn, vha, 0x702c,
916                     "Vendor request %s failed.\n", type);
917
918                 rval = 0;
919                 bsg_reply->result = (DID_ERROR << 16);
920                 bsg_reply->reply_payload_rcv_len = 0;
921         } else {
922                 ql_dbg(ql_dbg_user, vha, 0x702d,
923                     "Vendor request %s completed.\n", type);
924                 bsg_reply->result = (DID_OK << 16);
925                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
926                         bsg_job->reply_payload.sg_cnt, rsp_data,
927                         rsp_data_len);
928         }
929
930         bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
931             sizeof(response) + sizeof(uint8_t);
932         fw_sts_ptr = bsg_job->reply + sizeof(struct fc_bsg_reply);
933         memcpy(bsg_job->reply + sizeof(struct fc_bsg_reply), response,
934                         sizeof(response));
935         fw_sts_ptr += sizeof(response);
936         *fw_sts_ptr = command_sent;
937
938 done_free_dma_rsp:
939         dma_free_coherent(&ha->pdev->dev, rsp_data_len,
940                 rsp_data, rsp_data_dma);
941 done_free_dma_req:
942         dma_free_coherent(&ha->pdev->dev, req_data_len,
943                 req_data, req_data_dma);
944 done_unmap_sg:
945         dma_unmap_sg(&ha->pdev->dev,
946             bsg_job->reply_payload.sg_list,
947             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
948 done_unmap_req_sg:
949         dma_unmap_sg(&ha->pdev->dev,
950             bsg_job->request_payload.sg_list,
951             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
952         if (!rval)
953                 bsg_job_done(bsg_job, bsg_reply->result,
954                                bsg_reply->reply_payload_rcv_len);
955         return rval;
956 }
957
958 static int
959 qla84xx_reset(struct bsg_job *bsg_job)
960 {
961         struct fc_bsg_request *bsg_request = bsg_job->request;
962         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
963         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
964         scsi_qla_host_t *vha = shost_priv(host);
965         struct qla_hw_data *ha = vha->hw;
966         int rval = 0;
967         uint32_t flag;
968
969         if (!IS_QLA84XX(ha)) {
970                 ql_dbg(ql_dbg_user, vha, 0x702f, "Not 84xx, exiting.\n");
971                 return -EINVAL;
972         }
973
974         flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
975
976         rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
977
978         if (rval) {
979                 ql_log(ql_log_warn, vha, 0x7030,
980                     "Vendor request 84xx reset failed.\n");
981                 rval = (DID_ERROR << 16);
982
983         } else {
984                 ql_dbg(ql_dbg_user, vha, 0x7031,
985                     "Vendor request 84xx reset completed.\n");
986                 bsg_reply->result = DID_OK;
987                 bsg_job_done(bsg_job, bsg_reply->result,
988                                bsg_reply->reply_payload_rcv_len);
989         }
990
991         return rval;
992 }
993
994 static int
995 qla84xx_updatefw(struct bsg_job *bsg_job)
996 {
997         struct fc_bsg_request *bsg_request = bsg_job->request;
998         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
999         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1000         scsi_qla_host_t *vha = shost_priv(host);
1001         struct qla_hw_data *ha = vha->hw;
1002         struct verify_chip_entry_84xx *mn = NULL;
1003         dma_addr_t mn_dma, fw_dma;
1004         void *fw_buf = NULL;
1005         int rval = 0;
1006         uint32_t sg_cnt;
1007         uint32_t data_len;
1008         uint16_t options;
1009         uint32_t flag;
1010         uint32_t fw_ver;
1011
1012         if (!IS_QLA84XX(ha)) {
1013                 ql_dbg(ql_dbg_user, vha, 0x7032,
1014                     "Not 84xx, exiting.\n");
1015                 return -EINVAL;
1016         }
1017
1018         sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1019                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1020         if (!sg_cnt) {
1021                 ql_log(ql_log_warn, vha, 0x7033,
1022                     "dma_map_sg returned %d for request.\n", sg_cnt);
1023                 return -ENOMEM;
1024         }
1025
1026         if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1027                 ql_log(ql_log_warn, vha, 0x7034,
1028                     "DMA mapping resulted in different sg counts, "
1029                     "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1030                     bsg_job->request_payload.sg_cnt, sg_cnt);
1031                 rval = -EAGAIN;
1032                 goto done_unmap_sg;
1033         }
1034
1035         data_len = bsg_job->request_payload.payload_len;
1036         fw_buf = dma_alloc_coherent(&ha->pdev->dev, data_len,
1037                 &fw_dma, GFP_KERNEL);
1038         if (!fw_buf) {
1039                 ql_log(ql_log_warn, vha, 0x7035,
1040                     "DMA alloc failed for fw_buf.\n");
1041                 rval = -ENOMEM;
1042                 goto done_unmap_sg;
1043         }
1044
1045         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1046                 bsg_job->request_payload.sg_cnt, fw_buf, data_len);
1047
1048         mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1049         if (!mn) {
1050                 ql_log(ql_log_warn, vha, 0x7036,
1051                     "DMA alloc failed for fw buffer.\n");
1052                 rval = -ENOMEM;
1053                 goto done_free_fw_buf;
1054         }
1055
1056         flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1057         fw_ver = get_unaligned_le32((uint32_t *)fw_buf + 2);
1058
1059         mn->entry_type = VERIFY_CHIP_IOCB_TYPE;
1060         mn->entry_count = 1;
1061
1062         options = VCO_FORCE_UPDATE | VCO_END_OF_DATA;
1063         if (flag == A84_ISSUE_UPDATE_DIAGFW_CMD)
1064                 options |= VCO_DIAG_FW;
1065
1066         mn->options = cpu_to_le16(options);
1067         mn->fw_ver =  cpu_to_le32(fw_ver);
1068         mn->fw_size =  cpu_to_le32(data_len);
1069         mn->fw_seq_size =  cpu_to_le32(data_len);
1070         put_unaligned_le64(fw_dma, &mn->dsd.address);
1071         mn->dsd.length = cpu_to_le32(data_len);
1072         mn->data_seg_cnt = cpu_to_le16(1);
1073
1074         rval = qla2x00_issue_iocb_timeout(vha, mn, mn_dma, 0, 120);
1075
1076         if (rval) {
1077                 ql_log(ql_log_warn, vha, 0x7037,
1078                     "Vendor request 84xx updatefw failed.\n");
1079
1080                 rval = (DID_ERROR << 16);
1081         } else {
1082                 ql_dbg(ql_dbg_user, vha, 0x7038,
1083                     "Vendor request 84xx updatefw completed.\n");
1084
1085                 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1086                 bsg_reply->result = DID_OK;
1087         }
1088
1089         dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1090
1091 done_free_fw_buf:
1092         dma_free_coherent(&ha->pdev->dev, data_len, fw_buf, fw_dma);
1093
1094 done_unmap_sg:
1095         dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1096                 bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1097
1098         if (!rval)
1099                 bsg_job_done(bsg_job, bsg_reply->result,
1100                                bsg_reply->reply_payload_rcv_len);
1101         return rval;
1102 }
1103
1104 static int
1105 qla84xx_mgmt_cmd(struct bsg_job *bsg_job)
1106 {
1107         struct fc_bsg_request *bsg_request = bsg_job->request;
1108         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1109         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1110         scsi_qla_host_t *vha = shost_priv(host);
1111         struct qla_hw_data *ha = vha->hw;
1112         struct access_chip_84xx *mn = NULL;
1113         dma_addr_t mn_dma, mgmt_dma;
1114         void *mgmt_b = NULL;
1115         int rval = 0;
1116         struct qla_bsg_a84_mgmt *ql84_mgmt;
1117         uint32_t sg_cnt;
1118         uint32_t data_len = 0;
1119         uint32_t dma_direction = DMA_NONE;
1120
1121         if (!IS_QLA84XX(ha)) {
1122                 ql_log(ql_log_warn, vha, 0x703a,
1123                     "Not 84xx, exiting.\n");
1124                 return -EINVAL;
1125         }
1126
1127         mn = dma_pool_zalloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
1128         if (!mn) {
1129                 ql_log(ql_log_warn, vha, 0x703c,
1130                     "DMA alloc failed for fw buffer.\n");
1131                 return -ENOMEM;
1132         }
1133
1134         mn->entry_type = ACCESS_CHIP_IOCB_TYPE;
1135         mn->entry_count = 1;
1136         ql84_mgmt = (void *)bsg_request + sizeof(struct fc_bsg_request);
1137         switch (ql84_mgmt->mgmt.cmd) {
1138         case QLA84_MGMT_READ_MEM:
1139         case QLA84_MGMT_GET_INFO:
1140                 sg_cnt = dma_map_sg(&ha->pdev->dev,
1141                         bsg_job->reply_payload.sg_list,
1142                         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1143                 if (!sg_cnt) {
1144                         ql_log(ql_log_warn, vha, 0x703d,
1145                             "dma_map_sg returned %d for reply.\n", sg_cnt);
1146                         rval = -ENOMEM;
1147                         goto exit_mgmt;
1148                 }
1149
1150                 dma_direction = DMA_FROM_DEVICE;
1151
1152                 if (sg_cnt != bsg_job->reply_payload.sg_cnt) {
1153                         ql_log(ql_log_warn, vha, 0x703e,
1154                             "DMA mapping resulted in different sg counts, "
1155                             "reply_sg_cnt: %x dma_reply_sg_cnt: %x.\n",
1156                             bsg_job->reply_payload.sg_cnt, sg_cnt);
1157                         rval = -EAGAIN;
1158                         goto done_unmap_sg;
1159                 }
1160
1161                 data_len = bsg_job->reply_payload.payload_len;
1162
1163                 mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1164                     &mgmt_dma, GFP_KERNEL);
1165                 if (!mgmt_b) {
1166                         ql_log(ql_log_warn, vha, 0x703f,
1167                             "DMA alloc failed for mgmt_b.\n");
1168                         rval = -ENOMEM;
1169                         goto done_unmap_sg;
1170                 }
1171
1172                 if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) {
1173                         mn->options = cpu_to_le16(ACO_DUMP_MEMORY);
1174                         mn->parameter1 =
1175                                 cpu_to_le32(
1176                                 ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1177
1178                 } else if (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO) {
1179                         mn->options = cpu_to_le16(ACO_REQUEST_INFO);
1180                         mn->parameter1 =
1181                                 cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.info.type);
1182
1183                         mn->parameter2 =
1184                                 cpu_to_le32(
1185                                 ql84_mgmt->mgmt.mgmtp.u.info.context);
1186                 }
1187                 break;
1188
1189         case QLA84_MGMT_WRITE_MEM:
1190                 sg_cnt = dma_map_sg(&ha->pdev->dev,
1191                         bsg_job->request_payload.sg_list,
1192                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1193
1194                 if (!sg_cnt) {
1195                         ql_log(ql_log_warn, vha, 0x7040,
1196                             "dma_map_sg returned %d.\n", sg_cnt);
1197                         rval = -ENOMEM;
1198                         goto exit_mgmt;
1199                 }
1200
1201                 dma_direction = DMA_TO_DEVICE;
1202
1203                 if (sg_cnt != bsg_job->request_payload.sg_cnt) {
1204                         ql_log(ql_log_warn, vha, 0x7041,
1205                             "DMA mapping resulted in different sg counts, "
1206                             "request_sg_cnt: %x dma_request_sg_cnt: %x.\n",
1207                             bsg_job->request_payload.sg_cnt, sg_cnt);
1208                         rval = -EAGAIN;
1209                         goto done_unmap_sg;
1210                 }
1211
1212                 data_len = bsg_job->request_payload.payload_len;
1213                 mgmt_b = dma_alloc_coherent(&ha->pdev->dev, data_len,
1214                         &mgmt_dma, GFP_KERNEL);
1215                 if (!mgmt_b) {
1216                         ql_log(ql_log_warn, vha, 0x7042,
1217                             "DMA alloc failed for mgmt_b.\n");
1218                         rval = -ENOMEM;
1219                         goto done_unmap_sg;
1220                 }
1221
1222                 sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1223                         bsg_job->request_payload.sg_cnt, mgmt_b, data_len);
1224
1225                 mn->options = cpu_to_le16(ACO_LOAD_MEMORY);
1226                 mn->parameter1 =
1227                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.mem.start_addr);
1228                 break;
1229
1230         case QLA84_MGMT_CHNG_CONFIG:
1231                 mn->options = cpu_to_le16(ACO_CHANGE_CONFIG_PARAM);
1232                 mn->parameter1 =
1233                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.id);
1234
1235                 mn->parameter2 =
1236                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param0);
1237
1238                 mn->parameter3 =
1239                         cpu_to_le32(ql84_mgmt->mgmt.mgmtp.u.config.param1);
1240                 break;
1241
1242         default:
1243                 rval = -EIO;
1244                 goto exit_mgmt;
1245         }
1246
1247         if (ql84_mgmt->mgmt.cmd != QLA84_MGMT_CHNG_CONFIG) {
1248                 mn->total_byte_cnt = cpu_to_le32(ql84_mgmt->mgmt.len);
1249                 mn->dseg_count = cpu_to_le16(1);
1250                 put_unaligned_le64(mgmt_dma, &mn->dsd.address);
1251                 mn->dsd.length = cpu_to_le32(ql84_mgmt->mgmt.len);
1252         }
1253
1254         rval = qla2x00_issue_iocb(vha, mn, mn_dma, 0);
1255
1256         if (rval) {
1257                 ql_log(ql_log_warn, vha, 0x7043,
1258                     "Vendor request 84xx mgmt failed.\n");
1259
1260                 rval = (DID_ERROR << 16);
1261
1262         } else {
1263                 ql_dbg(ql_dbg_user, vha, 0x7044,
1264                     "Vendor request 84xx mgmt completed.\n");
1265
1266                 bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1267                 bsg_reply->result = DID_OK;
1268
1269                 if ((ql84_mgmt->mgmt.cmd == QLA84_MGMT_READ_MEM) ||
1270                         (ql84_mgmt->mgmt.cmd == QLA84_MGMT_GET_INFO)) {
1271                         bsg_reply->reply_payload_rcv_len =
1272                                 bsg_job->reply_payload.payload_len;
1273
1274                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1275                                 bsg_job->reply_payload.sg_cnt, mgmt_b,
1276                                 data_len);
1277                 }
1278         }
1279
1280 done_unmap_sg:
1281         if (mgmt_b)
1282                 dma_free_coherent(&ha->pdev->dev, data_len, mgmt_b, mgmt_dma);
1283
1284         if (dma_direction == DMA_TO_DEVICE)
1285                 dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
1286                         bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1287         else if (dma_direction == DMA_FROM_DEVICE)
1288                 dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
1289                         bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1290
1291 exit_mgmt:
1292         dma_pool_free(ha->s_dma_pool, mn, mn_dma);
1293
1294         if (!rval)
1295                 bsg_job_done(bsg_job, bsg_reply->result,
1296                                bsg_reply->reply_payload_rcv_len);
1297         return rval;
1298 }
1299
1300 static int
1301 qla24xx_iidma(struct bsg_job *bsg_job)
1302 {
1303         struct fc_bsg_request *bsg_request = bsg_job->request;
1304         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1305         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1306         scsi_qla_host_t *vha = shost_priv(host);
1307         int rval = 0;
1308         struct qla_port_param *port_param = NULL;
1309         fc_port_t *fcport = NULL;
1310         int found = 0;
1311         uint16_t mb[MAILBOX_REGISTER_COUNT];
1312         uint8_t *rsp_ptr = NULL;
1313
1314         if (!IS_IIDMA_CAPABLE(vha->hw)) {
1315                 ql_log(ql_log_info, vha, 0x7046, "iiDMA not supported.\n");
1316                 return -EINVAL;
1317         }
1318
1319         port_param = (void *)bsg_request + sizeof(struct fc_bsg_request);
1320         if (port_param->fc_scsi_addr.dest_type != EXT_DEF_TYPE_WWPN) {
1321                 ql_log(ql_log_warn, vha, 0x7048,
1322                     "Invalid destination type.\n");
1323                 return -EINVAL;
1324         }
1325
1326         list_for_each_entry(fcport, &vha->vp_fcports, list) {
1327                 if (fcport->port_type != FCT_TARGET)
1328                         continue;
1329
1330                 if (memcmp(port_param->fc_scsi_addr.dest_addr.wwpn,
1331                         fcport->port_name, sizeof(fcport->port_name)))
1332                         continue;
1333
1334                 found = 1;
1335                 break;
1336         }
1337
1338         if (!found) {
1339                 ql_log(ql_log_warn, vha, 0x7049,
1340                     "Failed to find port.\n");
1341                 return -EINVAL;
1342         }
1343
1344         if (atomic_read(&fcport->state) != FCS_ONLINE) {
1345                 ql_log(ql_log_warn, vha, 0x704a,
1346                     "Port is not online.\n");
1347                 return -EINVAL;
1348         }
1349
1350         if (fcport->flags & FCF_LOGIN_NEEDED) {
1351                 ql_log(ql_log_warn, vha, 0x704b,
1352                     "Remote port not logged in flags = 0x%x.\n", fcport->flags);
1353                 return -EINVAL;
1354         }
1355
1356         if (port_param->mode)
1357                 rval = qla2x00_set_idma_speed(vha, fcport->loop_id,
1358                         port_param->speed, mb);
1359         else
1360                 rval = qla2x00_get_idma_speed(vha, fcport->loop_id,
1361                         &port_param->speed, mb);
1362
1363         if (rval) {
1364                 ql_log(ql_log_warn, vha, 0x704c,
1365                     "iiDMA cmd failed for %8phN -- "
1366                     "%04x %x %04x %04x.\n", fcport->port_name,
1367                     rval, fcport->fp_speed, mb[0], mb[1]);
1368                 rval = (DID_ERROR << 16);
1369         } else {
1370                 if (!port_param->mode) {
1371                         bsg_job->reply_len = sizeof(struct fc_bsg_reply) +
1372                                 sizeof(struct qla_port_param);
1373
1374                         rsp_ptr = ((uint8_t *)bsg_reply) +
1375                                 sizeof(struct fc_bsg_reply);
1376
1377                         memcpy(rsp_ptr, port_param,
1378                                 sizeof(struct qla_port_param));
1379                 }
1380
1381                 bsg_reply->result = DID_OK;
1382                 bsg_job_done(bsg_job, bsg_reply->result,
1383                                bsg_reply->reply_payload_rcv_len);
1384         }
1385
1386         return rval;
1387 }
1388
1389 static int
1390 qla2x00_optrom_setup(struct bsg_job *bsg_job, scsi_qla_host_t *vha,
1391         uint8_t is_update)
1392 {
1393         struct fc_bsg_request *bsg_request = bsg_job->request;
1394         uint32_t start = 0;
1395         int valid = 0;
1396         struct qla_hw_data *ha = vha->hw;
1397
1398         if (unlikely(pci_channel_offline(ha->pdev)))
1399                 return -EINVAL;
1400
1401         start = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1402         if (start > ha->optrom_size) {
1403                 ql_log(ql_log_warn, vha, 0x7055,
1404                     "start %d > optrom_size %d.\n", start, ha->optrom_size);
1405                 return -EINVAL;
1406         }
1407
1408         if (ha->optrom_state != QLA_SWAITING) {
1409                 ql_log(ql_log_info, vha, 0x7056,
1410                     "optrom_state %d.\n", ha->optrom_state);
1411                 return -EBUSY;
1412         }
1413
1414         ha->optrom_region_start = start;
1415         ql_dbg(ql_dbg_user, vha, 0x7057, "is_update=%d.\n", is_update);
1416         if (is_update) {
1417                 if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0)
1418                         valid = 1;
1419                 else if (start == (ha->flt_region_boot * 4) ||
1420                     start == (ha->flt_region_fw * 4))
1421                         valid = 1;
1422                 else if (IS_QLA24XX_TYPE(ha) || IS_QLA25XX(ha) ||
1423                     IS_CNA_CAPABLE(ha) || IS_QLA2031(ha) || IS_QLA27XX(ha) ||
1424                     IS_QLA28XX(ha))
1425                         valid = 1;
1426                 if (!valid) {
1427                         ql_log(ql_log_warn, vha, 0x7058,
1428                             "Invalid start region 0x%x/0x%x.\n", start,
1429                             bsg_job->request_payload.payload_len);
1430                         return -EINVAL;
1431                 }
1432
1433                 ha->optrom_region_size = start +
1434                     bsg_job->request_payload.payload_len > ha->optrom_size ?
1435                     ha->optrom_size - start :
1436                     bsg_job->request_payload.payload_len;
1437                 ha->optrom_state = QLA_SWRITING;
1438         } else {
1439                 ha->optrom_region_size = start +
1440                     bsg_job->reply_payload.payload_len > ha->optrom_size ?
1441                     ha->optrom_size - start :
1442                     bsg_job->reply_payload.payload_len;
1443                 ha->optrom_state = QLA_SREADING;
1444         }
1445
1446         ha->optrom_buffer = vzalloc(ha->optrom_region_size);
1447         if (!ha->optrom_buffer) {
1448                 ql_log(ql_log_warn, vha, 0x7059,
1449                     "Read: Unable to allocate memory for optrom retrieval "
1450                     "(%x)\n", ha->optrom_region_size);
1451
1452                 ha->optrom_state = QLA_SWAITING;
1453                 return -ENOMEM;
1454         }
1455
1456         return 0;
1457 }
1458
1459 static int
1460 qla2x00_read_optrom(struct bsg_job *bsg_job)
1461 {
1462         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1463         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1464         scsi_qla_host_t *vha = shost_priv(host);
1465         struct qla_hw_data *ha = vha->hw;
1466         int rval = 0;
1467
1468         if (ha->flags.nic_core_reset_hdlr_active)
1469                 return -EBUSY;
1470
1471         mutex_lock(&ha->optrom_mutex);
1472         rval = qla2x00_optrom_setup(bsg_job, vha, 0);
1473         if (rval) {
1474                 mutex_unlock(&ha->optrom_mutex);
1475                 return rval;
1476         }
1477
1478         ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
1479             ha->optrom_region_start, ha->optrom_region_size);
1480
1481         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1482             bsg_job->reply_payload.sg_cnt, ha->optrom_buffer,
1483             ha->optrom_region_size);
1484
1485         bsg_reply->reply_payload_rcv_len = ha->optrom_region_size;
1486         bsg_reply->result = DID_OK;
1487         vfree(ha->optrom_buffer);
1488         ha->optrom_buffer = NULL;
1489         ha->optrom_state = QLA_SWAITING;
1490         mutex_unlock(&ha->optrom_mutex);
1491         bsg_job_done(bsg_job, bsg_reply->result,
1492                        bsg_reply->reply_payload_rcv_len);
1493         return rval;
1494 }
1495
1496 static int
1497 qla2x00_update_optrom(struct bsg_job *bsg_job)
1498 {
1499         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1500         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1501         scsi_qla_host_t *vha = shost_priv(host);
1502         struct qla_hw_data *ha = vha->hw;
1503         int rval = 0;
1504
1505         mutex_lock(&ha->optrom_mutex);
1506         rval = qla2x00_optrom_setup(bsg_job, vha, 1);
1507         if (rval) {
1508                 mutex_unlock(&ha->optrom_mutex);
1509                 return rval;
1510         }
1511
1512         /* Set the isp82xx_no_md_cap not to capture minidump */
1513         ha->flags.isp82xx_no_md_cap = 1;
1514
1515         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1516             bsg_job->request_payload.sg_cnt, ha->optrom_buffer,
1517             ha->optrom_region_size);
1518
1519         rval = ha->isp_ops->write_optrom(vha, ha->optrom_buffer,
1520             ha->optrom_region_start, ha->optrom_region_size);
1521
1522         if (rval) {
1523                 bsg_reply->result = -EINVAL;
1524                 rval = -EINVAL;
1525         } else {
1526                 bsg_reply->result = DID_OK;
1527         }
1528         vfree(ha->optrom_buffer);
1529         ha->optrom_buffer = NULL;
1530         ha->optrom_state = QLA_SWAITING;
1531         mutex_unlock(&ha->optrom_mutex);
1532         bsg_job_done(bsg_job, bsg_reply->result,
1533                        bsg_reply->reply_payload_rcv_len);
1534         return rval;
1535 }
1536
1537 static int
1538 qla2x00_update_fru_versions(struct bsg_job *bsg_job)
1539 {
1540         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1541         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1542         scsi_qla_host_t *vha = shost_priv(host);
1543         struct qla_hw_data *ha = vha->hw;
1544         int rval = 0;
1545         uint8_t bsg[DMA_POOL_SIZE];
1546         struct qla_image_version_list *list = (void *)bsg;
1547         struct qla_image_version *image;
1548         uint32_t count;
1549         dma_addr_t sfp_dma;
1550         void *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1551
1552         if (!sfp) {
1553                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1554                     EXT_STATUS_NO_MEMORY;
1555                 goto done;
1556         }
1557
1558         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1559             bsg_job->request_payload.sg_cnt, list, sizeof(bsg));
1560
1561         image = list->version;
1562         count = list->count;
1563         while (count--) {
1564                 memcpy(sfp, &image->field_info, sizeof(image->field_info));
1565                 rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1566                     image->field_address.device, image->field_address.offset,
1567                     sizeof(image->field_info), image->field_address.option);
1568                 if (rval) {
1569                         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1570                             EXT_STATUS_MAILBOX;
1571                         goto dealloc;
1572                 }
1573                 image++;
1574         }
1575
1576         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1577
1578 dealloc:
1579         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1580
1581 done:
1582         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1583         bsg_reply->result = DID_OK << 16;
1584         bsg_job_done(bsg_job, bsg_reply->result,
1585                        bsg_reply->reply_payload_rcv_len);
1586
1587         return 0;
1588 }
1589
1590 static int
1591 qla2x00_read_fru_status(struct bsg_job *bsg_job)
1592 {
1593         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1594         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1595         scsi_qla_host_t *vha = shost_priv(host);
1596         struct qla_hw_data *ha = vha->hw;
1597         int rval = 0;
1598         uint8_t bsg[DMA_POOL_SIZE];
1599         struct qla_status_reg *sr = (void *)bsg;
1600         dma_addr_t sfp_dma;
1601         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1602
1603         if (!sfp) {
1604                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1605                     EXT_STATUS_NO_MEMORY;
1606                 goto done;
1607         }
1608
1609         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1610             bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1611
1612         rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1613             sr->field_address.device, sr->field_address.offset,
1614             sizeof(sr->status_reg), sr->field_address.option);
1615         sr->status_reg = *sfp;
1616
1617         if (rval) {
1618                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1619                     EXT_STATUS_MAILBOX;
1620                 goto dealloc;
1621         }
1622
1623         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1624             bsg_job->reply_payload.sg_cnt, sr, sizeof(*sr));
1625
1626         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1627
1628 dealloc:
1629         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1630
1631 done:
1632         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1633         bsg_reply->reply_payload_rcv_len = sizeof(*sr);
1634         bsg_reply->result = DID_OK << 16;
1635         bsg_job_done(bsg_job, bsg_reply->result,
1636                        bsg_reply->reply_payload_rcv_len);
1637
1638         return 0;
1639 }
1640
1641 static int
1642 qla2x00_write_fru_status(struct bsg_job *bsg_job)
1643 {
1644         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1645         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1646         scsi_qla_host_t *vha = shost_priv(host);
1647         struct qla_hw_data *ha = vha->hw;
1648         int rval = 0;
1649         uint8_t bsg[DMA_POOL_SIZE];
1650         struct qla_status_reg *sr = (void *)bsg;
1651         dma_addr_t sfp_dma;
1652         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1653
1654         if (!sfp) {
1655                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1656                     EXT_STATUS_NO_MEMORY;
1657                 goto done;
1658         }
1659
1660         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1661             bsg_job->request_payload.sg_cnt, sr, sizeof(*sr));
1662
1663         *sfp = sr->status_reg;
1664         rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1665             sr->field_address.device, sr->field_address.offset,
1666             sizeof(sr->status_reg), sr->field_address.option);
1667
1668         if (rval) {
1669                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1670                     EXT_STATUS_MAILBOX;
1671                 goto dealloc;
1672         }
1673
1674         bsg_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_reply->result = DID_OK << 16;
1682         bsg_job_done(bsg_job, bsg_reply->result,
1683                        bsg_reply->reply_payload_rcv_len);
1684
1685         return 0;
1686 }
1687
1688 static int
1689 qla2x00_write_i2c(struct bsg_job *bsg_job)
1690 {
1691         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1692         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1693         scsi_qla_host_t *vha = shost_priv(host);
1694         struct qla_hw_data *ha = vha->hw;
1695         int rval = 0;
1696         uint8_t bsg[DMA_POOL_SIZE];
1697         struct qla_i2c_access *i2c = (void *)bsg;
1698         dma_addr_t sfp_dma;
1699         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1700
1701         if (!sfp) {
1702                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1703                     EXT_STATUS_NO_MEMORY;
1704                 goto done;
1705         }
1706
1707         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1708             bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1709
1710         memcpy(sfp, i2c->buffer, i2c->length);
1711         rval = qla2x00_write_sfp(vha, sfp_dma, sfp,
1712             i2c->device, i2c->offset, i2c->length, i2c->option);
1713
1714         if (rval) {
1715                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1716                     EXT_STATUS_MAILBOX;
1717                 goto dealloc;
1718         }
1719
1720         bsg_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_reply->result = DID_OK << 16;
1728         bsg_job_done(bsg_job, bsg_reply->result,
1729                        bsg_reply->reply_payload_rcv_len);
1730
1731         return 0;
1732 }
1733
1734 static int
1735 qla2x00_read_i2c(struct bsg_job *bsg_job)
1736 {
1737         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1738         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1739         scsi_qla_host_t *vha = shost_priv(host);
1740         struct qla_hw_data *ha = vha->hw;
1741         int rval = 0;
1742         uint8_t bsg[DMA_POOL_SIZE];
1743         struct qla_i2c_access *i2c = (void *)bsg;
1744         dma_addr_t sfp_dma;
1745         uint8_t *sfp = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &sfp_dma);
1746
1747         if (!sfp) {
1748                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1749                     EXT_STATUS_NO_MEMORY;
1750                 goto done;
1751         }
1752
1753         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
1754             bsg_job->request_payload.sg_cnt, i2c, sizeof(*i2c));
1755
1756         rval = qla2x00_read_sfp(vha, sfp_dma, sfp,
1757                 i2c->device, i2c->offset, i2c->length, i2c->option);
1758
1759         if (rval) {
1760                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
1761                     EXT_STATUS_MAILBOX;
1762                 goto dealloc;
1763         }
1764
1765         memcpy(i2c->buffer, sfp, i2c->length);
1766         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
1767             bsg_job->reply_payload.sg_cnt, i2c, sizeof(*i2c));
1768
1769         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = 0;
1770
1771 dealloc:
1772         dma_pool_free(ha->s_dma_pool, sfp, sfp_dma);
1773
1774 done:
1775         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1776         bsg_reply->reply_payload_rcv_len = sizeof(*i2c);
1777         bsg_reply->result = DID_OK << 16;
1778         bsg_job_done(bsg_job, bsg_reply->result,
1779                        bsg_reply->reply_payload_rcv_len);
1780
1781         return 0;
1782 }
1783
1784 static int
1785 qla24xx_process_bidir_cmd(struct bsg_job *bsg_job)
1786 {
1787         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
1788         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1789         scsi_qla_host_t *vha = shost_priv(host);
1790         struct qla_hw_data *ha = vha->hw;
1791         uint32_t rval = EXT_STATUS_OK;
1792         uint16_t req_sg_cnt = 0;
1793         uint16_t rsp_sg_cnt = 0;
1794         uint16_t nextlid = 0;
1795         uint32_t tot_dsds;
1796         srb_t *sp = NULL;
1797         uint32_t req_data_len;
1798         uint32_t rsp_data_len;
1799
1800         /* Check the type of the adapter */
1801         if (!IS_BIDI_CAPABLE(ha)) {
1802                 ql_log(ql_log_warn, vha, 0x70a0,
1803                         "This adapter is not supported\n");
1804                 rval = EXT_STATUS_NOT_SUPPORTED;
1805                 goto done;
1806         }
1807
1808         if (test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
1809                 test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags) ||
1810                 test_bit(ISP_ABORT_RETRY, &vha->dpc_flags)) {
1811                 rval =  EXT_STATUS_BUSY;
1812                 goto done;
1813         }
1814
1815         /* Check if host is online */
1816         if (!vha->flags.online) {
1817                 ql_log(ql_log_warn, vha, 0x70a1,
1818                         "Host is not online\n");
1819                 rval = EXT_STATUS_DEVICE_OFFLINE;
1820                 goto done;
1821         }
1822
1823         /* Check if cable is plugged in or not */
1824         if (vha->device_flags & DFLG_NO_CABLE) {
1825                 ql_log(ql_log_warn, vha, 0x70a2,
1826                         "Cable is unplugged...\n");
1827                 rval = EXT_STATUS_INVALID_CFG;
1828                 goto done;
1829         }
1830
1831         /* Check if the switch is connected or not */
1832         if (ha->current_topology != ISP_CFG_F) {
1833                 ql_log(ql_log_warn, vha, 0x70a3,
1834                         "Host is not connected to the switch\n");
1835                 rval = EXT_STATUS_INVALID_CFG;
1836                 goto done;
1837         }
1838
1839         /* Check if operating mode is P2P */
1840         if (ha->operating_mode != P2P) {
1841                 ql_log(ql_log_warn, vha, 0x70a4,
1842                     "Host operating mode is not P2p\n");
1843                 rval = EXT_STATUS_INVALID_CFG;
1844                 goto done;
1845         }
1846
1847         mutex_lock(&ha->selflogin_lock);
1848         if (vha->self_login_loop_id == 0) {
1849                 /* Initialize all required  fields of fcport */
1850                 vha->bidir_fcport.vha = vha;
1851                 vha->bidir_fcport.d_id.b.al_pa = vha->d_id.b.al_pa;
1852                 vha->bidir_fcport.d_id.b.area = vha->d_id.b.area;
1853                 vha->bidir_fcport.d_id.b.domain = vha->d_id.b.domain;
1854                 vha->bidir_fcport.loop_id = vha->loop_id;
1855
1856                 if (qla2x00_fabric_login(vha, &(vha->bidir_fcport), &nextlid)) {
1857                         ql_log(ql_log_warn, vha, 0x70a7,
1858                             "Failed to login port %06X for bidirectional IOCB\n",
1859                             vha->bidir_fcport.d_id.b24);
1860                         mutex_unlock(&ha->selflogin_lock);
1861                         rval = EXT_STATUS_MAILBOX;
1862                         goto done;
1863                 }
1864                 vha->self_login_loop_id = nextlid - 1;
1865
1866         }
1867         /* Assign the self login loop id to fcport */
1868         mutex_unlock(&ha->selflogin_lock);
1869
1870         vha->bidir_fcport.loop_id = vha->self_login_loop_id;
1871
1872         req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1873                 bsg_job->request_payload.sg_list,
1874                 bsg_job->request_payload.sg_cnt,
1875                 DMA_TO_DEVICE);
1876
1877         if (!req_sg_cnt) {
1878                 rval = EXT_STATUS_NO_MEMORY;
1879                 goto done;
1880         }
1881
1882         rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
1883                 bsg_job->reply_payload.sg_list, bsg_job->reply_payload.sg_cnt,
1884                 DMA_FROM_DEVICE);
1885
1886         if (!rsp_sg_cnt) {
1887                 rval = EXT_STATUS_NO_MEMORY;
1888                 goto done_unmap_req_sg;
1889         }
1890
1891         if ((req_sg_cnt !=  bsg_job->request_payload.sg_cnt) ||
1892                 (rsp_sg_cnt != bsg_job->reply_payload.sg_cnt)) {
1893                 ql_dbg(ql_dbg_user, vha, 0x70a9,
1894                     "Dma mapping resulted in different sg counts "
1895                     "[request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt: "
1896                     "%x dma_reply_sg_cnt: %x]\n",
1897                     bsg_job->request_payload.sg_cnt, req_sg_cnt,
1898                     bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
1899                 rval = EXT_STATUS_NO_MEMORY;
1900                 goto done_unmap_sg;
1901         }
1902
1903         req_data_len = bsg_job->request_payload.payload_len;
1904         rsp_data_len = bsg_job->reply_payload.payload_len;
1905
1906         if (req_data_len != rsp_data_len) {
1907                 rval = EXT_STATUS_BUSY;
1908                 ql_log(ql_log_warn, vha, 0x70aa,
1909                     "req_data_len != rsp_data_len\n");
1910                 goto done_unmap_sg;
1911         }
1912
1913         /* Alloc SRB structure */
1914         sp = qla2x00_get_sp(vha, &(vha->bidir_fcport), GFP_KERNEL);
1915         if (!sp) {
1916                 ql_dbg(ql_dbg_user, vha, 0x70ac,
1917                     "Alloc SRB structure failed\n");
1918                 rval = EXT_STATUS_NO_MEMORY;
1919                 goto done_unmap_sg;
1920         }
1921
1922         /*Populate srb->ctx with bidir ctx*/
1923         sp->u.bsg_job = bsg_job;
1924         sp->free = qla2x00_bsg_sp_free;
1925         sp->type = SRB_BIDI_CMD;
1926         sp->done = qla2x00_bsg_job_done;
1927
1928         /* Add the read and write sg count */
1929         tot_dsds = rsp_sg_cnt + req_sg_cnt;
1930
1931         rval = qla2x00_start_bidir(sp, vha, tot_dsds);
1932         if (rval != EXT_STATUS_OK)
1933                 goto done_free_srb;
1934         /* the bsg request  will be completed in the interrupt handler */
1935         return rval;
1936
1937 done_free_srb:
1938         mempool_free(sp, ha->srb_mempool);
1939 done_unmap_sg:
1940         dma_unmap_sg(&ha->pdev->dev,
1941             bsg_job->reply_payload.sg_list,
1942             bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
1943 done_unmap_req_sg:
1944         dma_unmap_sg(&ha->pdev->dev,
1945             bsg_job->request_payload.sg_list,
1946             bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1947 done:
1948
1949         /* Return an error vendor specific response
1950          * and complete the bsg request
1951          */
1952         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = rval;
1953         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
1954         bsg_reply->reply_payload_rcv_len = 0;
1955         bsg_reply->result = (DID_OK) << 16;
1956         bsg_job_done(bsg_job, bsg_reply->result,
1957                        bsg_reply->reply_payload_rcv_len);
1958         /* Always return success, vendor rsp carries correct status */
1959         return 0;
1960 }
1961
1962 static int
1963 qlafx00_mgmt_cmd(struct bsg_job *bsg_job)
1964 {
1965         struct fc_bsg_request *bsg_request = bsg_job->request;
1966         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
1967         scsi_qla_host_t *vha = shost_priv(host);
1968         struct qla_hw_data *ha = vha->hw;
1969         int rval = (DID_ERROR << 16);
1970         struct qla_mt_iocb_rqst_fx00 *piocb_rqst;
1971         srb_t *sp;
1972         int req_sg_cnt = 0, rsp_sg_cnt = 0;
1973         struct fc_port *fcport;
1974         char  *type = "FC_BSG_HST_FX_MGMT";
1975
1976         /* Copy the IOCB specific information */
1977         piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
1978             &bsg_request->rqst_data.h_vendor.vendor_cmd[1];
1979
1980         /* Dump the vendor information */
1981         ql_dump_buffer(ql_dbg_user + ql_dbg_verbose , vha, 0x70cf,
1982             piocb_rqst, sizeof(*piocb_rqst));
1983
1984         if (!vha->flags.online) {
1985                 ql_log(ql_log_warn, vha, 0x70d0,
1986                     "Host is not online.\n");
1987                 rval = -EIO;
1988                 goto done;
1989         }
1990
1991         if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID) {
1992                 req_sg_cnt = dma_map_sg(&ha->pdev->dev,
1993                     bsg_job->request_payload.sg_list,
1994                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
1995                 if (!req_sg_cnt) {
1996                         ql_log(ql_log_warn, vha, 0x70c7,
1997                             "dma_map_sg return %d for request\n", req_sg_cnt);
1998                         rval = -ENOMEM;
1999                         goto done;
2000                 }
2001         }
2002
2003         if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) {
2004                 rsp_sg_cnt = dma_map_sg(&ha->pdev->dev,
2005                     bsg_job->reply_payload.sg_list,
2006                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2007                 if (!rsp_sg_cnt) {
2008                         ql_log(ql_log_warn, vha, 0x70c8,
2009                             "dma_map_sg return %d for reply\n", rsp_sg_cnt);
2010                         rval = -ENOMEM;
2011                         goto done_unmap_req_sg;
2012                 }
2013         }
2014
2015         ql_dbg(ql_dbg_user, vha, 0x70c9,
2016             "request_sg_cnt: %x dma_request_sg_cnt: %x reply_sg_cnt:%x "
2017             "dma_reply_sg_cnt: %x\n", bsg_job->request_payload.sg_cnt,
2018             req_sg_cnt, bsg_job->reply_payload.sg_cnt, rsp_sg_cnt);
2019
2020         /* Allocate a dummy fcport structure, since functions preparing the
2021          * IOCB and mailbox command retrieves port specific information
2022          * from fcport structure. For Host based ELS commands there will be
2023          * no fcport structure allocated
2024          */
2025         fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL);
2026         if (!fcport) {
2027                 ql_log(ql_log_warn, vha, 0x70ca,
2028                     "Failed to allocate fcport.\n");
2029                 rval = -ENOMEM;
2030                 goto done_unmap_rsp_sg;
2031         }
2032
2033         /* Alloc SRB structure */
2034         sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
2035         if (!sp) {
2036                 ql_log(ql_log_warn, vha, 0x70cb,
2037                     "qla2x00_get_sp failed.\n");
2038                 rval = -ENOMEM;
2039                 goto done_free_fcport;
2040         }
2041
2042         /* Initialize all required  fields of fcport */
2043         fcport->vha = vha;
2044         fcport->loop_id = le32_to_cpu(piocb_rqst->dataword);
2045
2046         sp->type = SRB_FXIOCB_BCMD;
2047         sp->name = "bsg_fx_mgmt";
2048         sp->iocbs = qla24xx_calc_ct_iocbs(req_sg_cnt + rsp_sg_cnt);
2049         sp->u.bsg_job = bsg_job;
2050         sp->free = qla2x00_bsg_sp_free;
2051         sp->done = qla2x00_bsg_job_done;
2052
2053         ql_dbg(ql_dbg_user, vha, 0x70cc,
2054             "bsg rqst type: %s fx_mgmt_type: %x id=%x\n",
2055             type, piocb_rqst->func_type, fcport->loop_id);
2056
2057         rval = qla2x00_start_sp(sp);
2058         if (rval != QLA_SUCCESS) {
2059                 ql_log(ql_log_warn, vha, 0x70cd,
2060                     "qla2x00_start_sp failed=%d.\n", rval);
2061                 mempool_free(sp, ha->srb_mempool);
2062                 rval = -EIO;
2063                 goto done_free_fcport;
2064         }
2065         return rval;
2066
2067 done_free_fcport:
2068         qla2x00_free_fcport(fcport);
2069
2070 done_unmap_rsp_sg:
2071         if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID)
2072                 dma_unmap_sg(&ha->pdev->dev,
2073                     bsg_job->reply_payload.sg_list,
2074                     bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
2075 done_unmap_req_sg:
2076         if (piocb_rqst->flags & SRB_FXDISC_REQ_DMA_VALID)
2077                 dma_unmap_sg(&ha->pdev->dev,
2078                     bsg_job->request_payload.sg_list,
2079                     bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
2080
2081 done:
2082         return rval;
2083 }
2084
2085 static int
2086 qla26xx_serdes_op(struct bsg_job *bsg_job)
2087 {
2088         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2089         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2090         scsi_qla_host_t *vha = shost_priv(host);
2091         int rval = 0;
2092         struct qla_serdes_reg sr;
2093
2094         memset(&sr, 0, sizeof(sr));
2095
2096         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2097             bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2098
2099         switch (sr.cmd) {
2100         case INT_SC_SERDES_WRITE_REG:
2101                 rval = qla2x00_write_serdes_word(vha, sr.addr, sr.val);
2102                 bsg_reply->reply_payload_rcv_len = 0;
2103                 break;
2104         case INT_SC_SERDES_READ_REG:
2105                 rval = qla2x00_read_serdes_word(vha, sr.addr, &sr.val);
2106                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2107                     bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2108                 bsg_reply->reply_payload_rcv_len = sizeof(sr);
2109                 break;
2110         default:
2111                 ql_dbg(ql_dbg_user, vha, 0x708c,
2112                     "Unknown serdes cmd %x.\n", sr.cmd);
2113                 rval = -EINVAL;
2114                 break;
2115         }
2116
2117         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2118             rval ? EXT_STATUS_MAILBOX : 0;
2119
2120         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2121         bsg_reply->result = DID_OK << 16;
2122         bsg_job_done(bsg_job, bsg_reply->result,
2123                        bsg_reply->reply_payload_rcv_len);
2124         return 0;
2125 }
2126
2127 static int
2128 qla8044_serdes_op(struct bsg_job *bsg_job)
2129 {
2130         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2131         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2132         scsi_qla_host_t *vha = shost_priv(host);
2133         int rval = 0;
2134         struct qla_serdes_reg_ex sr;
2135
2136         memset(&sr, 0, sizeof(sr));
2137
2138         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2139             bsg_job->request_payload.sg_cnt, &sr, sizeof(sr));
2140
2141         switch (sr.cmd) {
2142         case INT_SC_SERDES_WRITE_REG:
2143                 rval = qla8044_write_serdes_word(vha, sr.addr, sr.val);
2144                 bsg_reply->reply_payload_rcv_len = 0;
2145                 break;
2146         case INT_SC_SERDES_READ_REG:
2147                 rval = qla8044_read_serdes_word(vha, sr.addr, &sr.val);
2148                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2149                     bsg_job->reply_payload.sg_cnt, &sr, sizeof(sr));
2150                 bsg_reply->reply_payload_rcv_len = sizeof(sr);
2151                 break;
2152         default:
2153                 ql_dbg(ql_dbg_user, vha, 0x7020,
2154                     "Unknown serdes cmd %x.\n", sr.cmd);
2155                 rval = -EINVAL;
2156                 break;
2157         }
2158
2159         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2160             rval ? EXT_STATUS_MAILBOX : 0;
2161
2162         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2163         bsg_reply->result = DID_OK << 16;
2164         bsg_job_done(bsg_job, bsg_reply->result,
2165                        bsg_reply->reply_payload_rcv_len);
2166         return 0;
2167 }
2168
2169 static int
2170 qla27xx_get_flash_upd_cap(struct bsg_job *bsg_job)
2171 {
2172         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2173         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2174         scsi_qla_host_t *vha = shost_priv(host);
2175         struct qla_hw_data *ha = vha->hw;
2176         struct qla_flash_update_caps cap;
2177
2178         if (!(IS_QLA27XX(ha)) && !IS_QLA28XX(ha))
2179                 return -EPERM;
2180
2181         memset(&cap, 0, sizeof(cap));
2182         cap.capabilities = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2183                            (uint64_t)ha->fw_attributes_ext[0] << 32 |
2184                            (uint64_t)ha->fw_attributes_h << 16 |
2185                            (uint64_t)ha->fw_attributes;
2186
2187         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2188             bsg_job->reply_payload.sg_cnt, &cap, sizeof(cap));
2189         bsg_reply->reply_payload_rcv_len = sizeof(cap);
2190
2191         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2192             EXT_STATUS_OK;
2193
2194         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2195         bsg_reply->result = DID_OK << 16;
2196         bsg_job_done(bsg_job, bsg_reply->result,
2197                        bsg_reply->reply_payload_rcv_len);
2198         return 0;
2199 }
2200
2201 static int
2202 qla27xx_set_flash_upd_cap(struct bsg_job *bsg_job)
2203 {
2204         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2205         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2206         scsi_qla_host_t *vha = shost_priv(host);
2207         struct qla_hw_data *ha = vha->hw;
2208         uint64_t online_fw_attr = 0;
2209         struct qla_flash_update_caps cap;
2210
2211         if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2212                 return -EPERM;
2213
2214         memset(&cap, 0, sizeof(cap));
2215         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2216             bsg_job->request_payload.sg_cnt, &cap, sizeof(cap));
2217
2218         online_fw_attr = (uint64_t)ha->fw_attributes_ext[1] << 48 |
2219                          (uint64_t)ha->fw_attributes_ext[0] << 32 |
2220                          (uint64_t)ha->fw_attributes_h << 16 |
2221                          (uint64_t)ha->fw_attributes;
2222
2223         if (online_fw_attr != cap.capabilities) {
2224                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2225                     EXT_STATUS_INVALID_PARAM;
2226                 return -EINVAL;
2227         }
2228
2229         if (cap.outage_duration < MAX_LOOP_TIMEOUT)  {
2230                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2231                     EXT_STATUS_INVALID_PARAM;
2232                 return -EINVAL;
2233         }
2234
2235         bsg_reply->reply_payload_rcv_len = 0;
2236
2237         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2238             EXT_STATUS_OK;
2239
2240         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2241         bsg_reply->result = DID_OK << 16;
2242         bsg_job_done(bsg_job, bsg_reply->result,
2243                        bsg_reply->reply_payload_rcv_len);
2244         return 0;
2245 }
2246
2247 static int
2248 qla27xx_get_bbcr_data(struct bsg_job *bsg_job)
2249 {
2250         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2251         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2252         scsi_qla_host_t *vha = shost_priv(host);
2253         struct qla_hw_data *ha = vha->hw;
2254         struct qla_bbcr_data bbcr;
2255         uint16_t loop_id, topo, sw_cap;
2256         uint8_t domain, area, al_pa, state;
2257         int rval;
2258
2259         if (!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
2260                 return -EPERM;
2261
2262         memset(&bbcr, 0, sizeof(bbcr));
2263
2264         if (vha->flags.bbcr_enable)
2265                 bbcr.status = QLA_BBCR_STATUS_ENABLED;
2266         else
2267                 bbcr.status = QLA_BBCR_STATUS_DISABLED;
2268
2269         if (bbcr.status == QLA_BBCR_STATUS_ENABLED) {
2270                 rval = qla2x00_get_adapter_id(vha, &loop_id, &al_pa,
2271                         &area, &domain, &topo, &sw_cap);
2272                 if (rval != QLA_SUCCESS) {
2273                         bbcr.status = QLA_BBCR_STATUS_UNKNOWN;
2274                         bbcr.state = QLA_BBCR_STATE_OFFLINE;
2275                         bbcr.mbx1 = loop_id;
2276                         goto done;
2277                 }
2278
2279                 state = (vha->bbcr >> 12) & 0x1;
2280
2281                 if (state) {
2282                         bbcr.state = QLA_BBCR_STATE_OFFLINE;
2283                         bbcr.offline_reason_code = QLA_BBCR_REASON_LOGIN_REJECT;
2284                 } else {
2285                         bbcr.state = QLA_BBCR_STATE_ONLINE;
2286                         bbcr.negotiated_bbscn = (vha->bbcr >> 8) & 0xf;
2287                 }
2288
2289                 bbcr.configured_bbscn = vha->bbcr & 0xf;
2290         }
2291
2292 done:
2293         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2294                 bsg_job->reply_payload.sg_cnt, &bbcr, sizeof(bbcr));
2295         bsg_reply->reply_payload_rcv_len = sizeof(bbcr);
2296
2297         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2298
2299         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2300         bsg_reply->result = DID_OK << 16;
2301         bsg_job_done(bsg_job, bsg_reply->result,
2302                        bsg_reply->reply_payload_rcv_len);
2303         return 0;
2304 }
2305
2306 static int
2307 qla2x00_get_priv_stats(struct bsg_job *bsg_job)
2308 {
2309         struct fc_bsg_request *bsg_request = bsg_job->request;
2310         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2311         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2312         scsi_qla_host_t *vha = shost_priv(host);
2313         struct qla_hw_data *ha = vha->hw;
2314         struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev);
2315         struct link_statistics *stats = NULL;
2316         dma_addr_t stats_dma;
2317         int rval;
2318         uint32_t *cmd = bsg_request->rqst_data.h_vendor.vendor_cmd;
2319         uint options = cmd[0] == QL_VND_GET_PRIV_STATS_EX ? cmd[1] : 0;
2320
2321         if (test_bit(UNLOADING, &vha->dpc_flags))
2322                 return -ENODEV;
2323
2324         if (unlikely(pci_channel_offline(ha->pdev)))
2325                 return -ENODEV;
2326
2327         if (qla2x00_reset_active(vha))
2328                 return -EBUSY;
2329
2330         if (!IS_FWI2_CAPABLE(ha))
2331                 return -EPERM;
2332
2333         stats = dma_alloc_coherent(&ha->pdev->dev, sizeof(*stats), &stats_dma,
2334                                    GFP_KERNEL);
2335         if (!stats) {
2336                 ql_log(ql_log_warn, vha, 0x70e2,
2337                     "Failed to allocate memory for stats.\n");
2338                 return -ENOMEM;
2339         }
2340
2341         rval = qla24xx_get_isp_stats(base_vha, stats, stats_dma, options);
2342
2343         if (rval == QLA_SUCCESS) {
2344                 ql_dump_buffer(ql_dbg_user + ql_dbg_verbose, vha, 0x70e5,
2345                         stats, sizeof(*stats));
2346                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2347                         bsg_job->reply_payload.sg_cnt, stats, sizeof(*stats));
2348         }
2349
2350         bsg_reply->reply_payload_rcv_len = sizeof(*stats);
2351         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2352             rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2353
2354         bsg_job->reply_len = sizeof(*bsg_reply);
2355         bsg_reply->result = DID_OK << 16;
2356         bsg_job_done(bsg_job, bsg_reply->result,
2357                        bsg_reply->reply_payload_rcv_len);
2358
2359         dma_free_coherent(&ha->pdev->dev, sizeof(*stats),
2360                 stats, stats_dma);
2361
2362         return 0;
2363 }
2364
2365 static int
2366 qla2x00_do_dport_diagnostics(struct bsg_job *bsg_job)
2367 {
2368         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2369         struct Scsi_Host *host = fc_bsg_to_shost(bsg_job);
2370         scsi_qla_host_t *vha = shost_priv(host);
2371         int rval;
2372         struct qla_dport_diag *dd;
2373
2374         if (!IS_QLA83XX(vha->hw) && !IS_QLA27XX(vha->hw) &&
2375             !IS_QLA28XX(vha->hw))
2376                 return -EPERM;
2377
2378         dd = kmalloc(sizeof(*dd), GFP_KERNEL);
2379         if (!dd) {
2380                 ql_log(ql_log_warn, vha, 0x70db,
2381                     "Failed to allocate memory for dport.\n");
2382                 return -ENOMEM;
2383         }
2384
2385         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2386             bsg_job->request_payload.sg_cnt, dd, sizeof(*dd));
2387
2388         rval = qla26xx_dport_diagnostics(
2389             vha, dd->buf, sizeof(dd->buf), dd->options);
2390         if (rval == QLA_SUCCESS) {
2391                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2392                     bsg_job->reply_payload.sg_cnt, dd, sizeof(*dd));
2393         }
2394
2395         bsg_reply->reply_payload_rcv_len = sizeof(*dd);
2396         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] =
2397             rval ? EXT_STATUS_MAILBOX : EXT_STATUS_OK;
2398
2399         bsg_job->reply_len = sizeof(*bsg_reply);
2400         bsg_reply->result = DID_OK << 16;
2401         bsg_job_done(bsg_job, bsg_reply->result,
2402                        bsg_reply->reply_payload_rcv_len);
2403
2404         kfree(dd);
2405
2406         return 0;
2407 }
2408
2409 static int
2410 qla2x00_get_flash_image_status(struct bsg_job *bsg_job)
2411 {
2412         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2413         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2414         struct qla_hw_data *ha = vha->hw;
2415         struct qla_active_regions regions = { };
2416         struct active_regions active_regions = { };
2417
2418         qla27xx_get_active_image(vha, &active_regions);
2419         regions.global_image = active_regions.global;
2420
2421         if (IS_QLA28XX(ha)) {
2422                 qla28xx_get_aux_images(vha, &active_regions);
2423                 regions.board_config = active_regions.aux.board_config;
2424                 regions.vpd_nvram = active_regions.aux.vpd_nvram;
2425                 regions.npiv_config_0_1 = active_regions.aux.npiv_config_0_1;
2426                 regions.npiv_config_2_3 = active_regions.aux.npiv_config_2_3;
2427         }
2428
2429         ql_dbg(ql_dbg_user, vha, 0x70e1,
2430             "%s(%lu): FW=%u BCFG=%u VPDNVR=%u NPIV01=%u NPIV02=%u\n",
2431             __func__, vha->host_no, regions.global_image,
2432             regions.board_config, regions.vpd_nvram,
2433             regions.npiv_config_0_1, regions.npiv_config_2_3);
2434
2435         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2436             bsg_job->reply_payload.sg_cnt, &regions, sizeof(regions));
2437
2438         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2439         bsg_reply->reply_payload_rcv_len = sizeof(regions);
2440         bsg_reply->result = DID_OK << 16;
2441         bsg_job->reply_len = sizeof(struct fc_bsg_reply);
2442         bsg_job_done(bsg_job, bsg_reply->result,
2443             bsg_reply->reply_payload_rcv_len);
2444
2445         return 0;
2446 }
2447
2448 static int
2449 qla2x00_manage_host_stats(struct bsg_job *bsg_job)
2450 {
2451         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2452         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2453         struct ql_vnd_mng_host_stats_param *req_data;
2454         struct ql_vnd_mng_host_stats_resp rsp_data;
2455         u32 req_data_len;
2456         int ret = 0;
2457
2458         if (!vha->flags.online) {
2459                 ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2460                 return -EIO;
2461         }
2462
2463         req_data_len = bsg_job->request_payload.payload_len;
2464
2465         if (req_data_len != sizeof(struct ql_vnd_mng_host_stats_param)) {
2466                 ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2467                 return -EIO;
2468         }
2469
2470         req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2471         if (!req_data) {
2472                 ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2473                 return -ENOMEM;
2474         }
2475
2476         /* Copy the request buffer in req_data */
2477         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2478                           bsg_job->request_payload.sg_cnt, req_data,
2479                           req_data_len);
2480
2481         switch (req_data->action) {
2482         case QLA_STOP:
2483                 ret = qla2xxx_stop_stats(vha->host, req_data->stat_type);
2484                 break;
2485         case QLA_START:
2486                 ret = qla2xxx_start_stats(vha->host, req_data->stat_type);
2487                 break;
2488         case QLA_CLEAR:
2489                 ret = qla2xxx_reset_stats(vha->host, req_data->stat_type);
2490                 break;
2491         default:
2492                 ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2493                 ret = -EIO;
2494                 break;
2495         }
2496
2497         kfree(req_data);
2498
2499         /* Prepare response */
2500         rsp_data.status = ret;
2501         bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2502
2503         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2504         bsg_reply->reply_payload_rcv_len =
2505                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2506                                     bsg_job->reply_payload.sg_cnt,
2507                                     &rsp_data,
2508                                     sizeof(struct ql_vnd_mng_host_stats_resp));
2509
2510         bsg_reply->result = DID_OK;
2511         bsg_job_done(bsg_job, bsg_reply->result,
2512                      bsg_reply->reply_payload_rcv_len);
2513
2514         return ret;
2515 }
2516
2517 static int
2518 qla2x00_get_host_stats(struct bsg_job *bsg_job)
2519 {
2520         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2521         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2522         struct ql_vnd_stats_param *req_data;
2523         struct ql_vnd_host_stats_resp rsp_data;
2524         u32 req_data_len;
2525         int ret = 0;
2526         u64 ini_entry_count = 0;
2527         u64 entry_count = 0;
2528         u64 tgt_num = 0;
2529         u64 tmp_stat_type = 0;
2530         u64 response_len = 0;
2531         void *data;
2532
2533         req_data_len = bsg_job->request_payload.payload_len;
2534
2535         if (req_data_len != sizeof(struct ql_vnd_stats_param)) {
2536                 ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2537                 return -EIO;
2538         }
2539
2540         req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2541         if (!req_data) {
2542                 ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2543                 return -ENOMEM;
2544         }
2545
2546         /* Copy the request buffer in req_data */
2547         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2548                           bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2549
2550         /* Copy stat type to work on it */
2551         tmp_stat_type = req_data->stat_type;
2552
2553         if (tmp_stat_type & QLA2XX_TGT_SHT_LNK_DOWN) {
2554                 /* Num of tgts connected to this host */
2555                 tgt_num = qla2x00_get_num_tgts(vha);
2556                 /* unset BIT_17 */
2557                 tmp_stat_type &= ~(1 << 17);
2558         }
2559
2560         /* Total ini stats */
2561         ini_entry_count = qla2x00_count_set_bits(tmp_stat_type);
2562
2563         /* Total number of entries */
2564         entry_count = ini_entry_count + tgt_num;
2565
2566         response_len = sizeof(struct ql_vnd_host_stats_resp) +
2567                 (sizeof(struct ql_vnd_stat_entry) * entry_count);
2568
2569         if (response_len > bsg_job->reply_payload.payload_len) {
2570                 rsp_data.status = EXT_STATUS_BUFFER_TOO_SMALL;
2571                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2572                 bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2573
2574                 bsg_reply->reply_payload_rcv_len =
2575                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2576                                             bsg_job->reply_payload.sg_cnt, &rsp_data,
2577                                             sizeof(struct ql_vnd_mng_host_stats_resp));
2578
2579                 bsg_reply->result = DID_OK;
2580                 bsg_job_done(bsg_job, bsg_reply->result,
2581                              bsg_reply->reply_payload_rcv_len);
2582                 goto host_stat_out;
2583         }
2584
2585         data = kzalloc(response_len, GFP_KERNEL);
2586
2587         ret = qla2xxx_get_ini_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2588                                     data, response_len);
2589
2590         rsp_data.status = EXT_STATUS_OK;
2591         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2592
2593         bsg_reply->reply_payload_rcv_len = sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2594                                                                bsg_job->reply_payload.sg_cnt,
2595                                                                data, response_len);
2596         bsg_reply->result = DID_OK;
2597         bsg_job_done(bsg_job, bsg_reply->result,
2598                      bsg_reply->reply_payload_rcv_len);
2599
2600         kfree(data);
2601 host_stat_out:
2602         kfree(req_data);
2603         return ret;
2604 }
2605
2606 static struct fc_rport *
2607 qla2xxx_find_rport(scsi_qla_host_t *vha, uint32_t tgt_num)
2608 {
2609         fc_port_t *fcport = NULL;
2610
2611         list_for_each_entry(fcport, &vha->vp_fcports, list) {
2612                 if (fcport->rport->number == tgt_num)
2613                         return fcport->rport;
2614         }
2615         return NULL;
2616 }
2617
2618 static int
2619 qla2x00_get_tgt_stats(struct bsg_job *bsg_job)
2620 {
2621         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2622         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2623         struct ql_vnd_tgt_stats_param *req_data;
2624         u32 req_data_len;
2625         int ret = 0;
2626         u64 response_len = 0;
2627         struct ql_vnd_tgt_stats_resp *data = NULL;
2628         struct fc_rport *rport = NULL;
2629
2630         if (!vha->flags.online) {
2631                 ql_log(ql_log_warn, vha, 0x0000, "Host is not online.\n");
2632                 return -EIO;
2633         }
2634
2635         req_data_len = bsg_job->request_payload.payload_len;
2636
2637         if (req_data_len != sizeof(struct ql_vnd_stat_entry)) {
2638                 ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2639                 return -EIO;
2640         }
2641
2642         req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2643         if (!req_data) {
2644                 ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2645                 return -ENOMEM;
2646         }
2647
2648         /* Copy the request buffer in req_data */
2649         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2650                           bsg_job->request_payload.sg_cnt,
2651                           req_data, req_data_len);
2652
2653         response_len = sizeof(struct ql_vnd_tgt_stats_resp) +
2654                 sizeof(struct ql_vnd_stat_entry);
2655
2656         /* structure + size for one entry */
2657         data = kzalloc(response_len, GFP_KERNEL);
2658         if (!data) {
2659                 kfree(req_data);
2660                 return -ENOMEM;
2661         }
2662
2663         if (response_len > bsg_job->reply_payload.payload_len) {
2664                 data->status = EXT_STATUS_BUFFER_TOO_SMALL;
2665                 bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_BUFFER_TOO_SMALL;
2666                 bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_stats_resp);
2667
2668                 bsg_reply->reply_payload_rcv_len =
2669                         sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2670                                             bsg_job->reply_payload.sg_cnt, data,
2671                                             sizeof(struct ql_vnd_tgt_stats_resp));
2672
2673                 bsg_reply->result = DID_OK;
2674                 bsg_job_done(bsg_job, bsg_reply->result,
2675                              bsg_reply->reply_payload_rcv_len);
2676                 goto tgt_stat_out;
2677         }
2678
2679         rport = qla2xxx_find_rport(vha, req_data->tgt_id);
2680         if (!rport) {
2681                 ql_log(ql_log_warn, vha, 0x0000, "target %d not found.\n", req_data->tgt_id);
2682                 ret = EXT_STATUS_INVALID_PARAM;
2683                 data->status = EXT_STATUS_INVALID_PARAM;
2684                 goto reply;
2685         }
2686
2687         ret = qla2xxx_get_tgt_stats(fc_bsg_to_shost(bsg_job), req_data->stat_type,
2688                                     rport, (void *)data, response_len);
2689
2690         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2691 reply:
2692         bsg_reply->reply_payload_rcv_len =
2693                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2694                                     bsg_job->reply_payload.sg_cnt, data,
2695                                     response_len);
2696         bsg_reply->result = DID_OK;
2697         bsg_job_done(bsg_job, bsg_reply->result,
2698                      bsg_reply->reply_payload_rcv_len);
2699
2700 tgt_stat_out:
2701         kfree(data);
2702         kfree(req_data);
2703
2704         return ret;
2705 }
2706
2707 static int
2708 qla2x00_manage_host_port(struct bsg_job *bsg_job)
2709 {
2710         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2711         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2712         struct ql_vnd_mng_host_port_param *req_data;
2713         struct ql_vnd_mng_host_port_resp rsp_data;
2714         u32 req_data_len;
2715         int ret = 0;
2716
2717         req_data_len = bsg_job->request_payload.payload_len;
2718
2719         if (req_data_len != sizeof(struct ql_vnd_mng_host_port_param)) {
2720                 ql_log(ql_log_warn, vha, 0x0000, "req_data_len invalid.\n");
2721                 return -EIO;
2722         }
2723
2724         req_data = kzalloc(sizeof(*req_data), GFP_KERNEL);
2725         if (!req_data) {
2726                 ql_log(ql_log_warn, vha, 0x0000, "req_data memory allocation failure.\n");
2727                 return -ENOMEM;
2728         }
2729
2730         /* Copy the request buffer in req_data */
2731         sg_copy_to_buffer(bsg_job->request_payload.sg_list,
2732                           bsg_job->request_payload.sg_cnt, req_data, req_data_len);
2733
2734         switch (req_data->action) {
2735         case QLA_ENABLE:
2736                 ret = qla2xxx_enable_port(vha->host);
2737                 break;
2738         case QLA_DISABLE:
2739                 ret = qla2xxx_disable_port(vha->host);
2740                 break;
2741         default:
2742                 ql_log(ql_log_warn, vha, 0x0000, "Invalid action.\n");
2743                 ret = -EIO;
2744                 break;
2745         }
2746
2747         kfree(req_data);
2748
2749         /* Prepare response */
2750         rsp_data.status = ret;
2751         bsg_reply->reply_data.vendor_reply.vendor_rsp[0] = EXT_STATUS_OK;
2752         bsg_job->reply_payload.payload_len = sizeof(struct ql_vnd_mng_host_port_resp);
2753
2754         bsg_reply->reply_payload_rcv_len =
2755                 sg_copy_from_buffer(bsg_job->reply_payload.sg_list,
2756                                     bsg_job->reply_payload.sg_cnt, &rsp_data,
2757                                     sizeof(struct ql_vnd_mng_host_port_resp));
2758         bsg_reply->result = DID_OK;
2759         bsg_job_done(bsg_job, bsg_reply->result,
2760                      bsg_reply->reply_payload_rcv_len);
2761
2762         return ret;
2763 }
2764
2765 static int
2766 qla2x00_process_vendor_specific(struct bsg_job *bsg_job)
2767 {
2768         struct fc_bsg_request *bsg_request = bsg_job->request;
2769
2770         switch (bsg_request->rqst_data.h_vendor.vendor_cmd[0]) {
2771         case QL_VND_LOOPBACK:
2772                 return qla2x00_process_loopback(bsg_job);
2773
2774         case QL_VND_A84_RESET:
2775                 return qla84xx_reset(bsg_job);
2776
2777         case QL_VND_A84_UPDATE_FW:
2778                 return qla84xx_updatefw(bsg_job);
2779
2780         case QL_VND_A84_MGMT_CMD:
2781                 return qla84xx_mgmt_cmd(bsg_job);
2782
2783         case QL_VND_IIDMA:
2784                 return qla24xx_iidma(bsg_job);
2785
2786         case QL_VND_FCP_PRIO_CFG_CMD:
2787                 return qla24xx_proc_fcp_prio_cfg_cmd(bsg_job);
2788
2789         case QL_VND_READ_FLASH:
2790                 return qla2x00_read_optrom(bsg_job);
2791
2792         case QL_VND_UPDATE_FLASH:
2793                 return qla2x00_update_optrom(bsg_job);
2794
2795         case QL_VND_SET_FRU_VERSION:
2796                 return qla2x00_update_fru_versions(bsg_job);
2797
2798         case QL_VND_READ_FRU_STATUS:
2799                 return qla2x00_read_fru_status(bsg_job);
2800
2801         case QL_VND_WRITE_FRU_STATUS:
2802                 return qla2x00_write_fru_status(bsg_job);
2803
2804         case QL_VND_WRITE_I2C:
2805                 return qla2x00_write_i2c(bsg_job);
2806
2807         case QL_VND_READ_I2C:
2808                 return qla2x00_read_i2c(bsg_job);
2809
2810         case QL_VND_DIAG_IO_CMD:
2811                 return qla24xx_process_bidir_cmd(bsg_job);
2812
2813         case QL_VND_FX00_MGMT_CMD:
2814                 return qlafx00_mgmt_cmd(bsg_job);
2815
2816         case QL_VND_SERDES_OP:
2817                 return qla26xx_serdes_op(bsg_job);
2818
2819         case QL_VND_SERDES_OP_EX:
2820                 return qla8044_serdes_op(bsg_job);
2821
2822         case QL_VND_GET_FLASH_UPDATE_CAPS:
2823                 return qla27xx_get_flash_upd_cap(bsg_job);
2824
2825         case QL_VND_SET_FLASH_UPDATE_CAPS:
2826                 return qla27xx_set_flash_upd_cap(bsg_job);
2827
2828         case QL_VND_GET_BBCR_DATA:
2829                 return qla27xx_get_bbcr_data(bsg_job);
2830
2831         case QL_VND_GET_PRIV_STATS:
2832         case QL_VND_GET_PRIV_STATS_EX:
2833                 return qla2x00_get_priv_stats(bsg_job);
2834
2835         case QL_VND_DPORT_DIAGNOSTICS:
2836                 return qla2x00_do_dport_diagnostics(bsg_job);
2837
2838         case QL_VND_SS_GET_FLASH_IMAGE_STATUS:
2839                 return qla2x00_get_flash_image_status(bsg_job);
2840
2841         case QL_VND_MANAGE_HOST_STATS:
2842                 return qla2x00_manage_host_stats(bsg_job);
2843
2844         case QL_VND_GET_HOST_STATS:
2845                 return qla2x00_get_host_stats(bsg_job);
2846
2847         case QL_VND_GET_TGT_STATS:
2848                 return qla2x00_get_tgt_stats(bsg_job);
2849
2850         case QL_VND_MANAGE_HOST_PORT:
2851                 return qla2x00_manage_host_port(bsg_job);
2852
2853         default:
2854                 return -ENOSYS;
2855         }
2856 }
2857
2858 int
2859 qla24xx_bsg_request(struct bsg_job *bsg_job)
2860 {
2861         struct fc_bsg_request *bsg_request = bsg_job->request;
2862         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2863         int ret = -EINVAL;
2864         struct fc_rport *rport;
2865         struct Scsi_Host *host;
2866         scsi_qla_host_t *vha;
2867
2868         /* In case no data transferred. */
2869         bsg_reply->reply_payload_rcv_len = 0;
2870
2871         if (bsg_request->msgcode == FC_BSG_RPT_ELS) {
2872                 rport = fc_bsg_to_rport(bsg_job);
2873                 host = rport_to_shost(rport);
2874                 vha = shost_priv(host);
2875         } else {
2876                 host = fc_bsg_to_shost(bsg_job);
2877                 vha = shost_priv(host);
2878         }
2879
2880         /* Disable port will bring down the chip, allow enable command */
2881         if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
2882             bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
2883                 goto skip_chip_chk;
2884
2885         if (vha->hw->flags.port_isolated) {
2886                 bsg_reply->result = DID_ERROR;
2887                 /* operation not permitted */
2888                 return -EPERM;
2889         }
2890
2891         if (qla2x00_chip_is_down(vha)) {
2892                 ql_dbg(ql_dbg_user, vha, 0x709f,
2893                     "BSG: ISP abort active/needed -- cmd=%d.\n",
2894                     bsg_request->msgcode);
2895                 return -EBUSY;
2896         }
2897
2898 skip_chip_chk:
2899         ql_dbg(ql_dbg_user, vha, 0x7000,
2900             "Entered %s msgcode=0x%x.\n", __func__, bsg_request->msgcode);
2901
2902         switch (bsg_request->msgcode) {
2903         case FC_BSG_RPT_ELS:
2904         case FC_BSG_HST_ELS_NOLOGIN:
2905                 ret = qla2x00_process_els(bsg_job);
2906                 break;
2907         case FC_BSG_HST_CT:
2908                 ret = qla2x00_process_ct(bsg_job);
2909                 break;
2910         case FC_BSG_HST_VENDOR:
2911                 ret = qla2x00_process_vendor_specific(bsg_job);
2912                 break;
2913         case FC_BSG_HST_ADD_RPORT:
2914         case FC_BSG_HST_DEL_RPORT:
2915         case FC_BSG_RPT_CT:
2916         default:
2917                 ql_log(ql_log_warn, vha, 0x705a, "Unsupported BSG request.\n");
2918                 break;
2919         }
2920         return ret;
2921 }
2922
2923 int
2924 qla24xx_bsg_timeout(struct bsg_job *bsg_job)
2925 {
2926         struct fc_bsg_reply *bsg_reply = bsg_job->reply;
2927         scsi_qla_host_t *vha = shost_priv(fc_bsg_to_shost(bsg_job));
2928         struct qla_hw_data *ha = vha->hw;
2929         srb_t *sp;
2930         int cnt, que;
2931         unsigned long flags;
2932         struct req_que *req;
2933
2934         /* find the bsg job from the active list of commands */
2935         spin_lock_irqsave(&ha->hardware_lock, flags);
2936         for (que = 0; que < ha->max_req_queues; que++) {
2937                 req = ha->req_q_map[que];
2938                 if (!req)
2939                         continue;
2940
2941                 for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
2942                         sp = req->outstanding_cmds[cnt];
2943                         if (sp) {
2944                                 if (((sp->type == SRB_CT_CMD) ||
2945                                         (sp->type == SRB_ELS_CMD_HST) ||
2946                                         (sp->type == SRB_FXIOCB_BCMD))
2947                                         && (sp->u.bsg_job == bsg_job)) {
2948                                         req->outstanding_cmds[cnt] = NULL;
2949                                         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2950                                         if (ha->isp_ops->abort_command(sp)) {
2951                                                 ql_log(ql_log_warn, vha, 0x7089,
2952                                                     "mbx abort_command "
2953                                                     "failed.\n");
2954                                                 bsg_reply->result = -EIO;
2955                                         } else {
2956                                                 ql_dbg(ql_dbg_user, vha, 0x708a,
2957                                                     "mbx abort_command "
2958                                                     "success.\n");
2959                                                 bsg_reply->result = 0;
2960                                         }
2961                                         spin_lock_irqsave(&ha->hardware_lock, flags);
2962                                         goto done;
2963                                 }
2964                         }
2965                 }
2966         }
2967         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2968         ql_log(ql_log_info, vha, 0x708b, "SRB not found to abort.\n");
2969         bsg_reply->result = -ENXIO;
2970         return 0;
2971
2972 done:
2973         spin_unlock_irqrestore(&ha->hardware_lock, flags);
2974         sp->free(sp);
2975         return 0;
2976 }