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 #include "qla_target.h" 9 #include <linux/utsname.h> 10 11 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); 12 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); 13 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); 14 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *); 15 static int qla2x00_sns_rft_id(scsi_qla_host_t *); 16 static int qla2x00_sns_rnn_id(scsi_qla_host_t *); 17 18 /** 19 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. 20 * @ha: HA context 21 * @req_size: request size in bytes 22 * @rsp_size: response size in bytes 23 * 24 * Returns a pointer to the @ha's ms_iocb. 25 */ 26 void * 27 qla2x00_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) 28 { 29 struct qla_hw_data *ha = vha->hw; 30 ms_iocb_entry_t *ms_pkt; 31 32 ms_pkt = (ms_iocb_entry_t *)arg->iocb; 33 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 34 35 ms_pkt->entry_type = MS_IOCB_TYPE; 36 ms_pkt->entry_count = 1; 37 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); 38 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 39 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 40 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 41 ms_pkt->total_dsd_count = cpu_to_le16(2); 42 ms_pkt->rsp_bytecount = cpu_to_le32(arg->rsp_size); 43 ms_pkt->req_bytecount = cpu_to_le32(arg->req_size); 44 45 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(arg->req_dma)); 46 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(arg->req_dma)); 47 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 48 49 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 50 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); 51 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 52 53 vha->qla_stats.control_requests++; 54 55 return (ms_pkt); 56 } 57 58 /** 59 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. 60 * @ha: HA context 61 * @req_size: request size in bytes 62 * @rsp_size: response size in bytes 63 * 64 * Returns a pointer to the @ha's ms_iocb. 65 */ 66 void * 67 qla24xx_prep_ms_iocb(scsi_qla_host_t *vha, struct ct_arg *arg) 68 { 69 struct qla_hw_data *ha = vha->hw; 70 struct ct_entry_24xx *ct_pkt; 71 72 ct_pkt = (struct ct_entry_24xx *)arg->iocb; 73 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 74 75 ct_pkt->entry_type = CT_IOCB_TYPE; 76 ct_pkt->entry_count = 1; 77 ct_pkt->nport_handle = cpu_to_le16(arg->nport_handle); 78 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 79 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 80 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 81 ct_pkt->rsp_byte_count = cpu_to_le32(arg->rsp_size); 82 ct_pkt->cmd_byte_count = cpu_to_le32(arg->req_size); 83 84 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(arg->req_dma)); 85 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(arg->req_dma)); 86 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 87 88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(arg->rsp_dma)); 89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(arg->rsp_dma)); 90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 91 ct_pkt->vp_index = vha->vp_idx; 92 93 vha->qla_stats.control_requests++; 94 95 return (ct_pkt); 96 } 97 98 /** 99 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 100 * @ct_req: CT request buffer 101 * @cmd: GS command 102 * @rsp_size: response size in bytes 103 * 104 * Returns a pointer to the intitialized @ct_req. 105 */ 106 static inline struct ct_sns_req * 107 qla2x00_prep_ct_req(struct ct_sns_pkt *p, uint16_t cmd, uint16_t rsp_size) 108 { 109 memset(p, 0, sizeof(struct ct_sns_pkt)); 110 111 p->p.req.header.revision = 0x01; 112 p->p.req.header.gs_type = 0xFC; 113 p->p.req.header.gs_subtype = 0x02; 114 p->p.req.command = cpu_to_be16(cmd); 115 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 116 117 return &p->p.req; 118 } 119 120 int 121 qla2x00_chk_ms_status(scsi_qla_host_t *vha, ms_iocb_entry_t *ms_pkt, 122 struct ct_sns_rsp *ct_rsp, const char *routine) 123 { 124 int rval; 125 uint16_t comp_status; 126 struct qla_hw_data *ha = vha->hw; 127 128 rval = QLA_FUNCTION_FAILED; 129 if (ms_pkt->entry_status != 0) { 130 ql_dbg(ql_dbg_disc, vha, 0x2031, 131 "%s failed, error status (%x) on port_id: %02x%02x%02x.\n", 132 routine, ms_pkt->entry_status, vha->d_id.b.domain, 133 vha->d_id.b.area, vha->d_id.b.al_pa); 134 } else { 135 if (IS_FWI2_CAPABLE(ha)) 136 comp_status = le16_to_cpu( 137 ((struct ct_entry_24xx *)ms_pkt)->comp_status); 138 else 139 comp_status = le16_to_cpu(ms_pkt->status); 140 switch (comp_status) { 141 case CS_COMPLETE: 142 case CS_DATA_UNDERRUN: 143 case CS_DATA_OVERRUN: /* Overrun? */ 144 if (ct_rsp->header.response != 145 cpu_to_be16(CT_ACCEPT_RESPONSE)) { 146 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2077, 147 "%s failed rejected request on port_id: %02x%02x%02x Compeltion status 0x%x, response 0x%x\n", 148 routine, vha->d_id.b.domain, 149 vha->d_id.b.area, vha->d_id.b.al_pa, 150 comp_status, ct_rsp->header.response); 151 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 152 0x2078, (uint8_t *)&ct_rsp->header, 153 sizeof(struct ct_rsp_hdr)); 154 rval = QLA_INVALID_COMMAND; 155 } else 156 rval = QLA_SUCCESS; 157 break; 158 default: 159 ql_dbg(ql_dbg_disc, vha, 0x2033, 160 "%s failed, completion status (%x) on port_id: " 161 "%02x%02x%02x.\n", routine, comp_status, 162 vha->d_id.b.domain, vha->d_id.b.area, 163 vha->d_id.b.al_pa); 164 break; 165 } 166 } 167 return rval; 168 } 169 170 /** 171 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 172 * @ha: HA context 173 * @fcport: fcport entry to updated 174 * 175 * Returns 0 on success. 176 */ 177 int 178 qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 179 { 180 int rval; 181 182 ms_iocb_entry_t *ms_pkt; 183 struct ct_sns_req *ct_req; 184 struct ct_sns_rsp *ct_rsp; 185 struct qla_hw_data *ha = vha->hw; 186 struct ct_arg arg; 187 188 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 189 return qla2x00_sns_ga_nxt(vha, fcport); 190 191 arg.iocb = ha->ms_iocb; 192 arg.req_dma = ha->ct_sns_dma; 193 arg.rsp_dma = ha->ct_sns_dma; 194 arg.req_size = GA_NXT_REQ_SIZE; 195 arg.rsp_size = GA_NXT_RSP_SIZE; 196 arg.nport_handle = NPH_SNS; 197 198 /* Issue GA_NXT */ 199 /* Prepare common MS IOCB */ 200 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 201 202 /* Prepare CT request */ 203 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GA_NXT_CMD, 204 GA_NXT_RSP_SIZE); 205 ct_rsp = &ha->ct_sns->p.rsp; 206 207 /* Prepare CT arguments -- port_id */ 208 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 209 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 210 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 211 212 /* Execute MS IOCB */ 213 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 214 sizeof(ms_iocb_entry_t)); 215 if (rval != QLA_SUCCESS) { 216 /*EMPTY*/ 217 ql_dbg(ql_dbg_disc, vha, 0x2062, 218 "GA_NXT issue IOCB failed (%d).\n", rval); 219 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GA_NXT") != 220 QLA_SUCCESS) { 221 rval = QLA_FUNCTION_FAILED; 222 } else { 223 /* Populate fc_port_t entry. */ 224 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; 225 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; 226 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; 227 228 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, 229 WWN_SIZE); 230 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, 231 WWN_SIZE); 232 233 fcport->fc4_type = (ct_rsp->rsp.ga_nxt.fc4_types[2] & BIT_0) ? 234 FC4_TYPE_FCP_SCSI : FC4_TYPE_OTHER; 235 236 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && 237 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) 238 fcport->d_id.b.domain = 0xf0; 239 240 ql_dbg(ql_dbg_disc, vha, 0x2063, 241 "GA_NXT entry - nn %8phN pn %8phN " 242 "port_id=%02x%02x%02x.\n", 243 fcport->node_name, fcport->port_name, 244 fcport->d_id.b.domain, fcport->d_id.b.area, 245 fcport->d_id.b.al_pa); 246 } 247 248 return (rval); 249 } 250 251 static inline int 252 qla2x00_gid_pt_rsp_size(scsi_qla_host_t *vha) 253 { 254 return vha->hw->max_fibre_devices * 4 + 16; 255 } 256 257 /** 258 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. 259 * @ha: HA context 260 * @list: switch info entries to populate 261 * 262 * NOTE: Non-Nx_Ports are not requested. 263 * 264 * Returns 0 on success. 265 */ 266 int 267 qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 268 { 269 int rval; 270 uint16_t i; 271 272 ms_iocb_entry_t *ms_pkt; 273 struct ct_sns_req *ct_req; 274 struct ct_sns_rsp *ct_rsp; 275 276 struct ct_sns_gid_pt_data *gid_data; 277 struct qla_hw_data *ha = vha->hw; 278 uint16_t gid_pt_rsp_size; 279 struct ct_arg arg; 280 281 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 282 return qla2x00_sns_gid_pt(vha, list); 283 284 gid_data = NULL; 285 gid_pt_rsp_size = qla2x00_gid_pt_rsp_size(vha); 286 287 arg.iocb = ha->ms_iocb; 288 arg.req_dma = ha->ct_sns_dma; 289 arg.rsp_dma = ha->ct_sns_dma; 290 arg.req_size = GID_PT_REQ_SIZE; 291 arg.rsp_size = gid_pt_rsp_size; 292 arg.nport_handle = NPH_SNS; 293 294 /* Issue GID_PT */ 295 /* Prepare common MS IOCB */ 296 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 297 298 /* Prepare CT request */ 299 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GID_PT_CMD, gid_pt_rsp_size); 300 ct_rsp = &ha->ct_sns->p.rsp; 301 302 /* Prepare CT arguments -- port_type */ 303 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; 304 305 /* Execute MS IOCB */ 306 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 307 sizeof(ms_iocb_entry_t)); 308 if (rval != QLA_SUCCESS) { 309 /*EMPTY*/ 310 ql_dbg(ql_dbg_disc, vha, 0x2055, 311 "GID_PT issue IOCB failed (%d).\n", rval); 312 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "GID_PT") != 313 QLA_SUCCESS) { 314 rval = QLA_FUNCTION_FAILED; 315 } else { 316 /* Set port IDs in switch info list. */ 317 for (i = 0; i < ha->max_fibre_devices; i++) { 318 gid_data = &ct_rsp->rsp.gid_pt.entries[i]; 319 list[i].d_id.b.domain = gid_data->port_id[0]; 320 list[i].d_id.b.area = gid_data->port_id[1]; 321 list[i].d_id.b.al_pa = gid_data->port_id[2]; 322 memset(list[i].fabric_port_name, 0, WWN_SIZE); 323 list[i].fp_speed = PORT_SPEED_UNKNOWN; 324 325 /* Last one exit. */ 326 if (gid_data->control_byte & BIT_7) { 327 list[i].d_id.b.rsvd_1 = gid_data->control_byte; 328 break; 329 } 330 } 331 332 /* 333 * If we've used all available slots, then the switch is 334 * reporting back more devices than we can handle with this 335 * single call. Return a failed status, and let GA_NXT handle 336 * the overload. 337 */ 338 if (i == ha->max_fibre_devices) 339 rval = QLA_FUNCTION_FAILED; 340 } 341 342 return (rval); 343 } 344 345 /** 346 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. 347 * @ha: HA context 348 * @list: switch info entries to populate 349 * 350 * Returns 0 on success. 351 */ 352 int 353 qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 354 { 355 int rval = QLA_SUCCESS; 356 uint16_t i; 357 358 ms_iocb_entry_t *ms_pkt; 359 struct ct_sns_req *ct_req; 360 struct ct_sns_rsp *ct_rsp; 361 struct qla_hw_data *ha = vha->hw; 362 struct ct_arg arg; 363 364 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 365 return qla2x00_sns_gpn_id(vha, list); 366 367 arg.iocb = ha->ms_iocb; 368 arg.req_dma = ha->ct_sns_dma; 369 arg.rsp_dma = ha->ct_sns_dma; 370 arg.req_size = GPN_ID_REQ_SIZE; 371 arg.rsp_size = GPN_ID_RSP_SIZE; 372 arg.nport_handle = NPH_SNS; 373 374 for (i = 0; i < ha->max_fibre_devices; i++) { 375 /* Issue GPN_ID */ 376 /* Prepare common MS IOCB */ 377 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 378 379 /* Prepare CT request */ 380 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GPN_ID_CMD, 381 GPN_ID_RSP_SIZE); 382 ct_rsp = &ha->ct_sns->p.rsp; 383 384 /* Prepare CT arguments -- port_id */ 385 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 386 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 387 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 388 389 /* Execute MS IOCB */ 390 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 391 sizeof(ms_iocb_entry_t)); 392 if (rval != QLA_SUCCESS) { 393 /*EMPTY*/ 394 ql_dbg(ql_dbg_disc, vha, 0x2056, 395 "GPN_ID issue IOCB failed (%d).\n", rval); 396 break; 397 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 398 "GPN_ID") != QLA_SUCCESS) { 399 rval = QLA_FUNCTION_FAILED; 400 break; 401 } else { 402 /* Save portname */ 403 memcpy(list[i].port_name, 404 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 405 } 406 407 /* Last device exit. */ 408 if (list[i].d_id.b.rsvd_1 != 0) 409 break; 410 } 411 412 return (rval); 413 } 414 415 /** 416 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. 417 * @ha: HA context 418 * @list: switch info entries to populate 419 * 420 * Returns 0 on success. 421 */ 422 int 423 qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 424 { 425 int rval = QLA_SUCCESS; 426 uint16_t i; 427 struct qla_hw_data *ha = vha->hw; 428 ms_iocb_entry_t *ms_pkt; 429 struct ct_sns_req *ct_req; 430 struct ct_sns_rsp *ct_rsp; 431 struct ct_arg arg; 432 433 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 434 return qla2x00_sns_gnn_id(vha, list); 435 436 arg.iocb = ha->ms_iocb; 437 arg.req_dma = ha->ct_sns_dma; 438 arg.rsp_dma = ha->ct_sns_dma; 439 arg.req_size = GNN_ID_REQ_SIZE; 440 arg.rsp_size = GNN_ID_RSP_SIZE; 441 arg.nport_handle = NPH_SNS; 442 443 for (i = 0; i < ha->max_fibre_devices; i++) { 444 /* Issue GNN_ID */ 445 /* Prepare common MS IOCB */ 446 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 447 448 /* Prepare CT request */ 449 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GNN_ID_CMD, 450 GNN_ID_RSP_SIZE); 451 ct_rsp = &ha->ct_sns->p.rsp; 452 453 /* Prepare CT arguments -- port_id */ 454 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 455 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 456 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 457 458 /* Execute MS IOCB */ 459 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 460 sizeof(ms_iocb_entry_t)); 461 if (rval != QLA_SUCCESS) { 462 /*EMPTY*/ 463 ql_dbg(ql_dbg_disc, vha, 0x2057, 464 "GNN_ID issue IOCB failed (%d).\n", rval); 465 break; 466 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 467 "GNN_ID") != QLA_SUCCESS) { 468 rval = QLA_FUNCTION_FAILED; 469 break; 470 } else { 471 /* Save nodename */ 472 memcpy(list[i].node_name, 473 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); 474 475 ql_dbg(ql_dbg_disc, vha, 0x2058, 476 "GID_PT entry - nn %8phN pn %8phN " 477 "portid=%02x%02x%02x.\n", 478 list[i].node_name, list[i].port_name, 479 list[i].d_id.b.domain, list[i].d_id.b.area, 480 list[i].d_id.b.al_pa); 481 } 482 483 /* Last device exit. */ 484 if (list[i].d_id.b.rsvd_1 != 0) 485 break; 486 } 487 488 return (rval); 489 } 490 491 /** 492 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 493 * @ha: HA context 494 * 495 * Returns 0 on success. 496 */ 497 int 498 qla2x00_rft_id(scsi_qla_host_t *vha) 499 { 500 int rval; 501 struct qla_hw_data *ha = vha->hw; 502 ms_iocb_entry_t *ms_pkt; 503 struct ct_sns_req *ct_req; 504 struct ct_sns_rsp *ct_rsp; 505 struct ct_arg arg; 506 507 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 508 return qla2x00_sns_rft_id(vha); 509 510 arg.iocb = ha->ms_iocb; 511 arg.req_dma = ha->ct_sns_dma; 512 arg.rsp_dma = ha->ct_sns_dma; 513 arg.req_size = RFT_ID_REQ_SIZE; 514 arg.rsp_size = RFT_ID_RSP_SIZE; 515 arg.nport_handle = NPH_SNS; 516 517 /* Issue RFT_ID */ 518 /* Prepare common MS IOCB */ 519 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 520 521 /* Prepare CT request */ 522 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFT_ID_CMD, 523 RFT_ID_RSP_SIZE); 524 ct_rsp = &ha->ct_sns->p.rsp; 525 526 /* Prepare CT arguments -- port_id, FC-4 types */ 527 ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain; 528 ct_req->req.rft_id.port_id[1] = vha->d_id.b.area; 529 ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa; 530 531 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ 532 533 /* Execute MS IOCB */ 534 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 535 sizeof(ms_iocb_entry_t)); 536 if (rval != QLA_SUCCESS) { 537 /*EMPTY*/ 538 ql_dbg(ql_dbg_disc, vha, 0x2043, 539 "RFT_ID issue IOCB failed (%d).\n", rval); 540 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFT_ID") != 541 QLA_SUCCESS) { 542 rval = QLA_FUNCTION_FAILED; 543 } else { 544 ql_dbg(ql_dbg_disc, vha, 0x2044, 545 "RFT_ID exiting normally.\n"); 546 } 547 548 return (rval); 549 } 550 551 /** 552 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. 553 * @ha: HA context 554 * 555 * Returns 0 on success. 556 */ 557 int 558 qla2x00_rff_id(scsi_qla_host_t *vha) 559 { 560 int rval; 561 struct qla_hw_data *ha = vha->hw; 562 ms_iocb_entry_t *ms_pkt; 563 struct ct_sns_req *ct_req; 564 struct ct_sns_rsp *ct_rsp; 565 struct ct_arg arg; 566 567 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 568 ql_dbg(ql_dbg_disc, vha, 0x2046, 569 "RFF_ID call not supported on ISP2100/ISP2200.\n"); 570 return (QLA_SUCCESS); 571 } 572 573 arg.iocb = ha->ms_iocb; 574 arg.req_dma = ha->ct_sns_dma; 575 arg.rsp_dma = ha->ct_sns_dma; 576 arg.req_size = RFF_ID_REQ_SIZE; 577 arg.rsp_size = RFF_ID_RSP_SIZE; 578 arg.nport_handle = NPH_SNS; 579 580 /* Issue RFF_ID */ 581 /* Prepare common MS IOCB */ 582 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 583 584 /* Prepare CT request */ 585 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RFF_ID_CMD, 586 RFF_ID_RSP_SIZE); 587 ct_rsp = &ha->ct_sns->p.rsp; 588 589 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ 590 ct_req->req.rff_id.port_id[0] = vha->d_id.b.domain; 591 ct_req->req.rff_id.port_id[1] = vha->d_id.b.area; 592 ct_req->req.rff_id.port_id[2] = vha->d_id.b.al_pa; 593 594 qlt_rff_id(vha, ct_req); 595 596 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */ 597 598 /* Execute MS IOCB */ 599 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 600 sizeof(ms_iocb_entry_t)); 601 if (rval != QLA_SUCCESS) { 602 /*EMPTY*/ 603 ql_dbg(ql_dbg_disc, vha, 0x2047, 604 "RFF_ID issue IOCB failed (%d).\n", rval); 605 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RFF_ID") != 606 QLA_SUCCESS) { 607 rval = QLA_FUNCTION_FAILED; 608 } else { 609 ql_dbg(ql_dbg_disc, vha, 0x2048, 610 "RFF_ID exiting normally.\n"); 611 } 612 613 return (rval); 614 } 615 616 /** 617 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 618 * @ha: HA context 619 * 620 * Returns 0 on success. 621 */ 622 int 623 qla2x00_rnn_id(scsi_qla_host_t *vha) 624 { 625 int rval; 626 struct qla_hw_data *ha = vha->hw; 627 ms_iocb_entry_t *ms_pkt; 628 struct ct_sns_req *ct_req; 629 struct ct_sns_rsp *ct_rsp; 630 struct ct_arg arg; 631 632 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 633 return qla2x00_sns_rnn_id(vha); 634 635 arg.iocb = ha->ms_iocb; 636 arg.req_dma = ha->ct_sns_dma; 637 arg.rsp_dma = ha->ct_sns_dma; 638 arg.req_size = RNN_ID_REQ_SIZE; 639 arg.rsp_size = RNN_ID_RSP_SIZE; 640 arg.nport_handle = NPH_SNS; 641 642 /* Issue RNN_ID */ 643 /* Prepare common MS IOCB */ 644 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 645 646 /* Prepare CT request */ 647 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE); 648 ct_rsp = &ha->ct_sns->p.rsp; 649 650 /* Prepare CT arguments -- port_id, node_name */ 651 ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain; 652 ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area; 653 ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa; 654 655 memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE); 656 657 /* Execute MS IOCB */ 658 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 659 sizeof(ms_iocb_entry_t)); 660 if (rval != QLA_SUCCESS) { 661 /*EMPTY*/ 662 ql_dbg(ql_dbg_disc, vha, 0x204d, 663 "RNN_ID issue IOCB failed (%d).\n", rval); 664 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RNN_ID") != 665 QLA_SUCCESS) { 666 rval = QLA_FUNCTION_FAILED; 667 } else { 668 ql_dbg(ql_dbg_disc, vha, 0x204e, 669 "RNN_ID exiting normally.\n"); 670 } 671 672 return (rval); 673 } 674 675 void 676 qla2x00_get_sym_node_name(scsi_qla_host_t *vha, uint8_t *snn, size_t size) 677 { 678 struct qla_hw_data *ha = vha->hw; 679 680 if (IS_QLAFX00(ha)) 681 snprintf(snn, size, "%s FW:v%s DVR:v%s", ha->model_number, 682 ha->mr.fw_version, qla2x00_version_str); 683 else 684 snprintf(snn, size, 685 "%s FW:v%d.%02d.%02d DVR:v%s", ha->model_number, 686 ha->fw_major_version, ha->fw_minor_version, 687 ha->fw_subminor_version, qla2x00_version_str); 688 } 689 690 /** 691 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 692 * @ha: HA context 693 * 694 * Returns 0 on success. 695 */ 696 int 697 qla2x00_rsnn_nn(scsi_qla_host_t *vha) 698 { 699 int rval; 700 struct qla_hw_data *ha = vha->hw; 701 ms_iocb_entry_t *ms_pkt; 702 struct ct_sns_req *ct_req; 703 struct ct_sns_rsp *ct_rsp; 704 struct ct_arg arg; 705 706 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 707 ql_dbg(ql_dbg_disc, vha, 0x2050, 708 "RSNN_ID call unsupported on ISP2100/ISP2200.\n"); 709 return (QLA_SUCCESS); 710 } 711 712 arg.iocb = ha->ms_iocb; 713 arg.req_dma = ha->ct_sns_dma; 714 arg.rsp_dma = ha->ct_sns_dma; 715 arg.req_size = 0; 716 arg.rsp_size = RSNN_NN_RSP_SIZE; 717 arg.nport_handle = NPH_SNS; 718 719 /* Issue RSNN_NN */ 720 /* Prepare common MS IOCB */ 721 /* Request size adjusted after CT preparation */ 722 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 723 724 /* Prepare CT request */ 725 ct_req = qla2x00_prep_ct_req(ha->ct_sns, RSNN_NN_CMD, 726 RSNN_NN_RSP_SIZE); 727 ct_rsp = &ha->ct_sns->p.rsp; 728 729 /* Prepare CT arguments -- node_name, symbolic node_name, size */ 730 memcpy(ct_req->req.rsnn_nn.node_name, vha->node_name, WWN_SIZE); 731 732 /* Prepare the Symbolic Node Name */ 733 qla2x00_get_sym_node_name(vha, ct_req->req.rsnn_nn.sym_node_name, 734 sizeof(ct_req->req.rsnn_nn.sym_node_name)); 735 736 /* Calculate SNN length */ 737 ct_req->req.rsnn_nn.name_len = 738 (uint8_t)strlen(ct_req->req.rsnn_nn.sym_node_name); 739 740 /* Update MS IOCB request */ 741 ms_pkt->req_bytecount = 742 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len); 743 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 744 745 /* Execute MS IOCB */ 746 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 747 sizeof(ms_iocb_entry_t)); 748 if (rval != QLA_SUCCESS) { 749 /*EMPTY*/ 750 ql_dbg(ql_dbg_disc, vha, 0x2051, 751 "RSNN_NN issue IOCB failed (%d).\n", rval); 752 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RSNN_NN") != 753 QLA_SUCCESS) { 754 rval = QLA_FUNCTION_FAILED; 755 } else { 756 ql_dbg(ql_dbg_disc, vha, 0x2052, 757 "RSNN_NN exiting normally.\n"); 758 } 759 760 return (rval); 761 } 762 763 /** 764 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 765 * @ha: HA context 766 * @cmd: GS command 767 * @scmd_len: Subcommand length 768 * @data_size: response size in bytes 769 * 770 * Returns a pointer to the @ha's sns_cmd. 771 */ 772 static inline struct sns_cmd_pkt * 773 qla2x00_prep_sns_cmd(scsi_qla_host_t *vha, uint16_t cmd, uint16_t scmd_len, 774 uint16_t data_size) 775 { 776 uint16_t wc; 777 struct sns_cmd_pkt *sns_cmd; 778 struct qla_hw_data *ha = vha->hw; 779 780 sns_cmd = ha->sns_cmd; 781 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); 782 wc = data_size / 2; /* Size in 16bit words. */ 783 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); 784 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); 785 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); 786 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); 787 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); 788 wc = (data_size - 16) / 4; /* Size in 32bit words. */ 789 sns_cmd->p.cmd.size = cpu_to_le16(wc); 790 791 vha->qla_stats.control_requests++; 792 793 return (sns_cmd); 794 } 795 796 /** 797 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 798 * @ha: HA context 799 * @fcport: fcport entry to updated 800 * 801 * This command uses the old Exectute SNS Command mailbox routine. 802 * 803 * Returns 0 on success. 804 */ 805 static int 806 qla2x00_sns_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport) 807 { 808 int rval = QLA_SUCCESS; 809 struct qla_hw_data *ha = vha->hw; 810 struct sns_cmd_pkt *sns_cmd; 811 812 /* Issue GA_NXT. */ 813 /* Prepare SNS command request. */ 814 sns_cmd = qla2x00_prep_sns_cmd(vha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, 815 GA_NXT_SNS_DATA_SIZE); 816 817 /* Prepare SNS command arguments -- port_id. */ 818 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; 819 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; 820 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; 821 822 /* Execute SNS command. */ 823 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, 824 sizeof(struct sns_cmd_pkt)); 825 if (rval != QLA_SUCCESS) { 826 /*EMPTY*/ 827 ql_dbg(ql_dbg_disc, vha, 0x205f, 828 "GA_NXT Send SNS failed (%d).\n", rval); 829 } else if (sns_cmd->p.gan_data[8] != 0x80 || 830 sns_cmd->p.gan_data[9] != 0x02) { 831 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2084, 832 "GA_NXT failed, rejected request ga_nxt_rsp:\n"); 833 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2074, 834 sns_cmd->p.gan_data, 16); 835 rval = QLA_FUNCTION_FAILED; 836 } else { 837 /* Populate fc_port_t entry. */ 838 fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; 839 fcport->d_id.b.area = sns_cmd->p.gan_data[18]; 840 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; 841 842 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); 843 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); 844 845 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && 846 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) 847 fcport->d_id.b.domain = 0xf0; 848 849 ql_dbg(ql_dbg_disc, vha, 0x2061, 850 "GA_NXT entry - nn %8phN pn %8phN " 851 "port_id=%02x%02x%02x.\n", 852 fcport->node_name, fcport->port_name, 853 fcport->d_id.b.domain, fcport->d_id.b.area, 854 fcport->d_id.b.al_pa); 855 } 856 857 return (rval); 858 } 859 860 /** 861 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. 862 * @ha: HA context 863 * @list: switch info entries to populate 864 * 865 * This command uses the old Exectute SNS Command mailbox routine. 866 * 867 * NOTE: Non-Nx_Ports are not requested. 868 * 869 * Returns 0 on success. 870 */ 871 static int 872 qla2x00_sns_gid_pt(scsi_qla_host_t *vha, sw_info_t *list) 873 { 874 int rval; 875 struct qla_hw_data *ha = vha->hw; 876 uint16_t i; 877 uint8_t *entry; 878 struct sns_cmd_pkt *sns_cmd; 879 uint16_t gid_pt_sns_data_size; 880 881 gid_pt_sns_data_size = qla2x00_gid_pt_rsp_size(vha); 882 883 /* Issue GID_PT. */ 884 /* Prepare SNS command request. */ 885 sns_cmd = qla2x00_prep_sns_cmd(vha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, 886 gid_pt_sns_data_size); 887 888 /* Prepare SNS command arguments -- port_type. */ 889 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; 890 891 /* Execute SNS command. */ 892 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, 893 sizeof(struct sns_cmd_pkt)); 894 if (rval != QLA_SUCCESS) { 895 /*EMPTY*/ 896 ql_dbg(ql_dbg_disc, vha, 0x206d, 897 "GID_PT Send SNS failed (%d).\n", rval); 898 } else if (sns_cmd->p.gid_data[8] != 0x80 || 899 sns_cmd->p.gid_data[9] != 0x02) { 900 ql_dbg(ql_dbg_disc, vha, 0x202f, 901 "GID_PT failed, rejected request, gid_rsp:\n"); 902 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2081, 903 sns_cmd->p.gid_data, 16); 904 rval = QLA_FUNCTION_FAILED; 905 } else { 906 /* Set port IDs in switch info list. */ 907 for (i = 0; i < ha->max_fibre_devices; i++) { 908 entry = &sns_cmd->p.gid_data[(i * 4) + 16]; 909 list[i].d_id.b.domain = entry[1]; 910 list[i].d_id.b.area = entry[2]; 911 list[i].d_id.b.al_pa = entry[3]; 912 913 /* Last one exit. */ 914 if (entry[0] & BIT_7) { 915 list[i].d_id.b.rsvd_1 = entry[0]; 916 break; 917 } 918 } 919 920 /* 921 * If we've used all available slots, then the switch is 922 * reporting back more devices that we can handle with this 923 * single call. Return a failed status, and let GA_NXT handle 924 * the overload. 925 */ 926 if (i == ha->max_fibre_devices) 927 rval = QLA_FUNCTION_FAILED; 928 } 929 930 return (rval); 931 } 932 933 /** 934 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. 935 * @ha: HA context 936 * @list: switch info entries to populate 937 * 938 * This command uses the old Exectute SNS Command mailbox routine. 939 * 940 * Returns 0 on success. 941 */ 942 static int 943 qla2x00_sns_gpn_id(scsi_qla_host_t *vha, sw_info_t *list) 944 { 945 int rval = QLA_SUCCESS; 946 struct qla_hw_data *ha = vha->hw; 947 uint16_t i; 948 struct sns_cmd_pkt *sns_cmd; 949 950 for (i = 0; i < ha->max_fibre_devices; i++) { 951 /* Issue GPN_ID */ 952 /* Prepare SNS command request. */ 953 sns_cmd = qla2x00_prep_sns_cmd(vha, GPN_ID_CMD, 954 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); 955 956 /* Prepare SNS command arguments -- port_id. */ 957 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 958 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 959 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 960 961 /* Execute SNS command. */ 962 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 963 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 964 if (rval != QLA_SUCCESS) { 965 /*EMPTY*/ 966 ql_dbg(ql_dbg_disc, vha, 0x2032, 967 "GPN_ID Send SNS failed (%d).\n", rval); 968 } else if (sns_cmd->p.gpn_data[8] != 0x80 || 969 sns_cmd->p.gpn_data[9] != 0x02) { 970 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207e, 971 "GPN_ID failed, rejected request, gpn_rsp:\n"); 972 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207f, 973 sns_cmd->p.gpn_data, 16); 974 rval = QLA_FUNCTION_FAILED; 975 } else { 976 /* Save portname */ 977 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], 978 WWN_SIZE); 979 } 980 981 /* Last device exit. */ 982 if (list[i].d_id.b.rsvd_1 != 0) 983 break; 984 } 985 986 return (rval); 987 } 988 989 /** 990 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. 991 * @ha: HA context 992 * @list: switch info entries to populate 993 * 994 * This command uses the old Exectute SNS Command mailbox routine. 995 * 996 * Returns 0 on success. 997 */ 998 static int 999 qla2x00_sns_gnn_id(scsi_qla_host_t *vha, sw_info_t *list) 1000 { 1001 int rval = QLA_SUCCESS; 1002 struct qla_hw_data *ha = vha->hw; 1003 uint16_t i; 1004 struct sns_cmd_pkt *sns_cmd; 1005 1006 for (i = 0; i < ha->max_fibre_devices; i++) { 1007 /* Issue GNN_ID */ 1008 /* Prepare SNS command request. */ 1009 sns_cmd = qla2x00_prep_sns_cmd(vha, GNN_ID_CMD, 1010 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); 1011 1012 /* Prepare SNS command arguments -- port_id. */ 1013 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 1014 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 1015 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 1016 1017 /* Execute SNS command. */ 1018 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, 1019 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 1020 if (rval != QLA_SUCCESS) { 1021 /*EMPTY*/ 1022 ql_dbg(ql_dbg_disc, vha, 0x203f, 1023 "GNN_ID Send SNS failed (%d).\n", rval); 1024 } else if (sns_cmd->p.gnn_data[8] != 0x80 || 1025 sns_cmd->p.gnn_data[9] != 0x02) { 1026 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2082, 1027 "GNN_ID failed, rejected request, gnn_rsp:\n"); 1028 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207a, 1029 sns_cmd->p.gnn_data, 16); 1030 rval = QLA_FUNCTION_FAILED; 1031 } else { 1032 /* Save nodename */ 1033 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], 1034 WWN_SIZE); 1035 1036 ql_dbg(ql_dbg_disc, vha, 0x206e, 1037 "GID_PT entry - nn %8phN pn %8phN " 1038 "port_id=%02x%02x%02x.\n", 1039 list[i].node_name, list[i].port_name, 1040 list[i].d_id.b.domain, list[i].d_id.b.area, 1041 list[i].d_id.b.al_pa); 1042 } 1043 1044 /* Last device exit. */ 1045 if (list[i].d_id.b.rsvd_1 != 0) 1046 break; 1047 } 1048 1049 return (rval); 1050 } 1051 1052 /** 1053 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 1054 * @ha: HA context 1055 * 1056 * This command uses the old Exectute SNS Command mailbox routine. 1057 * 1058 * Returns 0 on success. 1059 */ 1060 static int 1061 qla2x00_sns_rft_id(scsi_qla_host_t *vha) 1062 { 1063 int rval; 1064 struct qla_hw_data *ha = vha->hw; 1065 struct sns_cmd_pkt *sns_cmd; 1066 1067 /* Issue RFT_ID. */ 1068 /* Prepare SNS command request. */ 1069 sns_cmd = qla2x00_prep_sns_cmd(vha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, 1070 RFT_ID_SNS_DATA_SIZE); 1071 1072 /* Prepare SNS command arguments -- port_id, FC-4 types */ 1073 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1074 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1075 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1076 1077 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ 1078 1079 /* Execute SNS command. */ 1080 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, 1081 sizeof(struct sns_cmd_pkt)); 1082 if (rval != QLA_SUCCESS) { 1083 /*EMPTY*/ 1084 ql_dbg(ql_dbg_disc, vha, 0x2060, 1085 "RFT_ID Send SNS failed (%d).\n", rval); 1086 } else if (sns_cmd->p.rft_data[8] != 0x80 || 1087 sns_cmd->p.rft_data[9] != 0x02) { 1088 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x2083, 1089 "RFT_ID failed, rejected request rft_rsp:\n"); 1090 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2080, 1091 sns_cmd->p.rft_data, 16); 1092 rval = QLA_FUNCTION_FAILED; 1093 } else { 1094 ql_dbg(ql_dbg_disc, vha, 0x2073, 1095 "RFT_ID exiting normally.\n"); 1096 } 1097 1098 return (rval); 1099 } 1100 1101 /** 1102 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 1103 * HBA. 1104 * @ha: HA context 1105 * 1106 * This command uses the old Exectute SNS Command mailbox routine. 1107 * 1108 * Returns 0 on success. 1109 */ 1110 static int 1111 qla2x00_sns_rnn_id(scsi_qla_host_t *vha) 1112 { 1113 int rval; 1114 struct qla_hw_data *ha = vha->hw; 1115 struct sns_cmd_pkt *sns_cmd; 1116 1117 /* Issue RNN_ID. */ 1118 /* Prepare SNS command request. */ 1119 sns_cmd = qla2x00_prep_sns_cmd(vha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, 1120 RNN_ID_SNS_DATA_SIZE); 1121 1122 /* Prepare SNS command arguments -- port_id, nodename. */ 1123 sns_cmd->p.cmd.param[0] = vha->d_id.b.al_pa; 1124 sns_cmd->p.cmd.param[1] = vha->d_id.b.area; 1125 sns_cmd->p.cmd.param[2] = vha->d_id.b.domain; 1126 1127 sns_cmd->p.cmd.param[4] = vha->node_name[7]; 1128 sns_cmd->p.cmd.param[5] = vha->node_name[6]; 1129 sns_cmd->p.cmd.param[6] = vha->node_name[5]; 1130 sns_cmd->p.cmd.param[7] = vha->node_name[4]; 1131 sns_cmd->p.cmd.param[8] = vha->node_name[3]; 1132 sns_cmd->p.cmd.param[9] = vha->node_name[2]; 1133 sns_cmd->p.cmd.param[10] = vha->node_name[1]; 1134 sns_cmd->p.cmd.param[11] = vha->node_name[0]; 1135 1136 /* Execute SNS command. */ 1137 rval = qla2x00_send_sns(vha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, 1138 sizeof(struct sns_cmd_pkt)); 1139 if (rval != QLA_SUCCESS) { 1140 /*EMPTY*/ 1141 ql_dbg(ql_dbg_disc, vha, 0x204a, 1142 "RNN_ID Send SNS failed (%d).\n", rval); 1143 } else if (sns_cmd->p.rnn_data[8] != 0x80 || 1144 sns_cmd->p.rnn_data[9] != 0x02) { 1145 ql_dbg(ql_dbg_disc + ql_dbg_buffer, vha, 0x207b, 1146 "RNN_ID failed, rejected request, rnn_rsp:\n"); 1147 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x207c, 1148 sns_cmd->p.rnn_data, 16); 1149 rval = QLA_FUNCTION_FAILED; 1150 } else { 1151 ql_dbg(ql_dbg_disc, vha, 0x204c, 1152 "RNN_ID exiting normally.\n"); 1153 } 1154 1155 return (rval); 1156 } 1157 1158 /** 1159 * qla2x00_mgmt_svr_login() - Login to fabric Management Service. 1160 * @ha: HA context 1161 * 1162 * Returns 0 on success. 1163 */ 1164 int 1165 qla2x00_mgmt_svr_login(scsi_qla_host_t *vha) 1166 { 1167 int ret, rval; 1168 uint16_t mb[MAILBOX_REGISTER_COUNT]; 1169 struct qla_hw_data *ha = vha->hw; 1170 ret = QLA_SUCCESS; 1171 if (vha->flags.management_server_logged_in) 1172 return ret; 1173 1174 rval = ha->isp_ops->fabric_login(vha, vha->mgmt_svr_loop_id, 0xff, 0xff, 1175 0xfa, mb, BIT_1); 1176 if (rval != QLA_SUCCESS || mb[0] != MBS_COMMAND_COMPLETE) { 1177 if (rval == QLA_MEMORY_ALLOC_FAILED) 1178 ql_dbg(ql_dbg_disc, vha, 0x2085, 1179 "Failed management_server login: loopid=%x " 1180 "rval=%d\n", vha->mgmt_svr_loop_id, rval); 1181 else 1182 ql_dbg(ql_dbg_disc, vha, 0x2024, 1183 "Failed management_server login: loopid=%x " 1184 "mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x.\n", 1185 vha->mgmt_svr_loop_id, mb[0], mb[1], mb[2], mb[6], 1186 mb[7]); 1187 ret = QLA_FUNCTION_FAILED; 1188 } else 1189 vha->flags.management_server_logged_in = 1; 1190 1191 return ret; 1192 } 1193 1194 /** 1195 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1196 * @ha: HA context 1197 * @req_size: request size in bytes 1198 * @rsp_size: response size in bytes 1199 * 1200 * Returns a pointer to the @ha's ms_iocb. 1201 */ 1202 void * 1203 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1204 uint32_t rsp_size) 1205 { 1206 ms_iocb_entry_t *ms_pkt; 1207 struct qla_hw_data *ha = vha->hw; 1208 ms_pkt = ha->ms_iocb; 1209 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 1210 1211 ms_pkt->entry_type = MS_IOCB_TYPE; 1212 ms_pkt->entry_count = 1; 1213 SET_TARGET_ID(ha, ms_pkt->loop_id, vha->mgmt_svr_loop_id); 1214 ms_pkt->control_flags = cpu_to_le16(CF_READ | CF_HEAD_TAG); 1215 ms_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1216 ms_pkt->cmd_dsd_count = cpu_to_le16(1); 1217 ms_pkt->total_dsd_count = cpu_to_le16(2); 1218 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 1219 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1220 1221 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1222 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1223 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1224 1225 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1226 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1227 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 1228 1229 return ms_pkt; 1230 } 1231 1232 /** 1233 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1234 * @ha: HA context 1235 * @req_size: request size in bytes 1236 * @rsp_size: response size in bytes 1237 * 1238 * Returns a pointer to the @ha's ms_iocb. 1239 */ 1240 void * 1241 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size, 1242 uint32_t rsp_size) 1243 { 1244 struct ct_entry_24xx *ct_pkt; 1245 struct qla_hw_data *ha = vha->hw; 1246 1247 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1248 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 1249 1250 ct_pkt->entry_type = CT_IOCB_TYPE; 1251 ct_pkt->entry_count = 1; 1252 ct_pkt->nport_handle = cpu_to_le16(vha->mgmt_svr_loop_id); 1253 ct_pkt->timeout = cpu_to_le16(ha->r_a_tov / 10 * 2); 1254 ct_pkt->cmd_dsd_count = cpu_to_le16(1); 1255 ct_pkt->rsp_dsd_count = cpu_to_le16(1); 1256 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 1257 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1258 1259 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1260 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1261 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1262 1263 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1264 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1265 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1266 ct_pkt->vp_index = vha->vp_idx; 1267 1268 return ct_pkt; 1269 } 1270 1271 static inline ms_iocb_entry_t * 1272 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *vha, uint32_t req_size) 1273 { 1274 struct qla_hw_data *ha = vha->hw; 1275 ms_iocb_entry_t *ms_pkt = ha->ms_iocb; 1276 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1277 1278 if (IS_FWI2_CAPABLE(ha)) { 1279 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1280 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1281 } else { 1282 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1283 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1284 } 1285 1286 return ms_pkt; 1287 } 1288 1289 /** 1290 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 1291 * @ct_req: CT request buffer 1292 * @cmd: GS command 1293 * @rsp_size: response size in bytes 1294 * 1295 * Returns a pointer to the intitialized @ct_req. 1296 */ 1297 static inline struct ct_sns_req * 1298 qla2x00_prep_ct_fdmi_req(struct ct_sns_pkt *p, uint16_t cmd, 1299 uint16_t rsp_size) 1300 { 1301 memset(p, 0, sizeof(struct ct_sns_pkt)); 1302 1303 p->p.req.header.revision = 0x01; 1304 p->p.req.header.gs_type = 0xFA; 1305 p->p.req.header.gs_subtype = 0x10; 1306 p->p.req.command = cpu_to_be16(cmd); 1307 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 1308 1309 return &p->p.req; 1310 } 1311 1312 /** 1313 * qla2x00_fdmi_rhba() - 1314 * @ha: HA context 1315 * 1316 * Returns 0 on success. 1317 */ 1318 static int 1319 qla2x00_fdmi_rhba(scsi_qla_host_t *vha) 1320 { 1321 int rval, alen; 1322 uint32_t size, sn; 1323 1324 ms_iocb_entry_t *ms_pkt; 1325 struct ct_sns_req *ct_req; 1326 struct ct_sns_rsp *ct_rsp; 1327 void *entries; 1328 struct ct_fdmi_hba_attr *eiter; 1329 struct qla_hw_data *ha = vha->hw; 1330 1331 /* Issue RHBA */ 1332 /* Prepare common MS IOCB */ 1333 /* Request size adjusted after CT preparation */ 1334 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1335 1336 /* Prepare CT request */ 1337 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, RHBA_RSP_SIZE); 1338 ct_rsp = &ha->ct_sns->p.rsp; 1339 1340 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1341 memcpy(ct_req->req.rhba.hba_identifier, vha->port_name, WWN_SIZE); 1342 ct_req->req.rhba.entry_count = cpu_to_be32(1); 1343 memcpy(ct_req->req.rhba.port_name, vha->port_name, WWN_SIZE); 1344 size = 2 * WWN_SIZE + 4 + 4; 1345 1346 /* Attributes */ 1347 ct_req->req.rhba.attrs.count = 1348 cpu_to_be32(FDMI_HBA_ATTR_COUNT); 1349 entries = ct_req->req.rhba.hba_identifier; 1350 1351 /* Nodename. */ 1352 eiter = entries + size; 1353 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1354 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1355 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1356 size += 4 + WWN_SIZE; 1357 1358 ql_dbg(ql_dbg_disc, vha, 0x2025, 1359 "NodeName = %8phN.\n", eiter->a.node_name); 1360 1361 /* Manufacturer. */ 1362 eiter = entries + size; 1363 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1364 alen = strlen(QLA2XXX_MANUFACTURER); 1365 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1366 "%s", "QLogic Corporation"); 1367 alen += 4 - (alen & 3); 1368 eiter->len = cpu_to_be16(4 + alen); 1369 size += 4 + alen; 1370 1371 ql_dbg(ql_dbg_disc, vha, 0x2026, 1372 "Manufacturer = %s.\n", eiter->a.manufacturer); 1373 1374 /* Serial number. */ 1375 eiter = entries + size; 1376 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1377 if (IS_FWI2_CAPABLE(ha)) 1378 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 1379 sizeof(eiter->a.serial_num)); 1380 else { 1381 sn = ((ha->serial0 & 0x1f) << 16) | 1382 (ha->serial2 << 8) | ha->serial1; 1383 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 1384 "%c%05d", 'A' + sn / 100000, sn % 100000); 1385 } 1386 alen = strlen(eiter->a.serial_num); 1387 alen += 4 - (alen & 3); 1388 eiter->len = cpu_to_be16(4 + alen); 1389 size += 4 + alen; 1390 1391 ql_dbg(ql_dbg_disc, vha, 0x2027, 1392 "Serial no. = %s.\n", eiter->a.serial_num); 1393 1394 /* Model name. */ 1395 eiter = entries + size; 1396 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 1397 snprintf(eiter->a.model, sizeof(eiter->a.model), 1398 "%s", ha->model_number); 1399 alen = strlen(eiter->a.model); 1400 alen += 4 - (alen & 3); 1401 eiter->len = cpu_to_be16(4 + alen); 1402 size += 4 + alen; 1403 1404 ql_dbg(ql_dbg_disc, vha, 0x2028, 1405 "Model Name = %s.\n", eiter->a.model); 1406 1407 /* Model description. */ 1408 eiter = entries + size; 1409 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1410 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 1411 "%s", ha->model_desc); 1412 alen = strlen(eiter->a.model_desc); 1413 alen += 4 - (alen & 3); 1414 eiter->len = cpu_to_be16(4 + alen); 1415 size += 4 + alen; 1416 1417 ql_dbg(ql_dbg_disc, vha, 0x2029, 1418 "Model Desc = %s.\n", eiter->a.model_desc); 1419 1420 /* Hardware version. */ 1421 eiter = entries + size; 1422 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1423 if (!IS_FWI2_CAPABLE(ha)) { 1424 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1425 "HW:%s", ha->adapter_id); 1426 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 1427 sizeof(eiter->a.hw_version))) { 1428 ; 1429 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 1430 sizeof(eiter->a.hw_version))) { 1431 ; 1432 } else { 1433 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1434 "HW:%s", ha->adapter_id); 1435 } 1436 alen = strlen(eiter->a.hw_version); 1437 alen += 4 - (alen & 3); 1438 eiter->len = cpu_to_be16(4 + alen); 1439 size += 4 + alen; 1440 1441 ql_dbg(ql_dbg_disc, vha, 0x202a, 1442 "Hardware ver = %s.\n", eiter->a.hw_version); 1443 1444 /* Driver version. */ 1445 eiter = entries + size; 1446 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1447 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 1448 "%s", qla2x00_version_str); 1449 alen = strlen(eiter->a.driver_version); 1450 alen += 4 - (alen & 3); 1451 eiter->len = cpu_to_be16(4 + alen); 1452 size += 4 + alen; 1453 1454 ql_dbg(ql_dbg_disc, vha, 0x202b, 1455 "Driver ver = %s.\n", eiter->a.driver_version); 1456 1457 /* Option ROM version. */ 1458 eiter = entries + size; 1459 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1460 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 1461 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1462 alen = strlen(eiter->a.orom_version); 1463 alen += 4 - (alen & 3); 1464 eiter->len = cpu_to_be16(4 + alen); 1465 size += 4 + alen; 1466 1467 ql_dbg(ql_dbg_disc, vha , 0x202c, 1468 "Optrom vers = %s.\n", eiter->a.orom_version); 1469 1470 /* Firmware version */ 1471 eiter = entries + size; 1472 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1473 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 1474 sizeof(eiter->a.fw_version)); 1475 alen = strlen(eiter->a.fw_version); 1476 alen += 4 - (alen & 3); 1477 eiter->len = cpu_to_be16(4 + alen); 1478 size += 4 + alen; 1479 1480 ql_dbg(ql_dbg_disc, vha, 0x202d, 1481 "Firmware vers = %s.\n", eiter->a.fw_version); 1482 1483 /* Update MS request size. */ 1484 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1485 1486 ql_dbg(ql_dbg_disc, vha, 0x202e, 1487 "RHBA identifier = %8phN size=%d.\n", 1488 ct_req->req.rhba.hba_identifier, size); 1489 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2076, 1490 entries, size); 1491 1492 /* Execute MS IOCB */ 1493 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1494 sizeof(ms_iocb_entry_t)); 1495 if (rval != QLA_SUCCESS) { 1496 /*EMPTY*/ 1497 ql_dbg(ql_dbg_disc, vha, 0x2030, 1498 "RHBA issue IOCB failed (%d).\n", rval); 1499 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 1500 QLA_SUCCESS) { 1501 rval = QLA_FUNCTION_FAILED; 1502 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1503 ct_rsp->header.explanation_code == 1504 CT_EXPL_ALREADY_REGISTERED) { 1505 ql_dbg(ql_dbg_disc, vha, 0x2034, 1506 "HBA already registered.\n"); 1507 rval = QLA_ALREADY_REGISTERED; 1508 } else { 1509 ql_dbg(ql_dbg_disc, vha, 0x20ad, 1510 "RHBA FDMI registration failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 1511 ct_rsp->header.reason_code, 1512 ct_rsp->header.explanation_code); 1513 } 1514 } else { 1515 ql_dbg(ql_dbg_disc, vha, 0x2035, 1516 "RHBA exiting normally.\n"); 1517 } 1518 1519 return rval; 1520 } 1521 1522 /** 1523 * qla2x00_fdmi_rpa() - 1524 * @ha: HA context 1525 * 1526 * Returns 0 on success. 1527 */ 1528 static int 1529 qla2x00_fdmi_rpa(scsi_qla_host_t *vha) 1530 { 1531 int rval, alen; 1532 uint32_t size; 1533 struct qla_hw_data *ha = vha->hw; 1534 ms_iocb_entry_t *ms_pkt; 1535 struct ct_sns_req *ct_req; 1536 struct ct_sns_rsp *ct_rsp; 1537 void *entries; 1538 struct ct_fdmi_port_attr *eiter; 1539 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1540 struct new_utsname *p_sysid = NULL; 1541 1542 /* Issue RPA */ 1543 /* Prepare common MS IOCB */ 1544 /* Request size adjusted after CT preparation */ 1545 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 1546 1547 /* Prepare CT request */ 1548 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, 1549 RPA_RSP_SIZE); 1550 ct_rsp = &ha->ct_sns->p.rsp; 1551 1552 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1553 memcpy(ct_req->req.rpa.port_name, vha->port_name, WWN_SIZE); 1554 size = WWN_SIZE + 4; 1555 1556 /* Attributes */ 1557 ct_req->req.rpa.attrs.count = cpu_to_be32(FDMI_PORT_ATTR_COUNT); 1558 entries = ct_req->req.rpa.port_name; 1559 1560 /* FC4 types. */ 1561 eiter = entries + size; 1562 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 1563 eiter->len = cpu_to_be16(4 + 32); 1564 eiter->a.fc4_types[2] = 0x01; 1565 size += 4 + 32; 1566 1567 ql_dbg(ql_dbg_disc, vha, 0x2039, 1568 "FC4_TYPES=%02x %02x.\n", 1569 eiter->a.fc4_types[2], 1570 eiter->a.fc4_types[1]); 1571 1572 /* Supported speed. */ 1573 eiter = entries + size; 1574 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 1575 eiter->len = cpu_to_be16(4 + 4); 1576 if (IS_CNA_CAPABLE(ha)) 1577 eiter->a.sup_speed = cpu_to_be32( 1578 FDMI_PORT_SPEED_10GB); 1579 else if (IS_QLA27XX(ha)) 1580 eiter->a.sup_speed = cpu_to_be32( 1581 FDMI_PORT_SPEED_32GB| 1582 FDMI_PORT_SPEED_16GB| 1583 FDMI_PORT_SPEED_8GB); 1584 else if (IS_QLA2031(ha)) 1585 eiter->a.sup_speed = cpu_to_be32( 1586 FDMI_PORT_SPEED_16GB| 1587 FDMI_PORT_SPEED_8GB| 1588 FDMI_PORT_SPEED_4GB); 1589 else if (IS_QLA25XX(ha)) 1590 eiter->a.sup_speed = cpu_to_be32( 1591 FDMI_PORT_SPEED_8GB| 1592 FDMI_PORT_SPEED_4GB| 1593 FDMI_PORT_SPEED_2GB| 1594 FDMI_PORT_SPEED_1GB); 1595 else if (IS_QLA24XX_TYPE(ha)) 1596 eiter->a.sup_speed = cpu_to_be32( 1597 FDMI_PORT_SPEED_4GB| 1598 FDMI_PORT_SPEED_2GB| 1599 FDMI_PORT_SPEED_1GB); 1600 else if (IS_QLA23XX(ha)) 1601 eiter->a.sup_speed = cpu_to_be32( 1602 FDMI_PORT_SPEED_2GB| 1603 FDMI_PORT_SPEED_1GB); 1604 else 1605 eiter->a.sup_speed = cpu_to_be32( 1606 FDMI_PORT_SPEED_1GB); 1607 size += 4 + 4; 1608 1609 ql_dbg(ql_dbg_disc, vha, 0x203a, 1610 "Supported_Speed=%x.\n", eiter->a.sup_speed); 1611 1612 /* Current speed. */ 1613 eiter = entries + size; 1614 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 1615 eiter->len = cpu_to_be16(4 + 4); 1616 switch (ha->link_data_rate) { 1617 case PORT_SPEED_1GB: 1618 eiter->a.cur_speed = 1619 cpu_to_be32(FDMI_PORT_SPEED_1GB); 1620 break; 1621 case PORT_SPEED_2GB: 1622 eiter->a.cur_speed = 1623 cpu_to_be32(FDMI_PORT_SPEED_2GB); 1624 break; 1625 case PORT_SPEED_4GB: 1626 eiter->a.cur_speed = 1627 cpu_to_be32(FDMI_PORT_SPEED_4GB); 1628 break; 1629 case PORT_SPEED_8GB: 1630 eiter->a.cur_speed = 1631 cpu_to_be32(FDMI_PORT_SPEED_8GB); 1632 break; 1633 case PORT_SPEED_10GB: 1634 eiter->a.cur_speed = 1635 cpu_to_be32(FDMI_PORT_SPEED_10GB); 1636 break; 1637 case PORT_SPEED_16GB: 1638 eiter->a.cur_speed = 1639 cpu_to_be32(FDMI_PORT_SPEED_16GB); 1640 break; 1641 case PORT_SPEED_32GB: 1642 eiter->a.cur_speed = 1643 cpu_to_be32(FDMI_PORT_SPEED_32GB); 1644 break; 1645 default: 1646 eiter->a.cur_speed = 1647 cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 1648 break; 1649 } 1650 size += 4 + 4; 1651 1652 ql_dbg(ql_dbg_disc, vha, 0x203b, 1653 "Current_Speed=%x.\n", eiter->a.cur_speed); 1654 1655 /* Max frame size. */ 1656 eiter = entries + size; 1657 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 1658 eiter->len = cpu_to_be16(4 + 4); 1659 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 1660 le16_to_cpu(icb24->frame_payload_size) : 1661 le16_to_cpu(ha->init_cb->frame_payload_size); 1662 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 1663 size += 4 + 4; 1664 1665 ql_dbg(ql_dbg_disc, vha, 0x203c, 1666 "Max_Frame_Size=%x.\n", eiter->a.max_frame_size); 1667 1668 /* OS device name. */ 1669 eiter = entries + size; 1670 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 1671 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 1672 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 1673 alen = strlen(eiter->a.os_dev_name); 1674 alen += 4 - (alen & 3); 1675 eiter->len = cpu_to_be16(4 + alen); 1676 size += 4 + alen; 1677 1678 ql_dbg(ql_dbg_disc, vha, 0x204b, 1679 "OS_Device_Name=%s.\n", eiter->a.os_dev_name); 1680 1681 /* Hostname. */ 1682 eiter = entries + size; 1683 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 1684 p_sysid = utsname(); 1685 if (p_sysid) { 1686 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1687 "%s", p_sysid->nodename); 1688 } else { 1689 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 1690 "%s", fc_host_system_hostname(vha->host)); 1691 } 1692 alen = strlen(eiter->a.host_name); 1693 alen += 4 - (alen & 3); 1694 eiter->len = cpu_to_be16(4 + alen); 1695 size += 4 + alen; 1696 1697 ql_dbg(ql_dbg_disc, vha, 0x203d, "HostName=%s.\n", eiter->a.host_name); 1698 1699 /* Update MS request size. */ 1700 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 1701 1702 ql_dbg(ql_dbg_disc, vha, 0x203e, 1703 "RPA portname %016llx, size = %d.\n", 1704 wwn_to_u64(ct_req->req.rpa.port_name), size); 1705 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x2079, 1706 entries, size); 1707 1708 /* Execute MS IOCB */ 1709 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 1710 sizeof(ms_iocb_entry_t)); 1711 if (rval != QLA_SUCCESS) { 1712 /*EMPTY*/ 1713 ql_dbg(ql_dbg_disc, vha, 0x2040, 1714 "RPA issue IOCB failed (%d).\n", rval); 1715 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 1716 QLA_SUCCESS) { 1717 rval = QLA_FUNCTION_FAILED; 1718 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1719 ct_rsp->header.explanation_code == 1720 CT_EXPL_ALREADY_REGISTERED) { 1721 ql_dbg(ql_dbg_disc, vha, 0x20cd, 1722 "RPA already registered.\n"); 1723 rval = QLA_ALREADY_REGISTERED; 1724 } 1725 1726 } else { 1727 ql_dbg(ql_dbg_disc, vha, 0x2041, 1728 "RPA exiting normally.\n"); 1729 } 1730 1731 return rval; 1732 } 1733 1734 /** 1735 * qla2x00_fdmiv2_rhba() - 1736 * @ha: HA context 1737 * 1738 * Returns 0 on success. 1739 */ 1740 static int 1741 qla2x00_fdmiv2_rhba(scsi_qla_host_t *vha) 1742 { 1743 int rval, alen; 1744 uint32_t size, sn; 1745 ms_iocb_entry_t *ms_pkt; 1746 struct ct_sns_req *ct_req; 1747 struct ct_sns_rsp *ct_rsp; 1748 void *entries; 1749 struct ct_fdmiv2_hba_attr *eiter; 1750 struct qla_hw_data *ha = vha->hw; 1751 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1752 struct new_utsname *p_sysid = NULL; 1753 1754 /* Issue RHBA */ 1755 /* Prepare common MS IOCB */ 1756 /* Request size adjusted after CT preparation */ 1757 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RHBA_RSP_SIZE); 1758 1759 /* Prepare CT request */ 1760 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RHBA_CMD, 1761 RHBA_RSP_SIZE); 1762 ct_rsp = &ha->ct_sns->p.rsp; 1763 1764 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1765 memcpy(ct_req->req.rhba2.hba_identifier, vha->port_name, WWN_SIZE); 1766 ct_req->req.rhba2.entry_count = cpu_to_be32(1); 1767 memcpy(ct_req->req.rhba2.port_name, vha->port_name, WWN_SIZE); 1768 size = 2 * WWN_SIZE + 4 + 4; 1769 1770 /* Attributes */ 1771 ct_req->req.rhba2.attrs.count = cpu_to_be32(FDMIV2_HBA_ATTR_COUNT); 1772 entries = ct_req->req.rhba2.hba_identifier; 1773 1774 /* Nodename. */ 1775 eiter = entries + size; 1776 eiter->type = cpu_to_be16(FDMI_HBA_NODE_NAME); 1777 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1778 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 1779 size += 4 + WWN_SIZE; 1780 1781 ql_dbg(ql_dbg_disc, vha, 0x207d, 1782 "NodeName = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 1783 1784 /* Manufacturer. */ 1785 eiter = entries + size; 1786 eiter->type = cpu_to_be16(FDMI_HBA_MANUFACTURER); 1787 snprintf(eiter->a.manufacturer, sizeof(eiter->a.manufacturer), 1788 "%s", "QLogic Corporation"); 1789 eiter->a.manufacturer[strlen("QLogic Corporation")] = '\0'; 1790 alen = strlen(eiter->a.manufacturer); 1791 alen += 4 - (alen & 3); 1792 eiter->len = cpu_to_be16(4 + alen); 1793 size += 4 + alen; 1794 1795 ql_dbg(ql_dbg_disc, vha, 0x20a5, 1796 "Manufacturer = %s.\n", eiter->a.manufacturer); 1797 1798 /* Serial number. */ 1799 eiter = entries + size; 1800 eiter->type = cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1801 if (IS_FWI2_CAPABLE(ha)) 1802 qla2xxx_get_vpd_field(vha, "SN", eiter->a.serial_num, 1803 sizeof(eiter->a.serial_num)); 1804 else { 1805 sn = ((ha->serial0 & 0x1f) << 16) | 1806 (ha->serial2 << 8) | ha->serial1; 1807 snprintf(eiter->a.serial_num, sizeof(eiter->a.serial_num), 1808 "%c%05d", 'A' + sn / 100000, sn % 100000); 1809 } 1810 alen = strlen(eiter->a.serial_num); 1811 alen += 4 - (alen & 3); 1812 eiter->len = cpu_to_be16(4 + alen); 1813 size += 4 + alen; 1814 1815 ql_dbg(ql_dbg_disc, vha, 0x20a6, 1816 "Serial no. = %s.\n", eiter->a.serial_num); 1817 1818 /* Model name. */ 1819 eiter = entries + size; 1820 eiter->type = cpu_to_be16(FDMI_HBA_MODEL); 1821 snprintf(eiter->a.model, sizeof(eiter->a.model), 1822 "%s", ha->model_number); 1823 alen = strlen(eiter->a.model); 1824 alen += 4 - (alen & 3); 1825 eiter->len = cpu_to_be16(4 + alen); 1826 size += 4 + alen; 1827 1828 ql_dbg(ql_dbg_disc, vha, 0x20a7, 1829 "Model Name = %s.\n", eiter->a.model); 1830 1831 /* Model description. */ 1832 eiter = entries + size; 1833 eiter->type = cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1834 snprintf(eiter->a.model_desc, sizeof(eiter->a.model_desc), 1835 "%s", ha->model_desc); 1836 alen = strlen(eiter->a.model_desc); 1837 alen += 4 - (alen & 3); 1838 eiter->len = cpu_to_be16(4 + alen); 1839 size += 4 + alen; 1840 1841 ql_dbg(ql_dbg_disc, vha, 0x20a8, 1842 "Model Desc = %s.\n", eiter->a.model_desc); 1843 1844 /* Hardware version. */ 1845 eiter = entries + size; 1846 eiter->type = cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1847 if (!IS_FWI2_CAPABLE(ha)) { 1848 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1849 "HW:%s", ha->adapter_id); 1850 } else if (qla2xxx_get_vpd_field(vha, "MN", eiter->a.hw_version, 1851 sizeof(eiter->a.hw_version))) { 1852 ; 1853 } else if (qla2xxx_get_vpd_field(vha, "EC", eiter->a.hw_version, 1854 sizeof(eiter->a.hw_version))) { 1855 ; 1856 } else { 1857 snprintf(eiter->a.hw_version, sizeof(eiter->a.hw_version), 1858 "HW:%s", ha->adapter_id); 1859 } 1860 alen = strlen(eiter->a.hw_version); 1861 alen += 4 - (alen & 3); 1862 eiter->len = cpu_to_be16(4 + alen); 1863 size += 4 + alen; 1864 1865 ql_dbg(ql_dbg_disc, vha, 0x20a9, 1866 "Hardware ver = %s.\n", eiter->a.hw_version); 1867 1868 /* Driver version. */ 1869 eiter = entries + size; 1870 eiter->type = cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1871 snprintf(eiter->a.driver_version, sizeof(eiter->a.driver_version), 1872 "%s", qla2x00_version_str); 1873 alen = strlen(eiter->a.driver_version); 1874 alen += 4 - (alen & 3); 1875 eiter->len = cpu_to_be16(4 + alen); 1876 size += 4 + alen; 1877 1878 ql_dbg(ql_dbg_disc, vha, 0x20aa, 1879 "Driver ver = %s.\n", eiter->a.driver_version); 1880 1881 /* Option ROM version. */ 1882 eiter = entries + size; 1883 eiter->type = cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1884 snprintf(eiter->a.orom_version, sizeof(eiter->a.orom_version), 1885 "%d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1886 alen = strlen(eiter->a.orom_version); 1887 alen += 4 - (alen & 3); 1888 eiter->len = cpu_to_be16(4 + alen); 1889 size += 4 + alen; 1890 1891 ql_dbg(ql_dbg_disc, vha , 0x20ab, 1892 "Optrom version = %d.%02d.\n", eiter->a.orom_version[1], 1893 eiter->a.orom_version[0]); 1894 1895 /* Firmware version */ 1896 eiter = entries + size; 1897 eiter->type = cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1898 ha->isp_ops->fw_version_str(vha, eiter->a.fw_version, 1899 sizeof(eiter->a.fw_version)); 1900 alen = strlen(eiter->a.fw_version); 1901 alen += 4 - (alen & 3); 1902 eiter->len = cpu_to_be16(4 + alen); 1903 size += 4 + alen; 1904 1905 ql_dbg(ql_dbg_disc, vha, 0x20ac, 1906 "Firmware vers = %s.\n", eiter->a.fw_version); 1907 1908 /* OS Name and Version */ 1909 eiter = entries + size; 1910 eiter->type = cpu_to_be16(FDMI_HBA_OS_NAME_AND_VERSION); 1911 p_sysid = utsname(); 1912 if (p_sysid) { 1913 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 1914 "%s %s %s", 1915 p_sysid->sysname, p_sysid->release, p_sysid->version); 1916 } else { 1917 snprintf(eiter->a.os_version, sizeof(eiter->a.os_version), 1918 "%s %s", "Linux", fc_host_system_hostname(vha->host)); 1919 } 1920 alen = strlen(eiter->a.os_version); 1921 alen += 4 - (alen & 3); 1922 eiter->len = cpu_to_be16(4 + alen); 1923 size += 4 + alen; 1924 1925 ql_dbg(ql_dbg_disc, vha, 0x20ae, 1926 "OS Name and Version = %s.\n", eiter->a.os_version); 1927 1928 /* MAX CT Payload Length */ 1929 eiter = entries + size; 1930 eiter->type = cpu_to_be16(FDMI_HBA_MAXIMUM_CT_PAYLOAD_LENGTH); 1931 eiter->a.max_ct_len = IS_FWI2_CAPABLE(ha) ? 1932 le16_to_cpu(icb24->frame_payload_size) : 1933 le16_to_cpu(ha->init_cb->frame_payload_size); 1934 eiter->a.max_ct_len = cpu_to_be32(eiter->a.max_ct_len); 1935 eiter->len = cpu_to_be16(4 + 4); 1936 size += 4 + 4; 1937 1938 ql_dbg(ql_dbg_disc, vha, 0x20af, 1939 "CT Payload Length = 0x%x.\n", eiter->a.max_ct_len); 1940 1941 /* Node Sybolic Name */ 1942 eiter = entries + size; 1943 eiter->type = cpu_to_be16(FDMI_HBA_NODE_SYMBOLIC_NAME); 1944 qla2x00_get_sym_node_name(vha, eiter->a.sym_name, 1945 sizeof(eiter->a.sym_name)); 1946 alen = strlen(eiter->a.sym_name); 1947 alen += 4 - (alen & 3); 1948 eiter->len = cpu_to_be16(4 + alen); 1949 size += 4 + alen; 1950 1951 ql_dbg(ql_dbg_disc, vha, 0x20b0, 1952 "Symbolic Name = %s.\n", eiter->a.sym_name); 1953 1954 /* Vendor Id */ 1955 eiter = entries + size; 1956 eiter->type = cpu_to_be16(FDMI_HBA_VENDOR_ID); 1957 eiter->a.vendor_id = cpu_to_be32(0x1077); 1958 eiter->len = cpu_to_be16(4 + 4); 1959 size += 4 + 4; 1960 1961 ql_dbg(ql_dbg_disc, vha, 0x20b1, 1962 "Vendor Id = %x.\n", eiter->a.vendor_id); 1963 1964 /* Num Ports */ 1965 eiter = entries + size; 1966 eiter->type = cpu_to_be16(FDMI_HBA_NUM_PORTS); 1967 eiter->a.num_ports = cpu_to_be32(1); 1968 eiter->len = cpu_to_be16(4 + 4); 1969 size += 4 + 4; 1970 1971 ql_dbg(ql_dbg_disc, vha, 0x20b2, 1972 "Port Num = %x.\n", eiter->a.num_ports); 1973 1974 /* Fabric Name */ 1975 eiter = entries + size; 1976 eiter->type = cpu_to_be16(FDMI_HBA_FABRIC_NAME); 1977 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 1978 eiter->len = cpu_to_be16(4 + WWN_SIZE); 1979 size += 4 + WWN_SIZE; 1980 1981 ql_dbg(ql_dbg_disc, vha, 0x20b3, 1982 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 1983 1984 /* BIOS Version */ 1985 eiter = entries + size; 1986 eiter->type = cpu_to_be16(FDMI_HBA_BOOT_BIOS_NAME); 1987 snprintf(eiter->a.bios_name, sizeof(eiter->a.bios_name), 1988 "BIOS %d.%02d", ha->bios_revision[1], ha->bios_revision[0]); 1989 alen = strlen(eiter->a.bios_name); 1990 alen += 4 - (alen & 3); 1991 eiter->len = cpu_to_be16(4 + alen); 1992 size += 4 + alen; 1993 1994 ql_dbg(ql_dbg_disc, vha, 0x20b4, 1995 "BIOS Name = %s\n", eiter->a.bios_name); 1996 1997 /* Vendor Identifier */ 1998 eiter = entries + size; 1999 eiter->type = cpu_to_be16(FDMI_HBA_TYPE_VENDOR_IDENTIFIER); 2000 snprintf(eiter->a.vendor_identifier, sizeof(eiter->a.vendor_identifier), 2001 "%s", "QLGC"); 2002 alen = strlen(eiter->a.vendor_identifier); 2003 alen += 4 - (alen & 3); 2004 eiter->len = cpu_to_be16(4 + alen); 2005 size += 4 + alen; 2006 2007 ql_dbg(ql_dbg_disc, vha, 0x20b1, 2008 "Vendor Identifier = %s.\n", eiter->a.vendor_identifier); 2009 2010 /* Update MS request size. */ 2011 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2012 2013 ql_dbg(ql_dbg_disc, vha, 0x20b5, 2014 "RHBA identifier = %016llx.\n", 2015 wwn_to_u64(ct_req->req.rhba2.hba_identifier)); 2016 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20b6, 2017 entries, size); 2018 2019 /* Execute MS IOCB */ 2020 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2021 sizeof(ms_iocb_entry_t)); 2022 if (rval != QLA_SUCCESS) { 2023 /*EMPTY*/ 2024 ql_dbg(ql_dbg_disc, vha, 0x20b7, 2025 "RHBA issue IOCB failed (%d).\n", rval); 2026 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RHBA") != 2027 QLA_SUCCESS) { 2028 rval = QLA_FUNCTION_FAILED; 2029 2030 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2031 ct_rsp->header.explanation_code == 2032 CT_EXPL_ALREADY_REGISTERED) { 2033 ql_dbg(ql_dbg_disc, vha, 0x20b8, 2034 "HBA already registered.\n"); 2035 rval = QLA_ALREADY_REGISTERED; 2036 } else { 2037 ql_dbg(ql_dbg_disc, vha, 0x2016, 2038 "RHBA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2039 ct_rsp->header.reason_code, 2040 ct_rsp->header.explanation_code); 2041 } 2042 } else { 2043 ql_dbg(ql_dbg_disc, vha, 0x20b9, 2044 "RHBA FDMI V2 exiting normally.\n"); 2045 } 2046 2047 return rval; 2048 } 2049 2050 /** 2051 * qla2x00_fdmi_dhba() - 2052 * @ha: HA context 2053 * 2054 * Returns 0 on success. 2055 */ 2056 static int 2057 qla2x00_fdmi_dhba(scsi_qla_host_t *vha) 2058 { 2059 int rval; 2060 struct qla_hw_data *ha = vha->hw; 2061 ms_iocb_entry_t *ms_pkt; 2062 struct ct_sns_req *ct_req; 2063 struct ct_sns_rsp *ct_rsp; 2064 2065 /* Issue RPA */ 2066 /* Prepare common MS IOCB */ 2067 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, DHBA_REQ_SIZE, 2068 DHBA_RSP_SIZE); 2069 2070 /* Prepare CT request */ 2071 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, DHBA_CMD, DHBA_RSP_SIZE); 2072 ct_rsp = &ha->ct_sns->p.rsp; 2073 2074 /* Prepare FDMI command arguments -- portname. */ 2075 memcpy(ct_req->req.dhba.port_name, vha->port_name, WWN_SIZE); 2076 2077 ql_dbg(ql_dbg_disc, vha, 0x2036, 2078 "DHBA portname = %8phN.\n", ct_req->req.dhba.port_name); 2079 2080 /* Execute MS IOCB */ 2081 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2082 sizeof(ms_iocb_entry_t)); 2083 if (rval != QLA_SUCCESS) { 2084 /*EMPTY*/ 2085 ql_dbg(ql_dbg_disc, vha, 0x2037, 2086 "DHBA issue IOCB failed (%d).\n", rval); 2087 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "DHBA") != 2088 QLA_SUCCESS) { 2089 rval = QLA_FUNCTION_FAILED; 2090 } else { 2091 ql_dbg(ql_dbg_disc, vha, 0x2038, 2092 "DHBA exiting normally.\n"); 2093 } 2094 2095 return rval; 2096 } 2097 2098 /** 2099 * qla2x00_fdmiv2_rpa() - 2100 * @ha: HA context 2101 * 2102 * Returns 0 on success. 2103 */ 2104 static int 2105 qla2x00_fdmiv2_rpa(scsi_qla_host_t *vha) 2106 { 2107 int rval, alen; 2108 uint32_t size; 2109 struct qla_hw_data *ha = vha->hw; 2110 ms_iocb_entry_t *ms_pkt; 2111 struct ct_sns_req *ct_req; 2112 struct ct_sns_rsp *ct_rsp; 2113 void *entries; 2114 struct ct_fdmiv2_port_attr *eiter; 2115 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 2116 struct new_utsname *p_sysid = NULL; 2117 2118 /* Issue RPA */ 2119 /* Prepare common MS IOCB */ 2120 /* Request size adjusted after CT preparation */ 2121 ms_pkt = ha->isp_ops->prep_ms_fdmi_iocb(vha, 0, RPA_RSP_SIZE); 2122 2123 /* Prepare CT request */ 2124 ct_req = qla2x00_prep_ct_fdmi_req(ha->ct_sns, RPA_CMD, RPA_RSP_SIZE); 2125 ct_rsp = &ha->ct_sns->p.rsp; 2126 2127 /* Prepare FDMI command arguments -- attribute block, attributes. */ 2128 memcpy(ct_req->req.rpa2.port_name, vha->port_name, WWN_SIZE); 2129 size = WWN_SIZE + 4; 2130 2131 /* Attributes */ 2132 ct_req->req.rpa2.attrs.count = cpu_to_be32(FDMIV2_PORT_ATTR_COUNT); 2133 entries = ct_req->req.rpa2.port_name; 2134 2135 /* FC4 types. */ 2136 eiter = entries + size; 2137 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPES); 2138 eiter->len = cpu_to_be16(4 + 32); 2139 eiter->a.fc4_types[2] = 0x01; 2140 size += 4 + 32; 2141 2142 ql_dbg(ql_dbg_disc, vha, 0x20ba, 2143 "FC4_TYPES=%02x %02x.\n", 2144 eiter->a.fc4_types[2], 2145 eiter->a.fc4_types[1]); 2146 2147 /* Supported speed. */ 2148 eiter = entries + size; 2149 eiter->type = cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 2150 eiter->len = cpu_to_be16(4 + 4); 2151 if (IS_CNA_CAPABLE(ha)) 2152 eiter->a.sup_speed = cpu_to_be32( 2153 FDMI_PORT_SPEED_10GB); 2154 else if (IS_QLA27XX(ha)) 2155 eiter->a.sup_speed = cpu_to_be32( 2156 FDMI_PORT_SPEED_32GB| 2157 FDMI_PORT_SPEED_16GB| 2158 FDMI_PORT_SPEED_8GB); 2159 else if (IS_QLA2031(ha)) 2160 eiter->a.sup_speed = cpu_to_be32( 2161 FDMI_PORT_SPEED_16GB| 2162 FDMI_PORT_SPEED_8GB| 2163 FDMI_PORT_SPEED_4GB); 2164 else if (IS_QLA25XX(ha)) 2165 eiter->a.sup_speed = cpu_to_be32( 2166 FDMI_PORT_SPEED_8GB| 2167 FDMI_PORT_SPEED_4GB| 2168 FDMI_PORT_SPEED_2GB| 2169 FDMI_PORT_SPEED_1GB); 2170 else if (IS_QLA24XX_TYPE(ha)) 2171 eiter->a.sup_speed = cpu_to_be32( 2172 FDMI_PORT_SPEED_4GB| 2173 FDMI_PORT_SPEED_2GB| 2174 FDMI_PORT_SPEED_1GB); 2175 else if (IS_QLA23XX(ha)) 2176 eiter->a.sup_speed = cpu_to_be32( 2177 FDMI_PORT_SPEED_2GB| 2178 FDMI_PORT_SPEED_1GB); 2179 else 2180 eiter->a.sup_speed = cpu_to_be32( 2181 FDMI_PORT_SPEED_1GB); 2182 size += 4 + 4; 2183 2184 ql_dbg(ql_dbg_disc, vha, 0x20bb, 2185 "Supported Port Speed = %x.\n", eiter->a.sup_speed); 2186 2187 /* Current speed. */ 2188 eiter = entries + size; 2189 eiter->type = cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 2190 eiter->len = cpu_to_be16(4 + 4); 2191 switch (ha->link_data_rate) { 2192 case PORT_SPEED_1GB: 2193 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_1GB); 2194 break; 2195 case PORT_SPEED_2GB: 2196 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_2GB); 2197 break; 2198 case PORT_SPEED_4GB: 2199 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_4GB); 2200 break; 2201 case PORT_SPEED_8GB: 2202 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_8GB); 2203 break; 2204 case PORT_SPEED_10GB: 2205 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_10GB); 2206 break; 2207 case PORT_SPEED_16GB: 2208 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_16GB); 2209 break; 2210 case PORT_SPEED_32GB: 2211 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_32GB); 2212 break; 2213 default: 2214 eiter->a.cur_speed = cpu_to_be32(FDMI_PORT_SPEED_UNKNOWN); 2215 break; 2216 } 2217 size += 4 + 4; 2218 2219 ql_dbg(ql_dbg_disc, vha, 0x20bc, 2220 "Current_Speed = %x.\n", eiter->a.cur_speed); 2221 2222 /* Max frame size. */ 2223 eiter = entries + size; 2224 eiter->type = cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 2225 eiter->len = cpu_to_be16(4 + 4); 2226 eiter->a.max_frame_size = IS_FWI2_CAPABLE(ha) ? 2227 le16_to_cpu(icb24->frame_payload_size): 2228 le16_to_cpu(ha->init_cb->frame_payload_size); 2229 eiter->a.max_frame_size = cpu_to_be32(eiter->a.max_frame_size); 2230 size += 4 + 4; 2231 2232 ql_dbg(ql_dbg_disc, vha, 0x20bc, 2233 "Max_Frame_Size = %x.\n", eiter->a.max_frame_size); 2234 2235 /* OS device name. */ 2236 eiter = entries + size; 2237 eiter->type = cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 2238 alen = strlen(QLA2XXX_DRIVER_NAME); 2239 snprintf(eiter->a.os_dev_name, sizeof(eiter->a.os_dev_name), 2240 "%s:host%lu", QLA2XXX_DRIVER_NAME, vha->host_no); 2241 alen += 4 - (alen & 3); 2242 eiter->len = cpu_to_be16(4 + alen); 2243 size += 4 + alen; 2244 2245 ql_dbg(ql_dbg_disc, vha, 0x20be, 2246 "OS_Device_Name = %s.\n", eiter->a.os_dev_name); 2247 2248 /* Hostname. */ 2249 eiter = entries + size; 2250 eiter->type = cpu_to_be16(FDMI_PORT_HOST_NAME); 2251 p_sysid = utsname(); 2252 if (p_sysid) { 2253 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2254 "%s", p_sysid->nodename); 2255 } else { 2256 snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), 2257 "%s", fc_host_system_hostname(vha->host)); 2258 } 2259 alen = strlen(eiter->a.host_name); 2260 alen += 4 - (alen & 3); 2261 eiter->len = cpu_to_be16(4 + alen); 2262 size += 4 + alen; 2263 2264 ql_dbg(ql_dbg_disc, vha, 0x203d, 2265 "HostName=%s.\n", eiter->a.host_name); 2266 2267 /* Node Name */ 2268 eiter = entries + size; 2269 eiter->type = cpu_to_be16(FDMI_PORT_NODE_NAME); 2270 memcpy(eiter->a.node_name, vha->node_name, WWN_SIZE); 2271 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2272 size += 4 + WWN_SIZE; 2273 2274 ql_dbg(ql_dbg_disc, vha, 0x20c0, 2275 "Node Name = %016llx.\n", wwn_to_u64(eiter->a.node_name)); 2276 2277 /* Port Name */ 2278 eiter = entries + size; 2279 eiter->type = cpu_to_be16(FDMI_PORT_NAME); 2280 memcpy(eiter->a.port_name, vha->port_name, WWN_SIZE); 2281 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2282 size += 4 + WWN_SIZE; 2283 2284 ql_dbg(ql_dbg_disc, vha, 0x20c1, 2285 "Port Name = %016llx.\n", wwn_to_u64(eiter->a.port_name)); 2286 2287 /* Port Symbolic Name */ 2288 eiter = entries + size; 2289 eiter->type = cpu_to_be16(FDMI_PORT_SYM_NAME); 2290 qla2x00_get_sym_node_name(vha, eiter->a.port_sym_name, 2291 sizeof(eiter->a.port_sym_name)); 2292 alen = strlen(eiter->a.port_sym_name); 2293 alen += 4 - (alen & 3); 2294 eiter->len = cpu_to_be16(4 + alen); 2295 size += 4 + alen; 2296 2297 ql_dbg(ql_dbg_disc, vha, 0x20c2, 2298 "port symbolic name = %s\n", eiter->a.port_sym_name); 2299 2300 /* Port Type */ 2301 eiter = entries + size; 2302 eiter->type = cpu_to_be16(FDMI_PORT_TYPE); 2303 eiter->a.port_type = cpu_to_be32(NS_NX_PORT_TYPE); 2304 eiter->len = cpu_to_be16(4 + 4); 2305 size += 4 + 4; 2306 2307 ql_dbg(ql_dbg_disc, vha, 0x20c3, 2308 "Port Type = %x.\n", eiter->a.port_type); 2309 2310 /* Class of Service */ 2311 eiter = entries + size; 2312 eiter->type = cpu_to_be16(FDMI_PORT_SUPP_COS); 2313 eiter->a.port_supported_cos = cpu_to_be32(FC_CLASS_3); 2314 eiter->len = cpu_to_be16(4 + 4); 2315 size += 4 + 4; 2316 2317 ql_dbg(ql_dbg_disc, vha, 0x20c4, 2318 "Supported COS = %08x\n", eiter->a.port_supported_cos); 2319 2320 /* Port Fabric Name */ 2321 eiter = entries + size; 2322 eiter->type = cpu_to_be16(FDMI_PORT_FABRIC_NAME); 2323 memcpy(eiter->a.fabric_name, vha->fabric_node_name, WWN_SIZE); 2324 eiter->len = cpu_to_be16(4 + WWN_SIZE); 2325 size += 4 + WWN_SIZE; 2326 2327 ql_dbg(ql_dbg_disc, vha, 0x20c5, 2328 "Fabric Name = %016llx.\n", wwn_to_u64(eiter->a.fabric_name)); 2329 2330 /* FC4_type */ 2331 eiter = entries + size; 2332 eiter->type = cpu_to_be16(FDMI_PORT_FC4_TYPE); 2333 eiter->a.port_fc4_type[0] = 0; 2334 eiter->a.port_fc4_type[1] = 0; 2335 eiter->a.port_fc4_type[2] = 1; 2336 eiter->a.port_fc4_type[3] = 0; 2337 eiter->len = cpu_to_be16(4 + 32); 2338 size += 4 + 32; 2339 2340 ql_dbg(ql_dbg_disc, vha, 0x20c6, 2341 "Port Active FC4 Type = %02x %02x.\n", 2342 eiter->a.port_fc4_type[2], eiter->a.port_fc4_type[1]); 2343 2344 /* Port State */ 2345 eiter = entries + size; 2346 eiter->type = cpu_to_be16(FDMI_PORT_STATE); 2347 eiter->a.port_state = cpu_to_be32(1); 2348 eiter->len = cpu_to_be16(4 + 4); 2349 size += 4 + 4; 2350 2351 ql_dbg(ql_dbg_disc, vha, 0x20c7, 2352 "Port State = %x.\n", eiter->a.port_state); 2353 2354 /* Number of Ports */ 2355 eiter = entries + size; 2356 eiter->type = cpu_to_be16(FDMI_PORT_COUNT); 2357 eiter->a.num_ports = cpu_to_be32(1); 2358 eiter->len = cpu_to_be16(4 + 4); 2359 size += 4 + 4; 2360 2361 ql_dbg(ql_dbg_disc, vha, 0x20c8, 2362 "Number of ports = %x.\n", eiter->a.num_ports); 2363 2364 /* Port Id */ 2365 eiter = entries + size; 2366 eiter->type = cpu_to_be16(FDMI_PORT_ID); 2367 eiter->a.port_id = cpu_to_be32(vha->d_id.b24); 2368 eiter->len = cpu_to_be16(4 + 4); 2369 size += 4 + 4; 2370 2371 ql_dbg(ql_dbg_disc, vha, 0x20c8, 2372 "Port Id = %x.\n", eiter->a.port_id); 2373 2374 /* Update MS request size. */ 2375 qla2x00_update_ms_fdmi_iocb(vha, size + 16); 2376 2377 ql_dbg(ql_dbg_disc, vha, 0x203e, 2378 "RPA portname= %8phN size=%d.\n", ct_req->req.rpa.port_name, size); 2379 ql_dump_buffer(ql_dbg_disc + ql_dbg_buffer, vha, 0x20ca, 2380 entries, size); 2381 2382 /* Execute MS IOCB */ 2383 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2384 sizeof(ms_iocb_entry_t)); 2385 if (rval != QLA_SUCCESS) { 2386 /*EMPTY*/ 2387 ql_dbg(ql_dbg_disc, vha, 0x20cb, 2388 "RPA FDMI v2 issue IOCB failed (%d).\n", rval); 2389 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, "RPA") != 2390 QLA_SUCCESS) { 2391 rval = QLA_FUNCTION_FAILED; 2392 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 2393 ct_rsp->header.explanation_code == 2394 CT_EXPL_ALREADY_REGISTERED) { 2395 ql_dbg(ql_dbg_disc, vha, 0x20ce, 2396 "RPA FDMI v2 already registered\n"); 2397 rval = QLA_ALREADY_REGISTERED; 2398 } else { 2399 ql_dbg(ql_dbg_disc, vha, 0x2020, 2400 "RPA FDMI v2 failed, CT Reason code: 0x%x, CT Explanation 0x%x\n", 2401 ct_rsp->header.reason_code, 2402 ct_rsp->header.explanation_code); 2403 } 2404 } else { 2405 ql_dbg(ql_dbg_disc, vha, 0x20cc, 2406 "RPA FDMI V2 exiting normally.\n"); 2407 } 2408 2409 return rval; 2410 } 2411 2412 /** 2413 * qla2x00_fdmi_register() - 2414 * @ha: HA context 2415 * 2416 * Returns 0 on success. 2417 */ 2418 int 2419 qla2x00_fdmi_register(scsi_qla_host_t *vha) 2420 { 2421 int rval = QLA_FUNCTION_FAILED; 2422 struct qla_hw_data *ha = vha->hw; 2423 2424 if (IS_QLA2100(ha) || IS_QLA2200(ha) || 2425 IS_QLAFX00(ha)) 2426 return QLA_FUNCTION_FAILED; 2427 2428 rval = qla2x00_mgmt_svr_login(vha); 2429 if (rval) 2430 return rval; 2431 2432 rval = qla2x00_fdmiv2_rhba(vha); 2433 if (rval) { 2434 if (rval != QLA_ALREADY_REGISTERED) 2435 goto try_fdmi; 2436 2437 rval = qla2x00_fdmi_dhba(vha); 2438 if (rval) 2439 goto try_fdmi; 2440 2441 rval = qla2x00_fdmiv2_rhba(vha); 2442 if (rval) 2443 goto try_fdmi; 2444 } 2445 rval = qla2x00_fdmiv2_rpa(vha); 2446 if (rval) 2447 goto try_fdmi; 2448 2449 goto out; 2450 2451 try_fdmi: 2452 rval = qla2x00_fdmi_rhba(vha); 2453 if (rval) { 2454 if (rval != QLA_ALREADY_REGISTERED) 2455 return rval; 2456 2457 rval = qla2x00_fdmi_dhba(vha); 2458 if (rval) 2459 return rval; 2460 2461 rval = qla2x00_fdmi_rhba(vha); 2462 if (rval) 2463 return rval; 2464 } 2465 rval = qla2x00_fdmi_rpa(vha); 2466 out: 2467 return rval; 2468 } 2469 2470 /** 2471 * qla2x00_gfpn_id() - SNS Get Fabric Port Name (GFPN_ID) query. 2472 * @ha: HA context 2473 * @list: switch info entries to populate 2474 * 2475 * Returns 0 on success. 2476 */ 2477 int 2478 qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list) 2479 { 2480 int rval = QLA_SUCCESS; 2481 uint16_t i; 2482 struct qla_hw_data *ha = vha->hw; 2483 ms_iocb_entry_t *ms_pkt; 2484 struct ct_sns_req *ct_req; 2485 struct ct_sns_rsp *ct_rsp; 2486 struct ct_arg arg; 2487 2488 if (!IS_IIDMA_CAPABLE(ha)) 2489 return QLA_FUNCTION_FAILED; 2490 2491 arg.iocb = ha->ms_iocb; 2492 arg.req_dma = ha->ct_sns_dma; 2493 arg.rsp_dma = ha->ct_sns_dma; 2494 arg.req_size = GFPN_ID_REQ_SIZE; 2495 arg.rsp_size = GFPN_ID_RSP_SIZE; 2496 arg.nport_handle = NPH_SNS; 2497 2498 for (i = 0; i < ha->max_fibre_devices; i++) { 2499 /* Issue GFPN_ID */ 2500 /* Prepare common MS IOCB */ 2501 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2502 2503 /* Prepare CT request */ 2504 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFPN_ID_CMD, 2505 GFPN_ID_RSP_SIZE); 2506 ct_rsp = &ha->ct_sns->p.rsp; 2507 2508 /* Prepare CT arguments -- port_id */ 2509 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2510 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2511 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2512 2513 /* Execute MS IOCB */ 2514 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2515 sizeof(ms_iocb_entry_t)); 2516 if (rval != QLA_SUCCESS) { 2517 /*EMPTY*/ 2518 ql_dbg(ql_dbg_disc, vha, 0x2023, 2519 "GFPN_ID issue IOCB failed (%d).\n", rval); 2520 break; 2521 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2522 "GFPN_ID") != QLA_SUCCESS) { 2523 rval = QLA_FUNCTION_FAILED; 2524 break; 2525 } else { 2526 /* Save fabric portname */ 2527 memcpy(list[i].fabric_port_name, 2528 ct_rsp->rsp.gfpn_id.port_name, WWN_SIZE); 2529 } 2530 2531 /* Last device exit. */ 2532 if (list[i].d_id.b.rsvd_1 != 0) 2533 break; 2534 } 2535 2536 return (rval); 2537 } 2538 2539 2540 static inline struct ct_sns_req * 2541 qla24xx_prep_ct_fm_req(struct ct_sns_pkt *p, uint16_t cmd, 2542 uint16_t rsp_size) 2543 { 2544 memset(p, 0, sizeof(struct ct_sns_pkt)); 2545 2546 p->p.req.header.revision = 0x01; 2547 p->p.req.header.gs_type = 0xFA; 2548 p->p.req.header.gs_subtype = 0x01; 2549 p->p.req.command = cpu_to_be16(cmd); 2550 p->p.req.max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 2551 2552 return &p->p.req; 2553 } 2554 2555 /** 2556 * qla2x00_gpsc() - FCS Get Port Speed Capabilities (GPSC) query. 2557 * @ha: HA context 2558 * @list: switch info entries to populate 2559 * 2560 * Returns 0 on success. 2561 */ 2562 int 2563 qla2x00_gpsc(scsi_qla_host_t *vha, sw_info_t *list) 2564 { 2565 int rval; 2566 uint16_t i; 2567 struct qla_hw_data *ha = vha->hw; 2568 ms_iocb_entry_t *ms_pkt; 2569 struct ct_sns_req *ct_req; 2570 struct ct_sns_rsp *ct_rsp; 2571 struct ct_arg arg; 2572 2573 if (!IS_IIDMA_CAPABLE(ha)) 2574 return QLA_FUNCTION_FAILED; 2575 if (!ha->flags.gpsc_supported) 2576 return QLA_FUNCTION_FAILED; 2577 2578 rval = qla2x00_mgmt_svr_login(vha); 2579 if (rval) 2580 return rval; 2581 2582 arg.iocb = ha->ms_iocb; 2583 arg.req_dma = ha->ct_sns_dma; 2584 arg.rsp_dma = ha->ct_sns_dma; 2585 arg.req_size = GPSC_REQ_SIZE; 2586 arg.rsp_size = GPSC_RSP_SIZE; 2587 arg.nport_handle = vha->mgmt_svr_loop_id; 2588 2589 for (i = 0; i < ha->max_fibre_devices; i++) { 2590 /* Issue GFPN_ID */ 2591 /* Prepare common MS IOCB */ 2592 ms_pkt = qla24xx_prep_ms_iocb(vha, &arg); 2593 2594 /* Prepare CT request */ 2595 ct_req = qla24xx_prep_ct_fm_req(ha->ct_sns, GPSC_CMD, 2596 GPSC_RSP_SIZE); 2597 ct_rsp = &ha->ct_sns->p.rsp; 2598 2599 /* Prepare CT arguments -- port_name */ 2600 memcpy(ct_req->req.gpsc.port_name, list[i].fabric_port_name, 2601 WWN_SIZE); 2602 2603 /* Execute MS IOCB */ 2604 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2605 sizeof(ms_iocb_entry_t)); 2606 if (rval != QLA_SUCCESS) { 2607 /*EMPTY*/ 2608 ql_dbg(ql_dbg_disc, vha, 0x2059, 2609 "GPSC issue IOCB failed (%d).\n", rval); 2610 } else if ((rval = qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2611 "GPSC")) != QLA_SUCCESS) { 2612 /* FM command unsupported? */ 2613 if (rval == QLA_INVALID_COMMAND && 2614 (ct_rsp->header.reason_code == 2615 CT_REASON_INVALID_COMMAND_CODE || 2616 ct_rsp->header.reason_code == 2617 CT_REASON_COMMAND_UNSUPPORTED)) { 2618 ql_dbg(ql_dbg_disc, vha, 0x205a, 2619 "GPSC command unsupported, disabling " 2620 "query.\n"); 2621 ha->flags.gpsc_supported = 0; 2622 rval = QLA_FUNCTION_FAILED; 2623 break; 2624 } 2625 rval = QLA_FUNCTION_FAILED; 2626 } else { 2627 /* Save port-speed */ 2628 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 2629 case BIT_15: 2630 list[i].fp_speed = PORT_SPEED_1GB; 2631 break; 2632 case BIT_14: 2633 list[i].fp_speed = PORT_SPEED_2GB; 2634 break; 2635 case BIT_13: 2636 list[i].fp_speed = PORT_SPEED_4GB; 2637 break; 2638 case BIT_12: 2639 list[i].fp_speed = PORT_SPEED_10GB; 2640 break; 2641 case BIT_11: 2642 list[i].fp_speed = PORT_SPEED_8GB; 2643 break; 2644 case BIT_10: 2645 list[i].fp_speed = PORT_SPEED_16GB; 2646 break; 2647 case BIT_8: 2648 list[i].fp_speed = PORT_SPEED_32GB; 2649 break; 2650 } 2651 2652 ql_dbg(ql_dbg_disc, vha, 0x205b, 2653 "GPSC ext entry - fpn " 2654 "%8phN speeds=%04x speed=%04x.\n", 2655 list[i].fabric_port_name, 2656 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 2657 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 2658 } 2659 2660 /* Last device exit. */ 2661 if (list[i].d_id.b.rsvd_1 != 0) 2662 break; 2663 } 2664 2665 return (rval); 2666 } 2667 2668 /** 2669 * qla2x00_gff_id() - SNS Get FC-4 Features (GFF_ID) query. 2670 * 2671 * @ha: HA context 2672 * @list: switch info entries to populate 2673 * 2674 */ 2675 void 2676 qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list) 2677 { 2678 int rval; 2679 uint16_t i; 2680 2681 ms_iocb_entry_t *ms_pkt; 2682 struct ct_sns_req *ct_req; 2683 struct ct_sns_rsp *ct_rsp; 2684 struct qla_hw_data *ha = vha->hw; 2685 uint8_t fcp_scsi_features = 0; 2686 struct ct_arg arg; 2687 2688 for (i = 0; i < ha->max_fibre_devices; i++) { 2689 /* Set default FC4 Type as UNKNOWN so the default is to 2690 * Process this port */ 2691 list[i].fc4_type = FC4_TYPE_UNKNOWN; 2692 2693 /* Do not attempt GFF_ID if we are not FWI_2 capable */ 2694 if (!IS_FWI2_CAPABLE(ha)) 2695 continue; 2696 2697 arg.iocb = ha->ms_iocb; 2698 arg.req_dma = ha->ct_sns_dma; 2699 arg.rsp_dma = ha->ct_sns_dma; 2700 arg.req_size = GFF_ID_REQ_SIZE; 2701 arg.rsp_size = GFF_ID_RSP_SIZE; 2702 arg.nport_handle = NPH_SNS; 2703 2704 /* Prepare common MS IOCB */ 2705 ms_pkt = ha->isp_ops->prep_ms_iocb(vha, &arg); 2706 2707 /* Prepare CT request */ 2708 ct_req = qla2x00_prep_ct_req(ha->ct_sns, GFF_ID_CMD, 2709 GFF_ID_RSP_SIZE); 2710 ct_rsp = &ha->ct_sns->p.rsp; 2711 2712 /* Prepare CT arguments -- port_id */ 2713 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 2714 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 2715 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 2716 2717 /* Execute MS IOCB */ 2718 rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma, 2719 sizeof(ms_iocb_entry_t)); 2720 2721 if (rval != QLA_SUCCESS) { 2722 ql_dbg(ql_dbg_disc, vha, 0x205c, 2723 "GFF_ID issue IOCB failed (%d).\n", rval); 2724 } else if (qla2x00_chk_ms_status(vha, ms_pkt, ct_rsp, 2725 "GFF_ID") != QLA_SUCCESS) { 2726 ql_dbg(ql_dbg_disc, vha, 0x205d, 2727 "GFF_ID IOCB status had a failure status code.\n"); 2728 } else { 2729 fcp_scsi_features = 2730 ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET]; 2731 fcp_scsi_features &= 0x0f; 2732 2733 if (fcp_scsi_features) 2734 list[i].fc4_type = FC4_TYPE_FCP_SCSI; 2735 else 2736 list[i].fc4_type = FC4_TYPE_OTHER; 2737 } 2738 2739 /* Last device exit. */ 2740 if (list[i].d_id.b.rsvd_1 != 0) 2741 break; 2742 } 2743 } 2744 2745 /* GID_PN completion processing. */ 2746 void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) 2747 { 2748 fc_port_t *fcport = ea->fcport; 2749 2750 ql_dbg(ql_dbg_disc, vha, 0xffff, 2751 "%s %8phC login state %d \n", 2752 __func__, fcport->port_name, fcport->fw_login_state); 2753 2754 if (ea->sp->gen2 != fcport->login_gen) { 2755 /* PLOGI/PRLI/LOGO came in while cmd was out.*/ 2756 ql_dbg(ql_dbg_disc, vha, 0xffff, 2757 "%s %8phC generation changed rscn %d|%d login %d|%d \n", 2758 __func__, fcport->port_name, fcport->last_rscn_gen, 2759 fcport->rscn_gen, fcport->last_login_gen, fcport->login_gen); 2760 return; 2761 } 2762 2763 if (!ea->rc) { 2764 if (ea->sp->gen1 == fcport->rscn_gen) { 2765 fcport->scan_state = QLA_FCPORT_FOUND; 2766 fcport->flags |= FCF_FABRIC_DEVICE; 2767 2768 if (fcport->d_id.b24 == ea->id.b24) { 2769 /* cable plugged into the same place */ 2770 switch (vha->host->active_mode) { 2771 case MODE_TARGET: 2772 /* NOOP. let the other guy login to us.*/ 2773 break; 2774 case MODE_INITIATOR: 2775 case MODE_DUAL: 2776 default: 2777 if (atomic_read(&fcport->state) == 2778 FCS_ONLINE) 2779 break; 2780 ql_dbg(ql_dbg_disc, vha, 0xffff, 2781 "%s %d %8phC post gnl\n", 2782 __func__, __LINE__, fcport->port_name); 2783 qla24xx_post_gnl_work(vha, fcport); 2784 break; 2785 } 2786 } else { /* fcport->d_id.b24 != ea->id.b24 */ 2787 fcport->d_id.b24 = ea->id.b24; 2788 if (fcport->deleted == QLA_SESS_DELETED) { 2789 ql_dbg(ql_dbg_disc, vha, 0xffff, 2790 "%s %d %8phC post del sess\n", 2791 __func__, __LINE__, fcport->port_name); 2792 qlt_schedule_sess_for_deletion_lock(fcport); 2793 } 2794 } 2795 } else { /* ea->sp->gen1 != fcport->rscn_gen */ 2796 ql_dbg(ql_dbg_disc, vha, 0xffff, 2797 "%s %d %8phC post gidpn\n", 2798 __func__, __LINE__, fcport->port_name); 2799 /* rscn came in while cmd was out */ 2800 qla24xx_post_gidpn_work(vha, fcport); 2801 } 2802 } else { /* ea->rc */ 2803 /* cable pulled */ 2804 if (ea->sp->gen1 == fcport->rscn_gen) { 2805 if (ea->sp->gen2 == fcport->login_gen) { 2806 ql_dbg(ql_dbg_disc, vha, 0xffff, 2807 "%s %d %8phC post del sess\n", __func__, 2808 __LINE__, fcport->port_name); 2809 qlt_schedule_sess_for_deletion_lock(fcport); 2810 } else { 2811 ql_dbg(ql_dbg_disc, vha, 0xffff, 2812 "%s %d %8phC login\n", __func__, __LINE__, 2813 fcport->port_name); 2814 qla24xx_fcport_handle_login(vha, fcport); 2815 } 2816 } else { 2817 ql_dbg(ql_dbg_disc, vha, 0xffff, 2818 "%s %d %8phC post gidpn\n", __func__, __LINE__, 2819 fcport->port_name); 2820 qla24xx_post_gidpn_work(vha, fcport); 2821 } 2822 } 2823 } /* gidpn_event */ 2824 2825 static void qla2x00_async_gidpn_sp_done(void *s, int res) 2826 { 2827 struct srb *sp = s; 2828 struct scsi_qla_host *vha = sp->vha; 2829 fc_port_t *fcport = sp->fcport; 2830 u8 *id = fcport->ct_desc.ct_sns->p.rsp.rsp.gid_pn.port_id; 2831 struct event_arg ea; 2832 2833 fcport->flags &= ~FCF_ASYNC_SENT; 2834 2835 memset(&ea, 0, sizeof(ea)); 2836 ea.fcport = fcport; 2837 ea.id.b.domain = id[0]; 2838 ea.id.b.area = id[1]; 2839 ea.id.b.al_pa = id[2]; 2840 ea.sp = sp; 2841 ea.rc = res; 2842 ea.event = FCME_GIDPN_DONE; 2843 2844 ql_dbg(ql_dbg_disc, vha, 0xffff, 2845 "Async done-%s res %x, WWPN %8phC ID %3phC \n", 2846 sp->name, res, fcport->port_name, id); 2847 2848 qla2x00_fcport_event_handler(vha, &ea); 2849 2850 sp->free(sp); 2851 } 2852 2853 int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport) 2854 { 2855 int rval = QLA_FUNCTION_FAILED; 2856 struct ct_sns_req *ct_req; 2857 srb_t *sp; 2858 2859 if (!vha->flags.online) 2860 goto done; 2861 2862 fcport->flags |= FCF_ASYNC_SENT; 2863 fcport->disc_state = DSC_GID_PN; 2864 fcport->scan_state = QLA_FCPORT_SCAN; 2865 sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC); 2866 if (!sp) 2867 goto done; 2868 2869 sp->type = SRB_CT_PTHRU_CMD; 2870 sp->name = "gidpn"; 2871 sp->gen1 = fcport->rscn_gen; 2872 sp->gen2 = fcport->login_gen; 2873 2874 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 2875 2876 /* CT_IU preamble */ 2877 ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GID_PN_CMD, 2878 GID_PN_RSP_SIZE); 2879 2880 /* GIDPN req */ 2881 memcpy(ct_req->req.gid_pn.port_name, fcport->port_name, 2882 WWN_SIZE); 2883 2884 /* req & rsp use the same buffer */ 2885 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 2886 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 2887 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 2888 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 2889 sp->u.iocb_cmd.u.ctarg.req_size = GID_PN_REQ_SIZE; 2890 sp->u.iocb_cmd.u.ctarg.rsp_size = GID_PN_RSP_SIZE; 2891 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 2892 2893 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 2894 sp->done = qla2x00_async_gidpn_sp_done; 2895 2896 rval = qla2x00_start_sp(sp); 2897 if (rval != QLA_SUCCESS) 2898 goto done_free_sp; 2899 2900 ql_dbg(ql_dbg_disc, vha, 0x206f, 2901 "Async-%s - %8phC hdl=%x loopid=%x portid %02x%02x%02x.\n", 2902 sp->name, fcport->port_name, 2903 sp->handle, fcport->loop_id, fcport->d_id.b.domain, 2904 fcport->d_id.b.area, fcport->d_id.b.al_pa); 2905 return rval; 2906 2907 done_free_sp: 2908 sp->free(sp); 2909 done: 2910 fcport->flags &= ~FCF_ASYNC_SENT; 2911 return rval; 2912 } 2913 2914 int qla24xx_post_gidpn_work(struct scsi_qla_host *vha, fc_port_t *fcport) 2915 { 2916 struct qla_work_evt *e; 2917 int ls; 2918 2919 ls = atomic_read(&vha->loop_state); 2920 if (((ls != LOOP_READY) && (ls != LOOP_UP)) || 2921 test_bit(UNLOADING, &vha->dpc_flags)) 2922 return 0; 2923 2924 e = qla2x00_alloc_work(vha, QLA_EVT_GIDPN); 2925 if (!e) 2926 return QLA_FUNCTION_FAILED; 2927 2928 e->u.fcport.fcport = fcport; 2929 return qla2x00_post_work(vha, e); 2930 } 2931 2932 int qla24xx_post_gpsc_work(struct scsi_qla_host *vha, fc_port_t *fcport) 2933 { 2934 struct qla_work_evt *e; 2935 2936 e = qla2x00_alloc_work(vha, QLA_EVT_GPSC); 2937 if (!e) 2938 return QLA_FUNCTION_FAILED; 2939 2940 e->u.fcport.fcport = fcport; 2941 return qla2x00_post_work(vha, e); 2942 } 2943 2944 static void qla24xx_async_gpsc_sp_done(void *s, int res) 2945 { 2946 struct srb *sp = s; 2947 struct scsi_qla_host *vha = sp->vha; 2948 struct qla_hw_data *ha = vha->hw; 2949 fc_port_t *fcport = sp->fcport; 2950 struct ct_sns_rsp *ct_rsp; 2951 struct event_arg ea; 2952 2953 ct_rsp = &fcport->ct_desc.ct_sns->p.rsp; 2954 2955 ql_dbg(ql_dbg_disc, vha, 0xffff, 2956 "Async done-%s res %x, WWPN %8phC \n", 2957 sp->name, res, fcport->port_name); 2958 2959 fcport->flags &= ~FCF_ASYNC_SENT; 2960 2961 if (res == (DID_ERROR << 16)) { 2962 /* entry status error */ 2963 goto done; 2964 } else if (res) { 2965 if ((ct_rsp->header.reason_code == 2966 CT_REASON_INVALID_COMMAND_CODE) || 2967 (ct_rsp->header.reason_code == 2968 CT_REASON_COMMAND_UNSUPPORTED)) { 2969 ql_dbg(ql_dbg_disc, vha, 0x205a, 2970 "GPSC command unsupported, disabling " 2971 "query.\n"); 2972 ha->flags.gpsc_supported = 0; 2973 res = QLA_SUCCESS; 2974 } 2975 } else { 2976 switch (be16_to_cpu(ct_rsp->rsp.gpsc.speed)) { 2977 case BIT_15: 2978 fcport->fp_speed = PORT_SPEED_1GB; 2979 break; 2980 case BIT_14: 2981 fcport->fp_speed = PORT_SPEED_2GB; 2982 break; 2983 case BIT_13: 2984 fcport->fp_speed = PORT_SPEED_4GB; 2985 break; 2986 case BIT_12: 2987 fcport->fp_speed = PORT_SPEED_10GB; 2988 break; 2989 case BIT_11: 2990 fcport->fp_speed = PORT_SPEED_8GB; 2991 break; 2992 case BIT_10: 2993 fcport->fp_speed = PORT_SPEED_16GB; 2994 break; 2995 case BIT_8: 2996 fcport->fp_speed = PORT_SPEED_32GB; 2997 break; 2998 } 2999 3000 ql_dbg(ql_dbg_disc, vha, 0xffff, 3001 "Async-%s OUT WWPN %8phC speeds=%04x speed=%04x.\n", 3002 sp->name, 3003 fcport->fabric_port_name, 3004 be16_to_cpu(ct_rsp->rsp.gpsc.speeds), 3005 be16_to_cpu(ct_rsp->rsp.gpsc.speed)); 3006 } 3007 done: 3008 memset(&ea, 0, sizeof(ea)); 3009 ea.event = FCME_GPSC_DONE; 3010 ea.rc = res; 3011 ea.fcport = fcport; 3012 qla2x00_fcport_event_handler(vha, &ea); 3013 3014 sp->free(sp); 3015 } 3016 3017 int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport) 3018 { 3019 int rval = QLA_FUNCTION_FAILED; 3020 struct ct_sns_req *ct_req; 3021 srb_t *sp; 3022 3023 if (!vha->flags.online) 3024 goto done; 3025 3026 fcport->flags |= FCF_ASYNC_SENT; 3027 sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL); 3028 if (!sp) 3029 goto done; 3030 3031 sp->type = SRB_CT_PTHRU_CMD; 3032 sp->name = "gpsc"; 3033 sp->gen1 = fcport->rscn_gen; 3034 sp->gen2 = fcport->login_gen; 3035 3036 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3037 3038 /* CT_IU preamble */ 3039 ct_req = qla24xx_prep_ct_fm_req(fcport->ct_desc.ct_sns, GPSC_CMD, 3040 GPSC_RSP_SIZE); 3041 3042 /* GPSC req */ 3043 memcpy(ct_req->req.gpsc.port_name, fcport->port_name, 3044 WWN_SIZE); 3045 3046 sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns; 3047 sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma; 3048 sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns; 3049 sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma; 3050 sp->u.iocb_cmd.u.ctarg.req_size = GPSC_REQ_SIZE; 3051 sp->u.iocb_cmd.u.ctarg.rsp_size = GPSC_RSP_SIZE; 3052 sp->u.iocb_cmd.u.ctarg.nport_handle = vha->mgmt_svr_loop_id; 3053 3054 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3055 sp->done = qla24xx_async_gpsc_sp_done; 3056 3057 rval = qla2x00_start_sp(sp); 3058 if (rval != QLA_SUCCESS) 3059 goto done_free_sp; 3060 3061 ql_dbg(ql_dbg_disc, vha, 0xffff, 3062 "Async-%s %8phC hdl=%x loopid=%x portid=%02x%02x%02x.\n", 3063 sp->name, fcport->port_name, sp->handle, 3064 fcport->loop_id, fcport->d_id.b.domain, 3065 fcport->d_id.b.area, fcport->d_id.b.al_pa); 3066 return rval; 3067 3068 done_free_sp: 3069 sp->free(sp); 3070 done: 3071 fcport->flags &= ~FCF_ASYNC_SENT; 3072 return rval; 3073 } 3074 3075 int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id) 3076 { 3077 struct qla_work_evt *e; 3078 3079 if (test_bit(UNLOADING, &vha->dpc_flags)) 3080 return 0; 3081 3082 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID); 3083 if (!e) 3084 return QLA_FUNCTION_FAILED; 3085 3086 e->u.gpnid.id = *id; 3087 return qla2x00_post_work(vha, e); 3088 } 3089 3090 void qla24xx_async_gpnid_done(scsi_qla_host_t *vha, srb_t *sp) 3091 { 3092 if (sp->u.iocb_cmd.u.ctarg.req) { 3093 dma_free_coherent(&vha->hw->pdev->dev, 3094 sizeof(struct ct_sns_pkt), 3095 sp->u.iocb_cmd.u.ctarg.req, 3096 sp->u.iocb_cmd.u.ctarg.req_dma); 3097 sp->u.iocb_cmd.u.ctarg.req = NULL; 3098 } 3099 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3100 dma_free_coherent(&vha->hw->pdev->dev, 3101 sizeof(struct ct_sns_pkt), 3102 sp->u.iocb_cmd.u.ctarg.rsp, 3103 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3104 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3105 } 3106 3107 sp->free(sp); 3108 } 3109 3110 void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea) 3111 { 3112 fc_port_t *fcport; 3113 unsigned long flags; 3114 3115 spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); 3116 fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1); 3117 spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); 3118 3119 if (fcport) { 3120 /* cable moved. just plugged in */ 3121 ql_dbg(ql_dbg_disc, vha, 0xffff, 3122 "%s %d %8phC post del sess\n", 3123 __func__, __LINE__, fcport->port_name); 3124 3125 fcport->rscn_gen++; 3126 fcport->d_id = ea->id; 3127 fcport->scan_state = QLA_FCPORT_FOUND; 3128 fcport->flags |= FCF_FABRIC_DEVICE; 3129 3130 qlt_schedule_sess_for_deletion_lock(fcport); 3131 } else { 3132 /* create new fcport */ 3133 ql_dbg(ql_dbg_disc, vha, 0xffff, 3134 "%s %d %8phC post new sess\n", 3135 __func__, __LINE__, ea->port_name); 3136 3137 qla24xx_post_newsess_work(vha, &ea->id, ea->port_name, NULL); 3138 } 3139 } 3140 3141 static void qla2x00_async_gpnid_sp_done(void *s, int res) 3142 { 3143 struct srb *sp = s; 3144 struct scsi_qla_host *vha = sp->vha; 3145 struct ct_sns_req *ct_req = 3146 (struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req; 3147 struct ct_sns_rsp *ct_rsp = 3148 (struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp; 3149 struct event_arg ea; 3150 struct qla_work_evt *e; 3151 3152 ql_dbg(ql_dbg_disc, vha, 0xffff, 3153 "Async done-%s res %x ID %3phC. %8phC\n", 3154 sp->name, res, ct_req->req.port_id.port_id, 3155 ct_rsp->rsp.gpn_id.port_name); 3156 3157 memset(&ea, 0, sizeof(ea)); 3158 memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 3159 ea.sp = sp; 3160 ea.id.b.domain = ct_req->req.port_id.port_id[0]; 3161 ea.id.b.area = ct_req->req.port_id.port_id[1]; 3162 ea.id.b.al_pa = ct_req->req.port_id.port_id[2]; 3163 ea.rc = res; 3164 ea.event = FCME_GPNID_DONE; 3165 3166 qla2x00_fcport_event_handler(vha, &ea); 3167 3168 e = qla2x00_alloc_work(vha, QLA_EVT_GPNID_DONE); 3169 if (!e) { 3170 /* please ignore kernel warning. otherwise, we have mem leak. */ 3171 if (sp->u.iocb_cmd.u.ctarg.req) { 3172 dma_free_coherent(&vha->hw->pdev->dev, 3173 sizeof(struct ct_sns_pkt), 3174 sp->u.iocb_cmd.u.ctarg.req, 3175 sp->u.iocb_cmd.u.ctarg.req_dma); 3176 sp->u.iocb_cmd.u.ctarg.req = NULL; 3177 } 3178 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3179 dma_free_coherent(&vha->hw->pdev->dev, 3180 sizeof(struct ct_sns_pkt), 3181 sp->u.iocb_cmd.u.ctarg.rsp, 3182 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3183 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3184 } 3185 3186 sp->free(sp); 3187 return; 3188 } 3189 3190 e->u.iosb.sp = sp; 3191 qla2x00_post_work(vha, e); 3192 } 3193 3194 /* Get WWPN with Nport ID. */ 3195 int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id) 3196 { 3197 int rval = QLA_FUNCTION_FAILED; 3198 struct ct_sns_req *ct_req; 3199 srb_t *sp; 3200 struct ct_sns_pkt *ct_sns; 3201 3202 if (!vha->flags.online) 3203 goto done; 3204 3205 sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL); 3206 if (!sp) 3207 goto done; 3208 3209 sp->type = SRB_CT_PTHRU_CMD; 3210 sp->name = "gpnid"; 3211 qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2); 3212 3213 sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev, 3214 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma, 3215 GFP_KERNEL); 3216 if (!sp->u.iocb_cmd.u.ctarg.req) { 3217 ql_log(ql_log_warn, vha, 0xffff, 3218 "Failed to allocate ct_sns request.\n"); 3219 goto done_free_sp; 3220 } 3221 3222 sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev, 3223 sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma, 3224 GFP_KERNEL); 3225 if (!sp->u.iocb_cmd.u.ctarg.rsp) { 3226 ql_log(ql_log_warn, vha, 0xffff, 3227 "Failed to allocate ct_sns request.\n"); 3228 goto done_free_sp; 3229 } 3230 3231 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp; 3232 memset(ct_sns, 0, sizeof(*ct_sns)); 3233 3234 ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req; 3235 /* CT_IU preamble */ 3236 ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE); 3237 3238 /* GPN_ID req */ 3239 ct_req->req.port_id.port_id[0] = id->b.domain; 3240 ct_req->req.port_id.port_id[1] = id->b.area; 3241 ct_req->req.port_id.port_id[2] = id->b.al_pa; 3242 3243 sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE; 3244 sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE; 3245 sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS; 3246 3247 sp->u.iocb_cmd.timeout = qla2x00_async_iocb_timeout; 3248 sp->done = qla2x00_async_gpnid_sp_done; 3249 3250 rval = qla2x00_start_sp(sp); 3251 if (rval != QLA_SUCCESS) 3252 goto done_free_sp; 3253 3254 ql_dbg(ql_dbg_disc, vha, 0xffff, 3255 "Async-%s hdl=%x ID %3phC.\n", sp->name, 3256 sp->handle, ct_req->req.port_id.port_id); 3257 return rval; 3258 3259 done_free_sp: 3260 if (sp->u.iocb_cmd.u.ctarg.req) { 3261 dma_free_coherent(&vha->hw->pdev->dev, 3262 sizeof(struct ct_sns_pkt), 3263 sp->u.iocb_cmd.u.ctarg.req, 3264 sp->u.iocb_cmd.u.ctarg.req_dma); 3265 sp->u.iocb_cmd.u.ctarg.req = NULL; 3266 } 3267 if (sp->u.iocb_cmd.u.ctarg.rsp) { 3268 dma_free_coherent(&vha->hw->pdev->dev, 3269 sizeof(struct ct_sns_pkt), 3270 sp->u.iocb_cmd.u.ctarg.rsp, 3271 sp->u.iocb_cmd.u.ctarg.rsp_dma); 3272 sp->u.iocb_cmd.u.ctarg.rsp = NULL; 3273 } 3274 3275 sp->free(sp); 3276 done: 3277 return rval; 3278 } 3279