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