1 /* $NetBSD: mpt.c,v 1.17 2014/09/27 16:14:16 jmcneill Exp $ */ 2 3 /* 4 * Copyright (c) 2000, 2001 by Greg Ansley 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice immediately at the beginning of the file, without modification, 11 * this list of conditions, and the following disclaimer. 12 * 2. The name of the author may not be used to endorse or promote products 13 * derived from this software without specific prior written permission. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 19 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 /* 28 * Additional Copyright (c) 2002 by Matthew Jacob under same license. 29 */ 30 /*- 31 * Copyright (c) 2002, 2006 by Matthew Jacob 32 * All rights reserved. 33 * 34 * Redistribution and use in source and binary forms, with or without 35 * modification, are permitted provided that the following conditions are 36 * met: 37 * 1. Redistributions of source code must retain the above copyright 38 * notice, this list of conditions and the following disclaimer. 39 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 40 * substantially similar to the "NO WARRANTY" disclaimer below 41 * ("Disclaimer") and any redistribution must be conditioned upon including 42 * a substantially similar Disclaimer requirement for further binary 43 * redistribution. 44 * 3. Neither the names of the above listed copyright holders nor the names 45 * of any contributors may be used to endorse or promote products derived 46 * from this software without specific prior written permission. 47 * 48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 49 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 52 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 56 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT 58 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 59 * 60 * Support from Chris Ellsworth in order to make SAS adapters work 61 * is gratefully acknowledged. 62 * 63 * 64 * Support from LSI-Logic has also gone a great deal toward making this a 65 * workable subsystem and is gratefully acknowledged. 66 */ 67 /*- 68 * Copyright (c) 2004, Avid Technology, Inc. and its contributors. 69 * Copyright (c) 2005, WHEEL Sp. z o.o. 70 * Copyright (c) 2004, 2005 Justin T. Gibbs 71 * All rights reserved. 72 * 73 * Redistribution and use in source and binary forms, with or without 74 * modification, are permitted provided that the following conditions are 75 * met: 76 * 1. Redistributions of source code must retain the above copyright 77 * notice, this list of conditions and the following disclaimer. 78 * 2. Redistributions in binary form must reproduce at minimum a disclaimer 79 * substantially similar to the "NO WARRANTY" disclaimer below 80 * ("Disclaimer") and any redistribution must be conditioned upon including 81 * a substantially similar Disclaimer requirement for further binary 82 * redistribution. 83 * 3. Neither the names of the above listed copyright holders nor the names 84 * of any contributors may be used to endorse or promote products derived 85 * from this software without specific prior written permission. 86 * 87 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 88 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 89 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 90 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 91 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 92 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 93 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 94 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 95 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 96 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF THE COPYRIGHT 97 * OWNER OR CONTRIBUTOR IS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 98 */ 99 100 101 /* 102 * mpt.c: 103 * 104 * Generic routines for LSI Fusion adapters. 105 * 106 * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for 107 * Wasabi Systems, Inc. 108 * 109 * Additional contributions by Garrett D'Amore on behalf of TELES AG. 110 */ 111 112 #include <sys/cdefs.h> 113 __KERNEL_RCSID(0, "$NetBSD: mpt.c,v 1.17 2014/09/27 16:14:16 jmcneill Exp $"); 114 115 #include <dev/ic/mpt.h> 116 117 #define MPT_MAX_TRYS 3 118 #define MPT_MAX_WAIT 300000 119 120 static int maxwait_ack = 0; 121 static int maxwait_int = 0; 122 static int maxwait_state = 0; 123 124 static inline u_int32_t 125 mpt_rd_db(mpt_softc_t *mpt) 126 { 127 return mpt_read(mpt, MPT_OFFSET_DOORBELL); 128 } 129 130 static inline u_int32_t 131 mpt_rd_intr(mpt_softc_t *mpt) 132 { 133 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS); 134 } 135 136 /* Busy wait for a door bell to be read by IOC */ 137 static int 138 mpt_wait_db_ack(mpt_softc_t *mpt) 139 { 140 int i; 141 for (i=0; i < MPT_MAX_WAIT; i++) { 142 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) { 143 maxwait_ack = i > maxwait_ack ? i : maxwait_ack; 144 return MPT_OK; 145 } 146 147 DELAY(100); 148 } 149 return MPT_FAIL; 150 } 151 152 /* Busy wait for a door bell interrupt */ 153 static int 154 mpt_wait_db_int(mpt_softc_t *mpt) 155 { 156 int i; 157 for (i=0; i < MPT_MAX_WAIT; i++) { 158 if (MPT_DB_INTR(mpt_rd_intr(mpt))) { 159 maxwait_int = i > maxwait_int ? i : maxwait_int; 160 return MPT_OK; 161 } 162 DELAY(100); 163 } 164 return MPT_FAIL; 165 } 166 167 /* Wait for IOC to transition to a give state */ 168 void 169 mpt_check_doorbell(mpt_softc_t *mpt) 170 { 171 u_int32_t db = mpt_rd_db(mpt); 172 if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) { 173 mpt_prt(mpt, "Device not running"); 174 mpt_print_db(db); 175 } 176 } 177 178 /* Wait for IOC to transition to a give state */ 179 static int 180 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state) 181 { 182 int i; 183 184 for (i = 0; i < MPT_MAX_WAIT; i++) { 185 u_int32_t db = mpt_rd_db(mpt); 186 if (MPT_STATE(db) == state) { 187 maxwait_state = i > maxwait_state ? i : maxwait_state; 188 return (MPT_OK); 189 } 190 DELAY(100); 191 } 192 return (MPT_FAIL); 193 } 194 195 196 /* Issue the reset COMMAND to the IOC */ 197 int 198 mpt_soft_reset(mpt_softc_t *mpt) 199 { 200 if (mpt->verbose) { 201 mpt_prt(mpt, "soft reset"); 202 } 203 204 /* Have to use hard reset if we are not in Running state */ 205 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) { 206 mpt_prt(mpt, "soft reset failed: device not running"); 207 return MPT_FAIL; 208 } 209 210 /* If door bell is in use we don't have a chance of getting 211 * a word in since the IOC probably crashed in message 212 * processing. So don't waste our time. 213 */ 214 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) { 215 mpt_prt(mpt, "soft reset failed: doorbell wedged"); 216 return MPT_FAIL; 217 } 218 219 /* Send the reset request to the IOC */ 220 mpt_write(mpt, MPT_OFFSET_DOORBELL, 221 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT); 222 if (mpt_wait_db_ack(mpt) != MPT_OK) { 223 mpt_prt(mpt, "soft reset failed: ack timeout"); 224 return MPT_FAIL; 225 } 226 227 /* Wait for the IOC to reload and come out of reset state */ 228 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) { 229 mpt_prt(mpt, "soft reset failed: device did not start running"); 230 return MPT_FAIL; 231 } 232 233 return MPT_OK; 234 } 235 236 /* This is a magic diagnostic reset that resets all the ARM 237 * processors in the chip. 238 */ 239 void 240 mpt_hard_reset(mpt_softc_t *mpt) 241 { 242 if (mpt->verbose) { 243 mpt_prt(mpt, "hard reset"); 244 } 245 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xff); 246 247 /* Enable diagnostic registers */ 248 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1); 249 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2); 250 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3); 251 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4); 252 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5); 253 254 /* Diag. port is now active so we can now hit the reset bit */ 255 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC); 256 257 DELAY(10000); 258 259 /* Disable Diagnostic Register */ 260 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF); 261 } 262 263 /* 264 * Reset the IOC when needed. Try software command first then if needed 265 * poke at the magic diagnostic reset. Note that a hard reset resets 266 * *both* IOCs on dual function chips (FC929 && LSI1030) as well as 267 * fouls up the PCI configuration registers. 268 */ 269 int 270 mpt_reset(mpt_softc_t *mpt) 271 { 272 int ret; 273 274 /* Try a soft reset */ 275 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) { 276 /* Failed; do a hard reset */ 277 mpt_hard_reset(mpt); 278 279 /* Wait for the IOC to reload and come out of reset state */ 280 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY); 281 if (ret != MPT_OK) { 282 mpt_prt(mpt, "failed to reset device"); 283 } 284 } 285 286 return ret; 287 } 288 289 /* Return a command buffer to the free queue */ 290 void 291 mpt_free_request(mpt_softc_t *mpt, request_t *req) 292 { 293 if (req == NULL || req != &mpt->request_pool[req->index]) { 294 panic("mpt_free_request bad req ptr\n"); 295 return; 296 } 297 req->sequence = 0; 298 req->xfer = NULL; 299 req->debug = REQ_FREE; 300 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link); 301 } 302 303 /* Get a command buffer from the free queue */ 304 request_t * 305 mpt_get_request(mpt_softc_t *mpt) 306 { 307 request_t *req; 308 req = SLIST_FIRST(&mpt->request_free_list); 309 if (req != NULL) { 310 if (req != &mpt->request_pool[req->index]) { 311 panic("mpt_get_request: corrupted request free list\n"); 312 } 313 if (req->xfer != NULL) { 314 panic("mpt_get_request: corrupted request free list (xfer)\n"); 315 } 316 SLIST_REMOVE_HEAD(&mpt->request_free_list, link); 317 req->debug = REQ_IN_PROGRESS; 318 } 319 return req; 320 } 321 322 /* Pass the command to the IOC */ 323 void 324 mpt_send_cmd(mpt_softc_t *mpt, request_t *req) 325 { 326 req->sequence = mpt->sequence++; 327 if (mpt->verbose > 1) { 328 u_int32_t *pReq; 329 pReq = req->req_vbuf; 330 mpt_prt(mpt, "Send Request %d (0x%x):", 331 req->index, req->req_pbuf); 332 mpt_prt(mpt, "%08x %08x %08x %08x", 333 pReq[0], pReq[1], pReq[2], pReq[3]); 334 mpt_prt(mpt, "%08x %08x %08x %08x", 335 pReq[4], pReq[5], pReq[6], pReq[7]); 336 mpt_prt(mpt, "%08x %08x %08x %08x", 337 pReq[8], pReq[9], pReq[10], pReq[11]); 338 mpt_prt(mpt, "%08x %08x %08x %08x", 339 pReq[12], pReq[13], pReq[14], pReq[15]); 340 } 341 MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 342 req->debug = REQ_ON_CHIP; 343 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf); 344 } 345 346 /* 347 * Give the reply buffer back to the IOC after we have 348 * finished processing it. 349 */ 350 void 351 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr) 352 { 353 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr); 354 } 355 356 /* Get a reply from the IOC */ 357 u_int32_t 358 mpt_pop_reply_queue(mpt_softc_t *mpt) 359 { 360 return mpt_read(mpt, MPT_OFFSET_REPLY_Q); 361 } 362 363 /* 364 * Send a command to the IOC via the handshake register. 365 * 366 * Only done at initialization time and for certain unusual 367 * commands such as device/bus reset as specified by LSI. 368 */ 369 int 370 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd) 371 { 372 int i; 373 u_int32_t data, *data32; 374 375 /* Check condition of the IOC */ 376 data = mpt_rd_db(mpt); 377 if (((MPT_STATE(data) != MPT_DB_STATE_READY) && 378 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) && 379 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) || 380 ( MPT_DB_IS_IN_USE(data) )) { 381 mpt_prt(mpt, "handshake aborted due to invalid doorbell state"); 382 mpt_print_db(data); 383 return(EBUSY); 384 } 385 386 /* We move things in 32 bit chunks */ 387 len = (len + 3) >> 2; 388 data32 = cmd; 389 390 /* Clear any left over pending doorbell interrupts */ 391 if (MPT_DB_INTR(mpt_rd_intr(mpt))) 392 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 393 394 /* 395 * Tell the handshake reg. we are going to send a command 396 * and how long it is going to be. 397 */ 398 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) | 399 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT); 400 mpt_write(mpt, MPT_OFFSET_DOORBELL, data); 401 402 /* Wait for the chip to notice */ 403 if (mpt_wait_db_int(mpt) != MPT_OK) { 404 mpt_prt(mpt, "mpt_send_handshake_cmd timeout1"); 405 return ETIMEDOUT; 406 } 407 408 /* Clear the interrupt */ 409 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 410 411 if (mpt_wait_db_ack(mpt) != MPT_OK) { 412 mpt_prt(mpt, "mpt_send_handshake_cmd timeout2"); 413 return ETIMEDOUT; 414 } 415 416 /* Send the command */ 417 for (i = 0; i < len; i++) { 418 mpt_write(mpt, MPT_OFFSET_DOORBELL, htole32(*data32++)); 419 if (mpt_wait_db_ack(mpt) != MPT_OK) { 420 mpt_prt(mpt, 421 "mpt_send_handshake_cmd timeout! index = %d", i); 422 return ETIMEDOUT; 423 } 424 } 425 return MPT_OK; 426 } 427 428 /* Get the response from the handshake register */ 429 int 430 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply) 431 { 432 int left, reply_left; 433 u_int16_t *data16; 434 MSG_DEFAULT_REPLY *hdr; 435 436 /* We move things out in 16 bit chunks */ 437 reply_len >>= 1; 438 data16 = (u_int16_t *)reply; 439 440 hdr = (MSG_DEFAULT_REPLY *)reply; 441 442 /* Get first word */ 443 if (mpt_wait_db_int(mpt) != MPT_OK) { 444 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1"); 445 return ETIMEDOUT; 446 } 447 *data16++ = le16toh(mpt_read(mpt, MPT_OFFSET_DOORBELL) & 448 MPT_DB_DATA_MASK); 449 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 450 451 /* Get Second Word */ 452 if (mpt_wait_db_int(mpt) != MPT_OK) { 453 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2"); 454 return ETIMEDOUT; 455 } 456 *data16++ = le16toh(mpt_read(mpt, MPT_OFFSET_DOORBELL) & 457 MPT_DB_DATA_MASK); 458 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 459 460 /* With the second word, we can now look at the length */ 461 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) { 462 mpt_prt(mpt, "reply length does not match message length: " 463 "got 0x%02x, expected 0x%02x", 464 hdr->MsgLength << 2, reply_len << 1); 465 } 466 467 /* Get rest of the reply; but don't overflow the provided buffer */ 468 left = (hdr->MsgLength << 1) - 2; 469 reply_left = reply_len - 2; 470 while (left--) { 471 u_int16_t datum; 472 473 if (mpt_wait_db_int(mpt) != MPT_OK) { 474 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3"); 475 return ETIMEDOUT; 476 } 477 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL); 478 479 if (reply_left-- > 0) 480 *data16++ = le16toh(datum & MPT_DB_DATA_MASK); 481 482 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 483 } 484 485 /* One more wait & clear at the end */ 486 if (mpt_wait_db_int(mpt) != MPT_OK) { 487 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout4"); 488 return ETIMEDOUT; 489 } 490 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 491 492 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 493 if (mpt->verbose > 1) 494 mpt_print_reply(hdr); 495 return (MPT_FAIL | hdr->IOCStatus); 496 } 497 498 return (0); 499 } 500 501 static int 502 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp) 503 { 504 MSG_IOC_FACTS f_req; 505 int error; 506 507 memset(&f_req, 0, sizeof f_req); 508 f_req.Function = MPI_FUNCTION_IOC_FACTS; 509 f_req.MsgContext = htole32(0x12071942); 510 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); 511 if (error) 512 return(error); 513 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); 514 return (error); 515 } 516 517 static int 518 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp) 519 { 520 MSG_PORT_FACTS f_req; 521 int error; 522 523 /* XXX: Only getting PORT FACTS for Port 0 */ 524 memset(&f_req, 0, sizeof f_req); 525 f_req.Function = MPI_FUNCTION_PORT_FACTS; 526 f_req.MsgContext = htole32(0x12071943); 527 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); 528 if (error) 529 return(error); 530 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); 531 return (error); 532 } 533 534 /* 535 * Send the initialization request. This is where we specify how many 536 * SCSI busses and how many devices per bus we wish to emulate. 537 * This is also the command that specifies the max size of the reply 538 * frames from the IOC that we will be allocating. 539 */ 540 static int 541 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who) 542 { 543 int error = 0; 544 MSG_IOC_INIT init; 545 MSG_IOC_INIT_REPLY reply; 546 547 memset(&init, 0, sizeof init); 548 init.WhoInit = who; 549 init.Function = MPI_FUNCTION_IOC_INIT; 550 init.MaxDevices = mpt->mpt_max_devices; 551 init.MaxBuses = 1; 552 init.ReplyFrameSize = htole16(MPT_REPLY_SIZE); 553 init.MsgContext = htole32(0x12071941); 554 555 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) { 556 return(error); 557 } 558 559 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply); 560 return (error); 561 } 562 563 564 /* 565 * Utiltity routine to read configuration headers and pages 566 */ 567 568 int 569 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber, 570 int PageAddress, fCONFIG_PAGE_HEADER *rslt) 571 { 572 int count; 573 request_t *req; 574 MSG_CONFIG *cfgp; 575 MSG_CONFIG_REPLY *reply; 576 577 req = mpt_get_request(mpt); 578 579 cfgp = req->req_vbuf; 580 memset(cfgp, 0, sizeof *cfgp); 581 582 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER; 583 cfgp->Function = MPI_FUNCTION_CONFIG; 584 cfgp->Header.PageNumber = (U8) PageNumber; 585 cfgp->Header.PageType = (U8) PageType; 586 cfgp->PageAddress = htole32(PageAddress); 587 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE), 588 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 589 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST)); 590 cfgp->MsgContext = htole32(req->index | 0x80000000); 591 592 mpt_check_doorbell(mpt); 593 mpt_send_cmd(mpt, req); 594 count = 0; 595 do { 596 DELAY(500); 597 mpt_intr(mpt); 598 if (++count == 1000) { 599 mpt_prt(mpt, "read_cfg_header timed out"); 600 return (-1); 601 } 602 } while (req->debug == REQ_ON_CHIP); 603 604 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 605 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 606 mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x", 607 reply->IOCStatus); 608 mpt_free_reply(mpt, (req->sequence << 1)); 609 return (-1); 610 } 611 memcpy(rslt, &reply->Header, sizeof (fCONFIG_PAGE_HEADER)); 612 mpt_free_reply(mpt, (req->sequence << 1)); 613 mpt_free_request(mpt, req); 614 return (0); 615 } 616 617 #define CFG_DATA_OFF 128 618 619 int 620 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 621 { 622 int count; 623 request_t *req; 624 SGE_SIMPLE32 *se; 625 MSG_CONFIG *cfgp; 626 size_t amt; 627 MSG_CONFIG_REPLY *reply; 628 629 req = mpt_get_request(mpt); 630 631 cfgp = req->req_vbuf; 632 memset(cfgp, 0, MPT_REQUEST_AREA); 633 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 634 cfgp->Function = MPI_FUNCTION_CONFIG; 635 cfgp->Header = *hdr; 636 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 637 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK; 638 cfgp->PageAddress = htole32(PageAddress); 639 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 640 se->Address = htole32(req->req_pbuf + CFG_DATA_OFF); 641 MPI_pSGE_SET_LENGTH(se, amt); 642 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 643 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 644 MPI_SGE_FLAGS_END_OF_LIST)); 645 se->FlagsLength = htole32(se->FlagsLength); 646 647 cfgp->MsgContext = htole32(req->index | 0x80000000); 648 649 mpt_check_doorbell(mpt); 650 mpt_send_cmd(mpt, req); 651 count = 0; 652 do { 653 DELAY(500); 654 mpt_intr(mpt); 655 if (++count == 1000) { 656 mpt_prt(mpt, "read_cfg_page timed out"); 657 return (-1); 658 } 659 } while (req->debug == REQ_ON_CHIP); 660 661 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 662 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 663 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x", 664 reply->IOCStatus); 665 mpt_free_reply(mpt, (req->sequence << 1)); 666 return (-1); 667 } 668 mpt_free_reply(mpt, (req->sequence << 1)); 669 #if 0 /* XXXJRT */ 670 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, 671 BUS_DMASYNC_POSTREAD); 672 #endif 673 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 674 cfgp->Header.PageNumber == 0) { 675 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0); 676 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 677 cfgp->Header.PageNumber == 1) { 678 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1); 679 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 680 cfgp->Header.PageNumber == 2) { 681 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2); 682 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 683 cfgp->Header.PageNumber == 0) { 684 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0); 685 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 686 cfgp->Header.PageNumber == 1) { 687 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1); 688 } 689 memcpy(hdr, (char *)req->req_vbuf + CFG_DATA_OFF, amt); 690 mpt_free_request(mpt, req); 691 return (0); 692 } 693 694 int 695 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 696 { 697 int count, hdr_attr; 698 request_t *req; 699 SGE_SIMPLE32 *se; 700 MSG_CONFIG *cfgp; 701 size_t amt; 702 MSG_CONFIG_REPLY *reply; 703 704 req = mpt_get_request(mpt); 705 706 cfgp = req->req_vbuf; 707 memset(cfgp, 0, sizeof *cfgp); 708 709 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK; 710 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE && 711 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) { 712 mpt_prt(mpt, "page type 0x%x not changeable", 713 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 714 return (-1); 715 } 716 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK; 717 718 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 719 cfgp->Function = MPI_FUNCTION_CONFIG; 720 cfgp->Header = *hdr; 721 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 722 cfgp->PageAddress = htole32(PageAddress); 723 724 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 725 se->Address = htole32(req->req_pbuf + CFG_DATA_OFF); 726 MPI_pSGE_SET_LENGTH(se, amt); 727 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 728 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 729 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC)); 730 se->FlagsLength = htole32(se->FlagsLength); 731 732 cfgp->MsgContext = htole32(req->index | 0x80000000); 733 734 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 735 cfgp->Header.PageNumber == 0) { 736 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0); 737 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 738 cfgp->Header.PageNumber == 1) { 739 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1); 740 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 741 cfgp->Header.PageNumber == 2) { 742 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2); 743 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 744 cfgp->Header.PageNumber == 0) { 745 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0); 746 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 747 cfgp->Header.PageNumber == 1) { 748 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1); 749 } 750 memcpy((char *)req->req_vbuf + CFG_DATA_OFF, hdr, amt); 751 /* Restore stripped out attributes */ 752 hdr->PageType |= hdr_attr; 753 754 mpt_check_doorbell(mpt); 755 mpt_send_cmd(mpt, req); 756 count = 0; 757 do { 758 DELAY(500); 759 mpt_intr(mpt); 760 if (++count == 1000) { 761 hdr->PageType |= hdr_attr; 762 mpt_prt(mpt, "mpt_write_cfg_page timed out"); 763 return (-1); 764 } 765 } while (req->debug == REQ_ON_CHIP); 766 767 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 768 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 769 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x", 770 le16toh(reply->IOCStatus)); 771 mpt_free_reply(mpt, (req->sequence << 1)); 772 return (-1); 773 } 774 mpt_free_reply(mpt, (req->sequence << 1)); 775 776 mpt_free_request(mpt, req); 777 return (0); 778 } 779 780 /* 781 * Read SCSI configuration information 782 */ 783 static int 784 mpt_read_config_info_spi(mpt_softc_t *mpt) 785 { 786 int rv, i; 787 788 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0, 789 0, &mpt->mpt_port_page0.Header); 790 if (rv) { 791 return (-1); 792 } 793 if (mpt->verbose > 1) { 794 mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x", 795 mpt->mpt_port_page0.Header.PageVersion, 796 mpt->mpt_port_page0.Header.PageLength, 797 mpt->mpt_port_page0.Header.PageNumber, 798 mpt->mpt_port_page0.Header.PageType); 799 } 800 801 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1, 802 0, &mpt->mpt_port_page1.Header); 803 if (rv) { 804 return (-1); 805 } 806 if (mpt->verbose > 1) { 807 mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x", 808 mpt->mpt_port_page1.Header.PageVersion, 809 mpt->mpt_port_page1.Header.PageLength, 810 mpt->mpt_port_page1.Header.PageNumber, 811 mpt->mpt_port_page1.Header.PageType); 812 } 813 814 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2, 815 0, &mpt->mpt_port_page2.Header); 816 if (rv) { 817 return (-1); 818 } 819 820 if (mpt->verbose > 1) { 821 mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x", 822 mpt->mpt_port_page1.Header.PageVersion, 823 mpt->mpt_port_page1.Header.PageLength, 824 mpt->mpt_port_page1.Header.PageNumber, 825 mpt->mpt_port_page1.Header.PageType); 826 } 827 828 for (i = 0; i < 16; i++) { 829 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 830 0, i, &mpt->mpt_dev_page0[i].Header); 831 if (rv) { 832 return (-1); 833 } 834 if (mpt->verbose > 1) { 835 mpt_prt(mpt, 836 "SPI Target %d Device Page 0 Header: %x %x %x %x", 837 i, mpt->mpt_dev_page0[i].Header.PageVersion, 838 mpt->mpt_dev_page0[i].Header.PageLength, 839 mpt->mpt_dev_page0[i].Header.PageNumber, 840 mpt->mpt_dev_page0[i].Header.PageType); 841 } 842 843 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 844 1, i, &mpt->mpt_dev_page1[i].Header); 845 if (rv) { 846 return (-1); 847 } 848 if (mpt->verbose > 1) { 849 mpt_prt(mpt, 850 "SPI Target %d Device Page 1 Header: %x %x %x %x", 851 i, mpt->mpt_dev_page1[i].Header.PageVersion, 852 mpt->mpt_dev_page1[i].Header.PageLength, 853 mpt->mpt_dev_page1[i].Header.PageNumber, 854 mpt->mpt_dev_page1[i].Header.PageType); 855 } 856 } 857 858 /* 859 * At this point, we don't *have* to fail. As long as we have 860 * valid config header information, we can (barely) lurch 861 * along. 862 */ 863 864 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header); 865 mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0); 866 if (rv) { 867 mpt_prt(mpt, "failed to read SPI Port Page 0"); 868 } else if (mpt->verbose > 1) { 869 mpt_prt(mpt, 870 "SPI Port Page 0: Capabilities %x PhysicalInterface %x", 871 mpt->mpt_port_page0.Capabilities, 872 mpt->mpt_port_page0.PhysicalInterface); 873 } 874 875 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header); 876 mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1); 877 if (rv) { 878 mpt_prt(mpt, "failed to read SPI Port Page 1"); 879 } else if (mpt->verbose > 1) { 880 mpt_prt(mpt, 881 "SPI Port Page 1: Configuration %x OnBusTimerValue %x", 882 mpt->mpt_port_page1.Configuration, 883 mpt->mpt_port_page1.OnBusTimerValue); 884 } 885 886 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header); 887 mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2); 888 if (rv) { 889 mpt_prt(mpt, "failed to read SPI Port Page 2"); 890 } else if (mpt->verbose > 1) { 891 mpt_prt(mpt, 892 "SPI Port Page 2: Flags %x Settings %x", 893 mpt->mpt_port_page2.PortFlags, 894 mpt->mpt_port_page2.PortSettings); 895 for (i = 0; i < 1; i++) { 896 mpt_prt(mpt, 897 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x", 898 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout, 899 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor, 900 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags); 901 } 902 } 903 904 for (i = 0; i < 16; i++) { 905 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header); 906 mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]); 907 if (rv) { 908 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i); 909 continue; 910 } 911 if (mpt->verbose > 1) { 912 mpt_prt(mpt, 913 "SPI Tgt %d Page 0: NParms %x Information %x", 914 i, mpt->mpt_dev_page0[i].NegotiatedParameters, 915 mpt->mpt_dev_page0[i].Information); 916 } 917 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header); 918 mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]); 919 if (rv) { 920 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i); 921 continue; 922 } 923 if (mpt->verbose > 1) { 924 mpt_prt(mpt, 925 "SPI Tgt %d Page 1: RParms %x Configuration %x", 926 i, mpt->mpt_dev_page1[i].RequestedParameters, 927 mpt->mpt_dev_page1[i].Configuration); 928 } 929 } 930 return (0); 931 } 932 933 /* 934 * Validate SPI configuration information. 935 * 936 * In particular, validate SPI Port Page 1. 937 */ 938 static int 939 mpt_set_initial_config_spi(mpt_softc_t *mpt) 940 { 941 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id; 942 943 mpt->mpt_disc_enable = 0xff; 944 mpt->mpt_tag_enable = 0; 945 946 if (mpt->mpt_port_page1.Configuration != pp1val) { 947 fCONFIG_PAGE_SCSI_PORT_1 tmp; 948 949 mpt_prt(mpt, 950 "SPI Port Page 1 Config value bad (%x)- should be %x", 951 mpt->mpt_port_page1.Configuration, pp1val); 952 tmp = mpt->mpt_port_page1; 953 tmp.Configuration = pp1val; 954 host2mpt_config_page_scsi_port_1(&tmp); 955 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) { 956 return (-1); 957 } 958 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) { 959 return (-1); 960 } 961 mpt2host_config_page_scsi_port_1(&tmp); 962 if (tmp.Configuration != pp1val) { 963 mpt_prt(mpt, 964 "failed to reset SPI Port Page 1 Config value"); 965 return (-1); 966 } 967 mpt->mpt_port_page1 = tmp; 968 } 969 970 i = 0; 971 for (i = 0; i < 16; i++) { 972 fCONFIG_PAGE_SCSI_DEVICE_1 tmp; 973 974 tmp = mpt->mpt_dev_page1[i]; 975 tmp.RequestedParameters = 0; 976 tmp.Configuration = 0; 977 if (mpt->verbose > 1) { 978 mpt_prt(mpt, 979 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x", 980 i, tmp.RequestedParameters, tmp.Configuration); 981 } 982 host2mpt_config_page_scsi_device_1(&tmp); 983 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) { 984 return (-1); 985 } 986 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) { 987 return (-1); 988 } 989 mpt2host_config_page_scsi_device_1(&tmp); 990 mpt->mpt_dev_page1[i] = tmp; 991 if (mpt->verbose > 1) { 992 mpt_prt(mpt, 993 "SPI Tgt %d Page 1: RParm %x Configuration %x", i, 994 mpt->mpt_dev_page1[i].RequestedParameters, 995 mpt->mpt_dev_page1[i].Configuration); 996 } 997 } 998 return (0); 999 } 1000 1001 /* 1002 * Enable IOC port 1003 */ 1004 static int 1005 mpt_send_port_enable(mpt_softc_t *mpt, int port) 1006 { 1007 int count; 1008 request_t *req; 1009 MSG_PORT_ENABLE *enable_req; 1010 1011 req = mpt_get_request(mpt); 1012 1013 enable_req = req->req_vbuf; 1014 memset(enable_req, 0, sizeof *enable_req); 1015 1016 enable_req->Function = MPI_FUNCTION_PORT_ENABLE; 1017 enable_req->MsgContext = htole32(req->index | 0x80000000); 1018 enable_req->PortNumber = port; 1019 1020 mpt_check_doorbell(mpt); 1021 if (mpt->verbose > 1) { 1022 mpt_prt(mpt, "enabling port %d", port); 1023 } 1024 mpt_send_cmd(mpt, req); 1025 1026 count = 0; 1027 do { 1028 DELAY(500); 1029 mpt_intr(mpt); 1030 if (++count == 100000) { 1031 mpt_prt(mpt, "port enable timed out"); 1032 return (-1); 1033 } 1034 } while (req->debug == REQ_ON_CHIP); 1035 mpt_free_request(mpt, req); 1036 return (0); 1037 } 1038 1039 /* 1040 * Enable/Disable asynchronous event reporting. 1041 * 1042 * NB: this is the first command we send via shared memory 1043 * instead of the handshake register. 1044 */ 1045 static int 1046 mpt_send_event_request(mpt_softc_t *mpt, int onoff) 1047 { 1048 request_t *req; 1049 MSG_EVENT_NOTIFY *enable_req; 1050 1051 req = mpt_get_request(mpt); 1052 1053 enable_req = req->req_vbuf; 1054 memset(enable_req, 0, sizeof *enable_req); 1055 1056 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 1057 enable_req->MsgContext = htole32(req->index | 0x80000000); 1058 enable_req->Switch = onoff; 1059 1060 mpt_check_doorbell(mpt); 1061 if (mpt->verbose > 1) { 1062 mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis"); 1063 } 1064 mpt_send_cmd(mpt, req); 1065 1066 return (0); 1067 } 1068 1069 /* 1070 * Un-mask the interrupts on the chip. 1071 */ 1072 void 1073 mpt_enable_ints(mpt_softc_t *mpt) 1074 { 1075 /* Unmask every thing except door bell int */ 1076 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK); 1077 } 1078 1079 /* 1080 * Mask the interrupts on the chip. 1081 */ 1082 void 1083 mpt_disable_ints(mpt_softc_t *mpt) 1084 { 1085 /* Mask all interrupts */ 1086 mpt_write(mpt, MPT_OFFSET_INTR_MASK, 1087 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK); 1088 } 1089 1090 /* (Re)Initialize the chip for use */ 1091 int 1092 mpt_hw_init(mpt_softc_t *mpt) 1093 { 1094 u_int32_t db; 1095 int try; 1096 1097 /* 1098 * Start by making sure we're not at FAULT or RESET state 1099 */ 1100 for (try = 0; try < MPT_MAX_TRYS; try++) { 1101 1102 db = mpt_rd_db(mpt); 1103 1104 switch (MPT_STATE(db)) { 1105 case MPT_DB_STATE_READY: 1106 return (0); 1107 1108 default: 1109 /* if peer has already reset us, don't do it again! */ 1110 if (MPT_WHO(db) == MPT_DB_INIT_PCIPEER) 1111 return (0); 1112 /*FALLTHRU*/ 1113 case MPT_DB_STATE_RESET: 1114 case MPT_DB_STATE_FAULT: 1115 if (mpt_reset(mpt) != MPT_OK) { 1116 DELAY(10000); 1117 continue; 1118 } 1119 break; 1120 } 1121 } 1122 return (EIO); 1123 } 1124 1125 int 1126 mpt_init(mpt_softc_t *mpt, u_int32_t who) 1127 { 1128 int try; 1129 MSG_IOC_FACTS_REPLY facts; 1130 MSG_PORT_FACTS_REPLY pfp; 1131 prop_dictionary_t dict; 1132 uint32_t ini_id; 1133 uint32_t pptr; 1134 int val; 1135 1136 /* Put all request buffers (back) on the free list */ 1137 SLIST_INIT(&mpt->request_free_list); 1138 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { 1139 mpt_free_request(mpt, &mpt->request_pool[val]); 1140 } 1141 1142 if (mpt->verbose > 1) { 1143 mpt_prt(mpt, "doorbell req = %s", 1144 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL))); 1145 } 1146 1147 /* 1148 * Start by making sure we're not at FAULT or RESET state 1149 */ 1150 if (mpt_hw_init(mpt) != 0) 1151 return (EIO); 1152 1153 dict = device_properties(mpt->sc_dev); 1154 1155 for (try = 0; try < MPT_MAX_TRYS; try++) { 1156 /* 1157 * No need to reset if the IOC is already in the READY state. 1158 */ 1159 1160 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) { 1161 mpt_prt(mpt, "mpt_get_iocfacts failed"); 1162 continue; 1163 } 1164 mpt2host_iocfacts_reply(&facts); 1165 1166 if (mpt->verbose > 1) { 1167 mpt_prt(mpt, 1168 "IOCFACTS: GlobalCredits=%d BlockSize=%u " 1169 "Request Frame Size %u", facts.GlobalCredits, 1170 facts.BlockSize, facts.RequestFrameSize); 1171 } 1172 mpt->mpt_max_devices = facts.MaxDevices; 1173 mpt->mpt_global_credits = facts.GlobalCredits; 1174 mpt->request_frame_size = facts.RequestFrameSize; 1175 1176 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) { 1177 mpt_prt(mpt, "mpt_get_portfacts failed"); 1178 continue; 1179 } 1180 mpt2host_portfacts_reply(&pfp); 1181 1182 if (mpt->verbose > 1) { 1183 mpt_prt(mpt, 1184 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d", 1185 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID, 1186 pfp.MaxDevices); 1187 } 1188 1189 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) { 1190 mpt_prt(mpt, "initiator role unsupported"); 1191 return (ENXIO); 1192 } 1193 1194 switch (pfp.PortType) { 1195 case MPI_PORTFACTS_PORTTYPE_FC: 1196 mpt->is_fc = 1; 1197 mpt->mpt_max_devices = 255; 1198 break; 1199 case MPI_PORTFACTS_PORTTYPE_SCSI: 1200 mpt->is_scsi = 1; 1201 /* some SPI controllers (VMWare, Sun) lie */ 1202 mpt->mpt_max_devices = 16; 1203 break; 1204 case MPI_PORTFACTS_PORTTYPE_SAS: 1205 mpt->is_sas = 1; 1206 break; 1207 default: 1208 mpt_prt(mpt, "Unsupported Port Type (%x)", 1209 pfp.PortType); 1210 return (ENXIO); 1211 } 1212 1213 if (!mpt->is_sas && !mpt->is_fc && 1214 prop_dictionary_get_uint32(dict, "scsi-initiator-id", &ini_id)) 1215 mpt->mpt_ini_id = ini_id; 1216 else 1217 mpt->mpt_ini_id = pfp.PortSCSIID; 1218 1219 if (mpt_send_ioc_init(mpt, who) != MPT_OK) { 1220 mpt_prt(mpt, "mpt_send_ioc_init failed"); 1221 continue; 1222 } 1223 1224 if (mpt->verbose > 1) { 1225 mpt_prt(mpt, "mpt_send_ioc_init ok"); 1226 } 1227 1228 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) { 1229 mpt_prt(mpt, "IOC failed to go to run state"); 1230 continue; 1231 } 1232 if (mpt->verbose > 1) { 1233 mpt_prt(mpt, "IOC now at RUNSTATE"); 1234 } 1235 1236 /* 1237 * Give it reply buffers 1238 * 1239 * Do *not* except global credits. 1240 */ 1241 for (val = 0, pptr = mpt->reply_phys; 1242 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE); 1243 pptr += MPT_REPLY_SIZE) { 1244 mpt_free_reply(mpt, pptr); 1245 if (++val == mpt->mpt_global_credits - 1) 1246 break; 1247 } 1248 1249 /* 1250 * Enable asynchronous event reporting 1251 */ 1252 mpt_send_event_request(mpt, 1); 1253 1254 1255 /* 1256 * Read set up initial configuration information 1257 * (SPI only for now) 1258 */ 1259 1260 if (mpt->is_scsi) { 1261 if (mpt_read_config_info_spi(mpt)) { 1262 return (EIO); 1263 } 1264 if (mpt_set_initial_config_spi(mpt)) { 1265 return (EIO); 1266 } 1267 } 1268 1269 /* 1270 * Now enable the port 1271 */ 1272 if (mpt_send_port_enable(mpt, 0) != MPT_OK) { 1273 mpt_prt(mpt, "failed to enable port 0"); 1274 continue; 1275 } 1276 1277 if (mpt->verbose > 1) { 1278 mpt_prt(mpt, "enabled port 0"); 1279 } 1280 1281 /* Everything worked */ 1282 break; 1283 } 1284 1285 if (try >= MPT_MAX_TRYS) { 1286 mpt_prt(mpt, "failed to initialize IOC"); 1287 return (EIO); 1288 } 1289 1290 if (mpt->verbose > 1) { 1291 mpt_prt(mpt, "enabling interrupts"); 1292 } 1293 1294 mpt_enable_ints(mpt); 1295 return (0); 1296 } 1297 1298 /* 1299 * Endian Conversion Functions- only used on Big Endian machines 1300 */ 1301 #if _BYTE_ORDER == _BIG_ENDIAN 1302 void 1303 mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge) 1304 { 1305 1306 MPT_2_HOST32(sge, FlagsLength); 1307 MPT_2_HOST32(sge, _u.Address64.Low); 1308 MPT_2_HOST32(sge, _u.Address64.High); 1309 } 1310 1311 void 1312 mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp) 1313 { 1314 1315 MPT_2_HOST16(rp, MsgVersion); 1316 #if 0 1317 MPT_2_HOST16(rp, HeaderVersion); 1318 #endif 1319 MPT_2_HOST32(rp, MsgContext); 1320 MPT_2_HOST16(rp, IOCExceptions); 1321 MPT_2_HOST16(rp, IOCStatus); 1322 MPT_2_HOST32(rp, IOCLogInfo); 1323 MPT_2_HOST16(rp, ReplyQueueDepth); 1324 MPT_2_HOST16(rp, RequestFrameSize); 1325 MPT_2_HOST16(rp, Reserved_0101_FWVersion); 1326 MPT_2_HOST16(rp, ProductID); 1327 MPT_2_HOST32(rp, CurrentHostMfaHighAddr); 1328 MPT_2_HOST16(rp, GlobalCredits); 1329 MPT_2_HOST32(rp, CurrentSenseBufferHighAddr); 1330 MPT_2_HOST16(rp, CurReplyFrameSize); 1331 MPT_2_HOST32(rp, FWImageSize); 1332 #if 0 1333 MPT_2_HOST32(rp, IOCCapabilities); 1334 #endif 1335 MPT_2_HOST32(rp, FWVersion.Word); 1336 #if 0 1337 MPT_2_HOST16(rp, HighPriorityQueueDepth); 1338 MPT_2_HOST16(rp, Reserved2); 1339 mpt2host_sge_simple_union(&rp->HostPageBufferSGE); 1340 MPT_2_HOST32(rp, ReplyFifoHostSignalingAddr); 1341 #endif 1342 } 1343 1344 void 1345 mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp) 1346 { 1347 1348 MPT_2_HOST16(pfp, Reserved); 1349 MPT_2_HOST16(pfp, Reserved1); 1350 MPT_2_HOST32(pfp, MsgContext); 1351 MPT_2_HOST16(pfp, Reserved2); 1352 MPT_2_HOST16(pfp, IOCStatus); 1353 MPT_2_HOST32(pfp, IOCLogInfo); 1354 MPT_2_HOST16(pfp, MaxDevices); 1355 MPT_2_HOST16(pfp, PortSCSIID); 1356 MPT_2_HOST16(pfp, ProtocolFlags); 1357 MPT_2_HOST16(pfp, MaxPostedCmdBuffers); 1358 MPT_2_HOST16(pfp, MaxPersistentIDs); 1359 MPT_2_HOST16(pfp, MaxLanBuckets); 1360 MPT_2_HOST16(pfp, Reserved4); 1361 MPT_2_HOST32(pfp, Reserved5); 1362 } 1363 1364 void 1365 mpt2host_config_page_scsi_port_0(fCONFIG_PAGE_SCSI_PORT_0 *sp0) 1366 { 1367 1368 MPT_2_HOST32(sp0, Capabilities); 1369 MPT_2_HOST32(sp0, PhysicalInterface); 1370 } 1371 1372 void 1373 mpt2host_config_page_scsi_port_1(fCONFIG_PAGE_SCSI_PORT_1 *sp1) 1374 { 1375 1376 MPT_2_HOST32(sp1, Configuration); 1377 MPT_2_HOST32(sp1, OnBusTimerValue); 1378 #if 0 1379 MPT_2_HOST16(sp1, IDConfig); 1380 #endif 1381 } 1382 1383 void 1384 host2mpt_config_page_scsi_port_1(fCONFIG_PAGE_SCSI_PORT_1 *sp1) 1385 { 1386 1387 HOST_2_MPT32(sp1, Configuration); 1388 HOST_2_MPT32(sp1, OnBusTimerValue); 1389 #if 0 1390 HOST_2_MPT16(sp1, IDConfig); 1391 #endif 1392 } 1393 1394 void 1395 mpt2host_config_page_scsi_port_2(fCONFIG_PAGE_SCSI_PORT_2 *sp2) 1396 { 1397 int i; 1398 1399 MPT_2_HOST32(sp2, PortFlags); 1400 MPT_2_HOST32(sp2, PortSettings); 1401 for (i = 0; i < sizeof(sp2->DeviceSettings) / 1402 sizeof(*sp2->DeviceSettings); i++) { 1403 MPT_2_HOST16(sp2, DeviceSettings[i].DeviceFlags); 1404 } 1405 } 1406 1407 void 1408 mpt2host_config_page_scsi_device_0(fCONFIG_PAGE_SCSI_DEVICE_0 *sd0) 1409 { 1410 1411 MPT_2_HOST32(sd0, NegotiatedParameters); 1412 MPT_2_HOST32(sd0, Information); 1413 } 1414 1415 void 1416 host2mpt_config_page_scsi_device_0(fCONFIG_PAGE_SCSI_DEVICE_0 *sd0) 1417 { 1418 1419 HOST_2_MPT32(sd0, NegotiatedParameters); 1420 HOST_2_MPT32(sd0, Information); 1421 } 1422 1423 void 1424 mpt2host_config_page_scsi_device_1(fCONFIG_PAGE_SCSI_DEVICE_1 *sd1) 1425 { 1426 1427 MPT_2_HOST32(sd1, RequestedParameters); 1428 MPT_2_HOST32(sd1, Reserved); 1429 MPT_2_HOST32(sd1, Configuration); 1430 } 1431 1432 void 1433 host2mpt_config_page_scsi_device_1(fCONFIG_PAGE_SCSI_DEVICE_1 *sd1) 1434 { 1435 1436 HOST_2_MPT32(sd1, RequestedParameters); 1437 HOST_2_MPT32(sd1, Reserved); 1438 HOST_2_MPT32(sd1, Configuration); 1439 } 1440 1441 void 1442 mpt2host_config_page_fc_port_0(fCONFIG_PAGE_FC_PORT_0 *fp0) 1443 { 1444 1445 MPT_2_HOST32(fp0, Flags); 1446 MPT_2_HOST32(fp0, PortIdentifier); 1447 MPT_2_HOST32(fp0, WWNN.Low); 1448 MPT_2_HOST32(fp0, WWNN.High); 1449 MPT_2_HOST32(fp0, WWPN.Low); 1450 MPT_2_HOST32(fp0, WWPN.High); 1451 MPT_2_HOST32(fp0, SupportedServiceClass); 1452 MPT_2_HOST32(fp0, SupportedSpeeds); 1453 MPT_2_HOST32(fp0, CurrentSpeed); 1454 MPT_2_HOST32(fp0, MaxFrameSize); 1455 MPT_2_HOST32(fp0, FabricWWNN.Low); 1456 MPT_2_HOST32(fp0, FabricWWNN.High); 1457 MPT_2_HOST32(fp0, FabricWWPN.Low); 1458 MPT_2_HOST32(fp0, FabricWWPN.High); 1459 MPT_2_HOST32(fp0, DiscoveredPortsCount); 1460 MPT_2_HOST32(fp0, MaxInitiators); 1461 } 1462 1463 void 1464 mpt2host_config_page_fc_port_1(fCONFIG_PAGE_FC_PORT_1 *fp1) 1465 { 1466 1467 MPT_2_HOST32(fp1, Flags); 1468 MPT_2_HOST32(fp1, NoSEEPROMWWNN.Low); 1469 MPT_2_HOST32(fp1, NoSEEPROMWWNN.High); 1470 MPT_2_HOST32(fp1, NoSEEPROMWWPN.Low); 1471 MPT_2_HOST32(fp1, NoSEEPROMWWPN.High); 1472 } 1473 1474 void 1475 host2mpt_config_page_fc_port_1(fCONFIG_PAGE_FC_PORT_1 *fp1) 1476 { 1477 1478 HOST_2_MPT32(fp1, Flags); 1479 HOST_2_MPT32(fp1, NoSEEPROMWWNN.Low); 1480 HOST_2_MPT32(fp1, NoSEEPROMWWNN.High); 1481 HOST_2_MPT32(fp1, NoSEEPROMWWPN.Low); 1482 HOST_2_MPT32(fp1, NoSEEPROMWWPN.High); 1483 } 1484 1485 void 1486 mpt2host_config_page_raid_vol_0(fCONFIG_PAGE_RAID_VOL_0 *volp) 1487 { 1488 int i; 1489 1490 MPT_2_HOST16(volp, VolumeStatus.Reserved); 1491 MPT_2_HOST16(volp, VolumeSettings.Settings); 1492 MPT_2_HOST32(volp, MaxLBA); 1493 #if 0 1494 MPT_2_HOST32(volp, MaxLBAHigh); 1495 #endif 1496 MPT_2_HOST32(volp, StripeSize); 1497 MPT_2_HOST32(volp, Reserved2); 1498 MPT_2_HOST32(volp, Reserved3); 1499 for (i = 0; i < MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX; i++) { 1500 MPT_2_HOST16(volp, PhysDisk[i].Reserved); 1501 } 1502 } 1503 1504 void 1505 mpt2host_config_page_raid_phys_disk_0(fCONFIG_PAGE_RAID_PHYS_DISK_0 *rpd0) 1506 { 1507 1508 MPT_2_HOST32(rpd0, Reserved1); 1509 MPT_2_HOST16(rpd0, PhysDiskStatus.Reserved); 1510 MPT_2_HOST32(rpd0, MaxLBA); 1511 MPT_2_HOST16(rpd0, ErrorData.Reserved); 1512 MPT_2_HOST16(rpd0, ErrorData.ErrorCount); 1513 MPT_2_HOST16(rpd0, ErrorData.SmartCount); 1514 } 1515 1516 void 1517 mpt2host_config_page_ioc_2(fCONFIG_PAGE_IOC_2 *ioc2) 1518 { 1519 MPT_2_HOST32(ioc2, CapabilitiesFlags); 1520 } 1521 1522 #endif 1523