2 * QLOGIC LINUX SOFTWARE
4 * QLogic ISP2x00 device driver for Linux 2.6.x
5 * Copyright (C) 2003-2004 QLogic Corporation
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
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.
23 static inline ms_iocb_entry_t *
24 qla2x00_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t);
26 static inline struct ct_sns_req *
27 qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
29 static inline struct sns_cmd_pkt *
30 qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
32 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
33 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
34 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
35 static int qla2x00_sns_gnn_id(scsi_qla_host_t *, sw_info_t *);
36 static int qla2x00_sns_rft_id(scsi_qla_host_t *);
37 static int qla2x00_sns_rff_id(scsi_qla_host_t *);
38 static int qla2x00_sns_rnn_id(scsi_qla_host_t *);
41 * qla2x00_prep_ms_iocb() - Prepare common MS IOCB fields for SNS CT query.
43 * @req_size: request size in bytes
44 * @rsp_size: response size in bytes
46 * Returns a pointer to the @ha's ms_iocb.
48 static inline ms_iocb_entry_t *
49 qla2x00_prep_ms_iocb(scsi_qla_host_t *ha, uint32_t req_size, uint32_t rsp_size)
51 ms_iocb_entry_t *ms_pkt;
54 memset(ms_pkt, 0, sizeof(ms_iocb_entry_t));
56 ms_pkt->entry_type = MS_IOCB_TYPE;
57 ms_pkt->entry_count = 1;
58 SET_TARGET_ID(ha, ms_pkt->loop_id, SIMPLE_NAME_SERVER);
59 ms_pkt->control_flags = __constant_cpu_to_le16(CF_READ | CF_HEAD_TAG);
60 ms_pkt->timeout = __constant_cpu_to_le16(25);
61 ms_pkt->cmd_dsd_count = __constant_cpu_to_le16(1);
62 ms_pkt->total_dsd_count = __constant_cpu_to_le16(2);
63 ms_pkt->rsp_bytecount = cpu_to_le32(rsp_size);
64 ms_pkt->req_bytecount = cpu_to_le32(req_size);
66 ms_pkt->dseg_req_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
67 ms_pkt->dseg_req_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
68 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
70 ms_pkt->dseg_rsp_address[0] = cpu_to_le32(LSD(ha->ct_sns_dma));
71 ms_pkt->dseg_rsp_address[1] = cpu_to_le32(MSD(ha->ct_sns_dma));
72 ms_pkt->dseg_rsp_length = ms_pkt->rsp_bytecount;
78 * qla2x00_prep_ct_req() - Prepare common CT request fields for SNS query.
79 * @ct_req: CT request buffer
81 * @rsp_size: response size in bytes
83 * Returns a pointer to the intitialized @ct_req.
85 static inline struct ct_sns_req *
86 qla2x00_prep_ct_req(struct ct_sns_req *ct_req, uint16_t cmd, uint16_t rsp_size)
88 memset(ct_req, 0, sizeof(struct ct_sns_pkt));
90 ct_req->header.revision = 0x01;
91 ct_req->header.gs_type = 0xFC;
92 ct_req->header.gs_subtype = 0x02;
93 ct_req->command = cpu_to_be16(cmd);
94 ct_req->max_rsp_size = cpu_to_be16((rsp_size - 16) / 4);
101 * qla2x00_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
103 * @fcport: fcport entry to updated
105 * Returns 0 on success.
108 qla2x00_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport)
112 ms_iocb_entry_t *ms_pkt;
113 struct ct_sns_req *ct_req;
114 struct ct_sns_rsp *ct_rsp;
116 if (IS_QLA2200(ha)) {
117 return (qla2x00_sns_ga_nxt(ha, fcport));
121 /* Prepare common MS IOCB */
122 ms_pkt = qla2x00_prep_ms_iocb(ha, GA_NXT_REQ_SIZE, GA_NXT_RSP_SIZE);
124 /* Prepare CT request */
125 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GA_NXT_CMD,
127 ct_rsp = &ha->ct_sns->p.rsp;
129 /* Prepare CT arguments -- port_id */
130 ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
131 ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
132 ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
134 /* Execute MS IOCB */
135 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
136 sizeof(ms_iocb_entry_t));
137 if (rval != QLA_SUCCESS) {
139 DEBUG2_3(printk("scsi(%ld): GA_NXT issue IOCB failed (%d).\n",
141 } else if (ct_rsp->header.response !=
142 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
143 DEBUG2_3(printk("scsi(%ld): GA_NXT failed, rejected request, "
144 "ga_nxt_rsp:\n", ha->host_no));
145 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
146 sizeof(struct ct_rsp_hdr)));
147 rval = QLA_FUNCTION_FAILED;
149 /* Populate fc_port_t entry. */
150 fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
151 fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
152 fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
154 memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
156 memcpy(fcport->port_name, ct_rsp->rsp.ga_nxt.port_name,
159 if (ct_rsp->rsp.ga_nxt.port_type != NS_N_PORT_TYPE &&
160 ct_rsp->rsp.ga_nxt.port_type != NS_NL_PORT_TYPE)
161 fcport->d_id.b.domain = 0xf0;
163 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - "
164 "nn %02x%02x%02x%02x%02x%02x%02x%02x "
165 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
166 "portid=%02x%02x%02x.\n",
168 fcport->node_name[0], fcport->node_name[1],
169 fcport->node_name[2], fcport->node_name[3],
170 fcport->node_name[4], fcport->node_name[5],
171 fcport->node_name[6], fcport->node_name[7],
172 fcport->port_name[0], fcport->port_name[1],
173 fcport->port_name[2], fcport->port_name[3],
174 fcport->port_name[4], fcport->port_name[5],
175 fcport->port_name[6], fcport->port_name[7],
176 fcport->d_id.b.domain, fcport->d_id.b.area,
177 fcport->d_id.b.al_pa));
184 * qla2x00_gid_pt() - SNS scan for fabric devices via GID_PT command.
186 * @list: switch info entries to populate
188 * NOTE: Non-Nx_Ports are not requested.
190 * Returns 0 on success.
193 qla2x00_gid_pt(scsi_qla_host_t *ha, sw_info_t *list)
198 ms_iocb_entry_t *ms_pkt;
199 struct ct_sns_req *ct_req;
200 struct ct_sns_rsp *ct_rsp;
202 struct ct_sns_gid_pt_data *gid_data;
204 if (IS_QLA2200(ha)) {
205 return (qla2x00_sns_gid_pt(ha, list));
211 /* Prepare common MS IOCB */
212 ms_pkt = qla2x00_prep_ms_iocb(ha, GID_PT_REQ_SIZE, GID_PT_RSP_SIZE);
214 /* Prepare CT request */
215 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GID_PT_CMD,
217 ct_rsp = &ha->ct_sns->p.rsp;
219 /* Prepare CT arguments -- port_type */
220 ct_req->req.gid_pt.port_type = NS_NX_PORT_TYPE;
222 /* Execute MS IOCB */
223 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
224 sizeof(ms_iocb_entry_t));
225 if (rval != QLA_SUCCESS) {
227 DEBUG2_3(printk("scsi(%ld): GID_PT issue IOCB failed (%d).\n",
229 } else if (ct_rsp->header.response !=
230 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
231 DEBUG2_3(printk("scsi(%ld): GID_PT failed, rejected request, "
232 "gid_pt_rsp:\n", ha->host_no));
233 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
234 sizeof(struct ct_rsp_hdr)));
235 rval = QLA_FUNCTION_FAILED;
237 /* Set port IDs in switch info list. */
238 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
239 gid_data = &ct_rsp->rsp.gid_pt.entries[i];
240 list[i].d_id.b.domain = gid_data->port_id[0];
241 list[i].d_id.b.area = gid_data->port_id[1];
242 list[i].d_id.b.al_pa = gid_data->port_id[2];
245 if (gid_data->control_byte & BIT_7) {
246 list[i].d_id.b.rsvd_1 = gid_data->control_byte;
252 * If we've used all available slots, then the switch is
253 * reporting back more devices than we can handle with this
254 * single call. Return a failed status, and let GA_NXT handle
257 if (i == MAX_FIBRE_DEVICES)
258 rval = QLA_FUNCTION_FAILED;
265 * qla2x00_gpn_id() - SNS Get Port Name (GPN_ID) query.
267 * @list: switch info entries to populate
269 * Returns 0 on success.
272 qla2x00_gpn_id(scsi_qla_host_t *ha, sw_info_t *list)
277 ms_iocb_entry_t *ms_pkt;
278 struct ct_sns_req *ct_req;
279 struct ct_sns_rsp *ct_rsp;
281 if (IS_QLA2200(ha)) {
282 return (qla2x00_sns_gpn_id(ha, list));
285 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
287 /* Prepare common MS IOCB */
288 ms_pkt = qla2x00_prep_ms_iocb(ha, GPN_ID_REQ_SIZE,
291 /* Prepare CT request */
292 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GPN_ID_CMD,
294 ct_rsp = &ha->ct_sns->p.rsp;
296 /* Prepare CT arguments -- port_id */
297 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
298 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
299 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
301 /* Execute MS IOCB */
302 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
303 sizeof(ms_iocb_entry_t));
304 if (rval != QLA_SUCCESS) {
306 DEBUG2_3(printk("scsi(%ld): GPN_ID issue IOCB failed "
307 "(%d).\n", ha->host_no, rval));
308 } else if (ct_rsp->header.response !=
309 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
310 DEBUG2_3(printk("scsi(%ld): GPN_ID failed, rejected "
311 "request, gpn_id_rsp:\n", ha->host_no));
312 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
313 sizeof(struct ct_rsp_hdr)));
314 rval = QLA_FUNCTION_FAILED;
317 memcpy(list[i].port_name,
318 ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
321 /* Last device exit. */
322 if (list[i].d_id.b.rsvd_1 != 0)
330 * qla2x00_gnn_id() - SNS Get Node Name (GNN_ID) query.
332 * @list: switch info entries to populate
334 * Returns 0 on success.
337 qla2x00_gnn_id(scsi_qla_host_t *ha, sw_info_t *list)
342 ms_iocb_entry_t *ms_pkt;
343 struct ct_sns_req *ct_req;
344 struct ct_sns_rsp *ct_rsp;
346 if (IS_QLA2200(ha)) {
347 return (qla2x00_sns_gnn_id(ha, list));
350 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
352 /* Prepare common MS IOCB */
353 ms_pkt = qla2x00_prep_ms_iocb(ha, GNN_ID_REQ_SIZE,
356 /* Prepare CT request */
357 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, GNN_ID_CMD,
359 ct_rsp = &ha->ct_sns->p.rsp;
361 /* Prepare CT arguments -- port_id */
362 ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
363 ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
364 ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
366 /* Execute MS IOCB */
367 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
368 sizeof(ms_iocb_entry_t));
369 if (rval != QLA_SUCCESS) {
371 DEBUG2_3(printk("scsi(%ld): GNN_ID issue IOCB failed "
372 "(%d).\n", ha->host_no, rval));
373 } else if (ct_rsp->header.response !=
374 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
375 DEBUG2_3(printk("scsi(%ld): GNN_ID failed, rejected "
376 "request, gnn_id_rsp:\n", ha->host_no));
377 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
378 sizeof(struct ct_rsp_hdr)));
379 rval = QLA_FUNCTION_FAILED;
382 memcpy(list[i].node_name,
383 ct_rsp->rsp.gnn_id.node_name, WWN_SIZE);
385 DEBUG2_3(printk("scsi(%ld): GID_PT entry - "
386 "nn %02x%02x%02x%02x%02x%02x%02x%02x "
387 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
388 "portid=%02x%02x%02x.\n",
390 list[i].node_name[0], list[i].node_name[1],
391 list[i].node_name[2], list[i].node_name[3],
392 list[i].node_name[4], list[i].node_name[5],
393 list[i].node_name[6], list[i].node_name[7],
394 list[i].port_name[0], list[i].port_name[1],
395 list[i].port_name[2], list[i].port_name[3],
396 list[i].port_name[4], list[i].port_name[5],
397 list[i].port_name[6], list[i].port_name[7],
398 list[i].d_id.b.domain, list[i].d_id.b.area,
399 list[i].d_id.b.al_pa));
402 /* Last device exit. */
403 if (list[i].d_id.b.rsvd_1 != 0)
411 * qla2x00_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
414 * Returns 0 on success.
417 qla2x00_rft_id(scsi_qla_host_t *ha)
421 ms_iocb_entry_t *ms_pkt;
422 struct ct_sns_req *ct_req;
423 struct ct_sns_rsp *ct_rsp;
425 if (IS_QLA2200(ha)) {
426 return (qla2x00_sns_rft_id(ha));
430 /* Prepare common MS IOCB */
431 ms_pkt = qla2x00_prep_ms_iocb(ha, RFT_ID_REQ_SIZE, RFT_ID_RSP_SIZE);
433 /* Prepare CT request */
434 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFT_ID_CMD,
436 ct_rsp = &ha->ct_sns->p.rsp;
438 /* Prepare CT arguments -- port_id, FC-4 types */
439 ct_req->req.rft_id.port_id[0] = ha->d_id.b.domain;
440 ct_req->req.rft_id.port_id[1] = ha->d_id.b.area;
441 ct_req->req.rft_id.port_id[2] = ha->d_id.b.al_pa;
443 ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
445 /* Execute MS IOCB */
446 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
447 sizeof(ms_iocb_entry_t));
448 if (rval != QLA_SUCCESS) {
450 DEBUG2_3(printk("scsi(%ld): RFT_ID issue IOCB failed (%d).\n",
452 } else if (ct_rsp->header.response !=
453 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
454 DEBUG2_3(printk("scsi(%ld): RFT_ID failed, rejected "
455 "request, rft_id_rsp:\n", ha->host_no));
456 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
457 sizeof(struct ct_rsp_hdr)));
458 rval = QLA_FUNCTION_FAILED;
460 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n",
468 * qla2x00_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the HBA.
471 * Returns 0 on success.
474 qla2x00_rff_id(scsi_qla_host_t *ha)
478 ms_iocb_entry_t *ms_pkt;
479 struct ct_sns_req *ct_req;
480 struct ct_sns_rsp *ct_rsp;
482 if (IS_QLA2200(ha)) {
483 return (qla2x00_sns_rff_id(ha));
487 /* Prepare common MS IOCB */
488 ms_pkt = qla2x00_prep_ms_iocb(ha, RFF_ID_REQ_SIZE, RFF_ID_RSP_SIZE);
490 /* Prepare CT request */
491 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RFF_ID_CMD,
493 ct_rsp = &ha->ct_sns->p.rsp;
495 /* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
496 ct_req->req.rff_id.port_id[0] = ha->d_id.b.domain;
497 ct_req->req.rff_id.port_id[1] = ha->d_id.b.area;
498 ct_req->req.rff_id.port_id[2] = ha->d_id.b.al_pa;
500 ct_req->req.rff_id.fc4_type = 0x08; /* SCSI - FCP */
502 /* Execute MS IOCB */
503 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
504 sizeof(ms_iocb_entry_t));
505 if (rval != QLA_SUCCESS) {
507 DEBUG2_3(printk("scsi(%ld): RFF_ID issue IOCB failed (%d).\n",
509 } else if (ct_rsp->header.response !=
510 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
511 DEBUG2_3(printk("scsi(%ld): RFF_ID failed, rejected "
512 "request, rff_id_rsp:\n", ha->host_no));
513 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
514 sizeof(struct ct_rsp_hdr)));
515 rval = QLA_FUNCTION_FAILED;
517 DEBUG2(printk("scsi(%ld): RFF_ID exiting normally.\n",
525 * qla2x00_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
528 * Returns 0 on success.
531 qla2x00_rnn_id(scsi_qla_host_t *ha)
535 ms_iocb_entry_t *ms_pkt;
536 struct ct_sns_req *ct_req;
537 struct ct_sns_rsp *ct_rsp;
539 if (IS_QLA2200(ha)) {
540 return (qla2x00_sns_rnn_id(ha));
544 /* Prepare common MS IOCB */
545 ms_pkt = qla2x00_prep_ms_iocb(ha, RNN_ID_REQ_SIZE, RNN_ID_RSP_SIZE);
547 /* Prepare CT request */
548 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RNN_ID_CMD,
550 ct_rsp = &ha->ct_sns->p.rsp;
552 /* Prepare CT arguments -- port_id, node_name */
553 ct_req->req.rnn_id.port_id[0] = ha->d_id.b.domain;
554 ct_req->req.rnn_id.port_id[1] = ha->d_id.b.area;
555 ct_req->req.rnn_id.port_id[2] = ha->d_id.b.al_pa;
557 memcpy(ct_req->req.rnn_id.node_name, ha->init_cb->node_name, WWN_SIZE);
559 /* Execute MS IOCB */
560 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
561 sizeof(ms_iocb_entry_t));
562 if (rval != QLA_SUCCESS) {
564 DEBUG2_3(printk("scsi(%ld): RNN_ID issue IOCB failed (%d).\n",
566 } else if (ct_rsp->header.response !=
567 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
568 DEBUG2_3(printk("scsi(%ld): RNN_ID failed, rejected "
569 "request, rnn_id_rsp:\n", ha->host_no));
570 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
571 sizeof(struct ct_rsp_hdr)));
572 rval = QLA_FUNCTION_FAILED;
574 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n",
582 * qla2x00_rsnn_nn() - SNS Register Symbolic Node Name (RSNN_NN) of the HBA.
585 * Returns 0 on success.
588 qla2x00_rsnn_nn(scsi_qla_host_t *ha)
594 ms_iocb_entry_t *ms_pkt;
595 struct ct_sns_req *ct_req;
596 struct ct_sns_rsp *ct_rsp;
598 if (IS_QLA2200(ha)) {
599 DEBUG2(printk("scsi(%ld): RSNN_ID call unsupported on "
600 "ISP2200.\n", ha->host_no));
601 return (QLA_SUCCESS);
605 /* Prepare common MS IOCB */
606 /* Request size adjusted after CT preparation */
607 ms_pkt = qla2x00_prep_ms_iocb(ha, 0, RSNN_NN_RSP_SIZE);
609 /* Prepare CT request */
610 ct_req = qla2x00_prep_ct_req(&ha->ct_sns->p.req, RSNN_NN_CMD,
612 ct_rsp = &ha->ct_sns->p.rsp;
614 /* Prepare CT arguments -- node_name, symbolic node_name, size */
615 memcpy(ct_req->req.rsnn_nn.node_name, ha->init_cb->node_name, WWN_SIZE);
617 /* Prepare the Symbolic Node Name */
619 snn = ct_req->req.rsnn_nn.sym_node_name;
620 strcpy(snn, ha->model_number);
621 /* Firmware version */
622 strcat(snn, " FW:v");
623 sprintf(version, "%d.%02d.%02d", ha->fw_major_version,
624 ha->fw_minor_version, ha->fw_subminor_version);
625 strcat(snn, version);
627 strcat(snn, " DVR:v");
628 strcat(snn, qla2x00_version_str);
630 /* Calculate SNN length */
631 ct_req->req.rsnn_nn.name_len = (uint8_t)strlen(snn);
633 /* Update MS IOCB request */
634 ms_pkt->req_bytecount =
635 cpu_to_le32(24 + 1 + ct_req->req.rsnn_nn.name_len);
636 ms_pkt->dseg_req_length = ms_pkt->req_bytecount;
638 /* Execute MS IOCB */
639 rval = qla2x00_issue_iocb(ha, ha->ms_iocb, ha->ms_iocb_dma,
640 sizeof(ms_iocb_entry_t));
641 if (rval != QLA_SUCCESS) {
643 DEBUG2_3(printk("scsi(%ld): RSNN_NN issue IOCB failed (%d).\n",
645 } else if (ct_rsp->header.response !=
646 __constant_cpu_to_be16(CT_ACCEPT_RESPONSE)) {
647 DEBUG2_3(printk("scsi(%ld): RSNN_NN failed, rejected "
648 "request, rsnn_id_rsp:\n", ha->host_no));
649 DEBUG2_3(qla2x00_dump_buffer((uint8_t *)&ct_rsp->header,
650 sizeof(struct ct_rsp_hdr)));
651 rval = QLA_FUNCTION_FAILED;
653 DEBUG2(printk("scsi(%ld): RSNN_NN exiting normally.\n",
662 * qla2x00_prep_sns_cmd() - Prepare common SNS command request fields for query.
665 * @scmd_len: Subcommand length
666 * @data_size: response size in bytes
668 * Returns a pointer to the @ha's sns_cmd.
670 static inline struct sns_cmd_pkt *
671 qla2x00_prep_sns_cmd(scsi_qla_host_t *ha, uint16_t cmd, uint16_t scmd_len,
675 struct sns_cmd_pkt *sns_cmd;
677 sns_cmd = ha->sns_cmd;
678 memset(sns_cmd, 0, sizeof(struct sns_cmd_pkt));
679 wc = data_size / 2; /* Size in 16bit words. */
680 sns_cmd->p.cmd.buffer_length = cpu_to_le16(wc);
681 sns_cmd->p.cmd.buffer_address[0] = cpu_to_le32(LSD(ha->sns_cmd_dma));
682 sns_cmd->p.cmd.buffer_address[1] = cpu_to_le32(MSD(ha->sns_cmd_dma));
683 sns_cmd->p.cmd.subcommand_length = cpu_to_le16(scmd_len);
684 sns_cmd->p.cmd.subcommand = cpu_to_le16(cmd);
685 wc = (data_size - 16) / 4; /* Size in 32bit words. */
686 sns_cmd->p.cmd.size = cpu_to_le16(wc);
692 * qla2x00_sns_ga_nxt() - SNS scan for fabric devices via GA_NXT command.
694 * @fcport: fcport entry to updated
696 * This command uses the old Exectute SNS Command mailbox routine.
698 * Returns 0 on success.
701 qla2x00_sns_ga_nxt(scsi_qla_host_t *ha, fc_port_t *fcport)
705 struct sns_cmd_pkt *sns_cmd;
708 /* Prepare SNS command request. */
709 sns_cmd = qla2x00_prep_sns_cmd(ha, GA_NXT_CMD, GA_NXT_SNS_SCMD_LEN,
710 GA_NXT_SNS_DATA_SIZE);
712 /* Prepare SNS command arguments -- port_id. */
713 sns_cmd->p.cmd.param[0] = fcport->d_id.b.al_pa;
714 sns_cmd->p.cmd.param[1] = fcport->d_id.b.area;
715 sns_cmd->p.cmd.param[2] = fcport->d_id.b.domain;
717 /* Execute SNS command. */
718 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GA_NXT_SNS_CMD_SIZE / 2,
719 sizeof(struct sns_cmd_pkt));
720 if (rval != QLA_SUCCESS) {
722 DEBUG2_3(printk("scsi(%ld): GA_NXT Send SNS failed (%d).\n",
724 } else if (sns_cmd->p.gan_data[8] != 0x80 ||
725 sns_cmd->p.gan_data[9] != 0x02) {
726 DEBUG2_3(printk("scsi(%ld): GA_NXT failed, rejected request, "
727 "ga_nxt_rsp:\n", ha->host_no));
728 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gan_data, 16));
729 rval = QLA_FUNCTION_FAILED;
731 /* Populate fc_port_t entry. */
732 fcport->d_id.b.domain = sns_cmd->p.gan_data[17];
733 fcport->d_id.b.area = sns_cmd->p.gan_data[18];
734 fcport->d_id.b.al_pa = sns_cmd->p.gan_data[19];
736 memcpy(fcport->node_name, &sns_cmd->p.gan_data[284], WWN_SIZE);
737 memcpy(fcport->port_name, &sns_cmd->p.gan_data[20], WWN_SIZE);
739 if (sns_cmd->p.gan_data[16] != NS_N_PORT_TYPE &&
740 sns_cmd->p.gan_data[16] != NS_NL_PORT_TYPE)
741 fcport->d_id.b.domain = 0xf0;
743 DEBUG2_3(printk("scsi(%ld): GA_NXT entry - "
744 "nn %02x%02x%02x%02x%02x%02x%02x%02x "
745 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
746 "portid=%02x%02x%02x.\n",
748 fcport->node_name[0], fcport->node_name[1],
749 fcport->node_name[2], fcport->node_name[3],
750 fcport->node_name[4], fcport->node_name[5],
751 fcport->node_name[6], fcport->node_name[7],
752 fcport->port_name[0], fcport->port_name[1],
753 fcport->port_name[2], fcport->port_name[3],
754 fcport->port_name[4], fcport->port_name[5],
755 fcport->port_name[6], fcport->port_name[7],
756 fcport->d_id.b.domain, fcport->d_id.b.area,
757 fcport->d_id.b.al_pa));
764 * qla2x00_sns_gid_pt() - SNS scan for fabric devices via GID_PT command.
766 * @list: switch info entries to populate
768 * This command uses the old Exectute SNS Command mailbox routine.
770 * NOTE: Non-Nx_Ports are not requested.
772 * Returns 0 on success.
775 qla2x00_sns_gid_pt(scsi_qla_host_t *ha, sw_info_t *list)
781 struct sns_cmd_pkt *sns_cmd;
784 /* Prepare SNS command request. */
785 sns_cmd = qla2x00_prep_sns_cmd(ha, GID_PT_CMD, GID_PT_SNS_SCMD_LEN,
786 GID_PT_SNS_DATA_SIZE);
788 /* Prepare SNS command arguments -- port_type. */
789 sns_cmd->p.cmd.param[0] = NS_NX_PORT_TYPE;
791 /* Execute SNS command. */
792 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, GID_PT_SNS_CMD_SIZE / 2,
793 sizeof(struct sns_cmd_pkt));
794 if (rval != QLA_SUCCESS) {
796 DEBUG2_3(printk("scsi(%ld): GID_PT Send SNS failed (%d).\n",
798 } else if (sns_cmd->p.gid_data[8] != 0x80 ||
799 sns_cmd->p.gid_data[9] != 0x02) {
800 DEBUG2_3(printk("scsi(%ld): GID_PT failed, rejected request, "
801 "gid_rsp:\n", ha->host_no));
802 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gid_data, 16));
803 rval = QLA_FUNCTION_FAILED;
805 /* Set port IDs in switch info list. */
806 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
807 entry = &sns_cmd->p.gid_data[(i * 4) + 16];
808 list[i].d_id.b.domain = entry[1];
809 list[i].d_id.b.area = entry[2];
810 list[i].d_id.b.al_pa = entry[3];
813 if (entry[0] & BIT_7) {
814 list[i].d_id.b.rsvd_1 = entry[0];
820 * If we've used all available slots, then the switch is
821 * reporting back more devices that we can handle with this
822 * single call. Return a failed status, and let GA_NXT handle
825 if (i == MAX_FIBRE_DEVICES)
826 rval = QLA_FUNCTION_FAILED;
833 * qla2x00_sns_gpn_id() - SNS Get Port Name (GPN_ID) query.
835 * @list: switch info entries to populate
837 * This command uses the old Exectute SNS Command mailbox routine.
839 * Returns 0 on success.
842 qla2x00_sns_gpn_id(scsi_qla_host_t *ha, sw_info_t *list)
847 struct sns_cmd_pkt *sns_cmd;
849 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
851 /* Prepare SNS command request. */
852 sns_cmd = qla2x00_prep_sns_cmd(ha, GPN_ID_CMD,
853 GPN_ID_SNS_SCMD_LEN, GPN_ID_SNS_DATA_SIZE);
855 /* Prepare SNS command arguments -- port_id. */
856 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
857 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
858 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
860 /* Execute SNS command. */
861 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma,
862 GPN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
863 if (rval != QLA_SUCCESS) {
865 DEBUG2_3(printk("scsi(%ld): GPN_ID Send SNS failed "
866 "(%d).\n", ha->host_no, rval));
867 } else if (sns_cmd->p.gpn_data[8] != 0x80 ||
868 sns_cmd->p.gpn_data[9] != 0x02) {
869 DEBUG2_3(printk("scsi(%ld): GPN_ID failed, rejected "
870 "request, gpn_rsp:\n", ha->host_no));
871 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gpn_data, 16));
872 rval = QLA_FUNCTION_FAILED;
875 memcpy(list[i].port_name, &sns_cmd->p.gpn_data[16],
879 /* Last device exit. */
880 if (list[i].d_id.b.rsvd_1 != 0)
888 * qla2x00_sns_gnn_id() - SNS Get Node Name (GNN_ID) query.
890 * @list: switch info entries to populate
892 * This command uses the old Exectute SNS Command mailbox routine.
894 * Returns 0 on success.
897 qla2x00_sns_gnn_id(scsi_qla_host_t *ha, sw_info_t *list)
902 struct sns_cmd_pkt *sns_cmd;
904 for (i = 0; i < MAX_FIBRE_DEVICES; i++) {
906 /* Prepare SNS command request. */
907 sns_cmd = qla2x00_prep_sns_cmd(ha, GNN_ID_CMD,
908 GNN_ID_SNS_SCMD_LEN, GNN_ID_SNS_DATA_SIZE);
910 /* Prepare SNS command arguments -- port_id. */
911 sns_cmd->p.cmd.param[0] = list[i].d_id.b.al_pa;
912 sns_cmd->p.cmd.param[1] = list[i].d_id.b.area;
913 sns_cmd->p.cmd.param[2] = list[i].d_id.b.domain;
915 /* Execute SNS command. */
916 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma,
917 GNN_ID_SNS_CMD_SIZE / 2, sizeof(struct sns_cmd_pkt));
918 if (rval != QLA_SUCCESS) {
920 DEBUG2_3(printk("scsi(%ld): GNN_ID Send SNS failed "
921 "(%d).\n", ha->host_no, rval));
922 } else if (sns_cmd->p.gnn_data[8] != 0x80 ||
923 sns_cmd->p.gnn_data[9] != 0x02) {
924 DEBUG2_3(printk("scsi(%ld): GNN_ID failed, rejected "
925 "request, gnn_rsp:\n", ha->host_no));
926 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.gnn_data, 16));
927 rval = QLA_FUNCTION_FAILED;
930 memcpy(list[i].node_name, &sns_cmd->p.gnn_data[16],
933 DEBUG2_3(printk("scsi(%ld): GID_PT entry - "
934 "nn %02x%02x%02x%02x%02x%02x%02x%02x "
935 "pn %02x%02x%02x%02x%02x%02x%02x%02x "
936 "portid=%02x%02x%02x.\n",
938 list[i].node_name[0], list[i].node_name[1],
939 list[i].node_name[2], list[i].node_name[3],
940 list[i].node_name[4], list[i].node_name[5],
941 list[i].node_name[6], list[i].node_name[7],
942 list[i].port_name[0], list[i].port_name[1],
943 list[i].port_name[2], list[i].port_name[3],
944 list[i].port_name[4], list[i].port_name[5],
945 list[i].port_name[6], list[i].port_name[7],
946 list[i].d_id.b.domain, list[i].d_id.b.area,
947 list[i].d_id.b.al_pa));
950 /* Last device exit. */
951 if (list[i].d_id.b.rsvd_1 != 0)
959 * qla2x00_snd_rft_id() - SNS Register FC-4 TYPEs (RFT_ID) supported by the HBA.
962 * This command uses the old Exectute SNS Command mailbox routine.
964 * Returns 0 on success.
967 qla2x00_sns_rft_id(scsi_qla_host_t *ha)
971 struct sns_cmd_pkt *sns_cmd;
974 /* Prepare SNS command request. */
975 sns_cmd = qla2x00_prep_sns_cmd(ha, RFT_ID_CMD, RFT_ID_SNS_SCMD_LEN,
976 RFT_ID_SNS_DATA_SIZE);
978 /* Prepare SNS command arguments -- port_id, FC-4 types */
979 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa;
980 sns_cmd->p.cmd.param[1] = ha->d_id.b.area;
981 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain;
983 sns_cmd->p.cmd.param[5] = 0x01; /* FCP-3 */
985 /* Execute SNS command. */
986 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RFT_ID_SNS_CMD_SIZE / 2,
987 sizeof(struct sns_cmd_pkt));
988 if (rval != QLA_SUCCESS) {
990 DEBUG2_3(printk("scsi(%ld): RFT_ID Send SNS failed (%d).\n",
992 } else if (sns_cmd->p.rft_data[8] != 0x80 ||
993 sns_cmd->p.rft_data[9] != 0x02) {
994 DEBUG2_3(printk("scsi(%ld): RFT_ID failed, rejected request, "
995 "rft_rsp:\n", ha->host_no));
996 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rft_data, 16));
997 rval = QLA_FUNCTION_FAILED;
999 DEBUG2(printk("scsi(%ld): RFT_ID exiting normally.\n",
1007 * qla2x00_sns_rff_id() - SNS Register FC-4 Features (RFF_ID) supported by the
1011 * This command uses the old Exectute SNS Command mailbox routine.
1013 * Returns 0 on success.
1016 qla2x00_sns_rff_id(scsi_qla_host_t *ha)
1020 struct sns_cmd_pkt *sns_cmd;
1023 /* Prepare SNS command request. */
1024 sns_cmd = qla2x00_prep_sns_cmd(ha, RFF_ID_CMD, RFF_ID_SNS_SCMD_LEN,
1025 RFF_ID_SNS_DATA_SIZE);
1027 /* Prepare SNS command arguments -- port_id, FC-4 feature, FC-4 type */
1028 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa;
1029 sns_cmd->p.cmd.param[1] = ha->d_id.b.area;
1030 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain;
1032 sns_cmd->p.cmd.param[6] = 0x08; /* SCSI - FCP */
1034 /* Execute SNS command. */
1035 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RFF_ID_SNS_CMD_SIZE / 2,
1036 sizeof(struct sns_cmd_pkt));
1037 if (rval != QLA_SUCCESS) {
1039 DEBUG2_3(printk("scsi(%ld): RFF_ID Send SNS failed (%d).\n",
1040 ha->host_no, rval));
1041 } else if (sns_cmd->p.rff_data[8] != 0x80 ||
1042 sns_cmd->p.rff_data[9] != 0x02) {
1043 DEBUG2_3(printk("scsi(%ld): RFF_ID failed, rejected request, "
1044 "rff_rsp:\n", ha->host_no));
1045 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rff_data, 16));
1046 rval = QLA_FUNCTION_FAILED;
1048 DEBUG2(printk("scsi(%ld): RFF_ID exiting normally.\n",
1056 * qla2x00_sns_rnn_id() - SNS Register Node Name (RNN_ID) of the HBA.
1060 * This command uses the old Exectute SNS Command mailbox routine.
1062 * Returns 0 on success.
1065 qla2x00_sns_rnn_id(scsi_qla_host_t *ha)
1069 struct sns_cmd_pkt *sns_cmd;
1072 /* Prepare SNS command request. */
1073 sns_cmd = qla2x00_prep_sns_cmd(ha, RNN_ID_CMD, RNN_ID_SNS_SCMD_LEN,
1074 RNN_ID_SNS_DATA_SIZE);
1076 /* Prepare SNS command arguments -- port_id, nodename. */
1077 sns_cmd->p.cmd.param[0] = ha->d_id.b.al_pa;
1078 sns_cmd->p.cmd.param[1] = ha->d_id.b.area;
1079 sns_cmd->p.cmd.param[2] = ha->d_id.b.domain;
1081 sns_cmd->p.cmd.param[4] = ha->init_cb->node_name[7];
1082 sns_cmd->p.cmd.param[5] = ha->init_cb->node_name[6];
1083 sns_cmd->p.cmd.param[6] = ha->init_cb->node_name[5];
1084 sns_cmd->p.cmd.param[7] = ha->init_cb->node_name[4];
1085 sns_cmd->p.cmd.param[8] = ha->init_cb->node_name[3];
1086 sns_cmd->p.cmd.param[9] = ha->init_cb->node_name[2];
1087 sns_cmd->p.cmd.param[10] = ha->init_cb->node_name[1];
1088 sns_cmd->p.cmd.param[11] = ha->init_cb->node_name[0];
1090 /* Execute SNS command. */
1091 rval = qla2x00_send_sns(ha, ha->sns_cmd_dma, RNN_ID_SNS_CMD_SIZE / 2,
1092 sizeof(struct sns_cmd_pkt));
1093 if (rval != QLA_SUCCESS) {
1095 DEBUG2_3(printk("scsi(%ld): RNN_ID Send SNS failed (%d).\n",
1096 ha->host_no, rval));
1097 } else if (sns_cmd->p.rnn_data[8] != 0x80 ||
1098 sns_cmd->p.rnn_data[9] != 0x02) {
1099 DEBUG2_3(printk("scsi(%ld): RNN_ID failed, rejected request, "
1100 "rnn_rsp:\n", ha->host_no));
1101 DEBUG2_3(qla2x00_dump_buffer(sns_cmd->p.rnn_data, 16));
1102 rval = QLA_FUNCTION_FAILED;
1104 DEBUG2(printk("scsi(%ld): RNN_ID exiting normally.\n",