1 /* 2 * QLOGIC LINUX SOFTWARE 3 * 4 * QLogic ISP2x00 device driver for Linux 2.6.x 5 * Copyright (C) 2003-2005 QLogic Corporation 6 * (www.qlogic.com) 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2, or (at your option) any 11 * later version. 12 * 13 * This program is distributed in the hope that it will be useful, but 14 * WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * General Public License for more details. 17 * 18 */ 19 #include "qla_def.h" 20 21 static inline struct ct_sns_req * 22 qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t); 23 24 static inline struct sns_cmd_pkt * 25 qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t); 26 27 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *); 28 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *); 29 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *); 30 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *); 31 static int qla2x00_sns_rft_id(scsi_qla_host_t *); 32 static int qla2x00_sns_rnn_id(scsi_qla_host_t *); 33 34 /** 35 * qla2x00_prep_ms_iocb() - Prepare common MS/CT IOCB fields for SNS CT query. 36 * @ha: HA context 37 * @req_size: request size in bytes 38 * @rsp_size: response size in bytes 39 * 40 * Returns a pointer to the @ha's ms_iocb. 41 */ 42 void * 43 qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) 44 { 45 ms_iocb_entry_t *ms_pkt; 46 47 ms_pkt = ha->ms_iocb; 48 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t)); 49 50 ms_pkt->entry_type = MS_IOCB_TYPE; 51 ms_pkt->entry_count = 1; 52 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER); 53 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG); 54 ms_pkt->timeout = __constant_cpu_to_le16(25); 55 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 56 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2); 57 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size); 58 ms_pkt->req_bytecount = cpu_to_le32(req_size); 59 60 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 61 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 62 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 63 64 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 65 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 66 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount; 67 68 return (ms_pkt); 69 } 70 71 /** 72 * qla24xx_prep_ms_iocb() - Prepare common CT IOCB fields for SNS CT query. 73 * @ha: HA context 74 * @req_size: request size in bytes 75 * @rsp_size: response size in bytes 76 * 77 * Returns a pointer to the @ha's ms_iocb. 78 */ 79 void * 80 qla24xx_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size) 81 { 82 struct ct_entry_24xx *ct_pkt; 83 84 ct_pkt = (struct ct_entry_24xx *)ha->ms_iocb; 85 memset(ct_pkt, 0, sizeof(struct ct_entry_24xx)); 86 87 ct_pkt->entry_type = CT_IOCB_TYPE; 88 ct_pkt->entry_count = 1; 89 ct_pkt->nport_handle = __constant_cpu_to_le16(NPH_SNS); 90 ct_pkt->timeout = __constant_cpu_to_le16(25); 91 ct_pkt->cmd_dsd_count = __constant_cpu_to_le16(1); 92 ct_pkt->rsp_dsd_count = __constant_cpu_to_le16(1); 93 ct_pkt->rsp_byte_count = cpu_to_le32(rsp_size); 94 ct_pkt->cmd_byte_count = cpu_to_le32(req_size); 95 96 ct_pkt->dseg_0_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 97 ct_pkt->dseg_0_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 98 ct_pkt->dseg_0_len = ct_pkt->cmd_byte_count; 99 100 ct_pkt->dseg_1_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma)); 101 ct_pkt->dseg_1_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma)); 102 ct_pkt->dseg_1_len = ct_pkt->rsp_byte_count; 103 104 return (ct_pkt); 105 } 106 107 /** 108 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query. 109 * @ct_req: CT request buffer 110 * @cmd: GS command 111 * @rsp_size: response size in bytes 112 * 113 * Returns a pointer to the intitialized @ct_req. 114 */ 115 static inline struct ct_sns_req * 116 qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size) 117 { 118 memset(ct_req, 0, sizeof(struct ct_sns_pkt)); 119 120 ct_req->header.revision = 0x01; 121 ct_req->header.gs_type = 0xFC; 122 ct_req->header.gs_subtype = 0x02; 123 ct_req->command = cpu_to_be16(cmd); 124 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4); 125 126 return (ct_req); 127 } 128 129 static int 130 qla2x00_chk_ms_status(scsi_qla_host_t *ha, ms_iocb_entry_t *ms_pkt, 131 struct ct_sns_rsp *ct_rsp, const char *routine) 132 { 133 int rval; 134 uint16_t comp_status; 135 136 rval = QLA_FUNCTION_FAILED; 137 if (ms_pkt->entry_status != 0) { 138 DEBUG2_3(printk("scsi(%ld): %s failed, error status (%x).\n", 139 ha->host_no, routine, ms_pkt->entry_status)); 140 } else { 141 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 142 comp_status = 143 ((struct ct_entry_24xx *)ms_pkt)->comp_status; 144 else 145 comp_status = le16_to_cpu(ms_pkt->status); 146 switch (comp_status) { 147 case CS_COMPLETE: 148 case CS_DATA_UNDERRUN: 149 case CS_DATA_OVERRUN: /* Overrun? */ 150 if (ct_rsp->header.response != 151 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) { 152 DEBUG2_3(printk("scsi(%ld): %s failed, " 153 "rejected request:\n", ha->host_no, 154 routine)); 155 DEBUG2_3(qla2x00_dump_buffer( 156 (uint8_t *)&ct_rsp->header, 157 sizeof(struct ct_rsp_hdr))); 158 } else 159 rval = QLA_SUCCESS; 160 break; 161 default: 162 DEBUG2_3(printk("scsi(%ld): %s failed, completion " 163 "status (%x).\n", ha->host_no, routine, 164 comp_status)); 165 break; 166 } 167 } 168 return rval; 169 } 170 171 /** 172 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 173 * @ha: HA context 174 * @fcport: fcport entry to updated 175 * 176 * Returns 0 on success. 177 */ 178 int 179 qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport) 180 { 181 int rval; 182 183 ms_iocb_entry_t *ms_pkt; 184 struct ct_sns_req *ct_req; 185 struct ct_sns_rsp *ct_rsp; 186 187 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 188 return (qla2x00_sns_ga_nxt(ha, fcport)); 189 } 190 191 /* Issue GA_NXT */ 192 /* Prepare common MS IOCB */ 193 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE); 194 195 /* Prepare CT request */ 196 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD, 197 GA_NXT_RSP_SIZE); 198 ct_rsp = &ha->ct_sns->p.rsp; 199 200 /* Prepare CT arguments -- port_id */ 201 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain; 202 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area; 203 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa; 204 205 /* Execute MS IOCB */ 206 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 207 sizeof(ms_iocb_entry_t)); 208 if (rval != QLA_SUCCESS) { 209 /*EMPTY*/ 210 DEBUG2_3(printk("scsi(%ld): GA_NXT issue IOCB failed (%d).\n", 211 ha->host_no, rval)); 212 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GA_NXT") != 213 QLA_SUCCESS) { 214 rval = QLA_FUNCTION_FAILED; 215 } else { 216 /* Populate fc_port_t entry. */ 217 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0]; 218 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1]; 219 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2]; 220 221 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name, 222 WWN_SIZE); 223 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name, 224 WWN_SIZE); 225 226 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE && 227 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE) 228 fcport->d_id.b.domain = 0xf0; 229 230 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - " 231 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 232 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 233 "portid=%02x%02x%02x.\n", 234 ha->host_no, 235 fcport->node_name[0], fcport->node_name[1], 236 fcport->node_name[2], fcport->node_name[3], 237 fcport->node_name[4], fcport->node_name[5], 238 fcport->node_name[6], fcport->node_name[7], 239 fcport->port_name[0], fcport->port_name[1], 240 fcport->port_name[2], fcport->port_name[3], 241 fcport->port_name[4], fcport->port_name[5], 242 fcport->port_name[6], fcport->port_name[7], 243 fcport->d_id.b.domain, fcport->d_id.b.area, 244 fcport->d_id.b.al_pa)); 245 } 246 247 return (rval); 248 } 249 250 /** 251 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command. 252 * @ha: HA context 253 * @list: switch info entries to populate 254 * 255 * NOTE: Non-Nx_Ports are not requested. 256 * 257 * Returns 0 on success. 258 */ 259 int 260 qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list) 261 { 262 int rval; 263 uint16_t i; 264 265 ms_iocb_entry_t *ms_pkt; 266 struct ct_sns_req *ct_req; 267 struct ct_sns_rsp *ct_rsp; 268 269 struct ct_sns_gid_pt_data *gid_data; 270 271 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 272 return (qla2x00_sns_gid_pt(ha, list)); 273 } 274 275 gid_data = NULL; 276 277 /* Issue GID_PT */ 278 /* Prepare common MS IOCB */ 279 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE); 280 281 /* Prepare CT request */ 282 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD, 283 GID_PT_RSP_SIZE); 284 ct_rsp = &ha->ct_sns->p.rsp; 285 286 /* Prepare CT arguments -- port_type */ 287 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE; 288 289 /* Execute MS IOCB */ 290 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 291 sizeof(ms_iocb_entry_t)); 292 if (rval != QLA_SUCCESS) { 293 /*EMPTY*/ 294 DEBUG2_3(printk("scsi(%ld): GID_PT issue IOCB failed (%d).\n", 295 ha->host_no, rval)); 296 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "GID_PT") != 297 QLA_SUCCESS) { 298 rval = QLA_FUNCTION_FAILED; 299 } else { 300 /* Set port IDs in switch info list. */ 301 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 302 gid_data = &ct_rsp->rsp.gid_pt.entries[i]; 303 list[i].d_id.b.domain = gid_data->port_id[0]; 304 list[i].d_id.b.area = gid_data->port_id[1]; 305 list[i].d_id.b.al_pa = gid_data->port_id[2]; 306 307 /* Last one exit. */ 308 if (gid_data->control_byte & BIT_7) { 309 list[i].d_id.b.rsvd_1 = gid_data->control_byte; 310 break; 311 } 312 } 313 314 /* 315 * If we've used all available slots, then the switch is 316 * reporting back more devices than we can handle with this 317 * single call. Return a failed status, and let GA_NXT handle 318 * the overload. 319 */ 320 if (i == MAX_FIBRE_DEVICES) 321 rval = QLA_FUNCTION_FAILED; 322 } 323 324 return (rval); 325 } 326 327 /** 328 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query. 329 * @ha: HA context 330 * @list: switch info entries to populate 331 * 332 * Returns 0 on success. 333 */ 334 int 335 qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list) 336 { 337 int rval; 338 uint16_t i; 339 340 ms_iocb_entry_t *ms_pkt; 341 struct ct_sns_req *ct_req; 342 struct ct_sns_rsp *ct_rsp; 343 344 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 345 return (qla2x00_sns_gpn_id(ha, list)); 346 } 347 348 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 349 /* Issue GPN_ID */ 350 /* Prepare common MS IOCB */ 351 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GPN_ID_REQ_SIZE, 352 GPN_ID_RSP_SIZE); 353 354 /* Prepare CT request */ 355 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD, 356 GPN_ID_RSP_SIZE); 357 ct_rsp = &ha->ct_sns->p.rsp; 358 359 /* Prepare CT arguments -- port_id */ 360 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 361 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 362 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 363 364 /* Execute MS IOCB */ 365 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 366 sizeof(ms_iocb_entry_t)); 367 if (rval != QLA_SUCCESS) { 368 /*EMPTY*/ 369 DEBUG2_3(printk("scsi(%ld): GPN_ID issue IOCB failed " 370 "(%d).\n", ha->host_no, rval)); 371 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, 372 "GPN_ID") != QLA_SUCCESS) { 373 rval = QLA_FUNCTION_FAILED; 374 } else { 375 /* Save portname */ 376 memcpy(list[i].port_name, 377 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE); 378 } 379 380 /* Last device exit. */ 381 if (list[i].d_id.b.rsvd_1 != 0) 382 break; 383 } 384 385 return (rval); 386 } 387 388 /** 389 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query. 390 * @ha: HA context 391 * @list: switch info entries to populate 392 * 393 * Returns 0 on success. 394 */ 395 int 396 qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list) 397 { 398 int rval; 399 uint16_t i; 400 401 ms_iocb_entry_t *ms_pkt; 402 struct ct_sns_req *ct_req; 403 struct ct_sns_rsp *ct_rsp; 404 405 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 406 return (qla2x00_sns_gnn_id(ha, list)); 407 } 408 409 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 410 /* Issue GNN_ID */ 411 /* Prepare common MS IOCB */ 412 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, GNN_ID_REQ_SIZE, 413 GNN_ID_RSP_SIZE); 414 415 /* Prepare CT request */ 416 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD, 417 GNN_ID_RSP_SIZE); 418 ct_rsp = &ha->ct_sns->p.rsp; 419 420 /* Prepare CT arguments -- port_id */ 421 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain; 422 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area; 423 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa; 424 425 /* Execute MS IOCB */ 426 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 427 sizeof(ms_iocb_entry_t)); 428 if (rval != QLA_SUCCESS) { 429 /*EMPTY*/ 430 DEBUG2_3(printk("scsi(%ld): GNN_ID issue IOCB failed " 431 "(%d).\n", ha->host_no, rval)); 432 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, 433 "GNN_ID") != QLA_SUCCESS) { 434 rval = QLA_FUNCTION_FAILED; 435 } else { 436 /* Save nodename */ 437 memcpy(list[i].node_name, 438 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE); 439 440 DEBUG2_3(printk("scsi(%ld): GID_PT entry - " 441 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 442 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 443 "portid=%02x%02x%02x.\n", 444 ha->host_no, 445 list[i].node_name[0], list[i].node_name[1], 446 list[i].node_name[2], list[i].node_name[3], 447 list[i].node_name[4], list[i].node_name[5], 448 list[i].node_name[6], list[i].node_name[7], 449 list[i].port_name[0], list[i].port_name[1], 450 list[i].port_name[2], list[i].port_name[3], 451 list[i].port_name[4], list[i].port_name[5], 452 list[i].port_name[6], list[i].port_name[7], 453 list[i].d_id.b.domain, list[i].d_id.b.area, 454 list[i].d_id.b.al_pa)); 455 } 456 457 /* Last device exit. */ 458 if (list[i].d_id.b.rsvd_1 != 0) 459 break; 460 } 461 462 return (rval); 463 } 464 465 /** 466 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 467 * @ha: HA context 468 * 469 * Returns 0 on success. 470 */ 471 int 472 qla2x00_rft_id(scsi_qla_host_t *ha) 473 { 474 int rval; 475 476 ms_iocb_entry_t *ms_pkt; 477 struct ct_sns_req *ct_req; 478 struct ct_sns_rsp *ct_rsp; 479 480 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 481 return (qla2x00_sns_rft_id(ha)); 482 } 483 484 /* Issue RFT_ID */ 485 /* Prepare common MS IOCB */ 486 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE); 487 488 /* Prepare CT request */ 489 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD, 490 RFT_ID_RSP_SIZE); 491 ct_rsp = &ha->ct_sns->p.rsp; 492 493 /* Prepare CT arguments -- port_id, FC-4 types */ 494 ct_req->req.rft_id.port_id[0] = ha->d_id.b.domain; 495 ct_req->req.rft_id.port_id[1] = ha->d_id.b.area; 496 ct_req->req.rft_id.port_id[2] = ha->d_id.b.al_pa; 497 498 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */ 499 500 /* Execute MS IOCB */ 501 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 502 sizeof(ms_iocb_entry_t)); 503 if (rval != QLA_SUCCESS) { 504 /*EMPTY*/ 505 DEBUG2_3(printk("scsi(%ld): RFT_ID issue IOCB failed (%d).\n", 506 ha->host_no, rval)); 507 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFT_ID") != 508 QLA_SUCCESS) { 509 rval = QLA_FUNCTION_FAILED; 510 } else { 511 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n", 512 ha->host_no)); 513 } 514 515 return (rval); 516 } 517 518 /** 519 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA. 520 * @ha: HA context 521 * 522 * Returns 0 on success. 523 */ 524 int 525 qla2x00_rff_id(scsi_qla_host_t *ha) 526 { 527 int rval; 528 529 ms_iocb_entry_t *ms_pkt; 530 struct ct_sns_req *ct_req; 531 struct ct_sns_rsp *ct_rsp; 532 533 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 534 DEBUG2(printk("scsi(%ld): RFF_ID call unsupported on " 535 "ISP2100/ISP2200.\n", ha->host_no)); 536 return (QLA_SUCCESS); 537 } 538 539 /* Issue RFF_ID */ 540 /* Prepare common MS IOCB */ 541 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE); 542 543 /* Prepare CT request */ 544 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD, 545 RFF_ID_RSP_SIZE); 546 ct_rsp = &ha->ct_sns->p.rsp; 547 548 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */ 549 ct_req->req.rff_id.port_id[0] = ha->d_id.b.domain; 550 ct_req->req.rff_id.port_id[1] = ha->d_id.b.area; 551 ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa; 552 553 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */ 554 555 /* Execute MS IOCB */ 556 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 557 sizeof(ms_iocb_entry_t)); 558 if (rval != QLA_SUCCESS) { 559 /*EMPTY*/ 560 DEBUG2_3(printk("scsi(%ld): RFF_ID issue IOCB failed (%d).\n", 561 ha->host_no, rval)); 562 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RFF_ID") != 563 QLA_SUCCESS) { 564 rval = QLA_FUNCTION_FAILED; 565 } else { 566 DEBUG2(printk("scsi(%ld): RFF_ID exiting normally.\n", 567 ha->host_no)); 568 } 569 570 return (rval); 571 } 572 573 /** 574 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 575 * @ha: HA context 576 * 577 * Returns 0 on success. 578 */ 579 int 580 qla2x00_rnn_id(scsi_qla_host_t *ha) 581 { 582 int rval; 583 584 ms_iocb_entry_t *ms_pkt; 585 struct ct_sns_req *ct_req; 586 struct ct_sns_rsp *ct_rsp; 587 588 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 589 return (qla2x00_sns_rnn_id(ha)); 590 } 591 592 /* Issue RNN_ID */ 593 /* Prepare common MS IOCB */ 594 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE); 595 596 /* Prepare CT request */ 597 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD, 598 RNN_ID_RSP_SIZE); 599 ct_rsp = &ha->ct_sns->p.rsp; 600 601 /* Prepare CT arguments -- port_id, node_name */ 602 ct_req->req.rnn_id.port_id[0] = ha->d_id.b.domain; 603 ct_req->req.rnn_id.port_id[1] = ha->d_id.b.area; 604 ct_req->req.rnn_id.port_id[2] = ha->d_id.b.al_pa; 605 606 memcpy(ct_req->req.rnn_id.node_name, ha->node_name, WWN_SIZE); 607 608 /* Execute MS IOCB */ 609 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 610 sizeof(ms_iocb_entry_t)); 611 if (rval != QLA_SUCCESS) { 612 /*EMPTY*/ 613 DEBUG2_3(printk("scsi(%ld): RNN_ID issue IOCB failed (%d).\n", 614 ha->host_no, rval)); 615 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RNN_ID") != 616 QLA_SUCCESS) { 617 rval = QLA_FUNCTION_FAILED; 618 } else { 619 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n", 620 ha->host_no)); 621 } 622 623 return (rval); 624 } 625 626 /** 627 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA. 628 * @ha: HA context 629 * 630 * Returns 0 on success. 631 */ 632 int 633 qla2x00_rsnn_nn(scsi_qla_host_t *ha) 634 { 635 int rval; 636 uint8_t *snn; 637 uint8_t version[20]; 638 639 ms_iocb_entry_t *ms_pkt; 640 struct ct_sns_req *ct_req; 641 struct ct_sns_rsp *ct_rsp; 642 643 if (IS_QLA2100(ha) || IS_QLA2200(ha)) { 644 DEBUG2(printk("scsi(%ld): RSNN_ID call unsupported on " 645 "ISP2100/ISP2200.\n", ha->host_no)); 646 return (QLA_SUCCESS); 647 } 648 649 /* Issue RSNN_NN */ 650 /* Prepare common MS IOCB */ 651 /* Request size adjusted after CT preparation */ 652 ms_pkt = ha->isp_ops.prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE); 653 654 /* Prepare CT request */ 655 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD, 656 RSNN_NN_RSP_SIZE); 657 ct_rsp = &ha->ct_sns->p.rsp; 658 659 /* Prepare CT arguments -- node_name, symbolic node_name, size */ 660 memcpy(ct_req->req.rsnn_nn.node_name, ha->node_name, WWN_SIZE); 661 662 /* Prepare the Symbolic Node Name */ 663 /* Board type */ 664 snn = ct_req->req.rsnn_nn.sym_node_name; 665 strcpy(snn, ha->model_number); 666 /* Firmware version */ 667 strcat(snn, " FW:v"); 668 sprintf(version, "%d.%02d.%02d", ha->fw_major_version, 669 ha->fw_minor_version, ha->fw_subminor_version); 670 strcat(snn, version); 671 /* Driver version */ 672 strcat(snn, " DVR:v"); 673 strcat(snn, qla2x00_version_str); 674 675 /* Calculate SNN length */ 676 ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn); 677 678 /* Update MS IOCB request */ 679 ms_pkt->req_bytecount = 680 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len); 681 ms_pkt->dseg_req_length = ms_pkt->req_bytecount; 682 683 /* Execute MS IOCB */ 684 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma, 685 sizeof(ms_iocb_entry_t)); 686 if (rval != QLA_SUCCESS) { 687 /*EMPTY*/ 688 DEBUG2_3(printk("scsi(%ld): RSNN_NN issue IOCB failed (%d).\n", 689 ha->host_no, rval)); 690 } else if (qla2x00_chk_ms_status(ha, ms_pkt, ct_rsp, "RSNN_NN") != 691 QLA_SUCCESS) { 692 rval = QLA_FUNCTION_FAILED; 693 } else { 694 DEBUG2(printk("scsi(%ld): RSNN_NN exiting normally.\n", 695 ha->host_no)); 696 } 697 698 return (rval); 699 } 700 701 702 /** 703 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query. 704 * @ha: HA context 705 * @cmd: GS command 706 * @scmd_len: Subcommand length 707 * @data_size: response size in bytes 708 * 709 * Returns a pointer to the @ha's sns_cmd. 710 */ 711 static inline struct sns_cmd_pkt * 712 qla2x00_prep_sns_cmd(scsi_qla_host_t *ha, uint16_t cmd, uint16_t scmd_len, 713 uint16_t data_size) 714 { 715 uint16_t wc; 716 struct sns_cmd_pkt *sns_cmd; 717 718 sns_cmd = ha->sns_cmd; 719 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt)); 720 wc = data_size / 2; /* Size in 16bit words. */ 721 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc); 722 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma)); 723 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma)); 724 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len); 725 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd); 726 wc = (data_size - 16) / 4; /* Size in 32bit words. */ 727 sns_cmd->p.cmd.size = cpu_to_le16(wc); 728 729 return (sns_cmd); 730 } 731 732 /** 733 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command. 734 * @ha: HA context 735 * @fcport: fcport entry to updated 736 * 737 * This command uses the old Exectute SNS Command mailbox routine. 738 * 739 * Returns 0 on success. 740 */ 741 static int 742 qla2x00_sns_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport) 743 { 744 int rval; 745 746 struct sns_cmd_pkt *sns_cmd; 747 748 /* Issue GA_NXT. */ 749 /* Prepare SNS command request. */ 750 sns_cmd = qla2x00_prep_sns_cmd(ha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN, 751 GA_NXT_SNS_DATA_SIZE); 752 753 /* Prepare SNS command arguments -- port_id. */ 754 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa; 755 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area; 756 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain; 757 758 /* Execute SNS command. */ 759 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2, 760 sizeof(struct sns_cmd_pkt)); 761 if (rval != QLA_SUCCESS) { 762 /*EMPTY*/ 763 DEBUG2_3(printk("scsi(%ld): GA_NXT Send SNS failed (%d).\n", 764 ha->host_no, rval)); 765 } else if (sns_cmd->p.gan_data[8] != 0x80 || 766 sns_cmd->p.gan_data[9] != 0x02) { 767 DEBUG2_3(printk("scsi(%ld): GA_NXT failed, rejected request, " 768 "ga_nxt_rsp:\n", ha->host_no)); 769 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gan_data, 16)); 770 rval = QLA_FUNCTION_FAILED; 771 } else { 772 /* Populate fc_port_t entry. */ 773 fcport->d_id.b.domain = sns_cmd->p.gan_data[17]; 774 fcport->d_id.b.area = sns_cmd->p.gan_data[18]; 775 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19]; 776 777 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE); 778 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE); 779 780 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE && 781 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE) 782 fcport->d_id.b.domain = 0xf0; 783 784 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - " 785 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 786 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 787 "portid=%02x%02x%02x.\n", 788 ha->host_no, 789 fcport->node_name[0], fcport->node_name[1], 790 fcport->node_name[2], fcport->node_name[3], 791 fcport->node_name[4], fcport->node_name[5], 792 fcport->node_name[6], fcport->node_name[7], 793 fcport->port_name[0], fcport->port_name[1], 794 fcport->port_name[2], fcport->port_name[3], 795 fcport->port_name[4], fcport->port_name[5], 796 fcport->port_name[6], fcport->port_name[7], 797 fcport->d_id.b.domain, fcport->d_id.b.area, 798 fcport->d_id.b.al_pa)); 799 } 800 801 return (rval); 802 } 803 804 /** 805 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command. 806 * @ha: HA context 807 * @list: switch info entries to populate 808 * 809 * This command uses the old Exectute SNS Command mailbox routine. 810 * 811 * NOTE: Non-Nx_Ports are not requested. 812 * 813 * Returns 0 on success. 814 */ 815 static int 816 qla2x00_sns_gid_pt(scsi_qla_host_t *ha, sw_info_t *list) 817 { 818 int rval; 819 820 uint16_t i; 821 uint8_t *entry; 822 struct sns_cmd_pkt *sns_cmd; 823 824 /* Issue GID_PT. */ 825 /* Prepare SNS command request. */ 826 sns_cmd = qla2x00_prep_sns_cmd(ha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN, 827 GID_PT_SNS_DATA_SIZE); 828 829 /* Prepare SNS command arguments -- port_type. */ 830 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE; 831 832 /* Execute SNS command. */ 833 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2, 834 sizeof(struct sns_cmd_pkt)); 835 if (rval != QLA_SUCCESS) { 836 /*EMPTY*/ 837 DEBUG2_3(printk("scsi(%ld): GID_PT Send SNS failed (%d).\n", 838 ha->host_no, rval)); 839 } else if (sns_cmd->p.gid_data[8] != 0x80 || 840 sns_cmd->p.gid_data[9] != 0x02) { 841 DEBUG2_3(printk("scsi(%ld): GID_PT failed, rejected request, " 842 "gid_rsp:\n", ha->host_no)); 843 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gid_data, 16)); 844 rval = QLA_FUNCTION_FAILED; 845 } else { 846 /* Set port IDs in switch info list. */ 847 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 848 entry = &sns_cmd->p.gid_data[(i * 4) + 16]; 849 list[i].d_id.b.domain = entry[1]; 850 list[i].d_id.b.area = entry[2]; 851 list[i].d_id.b.al_pa = entry[3]; 852 853 /* Last one exit. */ 854 if (entry[0] & BIT_7) { 855 list[i].d_id.b.rsvd_1 = entry[0]; 856 break; 857 } 858 } 859 860 /* 861 * If we've used all available slots, then the switch is 862 * reporting back more devices that we can handle with this 863 * single call. Return a failed status, and let GA_NXT handle 864 * the overload. 865 */ 866 if (i == MAX_FIBRE_DEVICES) 867 rval = QLA_FUNCTION_FAILED; 868 } 869 870 return (rval); 871 } 872 873 /** 874 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query. 875 * @ha: HA context 876 * @list: switch info entries to populate 877 * 878 * This command uses the old Exectute SNS Command mailbox routine. 879 * 880 * Returns 0 on success. 881 */ 882 static int 883 qla2x00_sns_gpn_id(scsi_qla_host_t *ha, sw_info_t *list) 884 { 885 int rval; 886 887 uint16_t i; 888 struct sns_cmd_pkt *sns_cmd; 889 890 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 891 /* Issue GPN_ID */ 892 /* Prepare SNS command request. */ 893 sns_cmd = qla2x00_prep_sns_cmd(ha, GPN_ID_CMD, 894 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE); 895 896 /* Prepare SNS command arguments -- port_id. */ 897 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 898 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 899 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 900 901 /* Execute SNS command. */ 902 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, 903 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 904 if (rval != QLA_SUCCESS) { 905 /*EMPTY*/ 906 DEBUG2_3(printk("scsi(%ld): GPN_ID Send SNS failed " 907 "(%d).\n", ha->host_no, rval)); 908 } else if (sns_cmd->p.gpn_data[8] != 0x80 || 909 sns_cmd->p.gpn_data[9] != 0x02) { 910 DEBUG2_3(printk("scsi(%ld): GPN_ID failed, rejected " 911 "request, gpn_rsp:\n", ha->host_no)); 912 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gpn_data, 16)); 913 rval = QLA_FUNCTION_FAILED; 914 } else { 915 /* Save portname */ 916 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16], 917 WWN_SIZE); 918 } 919 920 /* Last device exit. */ 921 if (list[i].d_id.b.rsvd_1 != 0) 922 break; 923 } 924 925 return (rval); 926 } 927 928 /** 929 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query. 930 * @ha: HA context 931 * @list: switch info entries to populate 932 * 933 * This command uses the old Exectute SNS Command mailbox routine. 934 * 935 * Returns 0 on success. 936 */ 937 static int 938 qla2x00_sns_gnn_id(scsi_qla_host_t *ha, sw_info_t *list) 939 { 940 int rval; 941 942 uint16_t i; 943 struct sns_cmd_pkt *sns_cmd; 944 945 for (i = 0; i < MAX_FIBRE_DEVICES; i++) { 946 /* Issue GNN_ID */ 947 /* Prepare SNS command request. */ 948 sns_cmd = qla2x00_prep_sns_cmd(ha, GNN_ID_CMD, 949 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE); 950 951 /* Prepare SNS command arguments -- port_id. */ 952 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa; 953 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area; 954 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain; 955 956 /* Execute SNS command. */ 957 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, 958 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt)); 959 if (rval != QLA_SUCCESS) { 960 /*EMPTY*/ 961 DEBUG2_3(printk("scsi(%ld): GNN_ID Send SNS failed " 962 "(%d).\n", ha->host_no, rval)); 963 } else if (sns_cmd->p.gnn_data[8] != 0x80 || 964 sns_cmd->p.gnn_data[9] != 0x02) { 965 DEBUG2_3(printk("scsi(%ld): GNN_ID failed, rejected " 966 "request, gnn_rsp:\n", ha->host_no)); 967 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gnn_data, 16)); 968 rval = QLA_FUNCTION_FAILED; 969 } else { 970 /* Save nodename */ 971 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16], 972 WWN_SIZE); 973 974 DEBUG2_3(printk("scsi(%ld): GID_PT entry - " 975 "nn %02x%02x%02x%02x%02x%02x%02x%02x " 976 "pn %02x%02x%02x%02x%02x%02x%02x%02x " 977 "portid=%02x%02x%02x.\n", 978 ha->host_no, 979 list[i].node_name[0], list[i].node_name[1], 980 list[i].node_name[2], list[i].node_name[3], 981 list[i].node_name[4], list[i].node_name[5], 982 list[i].node_name[6], list[i].node_name[7], 983 list[i].port_name[0], list[i].port_name[1], 984 list[i].port_name[2], list[i].port_name[3], 985 list[i].port_name[4], list[i].port_name[5], 986 list[i].port_name[6], list[i].port_name[7], 987 list[i].d_id.b.domain, list[i].d_id.b.area, 988 list[i].d_id.b.al_pa)); 989 } 990 991 /* Last device exit. */ 992 if (list[i].d_id.b.rsvd_1 != 0) 993 break; 994 } 995 996 return (rval); 997 } 998 999 /** 1000 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA. 1001 * @ha: HA context 1002 * 1003 * This command uses the old Exectute SNS Command mailbox routine. 1004 * 1005 * Returns 0 on success. 1006 */ 1007 static int 1008 qla2x00_sns_rft_id(scsi_qla_host_t *ha) 1009 { 1010 int rval; 1011 1012 struct sns_cmd_pkt *sns_cmd; 1013 1014 /* Issue RFT_ID. */ 1015 /* Prepare SNS command request. */ 1016 sns_cmd = qla2x00_prep_sns_cmd(ha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN, 1017 RFT_ID_SNS_DATA_SIZE); 1018 1019 /* Prepare SNS command arguments -- port_id, FC-4 types */ 1020 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa; 1021 sns_cmd->p.cmd.param[1] = ha->d_id.b.area; 1022 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain; 1023 1024 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */ 1025 1026 /* Execute SNS command. */ 1027 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2, 1028 sizeof(struct sns_cmd_pkt)); 1029 if (rval != QLA_SUCCESS) { 1030 /*EMPTY*/ 1031 DEBUG2_3(printk("scsi(%ld): RFT_ID Send SNS failed (%d).\n", 1032 ha->host_no, rval)); 1033 } else if (sns_cmd->p.rft_data[8] != 0x80 || 1034 sns_cmd->p.rft_data[9] != 0x02) { 1035 DEBUG2_3(printk("scsi(%ld): RFT_ID failed, rejected request, " 1036 "rft_rsp:\n", ha->host_no)); 1037 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rft_data, 16)); 1038 rval = QLA_FUNCTION_FAILED; 1039 } else { 1040 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n", 1041 ha->host_no)); 1042 } 1043 1044 return (rval); 1045 } 1046 1047 /** 1048 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA. 1049 * HBA. 1050 * @ha: HA context 1051 * 1052 * This command uses the old Exectute SNS Command mailbox routine. 1053 * 1054 * Returns 0 on success. 1055 */ 1056 static int 1057 qla2x00_sns_rnn_id(scsi_qla_host_t *ha) 1058 { 1059 int rval; 1060 1061 struct sns_cmd_pkt *sns_cmd; 1062 1063 /* Issue RNN_ID. */ 1064 /* Prepare SNS command request. */ 1065 sns_cmd = qla2x00_prep_sns_cmd(ha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN, 1066 RNN_ID_SNS_DATA_SIZE); 1067 1068 /* Prepare SNS command arguments -- port_id, nodename. */ 1069 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa; 1070 sns_cmd->p.cmd.param[1] = ha->d_id.b.area; 1071 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain; 1072 1073 sns_cmd->p.cmd.param[4] = ha->node_name[7]; 1074 sns_cmd->p.cmd.param[5] = ha->node_name[6]; 1075 sns_cmd->p.cmd.param[6] = ha->node_name[5]; 1076 sns_cmd->p.cmd.param[7] = ha->node_name[4]; 1077 sns_cmd->p.cmd.param[8] = ha->node_name[3]; 1078 sns_cmd->p.cmd.param[9] = ha->node_name[2]; 1079 sns_cmd->p.cmd.param[10] = ha->node_name[1]; 1080 sns_cmd->p.cmd.param[11] = ha->node_name[0]; 1081 1082 /* Execute SNS command. */ 1083 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2, 1084 sizeof(struct sns_cmd_pkt)); 1085 if (rval != QLA_SUCCESS) { 1086 /*EMPTY*/ 1087 DEBUG2_3(printk("scsi(%ld): RNN_ID Send SNS failed (%d).\n", 1088 ha->host_no, rval)); 1089 } else if (sns_cmd->p.rnn_data[8] != 0x80 || 1090 sns_cmd->p.rnn_data[9] != 0x02) { 1091 DEBUG2_3(printk("scsi(%ld): RNN_ID failed, rejected request, " 1092 "rnn_rsp:\n", ha->host_no)); 1093 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rnn_data, 16)); 1094 rval = QLA_FUNCTION_FAILED; 1095 } else { 1096 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n", 1097 ha->host_no)); 1098 } 1099 1100 return (rval); 1101 } 1102