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