1 /* 2 * QLogic Fibre Channel HBA Driver 3 * Copyright (c) 2003-2005 QLogic Corporation 4 * 5 * See LICENSE.qla2xxx for copyright and licensing details. 6 */ 7 #include "qla_def.h" 8 9 static inline struct ct_sns_req * 10 qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t); 11 12 static inline struct sns_cmd_pkt * 13 qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); 14 15 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); 16 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); 17 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); 18 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *); 19 static int qla2x00_sns_rft_id(scsi_qla_host_t *); 20 static int qla2x00_sns_rnn_id(scsi_qla_host_t *); 21 22 /** 23 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. 24 * @ha: HA context 25 * @req_size: request size in bytes 26 * @rsp_size: response size in bytes 27 * 28 * Returns a pointer to the @ha's ms_iocb. 29 */ 30 void * 31 qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) 32 { 33 ms_iocb_entry_t *ms_pkt; 34 35 ms_pkt = ha->ms_iocb; 36 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 37 38 ms_pkt->entry_type = MS_IOCB_TYPE; 39 ms_pkt->entry_count = 1; 40 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); 41 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); 42 ms_pkt->timeout = __constant_cpu_to_le16(25); 43 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 44 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); 45 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 46 ms_pkt->req_bytecount = cpu_to_le32(req_size); 47 48 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 49 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 50 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 51 52 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 53 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 54 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 55 56 return (ms_pkt); 57 } 58 59 /** 60 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. 61 * @ha: HA context 62 * @req_size: request size in bytes 63 * @rsp_size: response size in bytes 64 * 65 * Returns a pointer to the @ha's ms_iocb. 66 */ 67 void * 68 qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) 69 { 70 struct ct_entry_24xx *ct_pkt; 71 72 ct_pkt = (struct ct_entry_24xx *)ha->ms_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 = __constant_cpu_to_le16(NPH_SNS); 78 ct_pkt->timeout = __constant_cpu_to_le16(25); 79 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 80 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); 81 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 82 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 83 84 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 85 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 86 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 87 88 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 89 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 90 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 91 92 return (ct_pkt); 93 } 94 95 /** 96 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 97 * @ct_req: CT request buffer 98 * @cmd: GS command 99 * @rsp_size: response size in bytes 100 * 101 * Returns a pointer to the intitialized @ct_req. 102 */ 103 static inline struct ct_sns_req * 104 qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size) 105 { 106 memset(ct_req, 0, sizeof(struct ct_sns_pkt)); 107 108 ct_req->header.revision = 0x01; 109 ct_req->header.gs_type = 0xFC; 110 ct_req->header.gs_subtype = 0x02; 111 ct_req->command = cpu_to_be16(cmd); 112 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 113 114 return (ct_req); 115 } 116 117 static int 118 qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, 119 struct ct_sns_rsp *ct_rsp, const char *routine) 120 { 121 int rval; 122 uint16_t comp_status; 123 124 rval = QLA_FUNCTION_FAILED; 125 if (ms_pkt->entry_status != 0) { 126 DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", 127 ha->host_no, routine, ms_pkt->entry_status)); 128 } else { 129 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 130 comp_status = 131 ((struct ct_entry_24xx *)ms_pkt)->comp_status; 132 else 133 comp_status = le16_to_cpu(ms_pkt->status); 134 switch (comp_status) { 135 case CS_COMPLETE: 136 case CS_DATA_UNDERRUN: 137 case CS_DATA_OVERRUN: /* Overrun? */ 138 if (ct_rsp->header.response != 139 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { 140 DEBUG2_3(printk("scsi(%ld): %s failed, " 141 "rejected request:\n", ha->host_no, 142 routine)); 143 DEBUG2_3(qla2x00_dump_buffer( 144 (uint8_t *)&ct_rsp->header, 145 sizeof(struct ct_rsp_hdr))); 146 } else 147 rval = QLA_SUCCESS; 148 break; 149 default: 150 DEBUG2_3(printk("scsi(%ld): %s failed, completion " 151 "status (%x).\n", ha->host_no, routine, 152 comp_status)); 153 break; 154 } 155 } 156 return rval; 157 } 158 159 /** 160 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 161 * @ha: HA context 162 * @fcport: fcport entry to updated 163 * 164 * Returns 0 on success. 165 */ 166 int 167 qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport) 168 { 169 int rval; 170 171 ms_iocb_entry_t *ms_pkt; 172 struct ct_sns_req *ct_req; 173 struct ct_sns_rsp *ct_rsp; 174 175 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 176 return (qla2x00_sns_ga_nxt(ha, fcport)); 177 } 178 179 /* Issue GA_NXT */ 180 /* Prepare common MS IOCB */ 181 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE); 182 183 /* Prepare CT request */ 184 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, 185 GA_NXT_RSP_SIZE); 186 ct_rsp = &ha->ct_sns->p.rsp; 187 188 /* Prepare CT arguments -- port_id */ 189 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 190 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 191 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 192 193 /* Execute MS IOCB */ 194 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 195 sizeof(ms_iocb_entry_t)); 196 if (rval != QLA_SUCCESS) { 197 /*EMPTY*/ 198 DEBUG2_3(printk("scsi(%ld): GA_NXT issue IOCB failed (%d).\n", 199 ha->host_no, rval)); 200 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GA_NXT") != 201 QLA_SUCCESS) { 202 rval = QLA_FUNCTION_FAILED; 203 } else { 204 /* Populate fc_port_t entry. */ 205 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; 206 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; 207 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; 208 209 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, 210 WWN_SIZE); 211 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, 212 WWN_SIZE); 213 214 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && 215 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) 216 fcport->d_id.b.domain = 0xf0; 217 218 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - " 219 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 220 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 221 "portid=%02x%02x%02x.\n", 222 ha->host_no, 223 fcport->node_name[0], fcport->node_name[1], 224 fcport->node_name[2], fcport->node_name[3], 225 fcport->node_name[4], fcport->node_name[5], 226 fcport->node_name[6], fcport->node_name[7], 227 fcport->port_name[0], fcport->port_name[1], 228 fcport->port_name[2], fcport->port_name[3], 229 fcport->port_name[4], fcport->port_name[5], 230 fcport->port_name[6], fcport->port_name[7], 231 fcport->d_id.b.domain, fcport->d_id.b.area, 232 fcport->d_id.b.al_pa)); 233 } 234 235 return (rval); 236 } 237 238 /** 239 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. 240 * @ha: HA context 241 * @list: switch info entries to populate 242 * 243 * NOTE: Non-Nx_Ports are not requested. 244 * 245 * Returns 0 on success. 246 */ 247 int 248 qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list) 249 { 250 int rval; 251 uint16_t i; 252 253 ms_iocb_entry_t *ms_pkt; 254 struct ct_sns_req *ct_req; 255 struct ct_sns_rsp *ct_rsp; 256 257 struct ct_sns_gid_pt_data *gid_data; 258 259 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 260 return (qla2x00_sns_gid_pt(ha, list)); 261 } 262 263 gid_data = NULL; 264 265 /* Issue GID_PT */ 266 /* Prepare common MS IOCB */ 267 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE); 268 269 /* Prepare CT request */ 270 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, 271 GID_PT_RSP_SIZE); 272 ct_rsp = &ha->ct_sns->p.rsp; 273 274 /* Prepare CT arguments -- port_type */ 275 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; 276 277 /* Execute MS IOCB */ 278 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 279 sizeof(ms_iocb_entry_t)); 280 if (rval != QLA_SUCCESS) { 281 /*EMPTY*/ 282 DEBUG2_3(printk("scsi(%ld): GID_PT issue IOCB failed (%d).\n", 283 ha->host_no, rval)); 284 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GID_PT") != 285 QLA_SUCCESS) { 286 rval = QLA_FUNCTION_FAILED; 287 } else { 288 /* Set port IDs in switch info list. */ 289 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 290 gid_data = &ct_rsp->rsp.gid_pt.entries[i]; 291 list[i].d_id.b.domain = gid_data->port_id[0]; 292 list[i].d_id.b.area = gid_data->port_id[1]; 293 list[i].d_id.b.al_pa = gid_data->port_id[2]; 294 295 /* Last one exit. */ 296 if (gid_data->control_byte & BIT_7) { 297 list[i].d_id.b.rsvd_1 = gid_data->control_byte; 298 break; 299 } 300 } 301 302 /* 303 * If we've used all available slots, then the switch is 304 * reporting back more devices than we can handle with this 305 * single call. Return a failed status, and let GA_NXT handle 306 * the overload. 307 */ 308 if (i == MAX_FIBRE_DEVICES) 309 rval = QLA_FUNCTION_FAILED; 310 } 311 312 return (rval); 313 } 314 315 /** 316 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. 317 * @ha: HA context 318 * @list: switch info entries to populate 319 * 320 * Returns 0 on success. 321 */ 322 int 323 qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list) 324 { 325 int rval; 326 uint16_t i; 327 328 ms_iocb_entry_t *ms_pkt; 329 struct ct_sns_req *ct_req; 330 struct ct_sns_rsp *ct_rsp; 331 332 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 333 return (qla2x00_sns_gpn_id(ha, list)); 334 } 335 336 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 337 /* Issue GPN_ID */ 338 /* Prepare common MS IOCB */ 339 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE, 340 GPN_ID_RSP_SIZE); 341 342 /* Prepare CT request */ 343 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD, 344 GPN_ID_RSP_SIZE); 345 ct_rsp = &ha->ct_sns->p.rsp; 346 347 /* Prepare CT arguments -- port_id */ 348 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 349 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 350 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 351 352 /* Execute MS IOCB */ 353 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 354 sizeof(ms_iocb_entry_t)); 355 if (rval != QLA_SUCCESS) { 356 /*EMPTY*/ 357 DEBUG2_3(printk("scsi(%ld): GPN_ID issue IOCB failed " 358 "(%d).\n", ha->host_no, rval)); 359 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, 360 "GPN_ID") != QLA_SUCCESS) { 361 rval = QLA_FUNCTION_FAILED; 362 } else { 363 /* Save portname */ 364 memcpy(list[i].port_name, 365 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 366 } 367 368 /* Last device exit. */ 369 if (list[i].d_id.b.rsvd_1 != 0) 370 break; 371 } 372 373 return (rval); 374 } 375 376 /** 377 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. 378 * @ha: HA context 379 * @list: switch info entries to populate 380 * 381 * Returns 0 on success. 382 */ 383 int 384 qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list) 385 { 386 int rval; 387 uint16_t i; 388 389 ms_iocb_entry_t *ms_pkt; 390 struct ct_sns_req *ct_req; 391 struct ct_sns_rsp *ct_rsp; 392 393 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 394 return (qla2x00_sns_gnn_id(ha, list)); 395 } 396 397 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 398 /* Issue GNN_ID */ 399 /* Prepare common MS IOCB */ 400 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE, 401 GNN_ID_RSP_SIZE); 402 403 /* Prepare CT request */ 404 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD, 405 GNN_ID_RSP_SIZE); 406 ct_rsp = &ha->ct_sns->p.rsp; 407 408 /* Prepare CT arguments -- port_id */ 409 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 410 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 411 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 412 413 /* Execute MS IOCB */ 414 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 415 sizeof(ms_iocb_entry_t)); 416 if (rval != QLA_SUCCESS) { 417 /*EMPTY*/ 418 DEBUG2_3(printk("scsi(%ld): GNN_ID issue IOCB failed " 419 "(%d).\n", ha->host_no, rval)); 420 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, 421 "GNN_ID") != QLA_SUCCESS) { 422 rval = QLA_FUNCTION_FAILED; 423 } else { 424 /* Save nodename */ 425 memcpy(list[i].node_name, 426 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); 427 428 DEBUG2_3(printk("scsi(%ld): GID_PT entry - " 429 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 430 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 431 "portid=%02x%02x%02x.\n", 432 ha->host_no, 433 list[i].node_name[0], list[i].node_name[1], 434 list[i].node_name[2], list[i].node_name[3], 435 list[i].node_name[4], list[i].node_name[5], 436 list[i].node_name[6], list[i].node_name[7], 437 list[i].port_name[0], list[i].port_name[1], 438 list[i].port_name[2], list[i].port_name[3], 439 list[i].port_name[4], list[i].port_name[5], 440 list[i].port_name[6], list[i].port_name[7], 441 list[i].d_id.b.domain, list[i].d_id.b.area, 442 list[i].d_id.b.al_pa)); 443 } 444 445 /* Last device exit. */ 446 if (list[i].d_id.b.rsvd_1 != 0) 447 break; 448 } 449 450 return (rval); 451 } 452 453 /** 454 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 455 * @ha: HA context 456 * 457 * Returns 0 on success. 458 */ 459 int 460 qla2x00_rft_id(scsi_qla_host_t *ha) 461 { 462 int rval; 463 464 ms_iocb_entry_t *ms_pkt; 465 struct ct_sns_req *ct_req; 466 struct ct_sns_rsp *ct_rsp; 467 468 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 469 return (qla2x00_sns_rft_id(ha)); 470 } 471 472 /* Issue RFT_ID */ 473 /* Prepare common MS IOCB */ 474 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE); 475 476 /* Prepare CT request */ 477 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, 478 RFT_ID_RSP_SIZE); 479 ct_rsp = &ha->ct_sns->p.rsp; 480 481 /* Prepare CT arguments -- port_id, FC-4 types */ 482 ct_req->req.rft_id.port_id[0] = ha->d_id.b.domain; 483 ct_req->req.rft_id.port_id[1] = ha->d_id.b.area; 484 ct_req->req.rft_id.port_id[2] = ha->d_id.b.al_pa; 485 486 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ 487 488 /* Execute MS IOCB */ 489 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 490 sizeof(ms_iocb_entry_t)); 491 if (rval != QLA_SUCCESS) { 492 /*EMPTY*/ 493 DEBUG2_3(printk("scsi(%ld): RFT_ID issue IOCB failed (%d).\n", 494 ha->host_no, rval)); 495 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFT_ID") != 496 QLA_SUCCESS) { 497 rval = QLA_FUNCTION_FAILED; 498 } else { 499 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n", 500 ha->host_no)); 501 } 502 503 return (rval); 504 } 505 506 /** 507 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. 508 * @ha: HA context 509 * 510 * Returns 0 on success. 511 */ 512 int 513 qla2x00_rff_id(scsi_qla_host_t *ha) 514 { 515 int rval; 516 517 ms_iocb_entry_t *ms_pkt; 518 struct ct_sns_req *ct_req; 519 struct ct_sns_rsp *ct_rsp; 520 521 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 522 DEBUG2(printk("scsi(%ld): RFF_ID call unsupported on " 523 "ISP2100/ISP2200.\n", ha->host_no)); 524 return (QLA_SUCCESS); 525 } 526 527 /* Issue RFF_ID */ 528 /* Prepare common MS IOCB */ 529 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE); 530 531 /* Prepare CT request */ 532 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, 533 RFF_ID_RSP_SIZE); 534 ct_rsp = &ha->ct_sns->p.rsp; 535 536 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ 537 ct_req->req.rff_id.port_id[0] = ha->d_id.b.domain; 538 ct_req->req.rff_id.port_id[1] = ha->d_id.b.area; 539 ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa; 540 541 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */ 542 543 /* Execute MS IOCB */ 544 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 545 sizeof(ms_iocb_entry_t)); 546 if (rval != QLA_SUCCESS) { 547 /*EMPTY*/ 548 DEBUG2_3(printk("scsi(%ld): RFF_ID issue IOCB failed (%d).\n", 549 ha->host_no, rval)); 550 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFF_ID") != 551 QLA_SUCCESS) { 552 rval = QLA_FUNCTION_FAILED; 553 } else { 554 DEBUG2(printk("scsi(%ld): RFF_ID exiting normally.\n", 555 ha->host_no)); 556 } 557 558 return (rval); 559 } 560 561 /** 562 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 563 * @ha: HA context 564 * 565 * Returns 0 on success. 566 */ 567 int 568 qla2x00_rnn_id(scsi_qla_host_t *ha) 569 { 570 int rval; 571 572 ms_iocb_entry_t *ms_pkt; 573 struct ct_sns_req *ct_req; 574 struct ct_sns_rsp *ct_rsp; 575 576 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 577 return (qla2x00_sns_rnn_id(ha)); 578 } 579 580 /* Issue RNN_ID */ 581 /* Prepare common MS IOCB */ 582 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE); 583 584 /* Prepare CT request */ 585 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, 586 RNN_ID_RSP_SIZE); 587 ct_rsp = &ha->ct_sns->p.rsp; 588 589 /* Prepare CT arguments -- port_id, node_name */ 590 ct_req->req.rnn_id.port_id[0] = ha->d_id.b.domain; 591 ct_req->req.rnn_id.port_id[1] = ha->d_id.b.area; 592 ct_req->req.rnn_id.port_id[2] = ha->d_id.b.al_pa; 593 594 memcpy(ct_req->req.rnn_id.node_name, ha->node_name, WWN_SIZE); 595 596 /* Execute MS IOCB */ 597 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 598 sizeof(ms_iocb_entry_t)); 599 if (rval != QLA_SUCCESS) { 600 /*EMPTY*/ 601 DEBUG2_3(printk("scsi(%ld): RNN_ID issue IOCB failed (%d).\n", 602 ha->host_no, rval)); 603 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RNN_ID") != 604 QLA_SUCCESS) { 605 rval = QLA_FUNCTION_FAILED; 606 } else { 607 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n", 608 ha->host_no)); 609 } 610 611 return (rval); 612 } 613 614 /** 615 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 616 * @ha: HA context 617 * 618 * Returns 0 on success. 619 */ 620 int 621 qla2x00_rsnn_nn(scsi_qla_host_t *ha) 622 { 623 int rval; 624 uint8_t *snn; 625 uint8_t version[20]; 626 627 ms_iocb_entry_t *ms_pkt; 628 struct ct_sns_req *ct_req; 629 struct ct_sns_rsp *ct_rsp; 630 631 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 632 DEBUG2(printk("scsi(%ld): RSNN_ID call unsupported on " 633 "ISP2100/ISP2200.\n", ha->host_no)); 634 return (QLA_SUCCESS); 635 } 636 637 /* Issue RSNN_NN */ 638 /* Prepare common MS IOCB */ 639 /* Request size adjusted after CT preparation */ 640 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE); 641 642 /* Prepare CT request */ 643 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, 644 RSNN_NN_RSP_SIZE); 645 ct_rsp = &ha->ct_sns->p.rsp; 646 647 /* Prepare CT arguments -- node_name, symbolic node_name, size */ 648 memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); 649 650 /* Prepare the Symbolic Node Name */ 651 /* Board type */ 652 snn = ct_req->req.rsnn_nn.sym_node_name; 653 strcpy(snn, ha->model_number); 654 /* Firmware version */ 655 strcat(snn, " FW:v"); 656 sprintf(version, "%d.%02d.%02d", ha->fw_major_version, 657 ha->fw_minor_version, ha->fw_subminor_version); 658 strcat(snn, version); 659 /* Driver version */ 660 strcat(snn, " DVR:v"); 661 strcat(snn, qla2x00_version_str); 662 663 /* Calculate SNN length */ 664 ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn); 665 666 /* Update MS IOCB request */ 667 ms_pkt->req_bytecount = 668 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len); 669 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 670 671 /* Execute MS IOCB */ 672 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 673 sizeof(ms_iocb_entry_t)); 674 if (rval != QLA_SUCCESS) { 675 /*EMPTY*/ 676 DEBUG2_3(printk("scsi(%ld): RSNN_NN issue IOCB failed (%d).\n", 677 ha->host_no, rval)); 678 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RSNN_NN") != 679 QLA_SUCCESS) { 680 rval = QLA_FUNCTION_FAILED; 681 } else { 682 DEBUG2(printk("scsi(%ld): RSNN_NN exiting normally.\n", 683 ha->host_no)); 684 } 685 686 return (rval); 687 } 688 689 690 /** 691 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 692 * @ha: HA context 693 * @cmd: GS command 694 * @scmd_len: Subcommand length 695 * @data_size: response size in bytes 696 * 697 * Returns a pointer to the @ha's sns_cmd. 698 */ 699 static inline struct sns_cmd_pkt * 700 qla2x00_prep_sns_cmd(scsi_qla_host_t *ha, uint16_t cmd, uint16_t scmd_len, 701 uint16_t data_size) 702 { 703 uint16_t wc; 704 struct sns_cmd_pkt *sns_cmd; 705 706 sns_cmd = ha->sns_cmd; 707 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); 708 wc = data_size / 2; /* Size in 16bit words. */ 709 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); 710 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); 711 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); 712 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); 713 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); 714 wc = (data_size - 16) / 4; /* Size in 32bit words. */ 715 sns_cmd->p.cmd.size = cpu_to_le16(wc); 716 717 return (sns_cmd); 718 } 719 720 /** 721 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 722 * @ha: HA context 723 * @fcport: fcport entry to updated 724 * 725 * This command uses the old Exectute SNS Command mailbox routine. 726 * 727 * Returns 0 on success. 728 */ 729 static int 730 qla2x00_sns_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport) 731 { 732 int rval; 733 734 struct sns_cmd_pkt *sns_cmd; 735 736 /* Issue GA_NXT. */ 737 /* Prepare SNS command request. */ 738 sns_cmd = qla2x00_prep_sns_cmd(ha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, 739 GA_NXT_SNS_DATA_SIZE); 740 741 /* Prepare SNS command arguments -- port_id. */ 742 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; 743 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; 744 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; 745 746 /* Execute SNS command. */ 747 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, 748 sizeof(struct sns_cmd_pkt)); 749 if (rval != QLA_SUCCESS) { 750 /*EMPTY*/ 751 DEBUG2_3(printk("scsi(%ld): GA_NXT Send SNS failed (%d).\n", 752 ha->host_no, rval)); 753 } else if (sns_cmd->p.gan_data[8] != 0x80 || 754 sns_cmd->p.gan_data[9] != 0x02) { 755 DEBUG2_3(printk("scsi(%ld): GA_NXT failed, rejected request, " 756 "ga_nxt_rsp:\n", ha->host_no)); 757 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gan_data, 16)); 758 rval = QLA_FUNCTION_FAILED; 759 } else { 760 /* Populate fc_port_t entry. */ 761 fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; 762 fcport->d_id.b.area = sns_cmd->p.gan_data[18]; 763 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; 764 765 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); 766 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); 767 768 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && 769 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) 770 fcport->d_id.b.domain = 0xf0; 771 772 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - " 773 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 774 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 775 "portid=%02x%02x%02x.\n", 776 ha->host_no, 777 fcport->node_name[0], fcport->node_name[1], 778 fcport->node_name[2], fcport->node_name[3], 779 fcport->node_name[4], fcport->node_name[5], 780 fcport->node_name[6], fcport->node_name[7], 781 fcport->port_name[0], fcport->port_name[1], 782 fcport->port_name[2], fcport->port_name[3], 783 fcport->port_name[4], fcport->port_name[5], 784 fcport->port_name[6], fcport->port_name[7], 785 fcport->d_id.b.domain, fcport->d_id.b.area, 786 fcport->d_id.b.al_pa)); 787 } 788 789 return (rval); 790 } 791 792 /** 793 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. 794 * @ha: HA context 795 * @list: switch info entries to populate 796 * 797 * This command uses the old Exectute SNS Command mailbox routine. 798 * 799 * NOTE: Non-Nx_Ports are not requested. 800 * 801 * Returns 0 on success. 802 */ 803 static int 804 qla2x00_sns_gid_pt(scsi_qla_host_t *ha, sw_info_t *list) 805 { 806 int rval; 807 808 uint16_t i; 809 uint8_t *entry; 810 struct sns_cmd_pkt *sns_cmd; 811 812 /* Issue GID_PT. */ 813 /* Prepare SNS command request. */ 814 sns_cmd = qla2x00_prep_sns_cmd(ha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, 815 GID_PT_SNS_DATA_SIZE); 816 817 /* Prepare SNS command arguments -- port_type. */ 818 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; 819 820 /* Execute SNS command. */ 821 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, 822 sizeof(struct sns_cmd_pkt)); 823 if (rval != QLA_SUCCESS) { 824 /*EMPTY*/ 825 DEBUG2_3(printk("scsi(%ld): GID_PT Send SNS failed (%d).\n", 826 ha->host_no, rval)); 827 } else if (sns_cmd->p.gid_data[8] != 0x80 || 828 sns_cmd->p.gid_data[9] != 0x02) { 829 DEBUG2_3(printk("scsi(%ld): GID_PT failed, rejected request, " 830 "gid_rsp:\n", ha->host_no)); 831 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gid_data, 16)); 832 rval = QLA_FUNCTION_FAILED; 833 } else { 834 /* Set port IDs in switch info list. */ 835 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 836 entry = &sns_cmd->p.gid_data[(i * 4) + 16]; 837 list[i].d_id.b.domain = entry[1]; 838 list[i].d_id.b.area = entry[2]; 839 list[i].d_id.b.al_pa = entry[3]; 840 841 /* Last one exit. */ 842 if (entry[0] & BIT_7) { 843 list[i].d_id.b.rsvd_1 = entry[0]; 844 break; 845 } 846 } 847 848 /* 849 * If we've used all available slots, then the switch is 850 * reporting back more devices that we can handle with this 851 * single call. Return a failed status, and let GA_NXT handle 852 * the overload. 853 */ 854 if (i == MAX_FIBRE_DEVICES) 855 rval = QLA_FUNCTION_FAILED; 856 } 857 858 return (rval); 859 } 860 861 /** 862 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. 863 * @ha: HA context 864 * @list: switch info entries to populate 865 * 866 * This command uses the old Exectute SNS Command mailbox routine. 867 * 868 * Returns 0 on success. 869 */ 870 static int 871 qla2x00_sns_gpn_id(scsi_qla_host_t *ha, sw_info_t *list) 872 { 873 int rval; 874 875 uint16_t i; 876 struct sns_cmd_pkt *sns_cmd; 877 878 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 879 /* Issue GPN_ID */ 880 /* Prepare SNS command request. */ 881 sns_cmd = qla2x00_prep_sns_cmd(ha, GPN_ID_CMD, 882 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); 883 884 /* Prepare SNS command arguments -- port_id. */ 885 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 886 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 887 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 888 889 /* Execute SNS command. */ 890 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, 891 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 892 if (rval != QLA_SUCCESS) { 893 /*EMPTY*/ 894 DEBUG2_3(printk("scsi(%ld): GPN_ID Send SNS failed " 895 "(%d).\n", ha->host_no, rval)); 896 } else if (sns_cmd->p.gpn_data[8] != 0x80 || 897 sns_cmd->p.gpn_data[9] != 0x02) { 898 DEBUG2_3(printk("scsi(%ld): GPN_ID failed, rejected " 899 "request, gpn_rsp:\n", ha->host_no)); 900 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gpn_data, 16)); 901 rval = QLA_FUNCTION_FAILED; 902 } else { 903 /* Save portname */ 904 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], 905 WWN_SIZE); 906 } 907 908 /* Last device exit. */ 909 if (list[i].d_id.b.rsvd_1 != 0) 910 break; 911 } 912 913 return (rval); 914 } 915 916 /** 917 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. 918 * @ha: HA context 919 * @list: switch info entries to populate 920 * 921 * This command uses the old Exectute SNS Command mailbox routine. 922 * 923 * Returns 0 on success. 924 */ 925 static int 926 qla2x00_sns_gnn_id(scsi_qla_host_t *ha, sw_info_t *list) 927 { 928 int rval; 929 930 uint16_t i; 931 struct sns_cmd_pkt *sns_cmd; 932 933 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 934 /* Issue GNN_ID */ 935 /* Prepare SNS command request. */ 936 sns_cmd = qla2x00_prep_sns_cmd(ha, GNN_ID_CMD, 937 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); 938 939 /* Prepare SNS command arguments -- port_id. */ 940 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 941 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 942 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 943 944 /* Execute SNS command. */ 945 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, 946 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 947 if (rval != QLA_SUCCESS) { 948 /*EMPTY*/ 949 DEBUG2_3(printk("scsi(%ld): GNN_ID Send SNS failed " 950 "(%d).\n", ha->host_no, rval)); 951 } else if (sns_cmd->p.gnn_data[8] != 0x80 || 952 sns_cmd->p.gnn_data[9] != 0x02) { 953 DEBUG2_3(printk("scsi(%ld): GNN_ID failed, rejected " 954 "request, gnn_rsp:\n", ha->host_no)); 955 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gnn_data, 16)); 956 rval = QLA_FUNCTION_FAILED; 957 } else { 958 /* Save nodename */ 959 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], 960 WWN_SIZE); 961 962 DEBUG2_3(printk("scsi(%ld): GID_PT entry - " 963 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 964 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 965 "portid=%02x%02x%02x.\n", 966 ha->host_no, 967 list[i].node_name[0], list[i].node_name[1], 968 list[i].node_name[2], list[i].node_name[3], 969 list[i].node_name[4], list[i].node_name[5], 970 list[i].node_name[6], list[i].node_name[7], 971 list[i].port_name[0], list[i].port_name[1], 972 list[i].port_name[2], list[i].port_name[3], 973 list[i].port_name[4], list[i].port_name[5], 974 list[i].port_name[6], list[i].port_name[7], 975 list[i].d_id.b.domain, list[i].d_id.b.area, 976 list[i].d_id.b.al_pa)); 977 } 978 979 /* Last device exit. */ 980 if (list[i].d_id.b.rsvd_1 != 0) 981 break; 982 } 983 984 return (rval); 985 } 986 987 /** 988 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 989 * @ha: HA context 990 * 991 * This command uses the old Exectute SNS Command mailbox routine. 992 * 993 * Returns 0 on success. 994 */ 995 static int 996 qla2x00_sns_rft_id(scsi_qla_host_t *ha) 997 { 998 int rval; 999 1000 struct sns_cmd_pkt *sns_cmd; 1001 1002 /* Issue RFT_ID. */ 1003 /* Prepare SNS command request. */ 1004 sns_cmd = qla2x00_prep_sns_cmd(ha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, 1005 RFT_ID_SNS_DATA_SIZE); 1006 1007 /* Prepare SNS command arguments -- port_id, FC-4 types */ 1008 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa; 1009 sns_cmd->p.cmd.param[1] = ha->d_id.b.area; 1010 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain; 1011 1012 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ 1013 1014 /* Execute SNS command. */ 1015 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, 1016 sizeof(struct sns_cmd_pkt)); 1017 if (rval != QLA_SUCCESS) { 1018 /*EMPTY*/ 1019 DEBUG2_3(printk("scsi(%ld): RFT_ID Send SNS failed (%d).\n", 1020 ha->host_no, rval)); 1021 } else if (sns_cmd->p.rft_data[8] != 0x80 || 1022 sns_cmd->p.rft_data[9] != 0x02) { 1023 DEBUG2_3(printk("scsi(%ld): RFT_ID failed, rejected request, " 1024 "rft_rsp:\n", ha->host_no)); 1025 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rft_data, 16)); 1026 rval = QLA_FUNCTION_FAILED; 1027 } else { 1028 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n", 1029 ha->host_no)); 1030 } 1031 1032 return (rval); 1033 } 1034 1035 /** 1036 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 1037 * HBA. 1038 * @ha: HA context 1039 * 1040 * This command uses the old Exectute SNS Command mailbox routine. 1041 * 1042 * Returns 0 on success. 1043 */ 1044 static int 1045 qla2x00_sns_rnn_id(scsi_qla_host_t *ha) 1046 { 1047 int rval; 1048 1049 struct sns_cmd_pkt *sns_cmd; 1050 1051 /* Issue RNN_ID. */ 1052 /* Prepare SNS command request. */ 1053 sns_cmd = qla2x00_prep_sns_cmd(ha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, 1054 RNN_ID_SNS_DATA_SIZE); 1055 1056 /* Prepare SNS command arguments -- port_id, nodename. */ 1057 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa; 1058 sns_cmd->p.cmd.param[1] = ha->d_id.b.area; 1059 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain; 1060 1061 sns_cmd->p.cmd.param[4] = ha->node_name[7]; 1062 sns_cmd->p.cmd.param[5] = ha->node_name[6]; 1063 sns_cmd->p.cmd.param[6] = ha->node_name[5]; 1064 sns_cmd->p.cmd.param[7] = ha->node_name[4]; 1065 sns_cmd->p.cmd.param[8] = ha->node_name[3]; 1066 sns_cmd->p.cmd.param[9] = ha->node_name[2]; 1067 sns_cmd->p.cmd.param[10] = ha->node_name[1]; 1068 sns_cmd->p.cmd.param[11] = ha->node_name[0]; 1069 1070 /* Execute SNS command. */ 1071 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, 1072 sizeof(struct sns_cmd_pkt)); 1073 if (rval != QLA_SUCCESS) { 1074 /*EMPTY*/ 1075 DEBUG2_3(printk("scsi(%ld): RNN_ID Send SNS failed (%d).\n", 1076 ha->host_no, rval)); 1077 } else if (sns_cmd->p.rnn_data[8] != 0x80 || 1078 sns_cmd->p.rnn_data[9] != 0x02) { 1079 DEBUG2_3(printk("scsi(%ld): RNN_ID failed, rejected request, " 1080 "rnn_rsp:\n", ha->host_no)); 1081 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rnn_data, 16)); 1082 rval = QLA_FUNCTION_FAILED; 1083 } else { 1084 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n", 1085 ha->host_no)); 1086 } 1087 1088 return (rval); 1089 } 1090 1091 /** 1092 * qla2x00_mgmt_svr_login() - Login to fabric Managment Service. 1093 * @ha: HA context 1094 * 1095 * Returns 0 on success. 1096 */ 1097 static int 1098 qla2x00_mgmt_svr_login(scsi_qla_host_t *ha) 1099 { 1100 int ret; 1101 uint16_t mb[MAILBOX_REGISTER_COUNT]; 1102 1103 ret = QLA_SUCCESS; 1104 if (ha->flags.management_server_logged_in) 1105 return ret; 1106 1107 ha->isp_ops.fabric_login(ha, ha->mgmt_svr_loop_id, 0xff, 0xff, 0xfa, 1108 mb, BIT_1); 1109 if (mb[0] != MBS_COMMAND_COMPLETE) { 1110 DEBUG2_13(printk("%s(%ld): Failed MANAGEMENT_SERVER login: " 1111 "loop_id=%x mb[0]=%x mb[1]=%x mb[2]=%x mb[6]=%x mb[7]=%x\n", 1112 __func__, ha->host_no, ha->mgmt_svr_loop_id, mb[0], mb[1], 1113 mb[2], mb[6], mb[7])); 1114 ret = QLA_FUNCTION_FAILED; 1115 } else 1116 ha->flags.management_server_logged_in = 1; 1117 1118 return ret; 1119 } 1120 1121 /** 1122 * qla2x00_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1123 * @ha: HA context 1124 * @req_size: request size in bytes 1125 * @rsp_size: response size in bytes 1126 * 1127 * Returns a pointer to the @ha's ms_iocb. 1128 */ 1129 void * 1130 qla2x00_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, 1131 uint32_t rsp_size) 1132 { 1133 ms_iocb_entry_t *ms_pkt; 1134 1135 ms_pkt = ha->ms_iocb; 1136 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 1137 1138 ms_pkt->entry_type = MS_IOCB_TYPE; 1139 ms_pkt->entry_count = 1; 1140 SET_TARGET_ID(ha, ms_pkt->loop_id, ha->mgmt_svr_loop_id); 1141 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); 1142 ms_pkt->timeout = __constant_cpu_to_le16(59); 1143 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 1144 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); 1145 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 1146 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1147 1148 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1149 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1150 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1151 1152 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1153 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1154 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 1155 1156 return ms_pkt; 1157 } 1158 1159 /** 1160 * qla24xx_prep_ms_fdmi_iocb() - Prepare common MS IOCB fields for FDMI query. 1161 * @ha: HA context 1162 * @req_size: request size in bytes 1163 * @rsp_size: response size in bytes 1164 * 1165 * Returns a pointer to the @ha's ms_iocb. 1166 */ 1167 void * 1168 qla24xx_prep_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size, 1169 uint32_t rsp_size) 1170 { 1171 struct ct_entry_24xx *ct_pkt; 1172 1173 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1174 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 1175 1176 ct_pkt->entry_type = CT_IOCB_TYPE; 1177 ct_pkt->entry_count = 1; 1178 ct_pkt->nport_handle = cpu_to_le16(ha->mgmt_svr_loop_id); 1179 ct_pkt->timeout = __constant_cpu_to_le16(59); 1180 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 1181 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); 1182 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 1183 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1184 1185 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1186 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1187 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1188 1189 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 1190 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 1191 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 1192 1193 return ct_pkt; 1194 } 1195 1196 static inline ms_iocb_entry_t * 1197 qla2x00_update_ms_fdmi_iocb(scsi_qla_host_t *ha, uint32_t req_size) 1198 { 1199 ms_iocb_entry_t *ms_pkt = ha->ms_iocb; 1200 struct ct_entry_24xx *ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 1201 1202 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1203 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 1204 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 1205 } else { 1206 ms_pkt->req_bytecount = cpu_to_le32(req_size); 1207 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 1208 } 1209 1210 return ms_pkt; 1211 } 1212 1213 /** 1214 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 1215 * @ct_req: CT request buffer 1216 * @cmd: GS command 1217 * @rsp_size: response size in bytes 1218 * 1219 * Returns a pointer to the intitialized @ct_req. 1220 */ 1221 static inline struct ct_sns_req * 1222 qla2x00_prep_ct_fdmi_req(struct ct_sns_req *ct_req, uint16_t cmd, 1223 uint16_t rsp_size) 1224 { 1225 memset(ct_req, 0, sizeof(struct ct_sns_pkt)); 1226 1227 ct_req->header.revision = 0x01; 1228 ct_req->header.gs_type = 0xFA; 1229 ct_req->header.gs_subtype = 0x10; 1230 ct_req->command = cpu_to_be16(cmd); 1231 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 1232 1233 return ct_req; 1234 } 1235 1236 /** 1237 * qla2x00_fdmi_rhba() - 1238 * @ha: HA context 1239 * 1240 * Returns 0 on success. 1241 */ 1242 static int 1243 qla2x00_fdmi_rhba(scsi_qla_host_t *ha) 1244 { 1245 int rval, alen; 1246 uint32_t size, sn; 1247 1248 ms_iocb_entry_t *ms_pkt; 1249 struct ct_sns_req *ct_req; 1250 struct ct_sns_rsp *ct_rsp; 1251 uint8_t *entries; 1252 struct ct_fdmi_hba_attr *eiter; 1253 1254 /* Issue RHBA */ 1255 /* Prepare common MS IOCB */ 1256 /* Request size adjusted after CT preparation */ 1257 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RHBA_RSP_SIZE); 1258 1259 /* Prepare CT request */ 1260 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RHBA_CMD, 1261 RHBA_RSP_SIZE); 1262 ct_rsp = &ha->ct_sns->p.rsp; 1263 1264 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1265 memcpy(ct_req->req.rhba.hba_identifier, ha->port_name, WWN_SIZE); 1266 ct_req->req.rhba.entry_count = __constant_cpu_to_be32(1); 1267 memcpy(ct_req->req.rhba.port_name, ha->port_name, WWN_SIZE); 1268 size = 2 * WWN_SIZE + 4 + 4; 1269 1270 /* Attributes */ 1271 ct_req->req.rhba.attrs.count = 1272 __constant_cpu_to_be32(FDMI_HBA_ATTR_COUNT); 1273 entries = ct_req->req.rhba.hba_identifier; 1274 1275 /* Nodename. */ 1276 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1277 eiter->type = __constant_cpu_to_be16(FDMI_HBA_NODE_NAME); 1278 eiter->len = __constant_cpu_to_be16(4 + WWN_SIZE); 1279 memcpy(eiter->a.node_name, ha->node_name, WWN_SIZE); 1280 size += 4 + WWN_SIZE; 1281 1282 DEBUG13(printk("%s(%ld): NODENAME=%02x%02x%02x%02x%02x%02x%02x%02x.\n", 1283 __func__, ha->host_no, 1284 eiter->a.node_name[0], eiter->a.node_name[1], eiter->a.node_name[2], 1285 eiter->a.node_name[3], eiter->a.node_name[4], eiter->a.node_name[5], 1286 eiter->a.node_name[6], eiter->a.node_name[7])); 1287 1288 /* Manufacturer. */ 1289 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1290 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MANUFACTURER); 1291 strcpy(eiter->a.manufacturer, "QLogic Corporation"); 1292 alen = strlen(eiter->a.manufacturer); 1293 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1294 eiter->len = cpu_to_be16(4 + alen); 1295 size += 4 + alen; 1296 1297 DEBUG13(printk("%s(%ld): MANUFACTURER=%s.\n", __func__, ha->host_no, 1298 eiter->a.manufacturer)); 1299 1300 /* Serial number. */ 1301 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1302 eiter->type = __constant_cpu_to_be16(FDMI_HBA_SERIAL_NUMBER); 1303 sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; 1304 sprintf(eiter->a.serial_num, "%c%05d", 'A' + sn / 100000, sn % 100000); 1305 alen = strlen(eiter->a.serial_num); 1306 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1307 eiter->len = cpu_to_be16(4 + alen); 1308 size += 4 + alen; 1309 1310 DEBUG13(printk("%s(%ld): SERIALNO=%s.\n", __func__, ha->host_no, 1311 eiter->a.serial_num)); 1312 1313 /* Model name. */ 1314 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1315 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL); 1316 strcpy(eiter->a.model, ha->model_number); 1317 alen = strlen(eiter->a.model); 1318 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1319 eiter->len = cpu_to_be16(4 + alen); 1320 size += 4 + alen; 1321 1322 DEBUG13(printk("%s(%ld): MODEL_NAME=%s.\n", __func__, ha->host_no, 1323 eiter->a.model)); 1324 1325 /* Model description. */ 1326 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1327 eiter->type = __constant_cpu_to_be16(FDMI_HBA_MODEL_DESCRIPTION); 1328 if (ha->model_desc) 1329 strncpy(eiter->a.model_desc, ha->model_desc, 80); 1330 alen = strlen(eiter->a.model_desc); 1331 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1332 eiter->len = cpu_to_be16(4 + alen); 1333 size += 4 + alen; 1334 1335 DEBUG13(printk("%s(%ld): MODEL_DESC=%s.\n", __func__, ha->host_no, 1336 eiter->a.model_desc)); 1337 1338 /* Hardware version. */ 1339 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1340 eiter->type = __constant_cpu_to_be16(FDMI_HBA_HARDWARE_VERSION); 1341 strcpy(eiter->a.hw_version, ha->adapter_id); 1342 alen = strlen(eiter->a.hw_version); 1343 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1344 eiter->len = cpu_to_be16(4 + alen); 1345 size += 4 + alen; 1346 1347 DEBUG13(printk("%s(%ld): HARDWAREVER=%s.\n", __func__, ha->host_no, 1348 eiter->a.hw_version)); 1349 1350 /* Driver version. */ 1351 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1352 eiter->type = __constant_cpu_to_be16(FDMI_HBA_DRIVER_VERSION); 1353 strcpy(eiter->a.driver_version, qla2x00_version_str); 1354 alen = strlen(eiter->a.driver_version); 1355 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1356 eiter->len = cpu_to_be16(4 + alen); 1357 size += 4 + alen; 1358 1359 DEBUG13(printk("%s(%ld): DRIVERVER=%s.\n", __func__, ha->host_no, 1360 eiter->a.driver_version)); 1361 1362 /* Option ROM version. */ 1363 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1364 eiter->type = __constant_cpu_to_be16(FDMI_HBA_OPTION_ROM_VERSION); 1365 strcpy(eiter->a.orom_version, "0.00"); 1366 alen = strlen(eiter->a.orom_version); 1367 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1368 eiter->len = cpu_to_be16(4 + alen); 1369 size += 4 + alen; 1370 1371 DEBUG13(printk("%s(%ld): OPTROMVER=%s.\n", __func__, ha->host_no, 1372 eiter->a.orom_version)); 1373 1374 /* Firmware version */ 1375 eiter = (struct ct_fdmi_hba_attr *) (entries + size); 1376 eiter->type = __constant_cpu_to_be16(FDMI_HBA_FIRMWARE_VERSION); 1377 ha->isp_ops.fw_version_str(ha, eiter->a.fw_version); 1378 alen = strlen(eiter->a.fw_version); 1379 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1380 eiter->len = cpu_to_be16(4 + alen); 1381 size += 4 + alen; 1382 1383 DEBUG13(printk("%s(%ld): FIRMWAREVER=%s.\n", __func__, ha->host_no, 1384 eiter->a.fw_version)); 1385 1386 /* Update MS request size. */ 1387 qla2x00_update_ms_fdmi_iocb(ha, size + 16); 1388 1389 DEBUG13(printk("%s(%ld): RHBA identifier=" 1390 "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__, 1391 ha->host_no, ct_req->req.rhba.hba_identifier[0], 1392 ct_req->req.rhba.hba_identifier[1], 1393 ct_req->req.rhba.hba_identifier[2], 1394 ct_req->req.rhba.hba_identifier[3], 1395 ct_req->req.rhba.hba_identifier[4], 1396 ct_req->req.rhba.hba_identifier[5], 1397 ct_req->req.rhba.hba_identifier[6], 1398 ct_req->req.rhba.hba_identifier[7], size)); 1399 DEBUG13(qla2x00_dump_buffer(entries, size)); 1400 1401 /* Execute MS IOCB */ 1402 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 1403 sizeof(ms_iocb_entry_t)); 1404 if (rval != QLA_SUCCESS) { 1405 /*EMPTY*/ 1406 DEBUG2_3(printk("scsi(%ld): RHBA issue IOCB failed (%d).\n", 1407 ha->host_no, rval)); 1408 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RHBA") != 1409 QLA_SUCCESS) { 1410 rval = QLA_FUNCTION_FAILED; 1411 if (ct_rsp->header.reason_code == CT_REASON_CANNOT_PERFORM && 1412 ct_rsp->header.explanation_code == 1413 CT_EXPL_ALREADY_REGISTERED) { 1414 DEBUG2_13(printk("%s(%ld): HBA already registered.\n", 1415 __func__, ha->host_no)); 1416 rval = QLA_ALREADY_REGISTERED; 1417 } 1418 } else { 1419 DEBUG2(printk("scsi(%ld): RHBA exiting normally.\n", 1420 ha->host_no)); 1421 } 1422 1423 return rval; 1424 } 1425 1426 /** 1427 * qla2x00_fdmi_dhba() - 1428 * @ha: HA context 1429 * 1430 * Returns 0 on success. 1431 */ 1432 static int 1433 qla2x00_fdmi_dhba(scsi_qla_host_t *ha) 1434 { 1435 int rval; 1436 1437 ms_iocb_entry_t *ms_pkt; 1438 struct ct_sns_req *ct_req; 1439 struct ct_sns_rsp *ct_rsp; 1440 1441 /* Issue RPA */ 1442 /* Prepare common MS IOCB */ 1443 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, DHBA_REQ_SIZE, 1444 DHBA_RSP_SIZE); 1445 1446 /* Prepare CT request */ 1447 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, DHBA_CMD, 1448 DHBA_RSP_SIZE); 1449 ct_rsp = &ha->ct_sns->p.rsp; 1450 1451 /* Prepare FDMI command arguments -- portname. */ 1452 memcpy(ct_req->req.dhba.port_name, ha->port_name, WWN_SIZE); 1453 1454 DEBUG13(printk("%s(%ld): DHBA portname=" 1455 "%02x%02x%02x%02x%02x%02x%02x%02x.\n", __func__, ha->host_no, 1456 ct_req->req.dhba.port_name[0], ct_req->req.dhba.port_name[1], 1457 ct_req->req.dhba.port_name[2], ct_req->req.dhba.port_name[3], 1458 ct_req->req.dhba.port_name[4], ct_req->req.dhba.port_name[5], 1459 ct_req->req.dhba.port_name[6], ct_req->req.dhba.port_name[7])); 1460 1461 /* Execute MS IOCB */ 1462 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 1463 sizeof(ms_iocb_entry_t)); 1464 if (rval != QLA_SUCCESS) { 1465 /*EMPTY*/ 1466 DEBUG2_3(printk("scsi(%ld): DHBA issue IOCB failed (%d).\n", 1467 ha->host_no, rval)); 1468 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "DHBA") != 1469 QLA_SUCCESS) { 1470 rval = QLA_FUNCTION_FAILED; 1471 } else { 1472 DEBUG2(printk("scsi(%ld): DHBA exiting normally.\n", 1473 ha->host_no)); 1474 } 1475 1476 return rval; 1477 } 1478 1479 /** 1480 * qla2x00_fdmi_rpa() - 1481 * @ha: HA context 1482 * 1483 * Returns 0 on success. 1484 */ 1485 static int 1486 qla2x00_fdmi_rpa(scsi_qla_host_t *ha) 1487 { 1488 int rval, alen; 1489 uint32_t size, max_frame_size; 1490 1491 ms_iocb_entry_t *ms_pkt; 1492 struct ct_sns_req *ct_req; 1493 struct ct_sns_rsp *ct_rsp; 1494 uint8_t *entries; 1495 struct ct_fdmi_port_attr *eiter; 1496 struct init_cb_24xx *icb24 = (struct init_cb_24xx *)ha->init_cb; 1497 1498 /* Issue RPA */ 1499 /* Prepare common MS IOCB */ 1500 /* Request size adjusted after CT preparation */ 1501 ms_pkt = ha->isp_ops.prep_ms_fdmi_iocb(ha, 0, RPA_RSP_SIZE); 1502 1503 /* Prepare CT request */ 1504 ct_req = qla2x00_prep_ct_fdmi_req(&ha->ct_sns->p.req, RPA_CMD, 1505 RPA_RSP_SIZE); 1506 ct_rsp = &ha->ct_sns->p.rsp; 1507 1508 /* Prepare FDMI command arguments -- attribute block, attributes. */ 1509 memcpy(ct_req->req.rpa.port_name, ha->port_name, WWN_SIZE); 1510 size = WWN_SIZE + 4; 1511 1512 /* Attributes */ 1513 ct_req->req.rpa.attrs.count = 1514 __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); 1515 entries = ct_req->req.rpa.port_name; 1516 1517 /* FC4 types. */ 1518 eiter = (struct ct_fdmi_port_attr *) (entries + size); 1519 eiter->type = __constant_cpu_to_be16(FDMI_PORT_FC4_TYPES); 1520 eiter->len = __constant_cpu_to_be16(4 + 32); 1521 eiter->a.fc4_types[2] = 0x01; 1522 size += 4 + 32; 1523 1524 DEBUG13(printk("%s(%ld): FC4_TYPES=%02x %02x.\n", __func__, ha->host_no, 1525 eiter->a.fc4_types[2], eiter->a.fc4_types[1])); 1526 1527 /* Supported speed. */ 1528 eiter = (struct ct_fdmi_port_attr *) (entries + size); 1529 eiter->type = __constant_cpu_to_be16(FDMI_PORT_SUPPORT_SPEED); 1530 eiter->len = __constant_cpu_to_be16(4 + 4); 1531 if (IS_QLA25XX(ha)) 1532 eiter->a.sup_speed = __constant_cpu_to_be32(4); 1533 else if (IS_QLA24XX(ha)) 1534 eiter->a.sup_speed = __constant_cpu_to_be32(8); 1535 else if (IS_QLA23XX(ha)) 1536 eiter->a.sup_speed = __constant_cpu_to_be32(2); 1537 else 1538 eiter->a.sup_speed = __constant_cpu_to_be32(1); 1539 size += 4 + 4; 1540 1541 DEBUG13(printk("%s(%ld): SUPPORTED_SPEED=%x.\n", __func__, ha->host_no, 1542 eiter->a.sup_speed)); 1543 1544 /* Current speed. */ 1545 eiter = (struct ct_fdmi_port_attr *) (entries + size); 1546 eiter->type = __constant_cpu_to_be16(FDMI_PORT_CURRENT_SPEED); 1547 eiter->len = __constant_cpu_to_be16(4 + 4); 1548 switch (ha->link_data_rate) { 1549 case 0: 1550 eiter->a.cur_speed = __constant_cpu_to_be32(1); 1551 break; 1552 case 1: 1553 eiter->a.cur_speed = __constant_cpu_to_be32(2); 1554 break; 1555 case 3: 1556 eiter->a.cur_speed = __constant_cpu_to_be32(8); 1557 break; 1558 case 4: 1559 eiter->a.cur_speed = __constant_cpu_to_be32(4); 1560 break; 1561 } 1562 size += 4 + 4; 1563 1564 DEBUG13(printk("%s(%ld): CURRENT_SPEED=%x.\n", __func__, ha->host_no, 1565 eiter->a.cur_speed)); 1566 1567 /* Max frame size. */ 1568 eiter = (struct ct_fdmi_port_attr *) (entries + size); 1569 eiter->type = __constant_cpu_to_be16(FDMI_PORT_MAX_FRAME_SIZE); 1570 eiter->len = __constant_cpu_to_be16(4 + 4); 1571 max_frame_size = IS_QLA24XX(ha) || IS_QLA25XX(ha) ? 1572 (uint32_t) icb24->frame_payload_size: 1573 (uint32_t) ha->init_cb->frame_payload_size; 1574 eiter->a.max_frame_size = cpu_to_be32(max_frame_size); 1575 size += 4 + 4; 1576 1577 DEBUG13(printk("%s(%ld): MAX_FRAME_SIZE=%x.\n", __func__, ha->host_no, 1578 eiter->a.max_frame_size)); 1579 1580 /* OS device name. */ 1581 eiter = (struct ct_fdmi_port_attr *) (entries + size); 1582 eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); 1583 sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no); 1584 alen = strlen(eiter->a.os_dev_name); 1585 alen += (alen & 3) ? (4 - (alen & 3)) : 4; 1586 eiter->len = cpu_to_be16(4 + alen); 1587 size += 4 + alen; 1588 1589 DEBUG13(printk("%s(%ld): OS_DEVICE_NAME=%s.\n", __func__, ha->host_no, 1590 eiter->a.os_dev_name)); 1591 1592 /* Update MS request size. */ 1593 qla2x00_update_ms_fdmi_iocb(ha, size + 16); 1594 1595 DEBUG13(printk("%s(%ld): RPA portname=" 1596 "%02x%02x%02x%02x%02x%02x%02x%02x size=%d.\n", __func__, 1597 ha->host_no, ct_req->req.rpa.port_name[0], 1598 ct_req->req.rpa.port_name[1], ct_req->req.rpa.port_name[2], 1599 ct_req->req.rpa.port_name[3], ct_req->req.rpa.port_name[4], 1600 ct_req->req.rpa.port_name[5], ct_req->req.rpa.port_name[6], 1601 ct_req->req.rpa.port_name[7], size)); 1602 DEBUG13(qla2x00_dump_buffer(entries, size)); 1603 1604 /* Execute MS IOCB */ 1605 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 1606 sizeof(ms_iocb_entry_t)); 1607 if (rval != QLA_SUCCESS) { 1608 /*EMPTY*/ 1609 DEBUG2_3(printk("scsi(%ld): RPA issue IOCB failed (%d).\n", 1610 ha->host_no, rval)); 1611 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RPA") != 1612 QLA_SUCCESS) { 1613 rval = QLA_FUNCTION_FAILED; 1614 } else { 1615 DEBUG2(printk("scsi(%ld): RPA exiting normally.\n", 1616 ha->host_no)); 1617 } 1618 1619 return rval; 1620 } 1621 1622 /** 1623 * qla2x00_fdmi_register() - 1624 * @ha: HA context 1625 * 1626 * Returns 0 on success. 1627 */ 1628 int 1629 qla2x00_fdmi_register(scsi_qla_host_t *ha) 1630 { 1631 int rval; 1632 1633 rval = qla2x00_mgmt_svr_login(ha); 1634 if (rval) 1635 return rval; 1636 1637 rval = qla2x00_fdmi_rhba(ha); 1638 if (rval) { 1639 if (rval != QLA_ALREADY_REGISTERED) 1640 return rval; 1641 1642 rval = qla2x00_fdmi_dhba(ha); 1643 if (rval) 1644 return rval; 1645 1646 rval = qla2x00_fdmi_rhba(ha); 1647 if (rval) 1648 return rval; 1649 } 1650 rval = qla2x00_fdmi_rpa(ha); 1651 1652 return rval; 1653 } 1654