qla_mbx.c revision cca5335caf2d19ef8bd6b833445d2c6ca652a89b
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#include <linux/delay.h> 22#include <scsi/scsi_transport_fc.h> 23 24static void 25qla2x00_mbx_sem_timeout(unsigned long data) 26{ 27 struct semaphore *sem_ptr = (struct semaphore *)data; 28 29 DEBUG11(printk("qla2x00_sem_timeout: entered.\n");) 30 31 if (sem_ptr != NULL) { 32 up(sem_ptr); 33 } 34 35 DEBUG11(printk("qla2x00_mbx_sem_timeout: exiting.\n");) 36} 37 38/* 39 * qla2x00_mailbox_command 40 * Issue mailbox command and waits for completion. 41 * 42 * Input: 43 * ha = adapter block pointer. 44 * mcp = driver internal mbx struct pointer. 45 * 46 * Output: 47 * mb[MAX_MAILBOX_REGISTER_COUNT] = returned mailbox data. 48 * 49 * Returns: 50 * 0 : QLA_SUCCESS = cmd performed success 51 * 1 : QLA_FUNCTION_FAILED (error encountered) 52 * 6 : QLA_FUNCTION_TIMEOUT (timeout condition encountered) 53 * 54 * Context: 55 * Kernel context. 56 */ 57static int 58qla2x00_mailbox_command(scsi_qla_host_t *ha, mbx_cmd_t *mcp) 59{ 60 int rval; 61 unsigned long flags = 0; 62 device_reg_t __iomem *reg = ha->iobase; 63 struct timer_list tmp_intr_timer; 64 uint8_t abort_active; 65 uint8_t io_lock_on = ha->flags.init_done; 66 uint16_t command; 67 uint16_t *iptr; 68 uint16_t __iomem *optr; 69 uint32_t cnt; 70 uint32_t mboxes; 71 unsigned long mbx_flags = 0; 72 unsigned long wait_time; 73 74 rval = QLA_SUCCESS; 75 abort_active = test_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 76 77 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 78 79 /* 80 * Wait for active mailbox commands to finish by waiting at most tov 81 * seconds. This is to serialize actual issuing of mailbox cmds during 82 * non ISP abort time. 83 */ 84 if (!abort_active) { 85 if (qla2x00_down_timeout(&ha->mbx_cmd_sem, mcp->tov * HZ)) { 86 /* Timeout occurred. Return error. */ 87 DEBUG2_3_11(printk("%s(%ld): cmd access timeout. " 88 "Exiting.\n", __func__, ha->host_no);) 89 return QLA_FUNCTION_TIMEOUT; 90 } 91 } 92 93 ha->flags.mbox_busy = 1; 94 /* Save mailbox command for debug */ 95 ha->mcp = mcp; 96 97 /* Try to get mailbox register access */ 98 if (!abort_active) 99 spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); 100 101 DEBUG11(printk("scsi(%ld): prepare to issue mbox cmd=0x%x.\n", 102 ha->host_no, mcp->mb[0]);) 103 104 spin_lock_irqsave(&ha->hardware_lock, flags); 105 106 /* Load mailbox registers. */ 107 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 108 optr = (uint16_t __iomem *)®->isp24.mailbox0; 109 else 110 optr = (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 0); 111 112 iptr = mcp->mb; 113 command = mcp->mb[0]; 114 mboxes = mcp->out_mb; 115 116 for (cnt = 0; cnt < ha->mbx_count; cnt++) { 117 if (IS_QLA2200(ha) && cnt == 8) 118 optr = 119 (uint16_t __iomem *)MAILBOX_REG(ha, ®->isp, 8); 120 if (mboxes & BIT_0) 121 WRT_REG_WORD(optr, *iptr); 122 123 mboxes >>= 1; 124 optr++; 125 iptr++; 126 } 127 128#if defined(QL_DEBUG_LEVEL_1) 129 printk("%s(%ld): Loaded MBX registers (displayed in bytes) = \n", 130 __func__, ha->host_no); 131 qla2x00_dump_buffer((uint8_t *)mcp->mb, 16); 132 printk("\n"); 133 qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x10), 16); 134 printk("\n"); 135 qla2x00_dump_buffer(((uint8_t *)mcp->mb + 0x20), 8); 136 printk("\n"); 137 printk("%s(%ld): I/O address = %p.\n", __func__, ha->host_no, optr); 138 qla2x00_dump_regs(ha); 139#endif 140 141 /* Issue set host interrupt command to send cmd out. */ 142 ha->flags.mbox_int = 0; 143 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 144 145 /* Unlock mbx registers and wait for interrupt */ 146 DEBUG11(printk("%s(%ld): going to unlock irq & waiting for interrupt. " 147 "jiffies=%lx.\n", __func__, ha->host_no, jiffies);) 148 149 /* Wait for mbx cmd completion until timeout */ 150 151 if (!abort_active && io_lock_on) { 152 /* sleep on completion semaphore */ 153 DEBUG11(printk("%s(%ld): INTERRUPT MODE. Initializing timer.\n", 154 __func__, ha->host_no);) 155 156 init_timer(&tmp_intr_timer); 157 tmp_intr_timer.data = (unsigned long)&ha->mbx_intr_sem; 158 tmp_intr_timer.expires = jiffies + mcp->tov * HZ; 159 tmp_intr_timer.function = 160 (void (*)(unsigned long))qla2x00_mbx_sem_timeout; 161 162 DEBUG11(printk("%s(%ld): Adding timer.\n", __func__, 163 ha->host_no);) 164 add_timer(&tmp_intr_timer); 165 166 DEBUG11(printk("%s(%ld): going to unlock & sleep. " 167 "time=0x%lx.\n", __func__, ha->host_no, jiffies);) 168 169 set_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 170 171 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 172 WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); 173 else 174 WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); 175 spin_unlock_irqrestore(&ha->hardware_lock, flags); 176 177 if (!abort_active) 178 spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); 179 180 /* Wait for either the timer to expire 181 * or the mbox completion interrupt 182 */ 183 down(&ha->mbx_intr_sem); 184 185 DEBUG11(printk("%s(%ld): waking up. time=0x%lx\n", __func__, 186 ha->host_no, jiffies);) 187 clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); 188 189 /* delete the timer */ 190 del_timer(&tmp_intr_timer); 191 } else { 192 DEBUG3_11(printk("%s(%ld): cmd=%x POLLING MODE.\n", __func__, 193 ha->host_no, command);) 194 195 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) 196 WRT_REG_DWORD(®->isp24.hccr, HCCRX_SET_HOST_INT); 197 else 198 WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); 199 spin_unlock_irqrestore(&ha->hardware_lock, flags); 200 if (!abort_active) 201 spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); 202 203 wait_time = jiffies + mcp->tov * HZ; /* wait at most tov secs */ 204 while (!ha->flags.mbox_int) { 205 if (time_after(jiffies, wait_time)) 206 break; 207 208 /* Check for pending interrupts. */ 209 qla2x00_poll(ha); 210 211 udelay(10); /* v4.27 */ 212 } /* while */ 213 } 214 215 if (!abort_active) 216 spin_lock_irqsave(&ha->mbx_reg_lock, mbx_flags); 217 218 /* Check whether we timed out */ 219 if (ha->flags.mbox_int) { 220 uint16_t *iptr2; 221 222 DEBUG3_11(printk("%s(%ld): cmd %x completed.\n", __func__, 223 ha->host_no, command);) 224 225 /* Got interrupt. Clear the flag. */ 226 ha->flags.mbox_int = 0; 227 clear_bit(MBX_INTERRUPT, &ha->mbx_cmd_flags); 228 229 if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) 230 rval = QLA_FUNCTION_FAILED; 231 232 /* Load return mailbox registers. */ 233 iptr2 = mcp->mb; 234 iptr = (uint16_t *)&ha->mailbox_out[0]; 235 mboxes = mcp->in_mb; 236 for (cnt = 0; cnt < ha->mbx_count; cnt++) { 237 if (mboxes & BIT_0) 238 *iptr2 = *iptr; 239 240 mboxes >>= 1; 241 iptr2++; 242 iptr++; 243 } 244 } else { 245 246#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3) || \ 247 defined(QL_DEBUG_LEVEL_11) 248 uint16_t mb0; 249 uint32_t ictrl; 250 251 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 252 mb0 = RD_REG_WORD(®->isp24.mailbox0); 253 ictrl = RD_REG_DWORD(®->isp24.ictrl); 254 } else { 255 mb0 = RD_MAILBOX_REG(ha, ®->isp, 0); 256 ictrl = RD_REG_WORD(®->isp.ictrl); 257 } 258 printk("%s(%ld): **** MB Command Timeout for cmd %x ****\n", 259 __func__, ha->host_no, command); 260 printk("%s(%ld): icontrol=%x jiffies=%lx\n", __func__, 261 ha->host_no, ictrl, jiffies); 262 printk("%s(%ld): *** mailbox[0] = 0x%x ***\n", __func__, 263 ha->host_no, mb0); 264 qla2x00_dump_regs(ha); 265#endif 266 267 rval = QLA_FUNCTION_TIMEOUT; 268 } 269 270 if (!abort_active) 271 spin_unlock_irqrestore(&ha->mbx_reg_lock, mbx_flags); 272 273 ha->flags.mbox_busy = 0; 274 275 /* Clean up */ 276 ha->mcp = NULL; 277 278 if (!abort_active) { 279 DEBUG11(printk("%s(%ld): checking for additional resp " 280 "interrupt.\n", __func__, ha->host_no);) 281 282 /* polling mode for non isp_abort commands. */ 283 qla2x00_poll(ha); 284 } 285 286 if (rval == QLA_FUNCTION_TIMEOUT && 287 mcp->mb[0] != MBC_GEN_SYSTEM_ERROR) { 288 if (!io_lock_on || (mcp->flags & IOCTL_CMD)) { 289 /* not in dpc. schedule it for dpc to take over. */ 290 DEBUG(printk("%s(%ld): timeout schedule " 291 "isp_abort_needed.\n", __func__, ha->host_no);) 292 DEBUG2_3_11(printk("%s(%ld): timeout schedule " 293 "isp_abort_needed.\n", __func__, ha->host_no);) 294 qla_printk(KERN_WARNING, ha, 295 "Mailbox command timeout occured. Scheduling ISP " 296 "abort.\n"); 297 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 298 if (ha->dpc_wait && !ha->dpc_active) 299 up(ha->dpc_wait); 300 301 } else if (!abort_active) { 302 /* call abort directly since we are in the DPC thread */ 303 DEBUG(printk("%s(%ld): timeout calling abort_isp\n", 304 __func__, ha->host_no);) 305 DEBUG2_3_11(printk("%s(%ld): timeout calling " 306 "abort_isp\n", __func__, ha->host_no);) 307 qla_printk(KERN_WARNING, ha, 308 "Mailbox command timeout occured. Issuing ISP " 309 "abort.\n"); 310 311 set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 312 clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 313 if (qla2x00_abort_isp(ha)) { 314 /* Failed. retry later. */ 315 set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); 316 } 317 clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); 318 DEBUG(printk("%s(%ld): finished abort_isp\n", __func__, 319 ha->host_no);) 320 DEBUG2_3_11(printk("%s(%ld): finished abort_isp\n", 321 __func__, ha->host_no);) 322 } 323 } 324 325 /* Allow next mbx cmd to come in. */ 326 if (!abort_active) 327 up(&ha->mbx_cmd_sem); 328 329 if (rval) { 330 DEBUG2_3_11(printk("%s(%ld): **** FAILED. mbx0=%x, mbx1=%x, " 331 "mbx2=%x, cmd=%x ****\n", __func__, ha->host_no, 332 mcp->mb[0], mcp->mb[1], mcp->mb[2], command);) 333 } else { 334 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 335 } 336 337 return rval; 338} 339 340/* 341 * qla2x00_load_ram 342 * Load adapter RAM using DMA. 343 * 344 * Input: 345 * ha = adapter block pointer. 346 * 347 * Returns: 348 * qla2x00 local function return status code. 349 * 350 * Context: 351 * Kernel context. 352 */ 353int 354qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint16_t risc_addr, 355 uint16_t risc_code_size) 356{ 357 int rval; 358 mbx_cmd_t mc; 359 mbx_cmd_t *mcp = &mc; 360 uint32_t req_len; 361 dma_addr_t nml_dma; 362 uint32_t nml_len; 363 uint32_t normalized; 364 365 DEBUG11(printk("qla2x00_load_ram(%ld): entered.\n", 366 ha->host_no);) 367 368 req_len = risc_code_size; 369 nml_dma = 0; 370 nml_len = 0; 371 372 normalized = qla2x00_normalize_dma_addr(&req_dma, &req_len, &nml_dma, 373 &nml_len); 374 375 /* Load first segment */ 376 mcp->mb[0] = MBC_LOAD_RISC_RAM; 377 mcp->mb[1] = risc_addr; 378 mcp->mb[2] = MSW(req_dma); 379 mcp->mb[3] = LSW(req_dma); 380 mcp->mb[4] = (uint16_t)req_len; 381 mcp->mb[6] = MSW(MSD(req_dma)); 382 mcp->mb[7] = LSW(MSD(req_dma)); 383 mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 384 mcp->in_mb = MBX_0; 385 mcp->tov = 30; 386 mcp->flags = 0; 387 rval = qla2x00_mailbox_command(ha, mcp); 388 389 /* Load second segment - if necessary */ 390 if (normalized && (rval == QLA_SUCCESS)) { 391 mcp->mb[0] = MBC_LOAD_RISC_RAM; 392 mcp->mb[1] = risc_addr + (uint16_t)req_len; 393 mcp->mb[2] = MSW(nml_dma); 394 mcp->mb[3] = LSW(nml_dma); 395 mcp->mb[4] = (uint16_t)nml_len; 396 mcp->mb[6] = MSW(MSD(nml_dma)); 397 mcp->mb[7] = LSW(MSD(nml_dma)); 398 mcp->out_mb = MBX_7|MBX_6|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 399 mcp->in_mb = MBX_0; 400 mcp->tov = 30; 401 mcp->flags = 0; 402 rval = qla2x00_mailbox_command(ha, mcp); 403 } 404 405 if (rval == QLA_SUCCESS) { 406 /* Empty */ 407 DEBUG11(printk("qla2x00_load_ram(%ld): done.\n", ha->host_no);) 408 } else { 409 /* Empty */ 410 DEBUG2_3_11(printk("qla2x00_load_ram(%ld): failed. rval=%x " 411 "mb[0]=%x.\n", ha->host_no, rval, mcp->mb[0]);) 412 } 413 return rval; 414} 415 416/* 417 * qla2x00_load_ram_ext 418 * Load adapter extended RAM using DMA. 419 * 420 * Input: 421 * ha = adapter block pointer. 422 * 423 * Returns: 424 * qla2x00 local function return status code. 425 * 426 * Context: 427 * Kernel context. 428 */ 429int 430qla2x00_load_ram_ext(scsi_qla_host_t *ha, dma_addr_t req_dma, 431 uint32_t risc_addr, uint32_t risc_code_size) 432{ 433 int rval; 434 mbx_cmd_t mc; 435 mbx_cmd_t *mcp = &mc; 436 437 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 438 439 mcp->mb[0] = MBC_LOAD_RISC_RAM_EXTENDED; 440 mcp->mb[1] = LSW(risc_addr); 441 mcp->mb[2] = MSW(req_dma); 442 mcp->mb[3] = LSW(req_dma); 443 mcp->mb[6] = MSW(MSD(req_dma)); 444 mcp->mb[7] = LSW(MSD(req_dma)); 445 mcp->mb[8] = MSW(risc_addr); 446 mcp->out_mb = MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 447 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 448 mcp->mb[4] = MSW(risc_code_size); 449 mcp->mb[5] = LSW(risc_code_size); 450 mcp->out_mb |= MBX_5|MBX_4; 451 } else { 452 mcp->mb[4] = LSW(risc_code_size); 453 mcp->out_mb |= MBX_4; 454 } 455 456 mcp->in_mb = MBX_0; 457 mcp->tov = 30; 458 mcp->flags = 0; 459 rval = qla2x00_mailbox_command(ha, mcp); 460 461 if (rval != QLA_SUCCESS) { 462 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, 463 ha->host_no, rval, mcp->mb[0])); 464 } else { 465 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 466 } 467 468 return rval; 469} 470 471/* 472 * qla2x00_execute_fw 473 * Start adapter firmware. 474 * 475 * Input: 476 * ha = adapter block pointer. 477 * TARGET_QUEUE_LOCK must be released. 478 * ADAPTER_STATE_LOCK must be released. 479 * 480 * Returns: 481 * qla2x00 local function return status code. 482 * 483 * Context: 484 * Kernel context. 485 */ 486int 487qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) 488{ 489 int rval; 490 mbx_cmd_t mc; 491 mbx_cmd_t *mcp = &mc; 492 493 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 494 495 mcp->mb[0] = MBC_EXECUTE_FIRMWARE; 496 mcp->out_mb = MBX_0; 497 mcp->in_mb = MBX_0; 498 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 499 mcp->mb[1] = MSW(risc_addr); 500 mcp->mb[2] = LSW(risc_addr); 501 mcp->mb[3] = 0; 502 mcp->out_mb |= MBX_3|MBX_2|MBX_1; 503 mcp->in_mb |= MBX_1; 504 } else { 505 mcp->mb[1] = LSW(risc_addr); 506 mcp->out_mb |= MBX_1; 507 if (IS_QLA2322(ha) || IS_QLA6322(ha)) { 508 mcp->mb[2] = 0; 509 mcp->out_mb |= MBX_2; 510 } 511 } 512 513 mcp->tov = 30; 514 mcp->flags = 0; 515 rval = qla2x00_mailbox_command(ha, mcp); 516 517 if (rval != QLA_SUCCESS) { 518 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, 519 ha->host_no, rval, mcp->mb[0])); 520 } else { 521 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 522 DEBUG11(printk("%s(%ld): done exchanges=%x.\n", 523 __func__, ha->host_no, mcp->mb[1]);) 524 } else { 525 DEBUG11(printk("%s(%ld): done.\n", __func__, 526 ha->host_no);) 527 } 528 } 529 530 return rval; 531} 532 533/* 534 * qla2x00_get_fw_version 535 * Get firmware version. 536 * 537 * Input: 538 * ha: adapter state pointer. 539 * major: pointer for major number. 540 * minor: pointer for minor number. 541 * subminor: pointer for subminor number. 542 * 543 * Returns: 544 * qla2x00 local function return status code. 545 * 546 * Context: 547 * Kernel context. 548 */ 549void 550qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor, 551 uint16_t *subminor, uint16_t *attributes, uint32_t *memory) 552{ 553 int rval; 554 mbx_cmd_t mc; 555 mbx_cmd_t *mcp = &mc; 556 557 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 558 559 mcp->mb[0] = MBC_GET_FIRMWARE_VERSION; 560 mcp->out_mb = MBX_0; 561 mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 562 mcp->flags = 0; 563 mcp->tov = 30; 564 rval = qla2x00_mailbox_command(ha, mcp); 565 566 /* Return mailbox data. */ 567 *major = mcp->mb[1]; 568 *minor = mcp->mb[2]; 569 *subminor = mcp->mb[3]; 570 *attributes = mcp->mb[6]; 571 if (IS_QLA2100(ha) || IS_QLA2200(ha)) 572 *memory = 0x1FFFF; /* Defaults to 128KB. */ 573 else 574 *memory = (mcp->mb[5] << 16) | mcp->mb[4]; 575 576 if (rval != QLA_SUCCESS) { 577 /*EMPTY*/ 578 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, 579 ha->host_no, rval)); 580 } else { 581 /*EMPTY*/ 582 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 583 } 584} 585 586/* 587 * qla2x00_get_fw_options 588 * Set firmware options. 589 * 590 * Input: 591 * ha = adapter block pointer. 592 * fwopt = pointer for firmware options. 593 * 594 * Returns: 595 * qla2x00 local function return status code. 596 * 597 * Context: 598 * Kernel context. 599 */ 600int 601qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) 602{ 603 int rval; 604 mbx_cmd_t mc; 605 mbx_cmd_t *mcp = &mc; 606 607 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 608 609 mcp->mb[0] = MBC_GET_FIRMWARE_OPTION; 610 mcp->out_mb = MBX_0; 611 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 612 mcp->tov = 30; 613 mcp->flags = 0; 614 rval = qla2x00_mailbox_command(ha, mcp); 615 616 if (rval != QLA_SUCCESS) { 617 /*EMPTY*/ 618 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, 619 ha->host_no, rval)); 620 } else { 621 fwopts[0] = mcp->mb[0]; 622 fwopts[1] = mcp->mb[1]; 623 fwopts[2] = mcp->mb[2]; 624 fwopts[3] = mcp->mb[3]; 625 626 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 627 } 628 629 return rval; 630} 631 632 633/* 634 * qla2x00_set_fw_options 635 * Set firmware options. 636 * 637 * Input: 638 * ha = adapter block pointer. 639 * fwopt = pointer for firmware options. 640 * 641 * Returns: 642 * qla2x00 local function return status code. 643 * 644 * Context: 645 * Kernel context. 646 */ 647int 648qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts) 649{ 650 int rval; 651 mbx_cmd_t mc; 652 mbx_cmd_t *mcp = &mc; 653 654 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 655 656 mcp->mb[0] = MBC_SET_FIRMWARE_OPTION; 657 mcp->mb[1] = fwopts[1]; 658 mcp->mb[2] = fwopts[2]; 659 mcp->mb[3] = fwopts[3]; 660 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 661 mcp->in_mb = MBX_0; 662 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 663 mcp->in_mb |= MBX_1; 664 } else { 665 mcp->mb[10] = fwopts[10]; 666 mcp->mb[11] = fwopts[11]; 667 mcp->mb[12] = 0; /* Undocumented, but used */ 668 mcp->out_mb |= MBX_12|MBX_11|MBX_10; 669 } 670 mcp->tov = 30; 671 mcp->flags = 0; 672 rval = qla2x00_mailbox_command(ha, mcp); 673 674 fwopts[0] = mcp->mb[0]; 675 676 if (rval != QLA_SUCCESS) { 677 /*EMPTY*/ 678 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x/%x).\n", __func__, 679 ha->host_no, rval, mcp->mb[0], mcp->mb[1])); 680 } else { 681 /*EMPTY*/ 682 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 683 } 684 685 return rval; 686} 687 688/* 689 * qla2x00_mbx_reg_test 690 * Mailbox register wrap test. 691 * 692 * Input: 693 * ha = adapter block pointer. 694 * TARGET_QUEUE_LOCK must be released. 695 * ADAPTER_STATE_LOCK must be released. 696 * 697 * Returns: 698 * qla2x00 local function return status code. 699 * 700 * Context: 701 * Kernel context. 702 */ 703int 704qla2x00_mbx_reg_test(scsi_qla_host_t *ha) 705{ 706 int rval; 707 mbx_cmd_t mc; 708 mbx_cmd_t *mcp = &mc; 709 710 DEBUG11(printk("qla2x00_mbx_reg_test(%ld): entered.\n", ha->host_no);) 711 712 mcp->mb[0] = MBC_MAILBOX_REGISTER_TEST; 713 mcp->mb[1] = 0xAAAA; 714 mcp->mb[2] = 0x5555; 715 mcp->mb[3] = 0xAA55; 716 mcp->mb[4] = 0x55AA; 717 mcp->mb[5] = 0xA5A5; 718 mcp->mb[6] = 0x5A5A; 719 mcp->mb[7] = 0x2525; 720 mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 721 mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 722 mcp->tov = 30; 723 mcp->flags = 0; 724 rval = qla2x00_mailbox_command(ha, mcp); 725 726 if (rval == QLA_SUCCESS) { 727 if (mcp->mb[1] != 0xAAAA || mcp->mb[2] != 0x5555 || 728 mcp->mb[3] != 0xAA55 || mcp->mb[4] != 0x55AA) 729 rval = QLA_FUNCTION_FAILED; 730 if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A || 731 mcp->mb[7] != 0x2525) 732 rval = QLA_FUNCTION_FAILED; 733 } 734 735 if (rval != QLA_SUCCESS) { 736 /*EMPTY*/ 737 DEBUG2_3_11(printk("qla2x00_mbx_reg_test(%ld): failed=%x.\n", 738 ha->host_no, rval);) 739 } else { 740 /*EMPTY*/ 741 DEBUG11(printk("qla2x00_mbx_reg_test(%ld): done.\n", 742 ha->host_no);) 743 } 744 745 return rval; 746} 747 748/* 749 * qla2x00_verify_checksum 750 * Verify firmware checksum. 751 * 752 * Input: 753 * ha = adapter block pointer. 754 * TARGET_QUEUE_LOCK must be released. 755 * ADAPTER_STATE_LOCK must be released. 756 * 757 * Returns: 758 * qla2x00 local function return status code. 759 * 760 * Context: 761 * Kernel context. 762 */ 763int 764qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr) 765{ 766 int rval; 767 mbx_cmd_t mc; 768 mbx_cmd_t *mcp = &mc; 769 770 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 771 772 mcp->mb[0] = MBC_VERIFY_CHECKSUM; 773 mcp->out_mb = MBX_0; 774 mcp->in_mb = MBX_0; 775 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 776 mcp->mb[1] = MSW(risc_addr); 777 mcp->mb[2] = LSW(risc_addr); 778 mcp->out_mb |= MBX_2|MBX_1; 779 mcp->in_mb |= MBX_2|MBX_1; 780 } else { 781 mcp->mb[1] = LSW(risc_addr); 782 mcp->out_mb |= MBX_1; 783 mcp->in_mb |= MBX_1; 784 } 785 786 mcp->tov = 30; 787 mcp->flags = 0; 788 rval = qla2x00_mailbox_command(ha, mcp); 789 790 if (rval != QLA_SUCCESS) { 791 DEBUG2_3_11(printk("%s(%ld): failed=%x chk sum=%x.\n", __func__, 792 ha->host_no, rval, (IS_QLA24XX(ha) || IS_QLA25XX(ha) ? 793 (mcp->mb[2] << 16) | mcp->mb[1]: mcp->mb[1]));) 794 } else { 795 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 796 } 797 798 return rval; 799} 800 801/* 802 * qla2x00_issue_iocb 803 * Issue IOCB using mailbox command 804 * 805 * Input: 806 * ha = adapter state pointer. 807 * buffer = buffer pointer. 808 * phys_addr = physical address of buffer. 809 * size = size of buffer. 810 * TARGET_QUEUE_LOCK must be released. 811 * ADAPTER_STATE_LOCK must be released. 812 * 813 * Returns: 814 * qla2x00 local function return status code. 815 * 816 * Context: 817 * Kernel context. 818 */ 819int 820qla2x00_issue_iocb(scsi_qla_host_t *ha, void* buffer, dma_addr_t phys_addr, 821 size_t size) 822{ 823 int rval; 824 mbx_cmd_t mc; 825 mbx_cmd_t *mcp = &mc; 826 827 mcp->mb[0] = MBC_IOCB_COMMAND_A64; 828 mcp->mb[1] = 0; 829 mcp->mb[2] = MSW(phys_addr); 830 mcp->mb[3] = LSW(phys_addr); 831 mcp->mb[6] = MSW(MSD(phys_addr)); 832 mcp->mb[7] = LSW(MSD(phys_addr)); 833 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 834 mcp->in_mb = MBX_2|MBX_0; 835 mcp->tov = 30; 836 mcp->flags = 0; 837 rval = qla2x00_mailbox_command(ha, mcp); 838 839 if (rval != QLA_SUCCESS) { 840 /*EMPTY*/ 841 DEBUG(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", 842 ha->host_no, rval);) 843 DEBUG2(printk("qla2x00_issue_iocb(%ld): failed rval 0x%x\n", 844 ha->host_no, rval);) 845 } else { 846 sts_entry_t *sts_entry = (sts_entry_t *) buffer; 847 848 /* Mask reserved bits. */ 849 sts_entry->entry_status &= 850 IS_QLA24XX(ha) || IS_QLA25XX(ha) ? RF_MASK_24XX :RF_MASK; 851 } 852 853 return rval; 854} 855 856/* 857 * qla2x00_abort_command 858 * Abort command aborts a specified IOCB. 859 * 860 * Input: 861 * ha = adapter block pointer. 862 * sp = SB structure pointer. 863 * 864 * Returns: 865 * qla2x00 local function return status code. 866 * 867 * Context: 868 * Kernel context. 869 */ 870int 871qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp) 872{ 873 unsigned long flags = 0; 874 fc_port_t *fcport; 875 int rval; 876 uint32_t handle; 877 mbx_cmd_t mc; 878 mbx_cmd_t *mcp = &mc; 879 880 DEBUG11(printk("qla2x00_abort_command(%ld): entered.\n", ha->host_no);) 881 882 fcport = sp->fcport; 883 if (atomic_read(&ha->loop_state) == LOOP_DOWN || 884 atomic_read(&fcport->state) == FCS_DEVICE_LOST) { 885 return 1; 886 } 887 888 spin_lock_irqsave(&ha->hardware_lock, flags); 889 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { 890 if (ha->outstanding_cmds[handle] == sp) 891 break; 892 } 893 spin_unlock_irqrestore(&ha->hardware_lock, flags); 894 895 if (handle == MAX_OUTSTANDING_COMMANDS) { 896 /* command not found */ 897 return QLA_FUNCTION_FAILED; 898 } 899 900 mcp->mb[0] = MBC_ABORT_COMMAND; 901 if (HAS_EXTENDED_IDS(ha)) 902 mcp->mb[1] = fcport->loop_id; 903 else 904 mcp->mb[1] = fcport->loop_id << 8; 905 mcp->mb[2] = (uint16_t)handle; 906 mcp->mb[3] = (uint16_t)(handle >> 16); 907 mcp->mb[6] = (uint16_t)sp->cmd->device->lun; 908 mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 909 mcp->in_mb = MBX_0; 910 mcp->tov = 30; 911 mcp->flags = 0; 912 rval = qla2x00_mailbox_command(ha, mcp); 913 914 if (rval != QLA_SUCCESS) { 915 DEBUG2_3_11(printk("qla2x00_abort_command(%ld): failed=%x.\n", 916 ha->host_no, rval);) 917 } else { 918 sp->flags |= SRB_ABORT_PENDING; 919 DEBUG11(printk("qla2x00_abort_command(%ld): done.\n", 920 ha->host_no);) 921 } 922 923 return rval; 924} 925 926#if USE_ABORT_TGT 927/* 928 * qla2x00_abort_target 929 * Issue abort target mailbox command. 930 * 931 * Input: 932 * ha = adapter block pointer. 933 * 934 * Returns: 935 * qla2x00 local function return status code. 936 * 937 * Context: 938 * Kernel context. 939 */ 940int 941qla2x00_abort_target(fc_port_t *fcport) 942{ 943 int rval; 944 mbx_cmd_t mc; 945 mbx_cmd_t *mcp = &mc; 946 scsi_qla_host_t *ha; 947 948 if (fcport == NULL) 949 return 0; 950 951 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) 952 953 ha = fcport->ha; 954 mcp->mb[0] = MBC_ABORT_TARGET; 955 mcp->out_mb = MBX_2|MBX_1|MBX_0; 956 if (HAS_EXTENDED_IDS(ha)) { 957 mcp->mb[1] = fcport->loop_id; 958 mcp->mb[10] = 0; 959 mcp->out_mb |= MBX_10; 960 } else { 961 mcp->mb[1] = fcport->loop_id << 8; 962 } 963 mcp->mb[2] = ha->loop_reset_delay; 964 965 mcp->in_mb = MBX_0; 966 mcp->tov = 30; 967 mcp->flags = 0; 968 rval = qla2x00_mailbox_command(ha, mcp); 969 970 /* Issue marker command. */ 971 ha->marker_needed = 1; 972 973 if (rval != QLA_SUCCESS) { 974 DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n", 975 ha->host_no, rval);) 976 } else { 977 /*EMPTY*/ 978 DEBUG11(printk("qla2x00_abort_target(%ld): done.\n", 979 ha->host_no);) 980 } 981 982 return rval; 983} 984#endif 985 986/* 987 * qla2x00_target_reset 988 * Issue target reset mailbox command. 989 * 990 * Input: 991 * ha = adapter block pointer. 992 * TARGET_QUEUE_LOCK must be released. 993 * ADAPTER_STATE_LOCK must be released. 994 * 995 * Returns: 996 * qla2x00 local function return status code. 997 * 998 * Context: 999 * Kernel context. 1000 */ 1001int 1002qla2x00_target_reset(scsi_qla_host_t *ha, struct fc_port *fcport) 1003{ 1004 int rval; 1005 mbx_cmd_t mc; 1006 mbx_cmd_t *mcp = &mc; 1007 1008 DEBUG11(printk("qla2x00_target_reset(%ld): entered.\n", ha->host_no);) 1009 1010 if (atomic_read(&fcport->state) != FCS_ONLINE) 1011 return 0; 1012 1013 mcp->mb[0] = MBC_TARGET_RESET; 1014 if (HAS_EXTENDED_IDS(ha)) 1015 mcp->mb[1] = fcport->loop_id; 1016 else 1017 mcp->mb[1] = fcport->loop_id << 8; 1018 mcp->mb[2] = ha->loop_reset_delay; 1019 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1020 mcp->in_mb = MBX_0; 1021 mcp->tov = 30; 1022 mcp->flags = 0; 1023 rval = qla2x00_mailbox_command(ha, mcp); 1024 1025 if (rval != QLA_SUCCESS) { 1026 /*EMPTY*/ 1027 DEBUG2_3_11(printk("qla2x00_target_reset(%ld): failed=%x.\n", 1028 ha->host_no, rval);) 1029 } else { 1030 /*EMPTY*/ 1031 DEBUG11(printk("qla2x00_target_reset(%ld): done.\n", 1032 ha->host_no);) 1033 } 1034 1035 return rval; 1036} 1037 1038/* 1039 * qla2x00_get_adapter_id 1040 * Get adapter ID and topology. 1041 * 1042 * Input: 1043 * ha = adapter block pointer. 1044 * id = pointer for loop ID. 1045 * al_pa = pointer for AL_PA. 1046 * area = pointer for area. 1047 * domain = pointer for domain. 1048 * top = pointer for topology. 1049 * TARGET_QUEUE_LOCK must be released. 1050 * ADAPTER_STATE_LOCK must be released. 1051 * 1052 * Returns: 1053 * qla2x00 local function return status code. 1054 * 1055 * Context: 1056 * Kernel context. 1057 */ 1058int 1059qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa, 1060 uint8_t *area, uint8_t *domain, uint16_t *top) 1061{ 1062 int rval; 1063 mbx_cmd_t mc; 1064 mbx_cmd_t *mcp = &mc; 1065 1066 DEBUG11(printk("qla2x00_get_adapter_id(%ld): entered.\n", 1067 ha->host_no);) 1068 1069 mcp->mb[0] = MBC_GET_ADAPTER_LOOP_ID; 1070 mcp->out_mb = MBX_0; 1071 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1072 mcp->tov = 30; 1073 mcp->flags = 0; 1074 rval = qla2x00_mailbox_command(ha, mcp); 1075 1076 /* Return data. */ 1077 *id = mcp->mb[1]; 1078 *al_pa = LSB(mcp->mb[2]); 1079 *area = MSB(mcp->mb[2]); 1080 *domain = LSB(mcp->mb[3]); 1081 *top = mcp->mb[6]; 1082 1083 if (rval != QLA_SUCCESS) { 1084 /*EMPTY*/ 1085 DEBUG2_3_11(printk("qla2x00_get_adapter_id(%ld): failed=%x.\n", 1086 ha->host_no, rval);) 1087 } else { 1088 /*EMPTY*/ 1089 DEBUG11(printk("qla2x00_get_adapter_id(%ld): done.\n", 1090 ha->host_no);) 1091 } 1092 1093 return rval; 1094} 1095 1096/* 1097 * qla2x00_get_retry_cnt 1098 * Get current firmware login retry count and delay. 1099 * 1100 * Input: 1101 * ha = adapter block pointer. 1102 * retry_cnt = pointer to login retry count. 1103 * tov = pointer to login timeout value. 1104 * 1105 * Returns: 1106 * qla2x00 local function return status code. 1107 * 1108 * Context: 1109 * Kernel context. 1110 */ 1111int 1112qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov, 1113 uint16_t *r_a_tov) 1114{ 1115 int rval; 1116 uint16_t ratov; 1117 mbx_cmd_t mc; 1118 mbx_cmd_t *mcp = &mc; 1119 1120 DEBUG11(printk("qla2x00_get_retry_cnt(%ld): entered.\n", 1121 ha->host_no);) 1122 1123 mcp->mb[0] = MBC_GET_RETRY_COUNT; 1124 mcp->out_mb = MBX_0; 1125 mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1126 mcp->tov = 30; 1127 mcp->flags = 0; 1128 rval = qla2x00_mailbox_command(ha, mcp); 1129 1130 if (rval != QLA_SUCCESS) { 1131 /*EMPTY*/ 1132 DEBUG2_3_11(printk("qla2x00_get_retry_cnt(%ld): failed = %x.\n", 1133 ha->host_no, mcp->mb[0]);) 1134 } else { 1135 /* Convert returned data and check our values. */ 1136 *r_a_tov = mcp->mb[3] / 2; 1137 ratov = (mcp->mb[3]/2) / 10; /* mb[3] value is in 100ms */ 1138 if (mcp->mb[1] * ratov > (*retry_cnt) * (*tov)) { 1139 /* Update to the larger values */ 1140 *retry_cnt = (uint8_t)mcp->mb[1]; 1141 *tov = ratov; 1142 } 1143 1144 DEBUG11(printk("qla2x00_get_retry_cnt(%ld): done. mb3=%d " 1145 "ratov=%d.\n", ha->host_no, mcp->mb[3], ratov);) 1146 } 1147 1148 return rval; 1149} 1150 1151/* 1152 * qla2x00_init_firmware 1153 * Initialize adapter firmware. 1154 * 1155 * Input: 1156 * ha = adapter block pointer. 1157 * dptr = Initialization control block pointer. 1158 * size = size of initialization control block. 1159 * TARGET_QUEUE_LOCK must be released. 1160 * ADAPTER_STATE_LOCK must be released. 1161 * 1162 * Returns: 1163 * qla2x00 local function return status code. 1164 * 1165 * Context: 1166 * Kernel context. 1167 */ 1168int 1169qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size) 1170{ 1171 int rval; 1172 mbx_cmd_t mc; 1173 mbx_cmd_t *mcp = &mc; 1174 1175 DEBUG11(printk("qla2x00_init_firmware(%ld): entered.\n", 1176 ha->host_no);) 1177 1178 mcp->mb[0] = MBC_INITIALIZE_FIRMWARE; 1179 mcp->mb[2] = MSW(ha->init_cb_dma); 1180 mcp->mb[3] = LSW(ha->init_cb_dma); 1181 mcp->mb[4] = 0; 1182 mcp->mb[5] = 0; 1183 mcp->mb[6] = MSW(MSD(ha->init_cb_dma)); 1184 mcp->mb[7] = LSW(MSD(ha->init_cb_dma)); 1185 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1186 mcp->in_mb = MBX_5|MBX_4|MBX_0; 1187 mcp->buf_size = size; 1188 mcp->flags = MBX_DMA_OUT; 1189 mcp->tov = 30; 1190 rval = qla2x00_mailbox_command(ha, mcp); 1191 1192 if (rval != QLA_SUCCESS) { 1193 /*EMPTY*/ 1194 DEBUG2_3_11(printk("qla2x00_init_firmware(%ld): failed=%x " 1195 "mb0=%x.\n", 1196 ha->host_no, rval, mcp->mb[0]);) 1197 } else { 1198 /*EMPTY*/ 1199 DEBUG11(printk("qla2x00_init_firmware(%ld): done.\n", 1200 ha->host_no);) 1201 } 1202 1203 return rval; 1204} 1205 1206/* 1207 * qla2x00_get_port_database 1208 * Issue normal/enhanced get port database mailbox command 1209 * and copy device name as necessary. 1210 * 1211 * Input: 1212 * ha = adapter state pointer. 1213 * dev = structure pointer. 1214 * opt = enhanced cmd option byte. 1215 * 1216 * Returns: 1217 * qla2x00 local function return status code. 1218 * 1219 * Context: 1220 * Kernel context. 1221 */ 1222int 1223qla2x00_get_port_database(scsi_qla_host_t *ha, fc_port_t *fcport, uint8_t opt) 1224{ 1225 int rval; 1226 mbx_cmd_t mc; 1227 mbx_cmd_t *mcp = &mc; 1228 port_database_t *pd; 1229 struct port_database_24xx *pd24; 1230 dma_addr_t pd_dma; 1231 1232 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 1233 1234 pd24 = NULL; 1235 pd = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &pd_dma); 1236 if (pd == NULL) { 1237 DEBUG2_3(printk("%s(%ld): failed to allocate Port Database " 1238 "structure.\n", __func__, ha->host_no)); 1239 return QLA_MEMORY_ALLOC_FAILED; 1240 } 1241 memset(pd, 0, max(PORT_DATABASE_SIZE, PORT_DATABASE_24XX_SIZE)); 1242 1243 mcp->mb[0] = MBC_GET_PORT_DATABASE; 1244 if (opt != 0 && !IS_QLA24XX(ha) && !IS_QLA25XX(ha)) 1245 mcp->mb[0] = MBC_ENHANCED_GET_PORT_DATABASE; 1246 mcp->mb[2] = MSW(pd_dma); 1247 mcp->mb[3] = LSW(pd_dma); 1248 mcp->mb[6] = MSW(MSD(pd_dma)); 1249 mcp->mb[7] = LSW(MSD(pd_dma)); 1250 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 1251 mcp->in_mb = MBX_0; 1252 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1253 mcp->mb[1] = fcport->loop_id; 1254 mcp->mb[10] = opt; 1255 mcp->out_mb |= MBX_10|MBX_1; 1256 mcp->in_mb |= MBX_1; 1257 } else if (HAS_EXTENDED_IDS(ha)) { 1258 mcp->mb[1] = fcport->loop_id; 1259 mcp->mb[10] = opt; 1260 mcp->out_mb |= MBX_10|MBX_1; 1261 } else { 1262 mcp->mb[1] = fcport->loop_id << 8 | opt; 1263 mcp->out_mb |= MBX_1; 1264 } 1265 mcp->buf_size = (IS_QLA24XX(ha) || IS_QLA25XX(ha) ? 1266 PORT_DATABASE_24XX_SIZE : PORT_DATABASE_SIZE); 1267 mcp->flags = MBX_DMA_IN; 1268 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 1269 rval = qla2x00_mailbox_command(ha, mcp); 1270 if (rval != QLA_SUCCESS) 1271 goto gpd_error_out; 1272 1273 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1274 pd24 = (struct port_database_24xx *) pd; 1275 1276 /* Check for logged in state. */ 1277 if (pd24->current_login_state != PDS_PRLI_COMPLETE && 1278 pd24->last_login_state != PDS_PRLI_COMPLETE) { 1279 DEBUG2(printk("%s(%ld): Unable to verify " 1280 "login-state (%x/%x) for loop_id %x\n", 1281 __func__, ha->host_no, 1282 pd24->current_login_state, 1283 pd24->last_login_state, fcport->loop_id)); 1284 rval = QLA_FUNCTION_FAILED; 1285 goto gpd_error_out; 1286 } 1287 1288 /* Names are little-endian. */ 1289 memcpy(fcport->node_name, pd24->node_name, WWN_SIZE); 1290 memcpy(fcport->port_name, pd24->port_name, WWN_SIZE); 1291 1292 /* Get port_id of device. */ 1293 fcport->d_id.b.domain = pd24->port_id[0]; 1294 fcport->d_id.b.area = pd24->port_id[1]; 1295 fcport->d_id.b.al_pa = pd24->port_id[2]; 1296 fcport->d_id.b.rsvd_1 = 0; 1297 1298 /* If not target must be initiator or unknown type. */ 1299 if ((pd24->prli_svc_param_word_3[0] & BIT_4) == 0) 1300 fcport->port_type = FCT_INITIATOR; 1301 else 1302 fcport->port_type = FCT_TARGET; 1303 } else { 1304 /* Check for logged in state. */ 1305 if (pd->master_state != PD_STATE_PORT_LOGGED_IN && 1306 pd->slave_state != PD_STATE_PORT_LOGGED_IN) { 1307 rval = QLA_FUNCTION_FAILED; 1308 goto gpd_error_out; 1309 } 1310 1311 /* Names are little-endian. */ 1312 memcpy(fcport->node_name, pd->node_name, WWN_SIZE); 1313 memcpy(fcport->port_name, pd->port_name, WWN_SIZE); 1314 1315 /* Get port_id of device. */ 1316 fcport->d_id.b.domain = pd->port_id[0]; 1317 fcport->d_id.b.area = pd->port_id[3]; 1318 fcport->d_id.b.al_pa = pd->port_id[2]; 1319 fcport->d_id.b.rsvd_1 = 0; 1320 1321 /* Check for device require authentication. */ 1322 pd->common_features & BIT_5 ? (fcport->flags |= FCF_AUTH_REQ) : 1323 (fcport->flags &= ~FCF_AUTH_REQ); 1324 1325 /* If not target must be initiator or unknown type. */ 1326 if ((pd->prli_svc_param_word_3[0] & BIT_4) == 0) 1327 fcport->port_type = FCT_INITIATOR; 1328 else 1329 fcport->port_type = FCT_TARGET; 1330 1331 /* Passback COS information. */ 1332 fcport->supported_classes = (pd->options & BIT_4) ? 1333 FC_COS_CLASS2: FC_COS_CLASS3; 1334 } 1335 1336gpd_error_out: 1337 dma_pool_free(ha->s_dma_pool, pd, pd_dma); 1338 1339 if (rval != QLA_SUCCESS) { 1340 DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x.\n", 1341 __func__, ha->host_no, rval, mcp->mb[0], mcp->mb[1])); 1342 } else { 1343 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 1344 } 1345 1346 return rval; 1347} 1348 1349/* 1350 * qla2x00_get_firmware_state 1351 * Get adapter firmware state. 1352 * 1353 * Input: 1354 * ha = adapter block pointer. 1355 * dptr = pointer for firmware state. 1356 * TARGET_QUEUE_LOCK must be released. 1357 * ADAPTER_STATE_LOCK must be released. 1358 * 1359 * Returns: 1360 * qla2x00 local function return status code. 1361 * 1362 * Context: 1363 * Kernel context. 1364 */ 1365int 1366qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr) 1367{ 1368 int rval; 1369 mbx_cmd_t mc; 1370 mbx_cmd_t *mcp = &mc; 1371 1372 DEBUG11(printk("qla2x00_get_firmware_state(%ld): entered.\n", 1373 ha->host_no);) 1374 1375 mcp->mb[0] = MBC_GET_FIRMWARE_STATE; 1376 mcp->out_mb = MBX_0; 1377 mcp->in_mb = MBX_2|MBX_1|MBX_0; 1378 mcp->tov = 30; 1379 mcp->flags = 0; 1380 rval = qla2x00_mailbox_command(ha, mcp); 1381 1382 /* Return firmware state. */ 1383 *dptr = mcp->mb[1]; 1384 1385 if (rval != QLA_SUCCESS) { 1386 /*EMPTY*/ 1387 DEBUG2_3_11(printk("qla2x00_get_firmware_state(%ld): " 1388 "failed=%x.\n", ha->host_no, rval);) 1389 } else { 1390 /*EMPTY*/ 1391 DEBUG11(printk("qla2x00_get_firmware_state(%ld): done.\n", 1392 ha->host_no);) 1393 } 1394 1395 return rval; 1396} 1397 1398/* 1399 * qla2x00_get_port_name 1400 * Issue get port name mailbox command. 1401 * Returned name is in big endian format. 1402 * 1403 * Input: 1404 * ha = adapter block pointer. 1405 * loop_id = loop ID of device. 1406 * name = pointer for name. 1407 * TARGET_QUEUE_LOCK must be released. 1408 * ADAPTER_STATE_LOCK must be released. 1409 * 1410 * Returns: 1411 * qla2x00 local function return status code. 1412 * 1413 * Context: 1414 * Kernel context. 1415 */ 1416int 1417qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name, 1418 uint8_t opt) 1419{ 1420 int rval; 1421 mbx_cmd_t mc; 1422 mbx_cmd_t *mcp = &mc; 1423 1424 DEBUG11(printk("qla2x00_get_port_name(%ld): entered.\n", 1425 ha->host_no);) 1426 1427 mcp->mb[0] = MBC_GET_PORT_NAME; 1428 mcp->out_mb = MBX_1|MBX_0; 1429 if (HAS_EXTENDED_IDS(ha)) { 1430 mcp->mb[1] = loop_id; 1431 mcp->mb[10] = opt; 1432 mcp->out_mb |= MBX_10; 1433 } else { 1434 mcp->mb[1] = loop_id << 8 | opt; 1435 } 1436 1437 mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1438 mcp->tov = 30; 1439 mcp->flags = 0; 1440 rval = qla2x00_mailbox_command(ha, mcp); 1441 1442 if (rval != QLA_SUCCESS) { 1443 /*EMPTY*/ 1444 DEBUG2_3_11(printk("qla2x00_get_port_name(%ld): failed=%x.\n", 1445 ha->host_no, rval);) 1446 } else { 1447 if (name != NULL) { 1448 /* This function returns name in big endian. */ 1449 name[0] = LSB(mcp->mb[2]); 1450 name[1] = MSB(mcp->mb[2]); 1451 name[2] = LSB(mcp->mb[3]); 1452 name[3] = MSB(mcp->mb[3]); 1453 name[4] = LSB(mcp->mb[6]); 1454 name[5] = MSB(mcp->mb[6]); 1455 name[6] = LSB(mcp->mb[7]); 1456 name[7] = MSB(mcp->mb[7]); 1457 } 1458 1459 DEBUG11(printk("qla2x00_get_port_name(%ld): done.\n", 1460 ha->host_no);) 1461 } 1462 1463 return rval; 1464} 1465 1466/* 1467 * qla2x00_lip_reset 1468 * Issue LIP reset mailbox command. 1469 * 1470 * Input: 1471 * ha = adapter block pointer. 1472 * TARGET_QUEUE_LOCK must be released. 1473 * ADAPTER_STATE_LOCK must be released. 1474 * 1475 * Returns: 1476 * qla2x00 local function return status code. 1477 * 1478 * Context: 1479 * Kernel context. 1480 */ 1481int 1482qla2x00_lip_reset(scsi_qla_host_t *ha) 1483{ 1484 int rval; 1485 mbx_cmd_t mc; 1486 mbx_cmd_t *mcp = &mc; 1487 1488 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 1489 1490 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 1491 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 1492 mcp->mb[1] = BIT_0; 1493 mcp->mb[2] = 0xff; 1494 mcp->mb[3] = 0; 1495 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1496 } else { 1497 mcp->mb[0] = MBC_LIP_RESET; 1498 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1499 if (HAS_EXTENDED_IDS(ha)) { 1500 mcp->mb[1] = 0x00ff; 1501 mcp->mb[10] = 0; 1502 mcp->out_mb |= MBX_10; 1503 } else { 1504 mcp->mb[1] = 0xff00; 1505 } 1506 mcp->mb[2] = ha->loop_reset_delay; 1507 mcp->mb[3] = 0; 1508 } 1509 mcp->in_mb = MBX_0; 1510 mcp->tov = 30; 1511 mcp->flags = 0; 1512 rval = qla2x00_mailbox_command(ha, mcp); 1513 1514 if (rval != QLA_SUCCESS) { 1515 /*EMPTY*/ 1516 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", 1517 __func__, ha->host_no, rval);) 1518 } else { 1519 /*EMPTY*/ 1520 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 1521 } 1522 1523 return rval; 1524} 1525 1526/* 1527 * qla2x00_send_sns 1528 * Send SNS command. 1529 * 1530 * Input: 1531 * ha = adapter block pointer. 1532 * sns = pointer for command. 1533 * cmd_size = command size. 1534 * buf_size = response/command size. 1535 * TARGET_QUEUE_LOCK must be released. 1536 * ADAPTER_STATE_LOCK must be released. 1537 * 1538 * Returns: 1539 * qla2x00 local function return status code. 1540 * 1541 * Context: 1542 * Kernel context. 1543 */ 1544int 1545qla2x00_send_sns(scsi_qla_host_t *ha, dma_addr_t sns_phys_address, 1546 uint16_t cmd_size, size_t buf_size) 1547{ 1548 int rval; 1549 mbx_cmd_t mc; 1550 mbx_cmd_t *mcp = &mc; 1551 1552 DEBUG11(printk("qla2x00_send_sns(%ld): entered.\n", 1553 ha->host_no);) 1554 1555 DEBUG11(printk("qla2x00_send_sns: retry cnt=%d ratov=%d total " 1556 "tov=%d.\n", ha->retry_count, ha->login_timeout, mcp->tov);) 1557 1558 mcp->mb[0] = MBC_SEND_SNS_COMMAND; 1559 mcp->mb[1] = cmd_size; 1560 mcp->mb[2] = MSW(sns_phys_address); 1561 mcp->mb[3] = LSW(sns_phys_address); 1562 mcp->mb[6] = MSW(MSD(sns_phys_address)); 1563 mcp->mb[7] = LSW(MSD(sns_phys_address)); 1564 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 1565 mcp->in_mb = MBX_0|MBX_1; 1566 mcp->buf_size = buf_size; 1567 mcp->flags = MBX_DMA_OUT|MBX_DMA_IN; 1568 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 1569 rval = qla2x00_mailbox_command(ha, mcp); 1570 1571 if (rval != QLA_SUCCESS) { 1572 /*EMPTY*/ 1573 DEBUG(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " 1574 "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) 1575 DEBUG2_3_11(printk("qla2x00_send_sns(%ld): failed=%x mb[0]=%x " 1576 "mb[1]=%x.\n", ha->host_no, rval, mcp->mb[0], mcp->mb[1]);) 1577 } else { 1578 /*EMPTY*/ 1579 DEBUG11(printk("qla2x00_send_sns(%ld): done.\n", ha->host_no);) 1580 } 1581 1582 return rval; 1583} 1584 1585int 1586qla24xx_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, 1587 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 1588{ 1589 int rval; 1590 1591 struct logio_entry_24xx *lg; 1592 dma_addr_t lg_dma; 1593 uint32_t iop[2]; 1594 1595 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 1596 1597 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 1598 if (lg == NULL) { 1599 DEBUG2_3(printk("%s(%ld): failed to allocate Login IOCB.\n", 1600 __func__, ha->host_no)); 1601 return QLA_MEMORY_ALLOC_FAILED; 1602 } 1603 memset(lg, 0, sizeof(struct logio_entry_24xx)); 1604 1605 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 1606 lg->entry_count = 1; 1607 lg->nport_handle = cpu_to_le16(loop_id); 1608 lg->control_flags = __constant_cpu_to_le16(LCF_COMMAND_PLOGI); 1609 if (opt & BIT_0) 1610 lg->control_flags |= __constant_cpu_to_le16(LCF_COND_PLOGI); 1611 lg->port_id[0] = al_pa; 1612 lg->port_id[1] = area; 1613 lg->port_id[2] = domain; 1614 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); 1615 if (rval != QLA_SUCCESS) { 1616 DEBUG2_3_11(printk("%s(%ld): failed to issue Login IOCB " 1617 "(%x).\n", __func__, ha->host_no, rval);) 1618 } else if (lg->entry_status != 0) { 1619 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 1620 "-- error status (%x).\n", __func__, ha->host_no, 1621 lg->entry_status)); 1622 rval = QLA_FUNCTION_FAILED; 1623 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { 1624 iop[0] = le32_to_cpu(lg->io_parameter[0]); 1625 iop[1] = le32_to_cpu(lg->io_parameter[1]); 1626 1627 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 1628 "-- completion status (%x) ioparam=%x/%x.\n", __func__, 1629 ha->host_no, le16_to_cpu(lg->comp_status), iop[0], 1630 iop[1])); 1631 1632 switch (iop[0]) { 1633 case LSC_SCODE_PORTID_USED: 1634 mb[0] = MBS_PORT_ID_USED; 1635 mb[1] = LSW(iop[1]); 1636 break; 1637 case LSC_SCODE_NPORT_USED: 1638 mb[0] = MBS_LOOP_ID_USED; 1639 break; 1640 case LSC_SCODE_NOLINK: 1641 case LSC_SCODE_NOIOCB: 1642 case LSC_SCODE_NOXCB: 1643 case LSC_SCODE_CMD_FAILED: 1644 case LSC_SCODE_NOFABRIC: 1645 case LSC_SCODE_FW_NOT_READY: 1646 case LSC_SCODE_NOT_LOGGED_IN: 1647 case LSC_SCODE_NOPCB: 1648 case LSC_SCODE_ELS_REJECT: 1649 case LSC_SCODE_CMD_PARAM_ERR: 1650 case LSC_SCODE_NONPORT: 1651 case LSC_SCODE_LOGGED_IN: 1652 case LSC_SCODE_NOFLOGI_ACC: 1653 default: 1654 mb[0] = MBS_COMMAND_ERROR; 1655 break; 1656 } 1657 } else { 1658 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 1659 1660 iop[0] = le32_to_cpu(lg->io_parameter[0]); 1661 1662 mb[0] = MBS_COMMAND_COMPLETE; 1663 mb[1] = 0; 1664 if (iop[0] & BIT_4) { 1665 if (iop[0] & BIT_8) 1666 mb[1] |= BIT_1; 1667 } else 1668 mb[1] = BIT_0; 1669 1670 /* Passback COS information. */ 1671 mb[10] = 0; 1672 if (lg->io_parameter[7] || lg->io_parameter[8]) 1673 mb[10] |= BIT_0; /* Class 2. */ 1674 if (lg->io_parameter[9] || lg->io_parameter[10]) 1675 mb[10] |= BIT_1; /* Class 3. */ 1676 } 1677 1678 dma_pool_free(ha->s_dma_pool, lg, lg_dma); 1679 1680 return rval; 1681} 1682 1683/* 1684 * qla2x00_login_fabric 1685 * Issue login fabric port mailbox command. 1686 * 1687 * Input: 1688 * ha = adapter block pointer. 1689 * loop_id = device loop ID. 1690 * domain = device domain. 1691 * area = device area. 1692 * al_pa = device AL_PA. 1693 * status = pointer for return status. 1694 * opt = command options. 1695 * TARGET_QUEUE_LOCK must be released. 1696 * ADAPTER_STATE_LOCK must be released. 1697 * 1698 * Returns: 1699 * qla2x00 local function return status code. 1700 * 1701 * Context: 1702 * Kernel context. 1703 */ 1704int 1705qla2x00_login_fabric(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, 1706 uint8_t area, uint8_t al_pa, uint16_t *mb, uint8_t opt) 1707{ 1708 int rval; 1709 mbx_cmd_t mc; 1710 mbx_cmd_t *mcp = &mc; 1711 1712 DEBUG11(printk("qla2x00_login_fabric(%ld): entered.\n", ha->host_no);) 1713 1714 mcp->mb[0] = MBC_LOGIN_FABRIC_PORT; 1715 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1716 if (HAS_EXTENDED_IDS(ha)) { 1717 mcp->mb[1] = loop_id; 1718 mcp->mb[10] = opt; 1719 mcp->out_mb |= MBX_10; 1720 } else { 1721 mcp->mb[1] = (loop_id << 8) | opt; 1722 } 1723 mcp->mb[2] = domain; 1724 mcp->mb[3] = area << 8 | al_pa; 1725 1726 mcp->in_mb = MBX_7|MBX_6|MBX_2|MBX_1|MBX_0; 1727 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 1728 mcp->flags = 0; 1729 rval = qla2x00_mailbox_command(ha, mcp); 1730 1731 /* Return mailbox statuses. */ 1732 if (mb != NULL) { 1733 mb[0] = mcp->mb[0]; 1734 mb[1] = mcp->mb[1]; 1735 mb[2] = mcp->mb[2]; 1736 mb[6] = mcp->mb[6]; 1737 mb[7] = mcp->mb[7]; 1738 /* COS retrieved from Get-Port-Database mailbox command. */ 1739 mb[10] = 0; 1740 } 1741 1742 if (rval != QLA_SUCCESS) { 1743 /* RLU tmp code: need to change main mailbox_command function to 1744 * return ok even when the mailbox completion value is not 1745 * SUCCESS. The caller needs to be responsible to interpret 1746 * the return values of this mailbox command if we're not 1747 * to change too much of the existing code. 1748 */ 1749 if (mcp->mb[0] == 0x4001 || mcp->mb[0] == 0x4002 || 1750 mcp->mb[0] == 0x4003 || mcp->mb[0] == 0x4005 || 1751 mcp->mb[0] == 0x4006) 1752 rval = QLA_SUCCESS; 1753 1754 /*EMPTY*/ 1755 DEBUG2_3_11(printk("qla2x00_login_fabric(%ld): failed=%x " 1756 "mb[0]=%x mb[1]=%x mb[2]=%x.\n", ha->host_no, rval, 1757 mcp->mb[0], mcp->mb[1], mcp->mb[2]);) 1758 } else { 1759 /*EMPTY*/ 1760 DEBUG11(printk("qla2x00_login_fabric(%ld): done.\n", 1761 ha->host_no);) 1762 } 1763 1764 return rval; 1765} 1766 1767/* 1768 * qla2x00_login_local_device 1769 * Issue login loop port mailbox command. 1770 * 1771 * Input: 1772 * ha = adapter block pointer. 1773 * loop_id = device loop ID. 1774 * opt = command options. 1775 * 1776 * Returns: 1777 * Return status code. 1778 * 1779 * Context: 1780 * Kernel context. 1781 * 1782 */ 1783int 1784qla2x00_login_local_device(scsi_qla_host_t *ha, uint16_t loop_id, 1785 uint16_t *mb_ret, uint8_t opt) 1786{ 1787 int rval; 1788 mbx_cmd_t mc; 1789 mbx_cmd_t *mcp = &mc; 1790 1791 DEBUG3(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 1792 1793 mcp->mb[0] = MBC_LOGIN_LOOP_PORT; 1794 if (HAS_EXTENDED_IDS(ha)) 1795 mcp->mb[1] = loop_id; 1796 else 1797 mcp->mb[1] = loop_id << 8; 1798 mcp->mb[2] = opt; 1799 mcp->out_mb = MBX_2|MBX_1|MBX_0; 1800 mcp->in_mb = MBX_7|MBX_6|MBX_1|MBX_0; 1801 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 1802 mcp->flags = 0; 1803 rval = qla2x00_mailbox_command(ha, mcp); 1804 1805 /* Return mailbox statuses. */ 1806 if (mb_ret != NULL) { 1807 mb_ret[0] = mcp->mb[0]; 1808 mb_ret[1] = mcp->mb[1]; 1809 mb_ret[6] = mcp->mb[6]; 1810 mb_ret[7] = mcp->mb[7]; 1811 } 1812 1813 if (rval != QLA_SUCCESS) { 1814 /* AV tmp code: need to change main mailbox_command function to 1815 * return ok even when the mailbox completion value is not 1816 * SUCCESS. The caller needs to be responsible to interpret 1817 * the return values of this mailbox command if we're not 1818 * to change too much of the existing code. 1819 */ 1820 if (mcp->mb[0] == 0x4005 || mcp->mb[0] == 0x4006) 1821 rval = QLA_SUCCESS; 1822 1823 DEBUG(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " 1824 "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, 1825 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) 1826 DEBUG2_3(printk("%s(%ld): failed=%x mb[0]=%x mb[1]=%x " 1827 "mb[6]=%x mb[7]=%x.\n", __func__, ha->host_no, rval, 1828 mcp->mb[0], mcp->mb[1], mcp->mb[6], mcp->mb[7]);) 1829 } else { 1830 /*EMPTY*/ 1831 DEBUG3(printk("%s(%ld): done.\n", __func__, ha->host_no);) 1832 } 1833 1834 return (rval); 1835} 1836 1837int 1838qla24xx_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, 1839 uint8_t area, uint8_t al_pa) 1840{ 1841 int rval; 1842 struct logio_entry_24xx *lg; 1843 dma_addr_t lg_dma; 1844 1845 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 1846 1847 lg = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &lg_dma); 1848 if (lg == NULL) { 1849 DEBUG2_3(printk("%s(%ld): failed to allocate Logout IOCB.\n", 1850 __func__, ha->host_no)); 1851 return QLA_MEMORY_ALLOC_FAILED; 1852 } 1853 memset(lg, 0, sizeof(struct logio_entry_24xx)); 1854 1855 lg->entry_type = LOGINOUT_PORT_IOCB_TYPE; 1856 lg->entry_count = 1; 1857 lg->nport_handle = cpu_to_le16(loop_id); 1858 lg->control_flags = 1859 __constant_cpu_to_le16(LCF_COMMAND_LOGO|LCF_EXPL_LOGO); 1860 lg->port_id[0] = al_pa; 1861 lg->port_id[1] = area; 1862 lg->port_id[2] = domain; 1863 rval = qla2x00_issue_iocb(ha, lg, lg_dma, 0); 1864 if (rval != QLA_SUCCESS) { 1865 DEBUG2_3_11(printk("%s(%ld): failed to issue Logout IOCB " 1866 "(%x).\n", __func__, ha->host_no, rval);) 1867 } else if (lg->entry_status != 0) { 1868 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 1869 "-- error status (%x).\n", __func__, ha->host_no, 1870 lg->entry_status)); 1871 rval = QLA_FUNCTION_FAILED; 1872 } else if (lg->comp_status != __constant_cpu_to_le16(CS_COMPLETE)) { 1873 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 1874 "-- completion status (%x) ioparam=%x/%x.\n", __func__, 1875 ha->host_no, le16_to_cpu(lg->comp_status), 1876 le32_to_cpu(lg->io_parameter[0]), 1877 le32_to_cpu(lg->io_parameter[1]));) 1878 } else { 1879 /*EMPTY*/ 1880 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 1881 } 1882 1883 dma_pool_free(ha->s_dma_pool, lg, lg_dma); 1884 1885 return rval; 1886} 1887 1888/* 1889 * qla2x00_fabric_logout 1890 * Issue logout fabric port mailbox command. 1891 * 1892 * Input: 1893 * ha = adapter block pointer. 1894 * loop_id = device loop ID. 1895 * TARGET_QUEUE_LOCK must be released. 1896 * ADAPTER_STATE_LOCK must be released. 1897 * 1898 * Returns: 1899 * qla2x00 local function return status code. 1900 * 1901 * Context: 1902 * Kernel context. 1903 */ 1904int 1905qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain, 1906 uint8_t area, uint8_t al_pa) 1907{ 1908 int rval; 1909 mbx_cmd_t mc; 1910 mbx_cmd_t *mcp = &mc; 1911 1912 DEBUG11(printk("qla2x00_fabric_logout(%ld): entered.\n", 1913 ha->host_no);) 1914 1915 mcp->mb[0] = MBC_LOGOUT_FABRIC_PORT; 1916 mcp->out_mb = MBX_1|MBX_0; 1917 if (HAS_EXTENDED_IDS(ha)) { 1918 mcp->mb[1] = loop_id; 1919 mcp->mb[10] = 0; 1920 mcp->out_mb |= MBX_10; 1921 } else { 1922 mcp->mb[1] = loop_id << 8; 1923 } 1924 1925 mcp->in_mb = MBX_1|MBX_0; 1926 mcp->tov = 30; 1927 mcp->flags = 0; 1928 rval = qla2x00_mailbox_command(ha, mcp); 1929 1930 if (rval != QLA_SUCCESS) { 1931 /*EMPTY*/ 1932 DEBUG2_3_11(printk("qla2x00_fabric_logout(%ld): failed=%x " 1933 "mbx1=%x.\n", ha->host_no, rval, mcp->mb[1]);) 1934 } else { 1935 /*EMPTY*/ 1936 DEBUG11(printk("qla2x00_fabric_logout(%ld): done.\n", 1937 ha->host_no);) 1938 } 1939 1940 return rval; 1941} 1942 1943/* 1944 * qla2x00_full_login_lip 1945 * Issue full login LIP mailbox command. 1946 * 1947 * Input: 1948 * ha = adapter block pointer. 1949 * TARGET_QUEUE_LOCK must be released. 1950 * ADAPTER_STATE_LOCK must be released. 1951 * 1952 * Returns: 1953 * qla2x00 local function return status code. 1954 * 1955 * Context: 1956 * Kernel context. 1957 */ 1958int 1959qla2x00_full_login_lip(scsi_qla_host_t *ha) 1960{ 1961 int rval; 1962 mbx_cmd_t mc; 1963 mbx_cmd_t *mcp = &mc; 1964 1965 DEBUG11(printk("qla2x00_full_login_lip(%ld): entered.\n", 1966 ha->host_no);) 1967 1968 mcp->mb[0] = MBC_LIP_FULL_LOGIN; 1969 mcp->mb[1] = 0; 1970 mcp->mb[2] = 0xff; 1971 mcp->mb[3] = 0; 1972 mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0; 1973 mcp->in_mb = MBX_0; 1974 mcp->tov = 30; 1975 mcp->flags = 0; 1976 rval = qla2x00_mailbox_command(ha, mcp); 1977 1978 if (rval != QLA_SUCCESS) { 1979 /*EMPTY*/ 1980 DEBUG2_3_11(printk("qla2x00_full_login_lip(%ld): failed=%x.\n", 1981 ha->host_no, rval);) 1982 } else { 1983 /*EMPTY*/ 1984 DEBUG11(printk("qla2x00_full_login_lip(%ld): done.\n", 1985 ha->host_no);) 1986 } 1987 1988 return rval; 1989} 1990 1991/* 1992 * qla2x00_get_id_list 1993 * 1994 * Input: 1995 * ha = adapter block pointer. 1996 * 1997 * Returns: 1998 * qla2x00 local function return status code. 1999 * 2000 * Context: 2001 * Kernel context. 2002 */ 2003int 2004qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, 2005 uint16_t *entries) 2006{ 2007 int rval; 2008 mbx_cmd_t mc; 2009 mbx_cmd_t *mcp = &mc; 2010 2011 DEBUG11(printk("qla2x00_get_id_list(%ld): entered.\n", 2012 ha->host_no);) 2013 2014 if (id_list == NULL) 2015 return QLA_FUNCTION_FAILED; 2016 2017 mcp->mb[0] = MBC_GET_ID_LIST; 2018 mcp->out_mb = MBX_0; 2019 if (IS_QLA24XX(ha) || IS_QLA25XX(ha)) { 2020 mcp->mb[2] = MSW(id_list_dma); 2021 mcp->mb[3] = LSW(id_list_dma); 2022 mcp->mb[6] = MSW(MSD(id_list_dma)); 2023 mcp->mb[7] = LSW(MSD(id_list_dma)); 2024 mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2; 2025 } else { 2026 mcp->mb[1] = MSW(id_list_dma); 2027 mcp->mb[2] = LSW(id_list_dma); 2028 mcp->mb[3] = MSW(MSD(id_list_dma)); 2029 mcp->mb[6] = LSW(MSD(id_list_dma)); 2030 mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1; 2031 } 2032 mcp->in_mb = MBX_1|MBX_0; 2033 mcp->tov = 30; 2034 mcp->flags = 0; 2035 rval = qla2x00_mailbox_command(ha, mcp); 2036 2037 if (rval != QLA_SUCCESS) { 2038 /*EMPTY*/ 2039 DEBUG2_3_11(printk("qla2x00_get_id_list(%ld): failed=%x.\n", 2040 ha->host_no, rval);) 2041 } else { 2042 *entries = mcp->mb[1]; 2043 DEBUG11(printk("qla2x00_get_id_list(%ld): done.\n", 2044 ha->host_no);) 2045 } 2046 2047 return rval; 2048} 2049 2050/* 2051 * qla2x00_get_resource_cnts 2052 * Get current firmware resource counts. 2053 * 2054 * Input: 2055 * ha = adapter block pointer. 2056 * 2057 * Returns: 2058 * qla2x00 local function return status code. 2059 * 2060 * Context: 2061 * Kernel context. 2062 */ 2063int 2064qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, 2065 uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt) 2066{ 2067 int rval; 2068 mbx_cmd_t mc; 2069 mbx_cmd_t *mcp = &mc; 2070 2071 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 2072 2073 mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; 2074 mcp->out_mb = MBX_0; 2075 mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; 2076 mcp->tov = 30; 2077 mcp->flags = 0; 2078 rval = qla2x00_mailbox_command(ha, mcp); 2079 2080 if (rval != QLA_SUCCESS) { 2081 /*EMPTY*/ 2082 DEBUG2_3_11(printk("%s(%ld): failed = %x.\n", __func__, 2083 ha->host_no, mcp->mb[0]);) 2084 } else { 2085 DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " 2086 "mb7=%x mb10=%x.\n", __func__, ha->host_no, 2087 mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], 2088 mcp->mb[10])); 2089 2090 if (cur_xchg_cnt) 2091 *cur_xchg_cnt = mcp->mb[3]; 2092 if (orig_xchg_cnt) 2093 *orig_xchg_cnt = mcp->mb[6]; 2094 if (cur_iocb_cnt) 2095 *cur_iocb_cnt = mcp->mb[7]; 2096 if (orig_iocb_cnt) 2097 *orig_iocb_cnt = mcp->mb[10]; 2098 } 2099 2100 return (rval); 2101} 2102 2103#if defined(QL_DEBUG_LEVEL_3) 2104/* 2105 * qla2x00_get_fcal_position_map 2106 * Get FCAL (LILP) position map using mailbox command 2107 * 2108 * Input: 2109 * ha = adapter state pointer. 2110 * pos_map = buffer pointer (can be NULL). 2111 * 2112 * Returns: 2113 * qla2x00 local function return status code. 2114 * 2115 * Context: 2116 * Kernel context. 2117 */ 2118int 2119qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map) 2120{ 2121 int rval; 2122 mbx_cmd_t mc; 2123 mbx_cmd_t *mcp = &mc; 2124 char *pmap; 2125 dma_addr_t pmap_dma; 2126 2127 pmap = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &pmap_dma); 2128 if (pmap == NULL) { 2129 DEBUG2_3_11(printk("%s(%ld): **** Mem Alloc Failed ****", 2130 __func__, ha->host_no)); 2131 return QLA_MEMORY_ALLOC_FAILED; 2132 } 2133 memset(pmap, 0, FCAL_MAP_SIZE); 2134 2135 mcp->mb[0] = MBC_GET_FC_AL_POSITION_MAP; 2136 mcp->mb[2] = MSW(pmap_dma); 2137 mcp->mb[3] = LSW(pmap_dma); 2138 mcp->mb[6] = MSW(MSD(pmap_dma)); 2139 mcp->mb[7] = LSW(MSD(pmap_dma)); 2140 mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2141 mcp->in_mb = MBX_1|MBX_0; 2142 mcp->buf_size = FCAL_MAP_SIZE; 2143 mcp->flags = MBX_DMA_IN; 2144 mcp->tov = (ha->login_timeout * 2) + (ha->login_timeout / 2); 2145 rval = qla2x00_mailbox_command(ha, mcp); 2146 2147 if (rval == QLA_SUCCESS) { 2148 DEBUG11(printk("%s(%ld): (mb0=%x/mb1=%x) FC/AL Position Map " 2149 "size (%x)\n", __func__, ha->host_no, mcp->mb[0], 2150 mcp->mb[1], (unsigned)pmap[0])); 2151 DEBUG11(qla2x00_dump_buffer(pmap, pmap[0] + 1)); 2152 2153 if (pos_map) 2154 memcpy(pos_map, pmap, FCAL_MAP_SIZE); 2155 } 2156 dma_pool_free(ha->s_dma_pool, pmap, pmap_dma); 2157 2158 if (rval != QLA_SUCCESS) { 2159 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, 2160 ha->host_no, rval)); 2161 } else { 2162 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 2163 } 2164 2165 return rval; 2166} 2167 2168uint8_t 2169qla24xx_get_isp_stats(scsi_qla_host_t *ha, uint32_t *dwbuf, uint32_t dwords, 2170 uint16_t *status) 2171{ 2172 int rval; 2173 mbx_cmd_t mc; 2174 mbx_cmd_t *mcp = &mc; 2175 uint32_t *sbuf, *siter; 2176 dma_addr_t sbuf_dma; 2177 2178 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 2179 2180 if (dwords > (DMA_POOL_SIZE / 4)) { 2181 DEBUG2_3_11(printk("%s(%ld): Unabled to retrieve %d DWORDs " 2182 "(max %d).\n", __func__, ha->host_no, dwords, 2183 DMA_POOL_SIZE / 4)); 2184 return BIT_0; 2185 } 2186 sbuf = dma_pool_alloc(ha->s_dma_pool, GFP_ATOMIC, &sbuf_dma); 2187 if (sbuf == NULL) { 2188 DEBUG2_3_11(printk("%s(%ld): Failed to allocate memory.\n", 2189 __func__, ha->host_no)); 2190 return BIT_0; 2191 } 2192 memset(sbuf, 0, DMA_POOL_SIZE); 2193 2194 mcp->mb[0] = MBC_GET_LINK_PRIV_STATS; 2195 mcp->mb[2] = MSW(sbuf_dma); 2196 mcp->mb[3] = LSW(sbuf_dma); 2197 mcp->mb[6] = MSW(MSD(sbuf_dma)); 2198 mcp->mb[7] = LSW(MSD(sbuf_dma)); 2199 mcp->mb[8] = dwords; 2200 mcp->mb[10] = 0; 2201 mcp->out_mb = MBX_10|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0; 2202 mcp->in_mb = MBX_2|MBX_1|MBX_0; 2203 mcp->tov = 30; 2204 mcp->flags = IOCTL_CMD; 2205 rval = qla2x00_mailbox_command(ha, mcp); 2206 2207 if (rval == QLA_SUCCESS) { 2208 if (mcp->mb[0] != MBS_COMMAND_COMPLETE) { 2209 DEBUG2_3_11(printk("%s(%ld): cmd failed. mbx0=%x.\n", 2210 __func__, ha->host_no, mcp->mb[0])); 2211 status[0] = mcp->mb[0]; 2212 rval = BIT_1; 2213 } else { 2214 /* Copy over data -- firmware data is LE. */ 2215 siter = sbuf; 2216 while (dwords--) 2217 *dwbuf++ = le32_to_cpu(*siter++); 2218 } 2219 } else { 2220 /* Failed. */ 2221 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, 2222 ha->host_no, rval)); 2223 rval = BIT_1; 2224 } 2225 2226 dma_pool_free(ha->s_dma_pool, sbuf, sbuf_dma); 2227 2228 return rval; 2229} 2230#endif 2231 2232int 2233qla24xx_abort_command(scsi_qla_host_t *ha, srb_t *sp) 2234{ 2235 int rval; 2236 fc_port_t *fcport; 2237 unsigned long flags = 0; 2238 2239 struct abort_entry_24xx *abt; 2240 dma_addr_t abt_dma; 2241 uint32_t handle; 2242 2243 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no);) 2244 2245 fcport = sp->fcport; 2246 if (atomic_read(&ha->loop_state) == LOOP_DOWN || 2247 atomic_read(&fcport->state) == FCS_DEVICE_LOST) { 2248 return QLA_FUNCTION_FAILED; 2249 } 2250 2251 spin_lock_irqsave(&ha->hardware_lock, flags); 2252 for (handle = 1; handle < MAX_OUTSTANDING_COMMANDS; handle++) { 2253 if (ha->outstanding_cmds[handle] == sp) 2254 break; 2255 } 2256 spin_unlock_irqrestore(&ha->hardware_lock, flags); 2257 if (handle == MAX_OUTSTANDING_COMMANDS) { 2258 /* Command not found. */ 2259 return QLA_FUNCTION_FAILED; 2260 } 2261 2262 abt = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &abt_dma); 2263 if (abt == NULL) { 2264 DEBUG2_3(printk("%s(%ld): failed to allocate Abort IOCB.\n", 2265 __func__, ha->host_no)); 2266 return QLA_MEMORY_ALLOC_FAILED; 2267 } 2268 memset(abt, 0, sizeof(struct abort_entry_24xx)); 2269 2270 abt->entry_type = ABORT_IOCB_TYPE; 2271 abt->entry_count = 1; 2272 abt->nport_handle = cpu_to_le16(fcport->loop_id); 2273 abt->handle_to_abort = handle; 2274 abt->port_id[0] = fcport->d_id.b.al_pa; 2275 abt->port_id[1] = fcport->d_id.b.area; 2276 abt->port_id[2] = fcport->d_id.b.domain; 2277 rval = qla2x00_issue_iocb(ha, abt, abt_dma, 0); 2278 if (rval != QLA_SUCCESS) { 2279 DEBUG2_3_11(printk("%s(%ld): failed to issue IOCB (%x).\n", 2280 __func__, ha->host_no, rval);) 2281 } else if (abt->entry_status != 0) { 2282 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 2283 "-- error status (%x).\n", __func__, ha->host_no, 2284 abt->entry_status)); 2285 rval = QLA_FUNCTION_FAILED; 2286 } else if (abt->nport_handle != __constant_cpu_to_le16(0)) { 2287 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 2288 "-- completion status (%x).\n", __func__, ha->host_no, 2289 le16_to_cpu(abt->nport_handle));) 2290 rval = QLA_FUNCTION_FAILED; 2291 } else { 2292 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 2293 sp->flags |= SRB_ABORT_PENDING; 2294 } 2295 2296 dma_pool_free(ha->s_dma_pool, abt, abt_dma); 2297 2298 return rval; 2299} 2300 2301struct tsk_mgmt_cmd { 2302 union { 2303 struct tsk_mgmt_entry tsk; 2304 struct sts_entry_24xx sts; 2305 } p; 2306}; 2307 2308int 2309qla24xx_abort_target(fc_port_t *fcport) 2310{ 2311 int rval; 2312 struct tsk_mgmt_cmd *tsk; 2313 dma_addr_t tsk_dma; 2314 scsi_qla_host_t *ha; 2315 2316 if (fcport == NULL) 2317 return 0; 2318 2319 DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no);) 2320 2321 ha = fcport->ha; 2322 tsk = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &tsk_dma); 2323 if (tsk == NULL) { 2324 DEBUG2_3(printk("%s(%ld): failed to allocate Task Management " 2325 "IOCB.\n", __func__, ha->host_no)); 2326 return QLA_MEMORY_ALLOC_FAILED; 2327 } 2328 memset(tsk, 0, sizeof(struct tsk_mgmt_cmd)); 2329 2330 tsk->p.tsk.entry_type = TSK_MGMT_IOCB_TYPE; 2331 tsk->p.tsk.entry_count = 1; 2332 tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id); 2333 tsk->p.tsk.timeout = __constant_cpu_to_le16(25); 2334 tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET); 2335 tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa; 2336 tsk->p.tsk.port_id[1] = fcport->d_id.b.area; 2337 tsk->p.tsk.port_id[2] = fcport->d_id.b.domain; 2338 rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0); 2339 if (rval != QLA_SUCCESS) { 2340 DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB " 2341 "(%x).\n", __func__, ha->host_no, rval);) 2342 goto atarget_done; 2343 } else if (tsk->p.sts.entry_status != 0) { 2344 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 2345 "-- error status (%x).\n", __func__, ha->host_no, 2346 tsk->p.sts.entry_status)); 2347 rval = QLA_FUNCTION_FAILED; 2348 goto atarget_done; 2349 } else if (tsk->p.sts.comp_status != 2350 __constant_cpu_to_le16(CS_COMPLETE)) { 2351 DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB " 2352 "-- completion status (%x).\n", __func__, 2353 ha->host_no, le16_to_cpu(tsk->p.sts.comp_status));) 2354 rval = QLA_FUNCTION_FAILED; 2355 goto atarget_done; 2356 } 2357 2358 /* Issue marker IOCB. */ 2359 rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID); 2360 if (rval != QLA_SUCCESS) { 2361 DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB " 2362 "(%x).\n", __func__, ha->host_no, rval);) 2363 } else { 2364 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no);) 2365 } 2366 2367atarget_done: 2368 dma_pool_free(ha->s_dma_pool, tsk, tsk_dma); 2369 2370 return rval; 2371} 2372 2373int 2374qla2x00_system_error(scsi_qla_host_t *ha) 2375{ 2376 int rval; 2377 mbx_cmd_t mc; 2378 mbx_cmd_t *mcp = &mc; 2379 2380 if (!IS_QLA24XX(ha) && !IS_QLA25XX(ha)) 2381 return QLA_FUNCTION_FAILED; 2382 2383 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 2384 2385 mcp->mb[0] = MBC_GEN_SYSTEM_ERROR; 2386 mcp->out_mb = MBX_0; 2387 mcp->in_mb = MBX_0; 2388 mcp->tov = 5; 2389 mcp->flags = 0; 2390 rval = qla2x00_mailbox_command(ha, mcp); 2391 2392 if (rval != QLA_SUCCESS) { 2393 DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__, 2394 ha->host_no, rval)); 2395 } else { 2396 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 2397 } 2398 2399 return rval; 2400} 2401 2402/** 2403 * qla2x00_get_serdes_params() - 2404 * @ha: HA context 2405 * 2406 * Returns 2407 */ 2408int 2409qla2x00_get_serdes_params(scsi_qla_host_t *ha, uint16_t *sw_em_1g, 2410 uint16_t *sw_em_2g, uint16_t *sw_em_4g) 2411{ 2412 int rval; 2413 mbx_cmd_t mc; 2414 mbx_cmd_t *mcp = &mc; 2415 2416 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 2417 2418 mcp->mb[0] = MBC_SERDES_PARAMS; 2419 mcp->mb[1] = 0; 2420 mcp->out_mb = MBX_1|MBX_0; 2421 mcp->in_mb = MBX_4|MBX_3|MBX_2|MBX_0; 2422 mcp->tov = 30; 2423 mcp->flags = 0; 2424 rval = qla2x00_mailbox_command(ha, mcp); 2425 2426 if (rval != QLA_SUCCESS) { 2427 /*EMPTY*/ 2428 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, 2429 ha->host_no, rval, mcp->mb[0])); 2430 } else { 2431 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 2432 2433 if (sw_em_1g) 2434 *sw_em_1g = mcp->mb[2]; 2435 if (sw_em_2g) 2436 *sw_em_2g = mcp->mb[3]; 2437 if (sw_em_4g) 2438 *sw_em_4g = mcp->mb[4]; 2439 } 2440 2441 return rval; 2442} 2443 2444/** 2445 * qla2x00_set_serdes_params() - 2446 * @ha: HA context 2447 * 2448 * Returns 2449 */ 2450int 2451qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g, 2452 uint16_t sw_em_2g, uint16_t sw_em_4g) 2453{ 2454 int rval; 2455 mbx_cmd_t mc; 2456 mbx_cmd_t *mcp = &mc; 2457 2458 DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); 2459 2460 mcp->mb[0] = MBC_SERDES_PARAMS; 2461 mcp->mb[1] = BIT_0; 2462 mcp->mb[2] = sw_em_1g; 2463 mcp->mb[3] = sw_em_2g; 2464 mcp->mb[4] = sw_em_4g; 2465 mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0; 2466 mcp->in_mb = MBX_0; 2467 mcp->tov = 30; 2468 mcp->flags = 0; 2469 rval = qla2x00_mailbox_command(ha, mcp); 2470 2471 if (rval != QLA_SUCCESS) { 2472 /*EMPTY*/ 2473 DEBUG2_3_11(printk("%s(%ld): failed=%x (%x).\n", __func__, 2474 ha->host_no, rval, mcp->mb[0])); 2475 } else { 2476 /*EMPTY*/ 2477 DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); 2478 } 2479 2480 return rval; 2481} 2482