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