1 /* $NetBSD: mpt.c,v 1.14 2010/04/28 22:45:27 chs 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.14 2010/04/28 22:45:27 chs 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 static int 569 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *); 570 571 static int 572 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber, 573 int PageAddress, fCONFIG_PAGE_HEADER *rslt) 574 { 575 int count; 576 request_t *req; 577 MSG_CONFIG *cfgp; 578 MSG_CONFIG_REPLY *reply; 579 580 req = mpt_get_request(mpt); 581 582 cfgp = req->req_vbuf; 583 memset(cfgp, 0, sizeof *cfgp); 584 585 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER; 586 cfgp->Function = MPI_FUNCTION_CONFIG; 587 cfgp->Header.PageNumber = (U8) PageNumber; 588 cfgp->Header.PageType = (U8) PageType; 589 cfgp->PageAddress = htole32(PageAddress); 590 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE), 591 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 592 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST)); 593 cfgp->MsgContext = htole32(req->index | 0x80000000); 594 595 mpt_check_doorbell(mpt); 596 mpt_send_cmd(mpt, req); 597 count = 0; 598 do { 599 DELAY(500); 600 mpt_intr(mpt); 601 if (++count == 1000) { 602 mpt_prt(mpt, "read_cfg_header timed out"); 603 return (-1); 604 } 605 } while (req->debug == REQ_ON_CHIP); 606 607 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 608 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 609 mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x", 610 reply->IOCStatus); 611 mpt_free_reply(mpt, (req->sequence << 1)); 612 return (-1); 613 } 614 memcpy(rslt, &reply->Header, sizeof (fCONFIG_PAGE_HEADER)); 615 mpt_free_reply(mpt, (req->sequence << 1)); 616 mpt_free_request(mpt, req); 617 return (0); 618 } 619 620 #define CFG_DATA_OFF 128 621 622 int 623 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 624 { 625 int count; 626 request_t *req; 627 SGE_SIMPLE32 *se; 628 MSG_CONFIG *cfgp; 629 size_t amt; 630 MSG_CONFIG_REPLY *reply; 631 632 req = mpt_get_request(mpt); 633 634 cfgp = req->req_vbuf; 635 memset(cfgp, 0, MPT_REQUEST_AREA); 636 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 637 cfgp->Function = MPI_FUNCTION_CONFIG; 638 cfgp->Header = *hdr; 639 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 640 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK; 641 cfgp->PageAddress = htole32(PageAddress); 642 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 643 se->Address = htole32(req->req_pbuf + CFG_DATA_OFF); 644 MPI_pSGE_SET_LENGTH(se, amt); 645 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 646 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 647 MPI_SGE_FLAGS_END_OF_LIST)); 648 se->FlagsLength = htole32(se->FlagsLength); 649 650 cfgp->MsgContext = htole32(req->index | 0x80000000); 651 652 mpt_check_doorbell(mpt); 653 mpt_send_cmd(mpt, req); 654 count = 0; 655 do { 656 DELAY(500); 657 mpt_intr(mpt); 658 if (++count == 1000) { 659 mpt_prt(mpt, "read_cfg_page timed out"); 660 return (-1); 661 } 662 } while (req->debug == REQ_ON_CHIP); 663 664 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 665 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 666 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x", 667 reply->IOCStatus); 668 mpt_free_reply(mpt, (req->sequence << 1)); 669 return (-1); 670 } 671 mpt_free_reply(mpt, (req->sequence << 1)); 672 #if 0 /* XXXJRT */ 673 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, 674 BUS_DMASYNC_POSTREAD); 675 #endif 676 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 677 cfgp->Header.PageNumber == 0) { 678 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0); 679 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 680 cfgp->Header.PageNumber == 1) { 681 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1); 682 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 683 cfgp->Header.PageNumber == 2) { 684 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2); 685 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 686 cfgp->Header.PageNumber == 0) { 687 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0); 688 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 689 cfgp->Header.PageNumber == 1) { 690 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1); 691 } 692 memcpy(hdr, (char *)req->req_vbuf + CFG_DATA_OFF, amt); 693 mpt_free_request(mpt, req); 694 return (0); 695 } 696 697 int 698 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 699 { 700 int count, hdr_attr; 701 request_t *req; 702 SGE_SIMPLE32 *se; 703 MSG_CONFIG *cfgp; 704 size_t amt; 705 MSG_CONFIG_REPLY *reply; 706 707 req = mpt_get_request(mpt); 708 709 cfgp = req->req_vbuf; 710 memset(cfgp, 0, sizeof *cfgp); 711 712 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK; 713 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE && 714 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) { 715 mpt_prt(mpt, "page type 0x%x not changeable", 716 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 717 return (-1); 718 } 719 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK; 720 721 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 722 cfgp->Function = MPI_FUNCTION_CONFIG; 723 cfgp->Header = *hdr; 724 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 725 cfgp->PageAddress = htole32(PageAddress); 726 727 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 728 se->Address = htole32(req->req_pbuf + CFG_DATA_OFF); 729 MPI_pSGE_SET_LENGTH(se, amt); 730 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 731 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 732 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC)); 733 se->FlagsLength = htole32(se->FlagsLength); 734 735 cfgp->MsgContext = htole32(req->index | 0x80000000); 736 737 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 738 cfgp->Header.PageNumber == 0) { 739 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0); 740 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 741 cfgp->Header.PageNumber == 1) { 742 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1); 743 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 744 cfgp->Header.PageNumber == 2) { 745 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2); 746 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 747 cfgp->Header.PageNumber == 0) { 748 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0); 749 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 750 cfgp->Header.PageNumber == 1) { 751 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1); 752 } 753 memcpy((char *)req->req_vbuf + CFG_DATA_OFF, hdr, amt); 754 /* Restore stripped out attributes */ 755 hdr->PageType |= hdr_attr; 756 757 mpt_check_doorbell(mpt); 758 mpt_send_cmd(mpt, req); 759 count = 0; 760 do { 761 DELAY(500); 762 mpt_intr(mpt); 763 if (++count == 1000) { 764 hdr->PageType |= hdr_attr; 765 mpt_prt(mpt, "mpt_write_cfg_page timed out"); 766 return (-1); 767 } 768 } while (req->debug == REQ_ON_CHIP); 769 770 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 771 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 772 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x", 773 le16toh(reply->IOCStatus)); 774 mpt_free_reply(mpt, (req->sequence << 1)); 775 return (-1); 776 } 777 mpt_free_reply(mpt, (req->sequence << 1)); 778 779 mpt_free_request(mpt, req); 780 return (0); 781 } 782 783 /* 784 * Read SCSI configuration information 785 */ 786 static int 787 mpt_read_config_info_spi(mpt_softc_t *mpt) 788 { 789 int rv, i; 790 791 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0, 792 0, &mpt->mpt_port_page0.Header); 793 if (rv) { 794 return (-1); 795 } 796 if (mpt->verbose > 1) { 797 mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x", 798 mpt->mpt_port_page0.Header.PageVersion, 799 mpt->mpt_port_page0.Header.PageLength, 800 mpt->mpt_port_page0.Header.PageNumber, 801 mpt->mpt_port_page0.Header.PageType); 802 } 803 804 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1, 805 0, &mpt->mpt_port_page1.Header); 806 if (rv) { 807 return (-1); 808 } 809 if (mpt->verbose > 1) { 810 mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x", 811 mpt->mpt_port_page1.Header.PageVersion, 812 mpt->mpt_port_page1.Header.PageLength, 813 mpt->mpt_port_page1.Header.PageNumber, 814 mpt->mpt_port_page1.Header.PageType); 815 } 816 817 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2, 818 0, &mpt->mpt_port_page2.Header); 819 if (rv) { 820 return (-1); 821 } 822 823 if (mpt->verbose > 1) { 824 mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x", 825 mpt->mpt_port_page1.Header.PageVersion, 826 mpt->mpt_port_page1.Header.PageLength, 827 mpt->mpt_port_page1.Header.PageNumber, 828 mpt->mpt_port_page1.Header.PageType); 829 } 830 831 for (i = 0; i < 16; i++) { 832 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 833 0, i, &mpt->mpt_dev_page0[i].Header); 834 if (rv) { 835 return (-1); 836 } 837 if (mpt->verbose > 1) { 838 mpt_prt(mpt, 839 "SPI Target %d Device Page 0 Header: %x %x %x %x", 840 i, mpt->mpt_dev_page0[i].Header.PageVersion, 841 mpt->mpt_dev_page0[i].Header.PageLength, 842 mpt->mpt_dev_page0[i].Header.PageNumber, 843 mpt->mpt_dev_page0[i].Header.PageType); 844 } 845 846 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 847 1, i, &mpt->mpt_dev_page1[i].Header); 848 if (rv) { 849 return (-1); 850 } 851 if (mpt->verbose > 1) { 852 mpt_prt(mpt, 853 "SPI Target %d Device Page 1 Header: %x %x %x %x", 854 i, mpt->mpt_dev_page1[i].Header.PageVersion, 855 mpt->mpt_dev_page1[i].Header.PageLength, 856 mpt->mpt_dev_page1[i].Header.PageNumber, 857 mpt->mpt_dev_page1[i].Header.PageType); 858 } 859 } 860 861 /* 862 * At this point, we don't *have* to fail. As long as we have 863 * valid config header information, we can (barely) lurch 864 * along. 865 */ 866 867 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header); 868 mpt2host_config_page_scsi_port_0(&mpt->mpt_port_page0); 869 if (rv) { 870 mpt_prt(mpt, "failed to read SPI Port Page 0"); 871 } else if (mpt->verbose > 1) { 872 mpt_prt(mpt, 873 "SPI Port Page 0: Capabilities %x PhysicalInterface %x", 874 mpt->mpt_port_page0.Capabilities, 875 mpt->mpt_port_page0.PhysicalInterface); 876 } 877 878 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header); 879 mpt2host_config_page_scsi_port_1(&mpt->mpt_port_page1); 880 if (rv) { 881 mpt_prt(mpt, "failed to read SPI Port Page 1"); 882 } else if (mpt->verbose > 1) { 883 mpt_prt(mpt, 884 "SPI Port Page 1: Configuration %x OnBusTimerValue %x", 885 mpt->mpt_port_page1.Configuration, 886 mpt->mpt_port_page1.OnBusTimerValue); 887 } 888 889 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header); 890 mpt2host_config_page_scsi_port_2(&mpt->mpt_port_page2); 891 if (rv) { 892 mpt_prt(mpt, "failed to read SPI Port Page 2"); 893 } else if (mpt->verbose > 1) { 894 mpt_prt(mpt, 895 "SPI Port Page 2: Flags %x Settings %x", 896 mpt->mpt_port_page2.PortFlags, 897 mpt->mpt_port_page2.PortSettings); 898 for (i = 0; i < 1; i++) { 899 mpt_prt(mpt, 900 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x", 901 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout, 902 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor, 903 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags); 904 } 905 } 906 907 for (i = 0; i < 16; i++) { 908 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header); 909 mpt2host_config_page_scsi_device_0(&mpt->mpt_dev_page0[i]); 910 if (rv) { 911 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i); 912 continue; 913 } 914 if (mpt->verbose > 1) { 915 mpt_prt(mpt, 916 "SPI Tgt %d Page 0: NParms %x Information %x", 917 i, mpt->mpt_dev_page0[i].NegotiatedParameters, 918 mpt->mpt_dev_page0[i].Information); 919 } 920 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header); 921 mpt2host_config_page_scsi_device_1(&mpt->mpt_dev_page1[i]); 922 if (rv) { 923 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i); 924 continue; 925 } 926 if (mpt->verbose > 1) { 927 mpt_prt(mpt, 928 "SPI Tgt %d Page 1: RParms %x Configuration %x", 929 i, mpt->mpt_dev_page1[i].RequestedParameters, 930 mpt->mpt_dev_page1[i].Configuration); 931 } 932 } 933 return (0); 934 } 935 936 /* 937 * Validate SPI configuration information. 938 * 939 * In particular, validate SPI Port Page 1. 940 */ 941 static int 942 mpt_set_initial_config_spi(mpt_softc_t *mpt) 943 { 944 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id; 945 946 mpt->mpt_disc_enable = 0xff; 947 mpt->mpt_tag_enable = 0; 948 949 if (mpt->mpt_port_page1.Configuration != pp1val) { 950 fCONFIG_PAGE_SCSI_PORT_1 tmp; 951 952 mpt_prt(mpt, 953 "SPI Port Page 1 Config value bad (%x)- should be %x", 954 mpt->mpt_port_page1.Configuration, pp1val); 955 tmp = mpt->mpt_port_page1; 956 tmp.Configuration = pp1val; 957 host2mpt_config_page_scsi_port_1(&tmp); 958 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) { 959 return (-1); 960 } 961 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) { 962 return (-1); 963 } 964 mpt2host_config_page_scsi_port_1(&tmp); 965 if (tmp.Configuration != pp1val) { 966 mpt_prt(mpt, 967 "failed to reset SPI Port Page 1 Config value"); 968 return (-1); 969 } 970 mpt->mpt_port_page1 = tmp; 971 } 972 973 i = 0; 974 for (i = 0; i < 16; i++) { 975 fCONFIG_PAGE_SCSI_DEVICE_1 tmp; 976 977 tmp = mpt->mpt_dev_page1[i]; 978 tmp.RequestedParameters = 0; 979 tmp.Configuration = 0; 980 if (mpt->verbose > 1) { 981 mpt_prt(mpt, 982 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x", 983 i, tmp.RequestedParameters, tmp.Configuration); 984 } 985 host2mpt_config_page_scsi_device_1(&tmp); 986 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) { 987 return (-1); 988 } 989 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) { 990 return (-1); 991 } 992 mpt2host_config_page_scsi_device_1(&tmp); 993 mpt->mpt_dev_page1[i] = tmp; 994 if (mpt->verbose > 1) { 995 mpt_prt(mpt, 996 "SPI Tgt %d Page 1: RParm %x Configuration %x", i, 997 mpt->mpt_dev_page1[i].RequestedParameters, 998 mpt->mpt_dev_page1[i].Configuration); 999 } 1000 } 1001 return (0); 1002 } 1003 1004 /* 1005 * Enable IOC port 1006 */ 1007 static int 1008 mpt_send_port_enable(mpt_softc_t *mpt, int port) 1009 { 1010 int count; 1011 request_t *req; 1012 MSG_PORT_ENABLE *enable_req; 1013 1014 req = mpt_get_request(mpt); 1015 1016 enable_req = req->req_vbuf; 1017 memset(enable_req, 0, sizeof *enable_req); 1018 1019 enable_req->Function = MPI_FUNCTION_PORT_ENABLE; 1020 enable_req->MsgContext = htole32(req->index | 0x80000000); 1021 enable_req->PortNumber = port; 1022 1023 mpt_check_doorbell(mpt); 1024 if (mpt->verbose > 1) { 1025 mpt_prt(mpt, "enabling port %d", port); 1026 } 1027 mpt_send_cmd(mpt, req); 1028 1029 count = 0; 1030 do { 1031 DELAY(500); 1032 mpt_intr(mpt); 1033 if (++count == 100000) { 1034 mpt_prt(mpt, "port enable timed out"); 1035 return (-1); 1036 } 1037 } while (req->debug == REQ_ON_CHIP); 1038 mpt_free_request(mpt, req); 1039 return (0); 1040 } 1041 1042 /* 1043 * Enable/Disable asynchronous event reporting. 1044 * 1045 * NB: this is the first command we send via shared memory 1046 * instead of the handshake register. 1047 */ 1048 static int 1049 mpt_send_event_request(mpt_softc_t *mpt, int onoff) 1050 { 1051 request_t *req; 1052 MSG_EVENT_NOTIFY *enable_req; 1053 1054 req = mpt_get_request(mpt); 1055 1056 enable_req = req->req_vbuf; 1057 memset(enable_req, 0, sizeof *enable_req); 1058 1059 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 1060 enable_req->MsgContext = htole32(req->index | 0x80000000); 1061 enable_req->Switch = onoff; 1062 1063 mpt_check_doorbell(mpt); 1064 if (mpt->verbose > 1) { 1065 mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis"); 1066 } 1067 mpt_send_cmd(mpt, req); 1068 1069 return (0); 1070 } 1071 1072 /* 1073 * Un-mask the interrupts on the chip. 1074 */ 1075 void 1076 mpt_enable_ints(mpt_softc_t *mpt) 1077 { 1078 /* Unmask every thing except door bell int */ 1079 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK); 1080 } 1081 1082 /* 1083 * Mask the interrupts on the chip. 1084 */ 1085 void 1086 mpt_disable_ints(mpt_softc_t *mpt) 1087 { 1088 /* Mask all interrupts */ 1089 mpt_write(mpt, MPT_OFFSET_INTR_MASK, 1090 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK); 1091 } 1092 1093 /* (Re)Initialize the chip for use */ 1094 int 1095 mpt_hw_init(mpt_softc_t *mpt) 1096 { 1097 u_int32_t db; 1098 int try; 1099 1100 /* 1101 * Start by making sure we're not at FAULT or RESET state 1102 */ 1103 for (try = 0; try < MPT_MAX_TRYS; try++) { 1104 1105 db = mpt_rd_db(mpt); 1106 1107 switch (MPT_STATE(db)) { 1108 case MPT_DB_STATE_READY: 1109 return (0); 1110 1111 default: 1112 /* if peer has already reset us, don't do it again! */ 1113 if (MPT_WHO(db) == MPT_DB_INIT_PCIPEER) 1114 return (0); 1115 /*FALLTHRU*/ 1116 case MPT_DB_STATE_RESET: 1117 case MPT_DB_STATE_FAULT: 1118 if (mpt_reset(mpt) != MPT_OK) { 1119 DELAY(10000); 1120 continue; 1121 } 1122 break; 1123 } 1124 } 1125 return (EIO); 1126 } 1127 1128 int 1129 mpt_init(mpt_softc_t *mpt, u_int32_t who) 1130 { 1131 int try; 1132 MSG_IOC_FACTS_REPLY facts; 1133 MSG_PORT_FACTS_REPLY pfp; 1134 u_int32_t pptr; 1135 int val; 1136 1137 /* Put all request buffers (back) on the free list */ 1138 SLIST_INIT(&mpt->request_free_list); 1139 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { 1140 mpt_free_request(mpt, &mpt->request_pool[val]); 1141 } 1142 1143 if (mpt->verbose > 1) { 1144 mpt_prt(mpt, "doorbell req = %s", 1145 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL))); 1146 } 1147 1148 /* 1149 * Start by making sure we're not at FAULT or RESET state 1150 */ 1151 if (mpt_hw_init(mpt) != 0) 1152 return (EIO); 1153 1154 for (try = 0; try < MPT_MAX_TRYS; try++) { 1155 /* 1156 * No need to reset if the IOC is already in the READY state. 1157 */ 1158 1159 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) { 1160 mpt_prt(mpt, "mpt_get_iocfacts failed"); 1161 continue; 1162 } 1163 mpt2host_iocfacts_reply(&facts); 1164 1165 if (mpt->verbose > 1) { 1166 mpt_prt(mpt, 1167 "IOCFACTS: GlobalCredits=%d BlockSize=%u " 1168 "Request Frame Size %u", facts.GlobalCredits, 1169 facts.BlockSize, facts.RequestFrameSize); 1170 } 1171 mpt->mpt_max_devices = facts.MaxDevices; 1172 mpt->mpt_global_credits = facts.GlobalCredits; 1173 mpt->request_frame_size = facts.RequestFrameSize; 1174 1175 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) { 1176 mpt_prt(mpt, "mpt_get_portfacts failed"); 1177 continue; 1178 } 1179 mpt2host_portfacts_reply(&pfp); 1180 1181 if (mpt->verbose > 1) { 1182 mpt_prt(mpt, 1183 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d", 1184 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID, 1185 pfp.MaxDevices); 1186 } 1187 1188 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) { 1189 mpt_prt(mpt, "initiator role unsupported"); 1190 return (ENXIO); 1191 } 1192 1193 switch (pfp.PortType) { 1194 case MPI_PORTFACTS_PORTTYPE_FC: 1195 mpt->is_fc = 1; 1196 mpt->mpt_max_devices = 255; 1197 break; 1198 case MPI_PORTFACTS_PORTTYPE_SCSI: 1199 mpt->is_scsi = 1; 1200 /* some SPI controllers (VMWare, Sun) lie */ 1201 mpt->mpt_max_devices = 16; 1202 break; 1203 case MPI_PORTFACTS_PORTTYPE_SAS: 1204 mpt->is_sas = 1; 1205 break; 1206 default: 1207 mpt_prt(mpt, "Unsupported Port Type (%x)", 1208 pfp.PortType); 1209 return (ENXIO); 1210 } 1211 1212 mpt->mpt_ini_id = pfp.PortSCSIID; 1213 1214 if (mpt_send_ioc_init(mpt, who) != MPT_OK) { 1215 mpt_prt(mpt, "mpt_send_ioc_init failed"); 1216 continue; 1217 } 1218 1219 if (mpt->verbose > 1) { 1220 mpt_prt(mpt, "mpt_send_ioc_init ok"); 1221 } 1222 1223 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) { 1224 mpt_prt(mpt, "IOC failed to go to run state"); 1225 continue; 1226 } 1227 if (mpt->verbose > 1) { 1228 mpt_prt(mpt, "IOC now at RUNSTATE"); 1229 } 1230 1231 /* 1232 * Give it reply buffers 1233 * 1234 * Do *not* except global credits. 1235 */ 1236 for (val = 0, pptr = mpt->reply_phys; 1237 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE); 1238 pptr += MPT_REPLY_SIZE) { 1239 mpt_free_reply(mpt, pptr); 1240 if (++val == mpt->mpt_global_credits - 1) 1241 break; 1242 } 1243 1244 /* 1245 * Enable asynchronous event reporting 1246 */ 1247 mpt_send_event_request(mpt, 1); 1248 1249 1250 /* 1251 * Read set up initial configuration information 1252 * (SPI only for now) 1253 */ 1254 1255 if (mpt->is_scsi) { 1256 if (mpt_read_config_info_spi(mpt)) { 1257 return (EIO); 1258 } 1259 if (mpt_set_initial_config_spi(mpt)) { 1260 return (EIO); 1261 } 1262 } 1263 1264 /* 1265 * Now enable the port 1266 */ 1267 if (mpt_send_port_enable(mpt, 0) != MPT_OK) { 1268 mpt_prt(mpt, "failed to enable port 0"); 1269 continue; 1270 } 1271 1272 if (mpt->verbose > 1) { 1273 mpt_prt(mpt, "enabled port 0"); 1274 } 1275 1276 /* Everything worked */ 1277 break; 1278 } 1279 1280 if (try >= MPT_MAX_TRYS) { 1281 mpt_prt(mpt, "failed to initialize IOC"); 1282 return (EIO); 1283 } 1284 1285 if (mpt->verbose > 1) { 1286 mpt_prt(mpt, "enabling interrupts"); 1287 } 1288 1289 mpt_enable_ints(mpt); 1290 return (0); 1291 } 1292 1293 /* 1294 * Endian Conversion Functions- only used on Big Endian machines 1295 */ 1296 #if _BYTE_ORDER == _BIG_ENDIAN 1297 void 1298 mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge) 1299 { 1300 1301 MPT_2_HOST32(sge, FlagsLength); 1302 MPT_2_HOST32(sge, _u.Address64.Low); 1303 MPT_2_HOST32(sge, _u.Address64.High); 1304 } 1305 1306 void 1307 mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp) 1308 { 1309 1310 MPT_2_HOST16(rp, MsgVersion); 1311 #if 0 1312 MPT_2_HOST16(rp, HeaderVersion); 1313 #endif 1314 MPT_2_HOST32(rp, MsgContext); 1315 MPT_2_HOST16(rp, IOCExceptions); 1316 MPT_2_HOST16(rp, IOCStatus); 1317 MPT_2_HOST32(rp, IOCLogInfo); 1318 MPT_2_HOST16(rp, ReplyQueueDepth); 1319 MPT_2_HOST16(rp, RequestFrameSize); 1320 MPT_2_HOST16(rp, Reserved_0101_FWVersion); 1321 MPT_2_HOST16(rp, ProductID); 1322 MPT_2_HOST32(rp, CurrentHostMfaHighAddr); 1323 MPT_2_HOST16(rp, GlobalCredits); 1324 MPT_2_HOST32(rp, CurrentSenseBufferHighAddr); 1325 MPT_2_HOST16(rp, CurReplyFrameSize); 1326 MPT_2_HOST32(rp, FWImageSize); 1327 #if 0 1328 MPT_2_HOST32(rp, IOCCapabilities); 1329 #endif 1330 MPT_2_HOST32(rp, FWVersion.Word); 1331 #if 0 1332 MPT_2_HOST16(rp, HighPriorityQueueDepth); 1333 MPT_2_HOST16(rp, Reserved2); 1334 mpt2host_sge_simple_union(&rp->HostPageBufferSGE); 1335 MPT_2_HOST32(rp, ReplyFifoHostSignalingAddr); 1336 #endif 1337 } 1338 1339 void 1340 mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp) 1341 { 1342 1343 MPT_2_HOST16(pfp, Reserved); 1344 MPT_2_HOST16(pfp, Reserved1); 1345 MPT_2_HOST32(pfp, MsgContext); 1346 MPT_2_HOST16(pfp, Reserved2); 1347 MPT_2_HOST16(pfp, IOCStatus); 1348 MPT_2_HOST32(pfp, IOCLogInfo); 1349 MPT_2_HOST16(pfp, MaxDevices); 1350 MPT_2_HOST16(pfp, PortSCSIID); 1351 MPT_2_HOST16(pfp, ProtocolFlags); 1352 MPT_2_HOST16(pfp, MaxPostedCmdBuffers); 1353 MPT_2_HOST16(pfp, MaxPersistentIDs); 1354 MPT_2_HOST16(pfp, MaxLanBuckets); 1355 MPT_2_HOST16(pfp, Reserved4); 1356 MPT_2_HOST32(pfp, Reserved5); 1357 } 1358 1359 void 1360 mpt2host_config_page_scsi_port_0(fCONFIG_PAGE_SCSI_PORT_0 *sp0) 1361 { 1362 1363 MPT_2_HOST32(sp0, Capabilities); 1364 MPT_2_HOST32(sp0, PhysicalInterface); 1365 } 1366 1367 void 1368 mpt2host_config_page_scsi_port_1(fCONFIG_PAGE_SCSI_PORT_1 *sp1) 1369 { 1370 1371 MPT_2_HOST32(sp1, Configuration); 1372 MPT_2_HOST32(sp1, OnBusTimerValue); 1373 #if 0 1374 MPT_2_HOST16(sp1, IDConfig); 1375 #endif 1376 } 1377 1378 void 1379 host2mpt_config_page_scsi_port_1(fCONFIG_PAGE_SCSI_PORT_1 *sp1) 1380 { 1381 1382 HOST_2_MPT32(sp1, Configuration); 1383 HOST_2_MPT32(sp1, OnBusTimerValue); 1384 #if 0 1385 HOST_2_MPT16(sp1, IDConfig); 1386 #endif 1387 } 1388 1389 void 1390 mpt2host_config_page_scsi_port_2(fCONFIG_PAGE_SCSI_PORT_2 *sp2) 1391 { 1392 int i; 1393 1394 MPT_2_HOST32(sp2, PortFlags); 1395 MPT_2_HOST32(sp2, PortSettings); 1396 for (i = 0; i < sizeof(sp2->DeviceSettings) / 1397 sizeof(*sp2->DeviceSettings); i++) { 1398 MPT_2_HOST16(sp2, DeviceSettings[i].DeviceFlags); 1399 } 1400 } 1401 1402 void 1403 mpt2host_config_page_scsi_device_0(fCONFIG_PAGE_SCSI_DEVICE_0 *sd0) 1404 { 1405 1406 MPT_2_HOST32(sd0, NegotiatedParameters); 1407 MPT_2_HOST32(sd0, Information); 1408 } 1409 1410 void 1411 host2mpt_config_page_scsi_device_0(fCONFIG_PAGE_SCSI_DEVICE_0 *sd0) 1412 { 1413 1414 HOST_2_MPT32(sd0, NegotiatedParameters); 1415 HOST_2_MPT32(sd0, Information); 1416 } 1417 1418 void 1419 mpt2host_config_page_scsi_device_1(fCONFIG_PAGE_SCSI_DEVICE_1 *sd1) 1420 { 1421 1422 MPT_2_HOST32(sd1, RequestedParameters); 1423 MPT_2_HOST32(sd1, Reserved); 1424 MPT_2_HOST32(sd1, Configuration); 1425 } 1426 1427 void 1428 host2mpt_config_page_scsi_device_1(fCONFIG_PAGE_SCSI_DEVICE_1 *sd1) 1429 { 1430 1431 HOST_2_MPT32(sd1, RequestedParameters); 1432 HOST_2_MPT32(sd1, Reserved); 1433 HOST_2_MPT32(sd1, Configuration); 1434 } 1435 1436 void 1437 mpt2host_config_page_fc_port_0(fCONFIG_PAGE_FC_PORT_0 *fp0) 1438 { 1439 1440 MPT_2_HOST32(fp0, Flags); 1441 MPT_2_HOST32(fp0, PortIdentifier); 1442 MPT_2_HOST32(fp0, WWNN.Low); 1443 MPT_2_HOST32(fp0, WWNN.High); 1444 MPT_2_HOST32(fp0, WWPN.Low); 1445 MPT_2_HOST32(fp0, WWPN.High); 1446 MPT_2_HOST32(fp0, SupportedServiceClass); 1447 MPT_2_HOST32(fp0, SupportedSpeeds); 1448 MPT_2_HOST32(fp0, CurrentSpeed); 1449 MPT_2_HOST32(fp0, MaxFrameSize); 1450 MPT_2_HOST32(fp0, FabricWWNN.Low); 1451 MPT_2_HOST32(fp0, FabricWWNN.High); 1452 MPT_2_HOST32(fp0, FabricWWPN.Low); 1453 MPT_2_HOST32(fp0, FabricWWPN.High); 1454 MPT_2_HOST32(fp0, DiscoveredPortsCount); 1455 MPT_2_HOST32(fp0, MaxInitiators); 1456 } 1457 1458 void 1459 mpt2host_config_page_fc_port_1(fCONFIG_PAGE_FC_PORT_1 *fp1) 1460 { 1461 1462 MPT_2_HOST32(fp1, Flags); 1463 MPT_2_HOST32(fp1, NoSEEPROMWWNN.Low); 1464 MPT_2_HOST32(fp1, NoSEEPROMWWNN.High); 1465 MPT_2_HOST32(fp1, NoSEEPROMWWPN.Low); 1466 MPT_2_HOST32(fp1, NoSEEPROMWWPN.High); 1467 } 1468 1469 void 1470 host2mpt_config_page_fc_port_1(fCONFIG_PAGE_FC_PORT_1 *fp1) 1471 { 1472 1473 HOST_2_MPT32(fp1, Flags); 1474 HOST_2_MPT32(fp1, NoSEEPROMWWNN.Low); 1475 HOST_2_MPT32(fp1, NoSEEPROMWWNN.High); 1476 HOST_2_MPT32(fp1, NoSEEPROMWWPN.Low); 1477 HOST_2_MPT32(fp1, NoSEEPROMWWPN.High); 1478 } 1479 1480 void 1481 mpt2host_config_page_raid_vol_0(fCONFIG_PAGE_RAID_VOL_0 *volp) 1482 { 1483 int i; 1484 1485 MPT_2_HOST16(volp, VolumeStatus.Reserved); 1486 MPT_2_HOST16(volp, VolumeSettings.Settings); 1487 MPT_2_HOST32(volp, MaxLBA); 1488 #if 0 1489 MPT_2_HOST32(volp, MaxLBAHigh); 1490 #endif 1491 MPT_2_HOST32(volp, StripeSize); 1492 MPT_2_HOST32(volp, Reserved2); 1493 MPT_2_HOST32(volp, Reserved3); 1494 for (i = 0; i < MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX; i++) { 1495 MPT_2_HOST16(volp, PhysDisk[i].Reserved); 1496 } 1497 } 1498 1499 void 1500 mpt2host_config_page_raid_phys_disk_0(fCONFIG_PAGE_RAID_PHYS_DISK_0 *rpd0) 1501 { 1502 1503 MPT_2_HOST32(rpd0, Reserved1); 1504 MPT_2_HOST16(rpd0, PhysDiskStatus.Reserved); 1505 MPT_2_HOST32(rpd0, MaxLBA); 1506 MPT_2_HOST16(rpd0, ErrorData.Reserved); 1507 MPT_2_HOST16(rpd0, ErrorData.ErrorCount); 1508 MPT_2_HOST16(rpd0, ErrorData.SmartCount); 1509 } 1510 1511 #endif 1512