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