1 /* $NetBSD: mpt.c,v 1.2 2003/04/16 23:02:14 thorpej 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 /* 32 * mpt.c: 33 * 34 * Generic routines for LSI Fusion adapters. 35 * 36 * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for 37 * Wasabi Systems, Inc. 38 */ 39 40 #include <dev/ic/mpt.h> 41 42 #define MPT_MAX_TRYS 3 43 #define MPT_MAX_WAIT 300000 44 45 static int maxwait_ack = 0; 46 static int maxwait_int = 0; 47 static int maxwait_state = 0; 48 49 static __inline u_int32_t 50 mpt_rd_db(mpt_softc_t *mpt) 51 { 52 return mpt_read(mpt, MPT_OFFSET_DOORBELL); 53 } 54 55 static __inline u_int32_t 56 mpt_rd_intr(mpt_softc_t *mpt) 57 { 58 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS); 59 } 60 61 /* Busy wait for a door bell to be read by IOC */ 62 static int 63 mpt_wait_db_ack(mpt_softc_t *mpt) 64 { 65 int i; 66 for (i=0; i < MPT_MAX_WAIT; i++) { 67 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) { 68 maxwait_ack = i > maxwait_ack ? i : maxwait_ack; 69 return MPT_OK; 70 } 71 72 DELAY(100); 73 } 74 return MPT_FAIL; 75 } 76 77 /* Busy wait for a door bell interrupt */ 78 static int 79 mpt_wait_db_int(mpt_softc_t *mpt) 80 { 81 int i; 82 for (i=0; i < MPT_MAX_WAIT; i++) { 83 if (MPT_DB_INTR(mpt_rd_intr(mpt))) { 84 maxwait_int = i > maxwait_int ? i : maxwait_int; 85 return MPT_OK; 86 } 87 DELAY(100); 88 } 89 return MPT_FAIL; 90 } 91 92 /* Wait for IOC to transition to a give state */ 93 void 94 mpt_check_doorbell(mpt_softc_t *mpt) 95 { 96 u_int32_t db = mpt_rd_db(mpt); 97 if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) { 98 mpt_prt(mpt, "Device not running"); 99 mpt_print_db(db); 100 } 101 } 102 103 /* Wait for IOC to transition to a give state */ 104 static int 105 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state) 106 { 107 int i; 108 109 for (i = 0; i < MPT_MAX_WAIT; i++) { 110 u_int32_t db = mpt_rd_db(mpt); 111 if (MPT_STATE(db) == state) { 112 maxwait_state = i > maxwait_state ? i : maxwait_state; 113 return (MPT_OK); 114 } 115 DELAY(100); 116 } 117 return (MPT_FAIL); 118 } 119 120 121 /* Issue the reset COMMAND to the IOC */ 122 int 123 mpt_soft_reset(mpt_softc_t *mpt) 124 { 125 if (mpt->verbose) { 126 mpt_prt(mpt, "soft reset"); 127 } 128 129 /* Have to use hard reset if we are not in Running state */ 130 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) { 131 mpt_prt(mpt, "soft reset failed: device not running"); 132 return MPT_FAIL; 133 } 134 135 /* If door bell is in use we don't have a chance of getting 136 * a word in since the IOC probably crashed in message 137 * processing. So don't waste our time. 138 */ 139 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) { 140 mpt_prt(mpt, "soft reset failed: doorbell wedged"); 141 return MPT_FAIL; 142 } 143 144 /* Send the reset request to the IOC */ 145 mpt_write(mpt, MPT_OFFSET_DOORBELL, 146 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT); 147 if (mpt_wait_db_ack(mpt) != MPT_OK) { 148 mpt_prt(mpt, "soft reset failed: ack timeout"); 149 return MPT_FAIL; 150 } 151 152 /* Wait for the IOC to reload and come out of reset state */ 153 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) { 154 mpt_prt(mpt, "soft reset failed: device did not start running"); 155 return MPT_FAIL; 156 } 157 158 return MPT_OK; 159 } 160 161 /* This is a magic diagnostic reset that resets all the ARM 162 * processors in the chip. 163 */ 164 void 165 mpt_hard_reset(mpt_softc_t *mpt) 166 { 167 /* This extra read comes for the Linux source 168 * released by LSI. It's function is undocumented! 169 */ 170 if (mpt->verbose) { 171 mpt_prt(mpt, "hard reset"); 172 } 173 mpt_read(mpt, MPT_OFFSET_FUBAR); 174 175 /* Enable diagnostic registers */ 176 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1); 177 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2); 178 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3); 179 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4); 180 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5); 181 182 /* Diag. port is now active so we can now hit the reset bit */ 183 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC); 184 185 DELAY(10000); 186 187 /* Disable Diagnostic Register */ 188 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF); 189 190 /* Restore the config register values */ 191 /* Hard resets are known to screw up the BAR for diagnostic 192 memory accesses (Mem1). */ 193 mpt_set_config_regs(mpt); 194 if (mpt->mpt2 != NULL) { 195 mpt_set_config_regs(mpt->mpt2); 196 } 197 198 /* Note that if there is no valid firmware to run, the doorbell will 199 remain in the reset state (0x00000000) */ 200 } 201 202 /* 203 * Reset the IOC when needed. Try software command first then if needed 204 * poke at the magic diagnostic reset. Note that a hard reset resets 205 * *both* IOCs on dual function chips (FC929 && LSI1030) as well as 206 * fouls up the PCI configuration registers. 207 */ 208 int 209 mpt_reset(mpt_softc_t *mpt) 210 { 211 int ret; 212 213 /* Try a soft reset */ 214 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) { 215 /* Failed; do a hard reset */ 216 mpt_hard_reset(mpt); 217 218 /* Wait for the IOC to reload and come out of reset state */ 219 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY); 220 if (ret != MPT_OK) { 221 mpt_prt(mpt, "failed to reset device"); 222 } 223 } 224 225 return ret; 226 } 227 228 /* Return a command buffer to the free queue */ 229 void 230 mpt_free_request(mpt_softc_t *mpt, request_t *req) 231 { 232 if (req == NULL || req != &mpt->request_pool[req->index]) { 233 panic("mpt_free_request bad req ptr\n"); 234 return; 235 } 236 req->sequence = 0; 237 req->xfer = NULL; 238 req->debug = REQ_FREE; 239 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link); 240 } 241 242 /* Get a command buffer from the free queue */ 243 request_t * 244 mpt_get_request(mpt_softc_t *mpt) 245 { 246 request_t *req; 247 req = SLIST_FIRST(&mpt->request_free_list); 248 if (req != NULL) { 249 if (req != &mpt->request_pool[req->index]) { 250 panic("mpt_get_request: corrupted request free list\n"); 251 } 252 if (req->xfer != NULL) { 253 panic("mpt_get_request: corrupted request free list (xfer)\n"); 254 } 255 SLIST_REMOVE_HEAD(&mpt->request_free_list, link); 256 req->debug = REQ_IN_PROGRESS; 257 } 258 return req; 259 } 260 261 /* Pass the command to the IOC */ 262 void 263 mpt_send_cmd(mpt_softc_t *mpt, request_t *req) 264 { 265 req->sequence = mpt->sequence++; 266 if (mpt->verbose > 1) { 267 u_int32_t *pReq; 268 pReq = req->req_vbuf; 269 mpt_prt(mpt, "Send Request %d (0x%x):", 270 req->index, req->req_pbuf); 271 mpt_prt(mpt, "%08x %08x %08x %08x", 272 pReq[0], pReq[1], pReq[2], pReq[3]); 273 mpt_prt(mpt, "%08x %08x %08x %08x", 274 pReq[4], pReq[5], pReq[6], pReq[7]); 275 mpt_prt(mpt, "%08x %08x %08x %08x", 276 pReq[8], pReq[9], pReq[10], pReq[11]); 277 mpt_prt(mpt, "%08x %08x %08x %08x", 278 pReq[12], pReq[13], pReq[14], pReq[15]); 279 } 280 MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 281 req->debug = REQ_ON_CHIP; 282 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf); 283 } 284 285 /* 286 * Give the reply buffer back to the IOC after we have 287 * finished processing it. 288 */ 289 void 290 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr) 291 { 292 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr); 293 } 294 295 /* Get a reply from the IOC */ 296 u_int32_t 297 mpt_pop_reply_queue(mpt_softc_t *mpt) 298 { 299 return mpt_read(mpt, MPT_OFFSET_REPLY_Q); 300 } 301 302 /* 303 * Send a command to the IOC via the handshake register. 304 * 305 * Only done at initialization time and for certain unusual 306 * commands such as device/bus reset as specified by LSI. 307 */ 308 int 309 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd) 310 { 311 int i; 312 u_int32_t data, *data32; 313 314 /* Check condition of the IOC */ 315 data = mpt_rd_db(mpt); 316 if (((MPT_STATE(data) != MPT_DB_STATE_READY) && 317 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) && 318 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) || 319 ( MPT_DB_IS_IN_USE(data) )) { 320 mpt_prt(mpt, "handshake aborted due to invalid doorbell state"); 321 mpt_print_db(data); 322 return(EBUSY); 323 } 324 325 /* We move things in 32 bit chunks */ 326 len = (len + 3) >> 2; 327 data32 = cmd; 328 329 /* Clear any left over pending doorbell interupts */ 330 if (MPT_DB_INTR(mpt_rd_intr(mpt))) 331 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 332 333 /* 334 * Tell the handshake reg. we are going to send a command 335 * and how long it is going to be. 336 */ 337 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) | 338 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT); 339 mpt_write(mpt, MPT_OFFSET_DOORBELL, data); 340 341 /* Wait for the chip to notice */ 342 if (mpt_wait_db_int(mpt) != MPT_OK) { 343 mpt_prt(mpt, "mpt_send_handshake_cmd timeout1"); 344 return ETIMEDOUT; 345 } 346 347 /* Clear the interrupt */ 348 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 349 350 if (mpt_wait_db_ack(mpt) != MPT_OK) { 351 mpt_prt(mpt, "mpt_send_handshake_cmd timeout2"); 352 return ETIMEDOUT; 353 } 354 355 /* Send the command */ 356 for (i = 0; i < len; i++) { 357 mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++); 358 if (mpt_wait_db_ack(mpt) != MPT_OK) { 359 mpt_prt(mpt, 360 "mpt_send_handshake_cmd timeout! index = %d", i); 361 return ETIMEDOUT; 362 } 363 } 364 return MPT_OK; 365 } 366 367 /* Get the response from the handshake register */ 368 int 369 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply) 370 { 371 int left, reply_left; 372 u_int16_t *data16; 373 MSG_DEFAULT_REPLY *hdr; 374 375 /* We move things out in 16 bit chunks */ 376 reply_len >>= 1; 377 data16 = (u_int16_t *)reply; 378 379 hdr = (MSG_DEFAULT_REPLY *)reply; 380 381 /* Get first word */ 382 if (mpt_wait_db_int(mpt) != MPT_OK) { 383 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1"); 384 return ETIMEDOUT; 385 } 386 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK; 387 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 388 389 /* Get Second Word */ 390 if (mpt_wait_db_int(mpt) != MPT_OK) { 391 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2"); 392 return ETIMEDOUT; 393 } 394 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK; 395 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 396 397 /* With the second word, we can now look at the length */ 398 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) { 399 mpt_prt(mpt, "reply length does not match message length: " 400 "got 0x%02x, expected 0x%02x", 401 hdr->MsgLength << 2, reply_len << 1); 402 } 403 404 /* Get rest of the reply; but don't overflow the provided buffer */ 405 left = (hdr->MsgLength << 1) - 2; 406 reply_left = reply_len - 2; 407 while (left--) { 408 u_int16_t datum; 409 410 if (mpt_wait_db_int(mpt) != MPT_OK) { 411 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3"); 412 return ETIMEDOUT; 413 } 414 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL); 415 416 if (reply_left-- > 0) 417 *data16++ = datum & MPT_DB_DATA_MASK; 418 419 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 420 } 421 422 /* One more wait & clear at the end */ 423 if (mpt_wait_db_int(mpt) != MPT_OK) { 424 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout4"); 425 return ETIMEDOUT; 426 } 427 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0); 428 429 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 430 if (mpt->verbose > 1) 431 mpt_print_reply(hdr); 432 return (MPT_FAIL | hdr->IOCStatus); 433 } 434 435 return (0); 436 } 437 438 static int 439 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp) 440 { 441 MSG_IOC_FACTS f_req; 442 int error; 443 444 bzero(&f_req, sizeof f_req); 445 f_req.Function = MPI_FUNCTION_IOC_FACTS; 446 f_req.MsgContext = 0x12071942; 447 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); 448 if (error) 449 return(error); 450 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); 451 return (error); 452 } 453 454 static int 455 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp) 456 { 457 MSG_PORT_FACTS f_req; 458 int error; 459 460 /* XXX: Only getting PORT FACTS for Port 0 */ 461 bzero(&f_req, sizeof f_req); 462 f_req.Function = MPI_FUNCTION_PORT_FACTS; 463 f_req.MsgContext = 0x12071943; 464 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); 465 if (error) 466 return(error); 467 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); 468 return (error); 469 } 470 471 /* 472 * Send the initialization request. This is where we specify how many 473 * SCSI busses and how many devices per bus we wish to emulate. 474 * This is also the command that specifies the max size of the reply 475 * frames from the IOC that we will be allocating. 476 */ 477 static int 478 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who) 479 { 480 int error = 0; 481 MSG_IOC_INIT init; 482 MSG_IOC_INIT_REPLY reply; 483 484 bzero(&init, sizeof init); 485 init.WhoInit = who; 486 init.Function = MPI_FUNCTION_IOC_INIT; 487 if (mpt->is_fc) { 488 init.MaxDevices = 255; 489 } else { 490 init.MaxDevices = 16; 491 } 492 init.MaxBuses = 1; 493 init.ReplyFrameSize = MPT_REPLY_SIZE; 494 init.MsgContext = 0x12071941; 495 496 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) { 497 return(error); 498 } 499 500 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply); 501 return (error); 502 } 503 504 505 /* 506 * Utiltity routine to read configuration headers and pages 507 */ 508 509 static int 510 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *); 511 512 static int 513 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber, 514 int PageAddress, fCONFIG_PAGE_HEADER *rslt) 515 { 516 int count; 517 request_t *req; 518 MSG_CONFIG *cfgp; 519 MSG_CONFIG_REPLY *reply; 520 521 req = mpt_get_request(mpt); 522 523 cfgp = req->req_vbuf; 524 bzero(cfgp, sizeof *cfgp); 525 526 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER; 527 cfgp->Function = MPI_FUNCTION_CONFIG; 528 cfgp->Header.PageNumber = (U8) PageNumber; 529 cfgp->Header.PageType = (U8) PageType; 530 cfgp->PageAddress = PageAddress; 531 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE), 532 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 533 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST)); 534 cfgp->MsgContext = req->index | 0x80000000; 535 536 mpt_check_doorbell(mpt); 537 mpt_send_cmd(mpt, req); 538 count = 0; 539 do { 540 DELAY(500); 541 mpt_intr(mpt); 542 if (++count == 1000) { 543 mpt_prt(mpt, "read_cfg_header timed out"); 544 return (-1); 545 } 546 } while (req->debug == REQ_ON_CHIP); 547 548 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 549 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 550 mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x", 551 reply->IOCStatus); 552 mpt_free_reply(mpt, (req->sequence << 1)); 553 return (-1); 554 } 555 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER)); 556 mpt_free_reply(mpt, (req->sequence << 1)); 557 mpt_free_request(mpt, req); 558 return (0); 559 } 560 561 #define CFG_DATA_OFF 128 562 563 int 564 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 565 { 566 int count; 567 request_t *req; 568 SGE_SIMPLE32 *se; 569 MSG_CONFIG *cfgp; 570 size_t amt; 571 MSG_CONFIG_REPLY *reply; 572 573 req = mpt_get_request(mpt); 574 575 cfgp = req->req_vbuf; 576 bzero(cfgp, MPT_REQUEST_AREA); 577 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 578 cfgp->Function = MPI_FUNCTION_CONFIG; 579 cfgp->Header = *hdr; 580 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 581 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK; 582 cfgp->PageAddress = PageAddress; 583 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 584 se->Address = req->req_pbuf + CFG_DATA_OFF; 585 MPI_pSGE_SET_LENGTH(se, amt); 586 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 587 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 588 MPI_SGE_FLAGS_END_OF_LIST)); 589 590 cfgp->MsgContext = 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_page 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_page: Config Info Status %x", 607 reply->IOCStatus); 608 mpt_free_reply(mpt, (req->sequence << 1)); 609 return (-1); 610 } 611 mpt_free_reply(mpt, (req->sequence << 1)); 612 #if 0 /* XXXJRT */ 613 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap, 614 BUS_DMASYNC_POSTREAD); 615 #endif 616 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 617 cfgp->Header.PageNumber == 0) { 618 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0); 619 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 620 cfgp->Header.PageNumber == 1) { 621 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1); 622 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT && 623 cfgp->Header.PageNumber == 2) { 624 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2); 625 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 626 cfgp->Header.PageNumber == 0) { 627 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0); 628 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE && 629 cfgp->Header.PageNumber == 1) { 630 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1); 631 } 632 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt); 633 mpt_free_request(mpt, req); 634 return (0); 635 } 636 637 int 638 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr) 639 { 640 int count, hdr_attr; 641 request_t *req; 642 SGE_SIMPLE32 *se; 643 MSG_CONFIG *cfgp; 644 size_t amt; 645 MSG_CONFIG_REPLY *reply; 646 647 req = mpt_get_request(mpt); 648 649 cfgp = req->req_vbuf; 650 bzero(cfgp, sizeof *cfgp); 651 652 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK; 653 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE && 654 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) { 655 mpt_prt(mpt, "page type 0x%x not changeable", 656 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 657 return (-1); 658 } 659 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK; 660 661 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 662 cfgp->Function = MPI_FUNCTION_CONFIG; 663 cfgp->Header = *hdr; 664 amt = (cfgp->Header.PageLength * sizeof (u_int32_t)); 665 cfgp->PageAddress = PageAddress; 666 667 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE; 668 se->Address = req->req_pbuf + CFG_DATA_OFF; 669 MPI_pSGE_SET_LENGTH(se, amt); 670 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT | 671 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER | 672 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC)); 673 674 cfgp->MsgContext = req->index | 0x80000000; 675 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 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt); 693 /* Restore stripped out attributes */ 694 hdr->PageType |= hdr_attr; 695 696 mpt_check_doorbell(mpt); 697 mpt_send_cmd(mpt, req); 698 count = 0; 699 do { 700 DELAY(500); 701 mpt_intr(mpt); 702 if (++count == 1000) { 703 hdr->PageType |= hdr_attr; 704 mpt_prt(mpt, "mpt_write_cfg_page timed out"); 705 return (-1); 706 } 707 } while (req->debug == REQ_ON_CHIP); 708 709 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence); 710 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 711 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x", 712 reply->IOCStatus); 713 mpt_free_reply(mpt, (req->sequence << 1)); 714 return (-1); 715 } 716 mpt_free_reply(mpt, (req->sequence << 1)); 717 718 mpt_free_request(mpt, req); 719 return (0); 720 } 721 722 /* 723 * Read SCSI configuration information 724 */ 725 static int 726 mpt_read_config_info_spi(mpt_softc_t *mpt) 727 { 728 int rv, i; 729 730 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0, 731 0, &mpt->mpt_port_page0.Header); 732 if (rv) { 733 return (-1); 734 } 735 if (mpt->verbose > 1) { 736 mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x", 737 mpt->mpt_port_page0.Header.PageVersion, 738 mpt->mpt_port_page0.Header.PageLength, 739 mpt->mpt_port_page0.Header.PageNumber, 740 mpt->mpt_port_page0.Header.PageType); 741 } 742 743 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1, 744 0, &mpt->mpt_port_page1.Header); 745 if (rv) { 746 return (-1); 747 } 748 if (mpt->verbose > 1) { 749 mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x", 750 mpt->mpt_port_page1.Header.PageVersion, 751 mpt->mpt_port_page1.Header.PageLength, 752 mpt->mpt_port_page1.Header.PageNumber, 753 mpt->mpt_port_page1.Header.PageType); 754 } 755 756 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2, 757 0, &mpt->mpt_port_page2.Header); 758 if (rv) { 759 return (-1); 760 } 761 762 if (mpt->verbose > 1) { 763 mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x", 764 mpt->mpt_port_page1.Header.PageVersion, 765 mpt->mpt_port_page1.Header.PageLength, 766 mpt->mpt_port_page1.Header.PageNumber, 767 mpt->mpt_port_page1.Header.PageType); 768 } 769 770 for (i = 0; i < 16; i++) { 771 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 772 0, i, &mpt->mpt_dev_page0[i].Header); 773 if (rv) { 774 return (-1); 775 } 776 if (mpt->verbose > 1) { 777 mpt_prt(mpt, 778 "SPI Target %d Device Page 0 Header: %x %x %x %x", 779 i, mpt->mpt_dev_page0[i].Header.PageVersion, 780 mpt->mpt_dev_page0[i].Header.PageLength, 781 mpt->mpt_dev_page0[i].Header.PageNumber, 782 mpt->mpt_dev_page0[i].Header.PageType); 783 } 784 785 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE, 786 1, i, &mpt->mpt_dev_page1[i].Header); 787 if (rv) { 788 return (-1); 789 } 790 if (mpt->verbose > 1) { 791 mpt_prt(mpt, 792 "SPI Target %d Device Page 1 Header: %x %x %x %x", 793 i, mpt->mpt_dev_page1[i].Header.PageVersion, 794 mpt->mpt_dev_page1[i].Header.PageLength, 795 mpt->mpt_dev_page1[i].Header.PageNumber, 796 mpt->mpt_dev_page1[i].Header.PageType); 797 } 798 } 799 800 /* 801 * At this point, we don't *have* to fail. As long as we have 802 * valid config header information, we can (barely) lurch 803 * along. 804 */ 805 806 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header); 807 if (rv) { 808 mpt_prt(mpt, "failed to read SPI Port Page 0"); 809 } else if (mpt->verbose > 1) { 810 mpt_prt(mpt, 811 "SPI Port Page 0: Capabilities %x PhysicalInterface %x", 812 mpt->mpt_port_page0.Capabilities, 813 mpt->mpt_port_page0.PhysicalInterface); 814 } 815 816 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header); 817 if (rv) { 818 mpt_prt(mpt, "failed to read SPI Port Page 1"); 819 } else if (mpt->verbose > 1) { 820 mpt_prt(mpt, 821 "SPI Port Page 1: Configuration %x OnBusTimerValue %x", 822 mpt->mpt_port_page1.Configuration, 823 mpt->mpt_port_page1.OnBusTimerValue); 824 } 825 826 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header); 827 if (rv) { 828 mpt_prt(mpt, "failed to read SPI Port Page 2"); 829 } else if (mpt->verbose > 1) { 830 mpt_prt(mpt, 831 "SPI Port Page 2: Flags %x Settings %x", 832 mpt->mpt_port_page2.PortFlags, 833 mpt->mpt_port_page2.PortSettings); 834 for (i = 0; i < 16; i++) { 835 mpt_prt(mpt, 836 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x", 837 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout, 838 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor, 839 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags); 840 } 841 } 842 843 for (i = 0; i < 16; i++) { 844 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header); 845 if (rv) { 846 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i); 847 continue; 848 } 849 if (mpt->verbose > 1) { 850 mpt_prt(mpt, 851 "SPI Tgt %d Page 0: NParms %x Information %x", 852 i, mpt->mpt_dev_page0[i].NegotiatedParameters, 853 mpt->mpt_dev_page0[i].Information); 854 } 855 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header); 856 if (rv) { 857 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i); 858 continue; 859 } 860 if (mpt->verbose > 1) { 861 mpt_prt(mpt, 862 "SPI Tgt %d Page 1: RParms %x Configuration %x", 863 i, mpt->mpt_dev_page1[i].RequestedParameters, 864 mpt->mpt_dev_page1[i].Configuration); 865 } 866 } 867 return (0); 868 } 869 870 /* 871 * Validate SPI configuration information. 872 * 873 * In particular, validate SPI Port Page 1. 874 */ 875 static int 876 mpt_set_initial_config_spi(mpt_softc_t *mpt) 877 { 878 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id; 879 880 mpt->mpt_disc_enable = 0xff; 881 mpt->mpt_tag_enable = 0; 882 883 if (mpt->mpt_port_page1.Configuration != pp1val) { 884 fCONFIG_PAGE_SCSI_PORT_1 tmp; 885 mpt_prt(mpt, 886 "SPI Port Page 1 Config value bad (%x)- should be %x", 887 mpt->mpt_port_page1.Configuration, pp1val); 888 tmp = mpt->mpt_port_page1; 889 tmp.Configuration = pp1val; 890 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) { 891 return (-1); 892 } 893 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) { 894 return (-1); 895 } 896 if (tmp.Configuration != pp1val) { 897 mpt_prt(mpt, 898 "failed to reset SPI Port Page 1 Config value"); 899 return (-1); 900 } 901 mpt->mpt_port_page1 = tmp; 902 } 903 904 for (i = 0; i < 16; i++) { 905 fCONFIG_PAGE_SCSI_DEVICE_1 tmp; 906 tmp = mpt->mpt_dev_page1[i]; 907 tmp.RequestedParameters = 0; 908 tmp.Configuration = 0; 909 if (mpt->verbose > 1) { 910 mpt_prt(mpt, 911 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x", 912 i, tmp.RequestedParameters, tmp.Configuration); 913 } 914 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) { 915 return (-1); 916 } 917 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) { 918 return (-1); 919 } 920 mpt->mpt_dev_page1[i] = tmp; 921 if (mpt->verbose > 1) { 922 mpt_prt(mpt, 923 "SPI Tgt %d Page 1: RParm %x Configuration %x", i, 924 mpt->mpt_dev_page1[i].RequestedParameters, 925 mpt->mpt_dev_page1[i].Configuration); 926 } 927 } 928 return (0); 929 } 930 931 /* 932 * Enable IOC port 933 */ 934 static int 935 mpt_send_port_enable(mpt_softc_t *mpt, int port) 936 { 937 int count; 938 request_t *req; 939 MSG_PORT_ENABLE *enable_req; 940 941 req = mpt_get_request(mpt); 942 943 enable_req = req->req_vbuf; 944 bzero(enable_req, sizeof *enable_req); 945 946 enable_req->Function = MPI_FUNCTION_PORT_ENABLE; 947 enable_req->MsgContext = req->index | 0x80000000; 948 enable_req->PortNumber = port; 949 950 mpt_check_doorbell(mpt); 951 if (mpt->verbose > 1) { 952 mpt_prt(mpt, "enabling port %d", port); 953 } 954 mpt_send_cmd(mpt, req); 955 956 count = 0; 957 do { 958 DELAY(500); 959 mpt_intr(mpt); 960 if (++count == 100000) { 961 mpt_prt(mpt, "port enable timed out"); 962 return (-1); 963 } 964 } while (req->debug == REQ_ON_CHIP); 965 mpt_free_request(mpt, req); 966 return (0); 967 } 968 969 /* 970 * Enable/Disable asynchronous event reporting. 971 * 972 * NB: this is the first command we send via shared memory 973 * instead of the handshake register. 974 */ 975 static int 976 mpt_send_event_request(mpt_softc_t *mpt, int onoff) 977 { 978 request_t *req; 979 MSG_EVENT_NOTIFY *enable_req; 980 981 req = mpt_get_request(mpt); 982 983 enable_req = req->req_vbuf; 984 bzero(enable_req, sizeof *enable_req); 985 986 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 987 enable_req->MsgContext = req->index | 0x80000000; 988 enable_req->Switch = onoff; 989 990 mpt_check_doorbell(mpt); 991 if (mpt->verbose > 1) { 992 mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis"); 993 } 994 mpt_send_cmd(mpt, req); 995 996 return (0); 997 } 998 999 /* 1000 * Un-mask the interupts on the chip. 1001 */ 1002 void 1003 mpt_enable_ints(mpt_softc_t *mpt) 1004 { 1005 /* Unmask every thing except door bell int */ 1006 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK); 1007 } 1008 1009 /* 1010 * Mask the interupts on the chip. 1011 */ 1012 void 1013 mpt_disable_ints(mpt_softc_t *mpt) 1014 { 1015 /* Mask all interrupts */ 1016 mpt_write(mpt, MPT_OFFSET_INTR_MASK, 1017 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK); 1018 } 1019 1020 /* (Re)Initialize the chip for use */ 1021 int 1022 mpt_init(mpt_softc_t *mpt, u_int32_t who) 1023 { 1024 int try; 1025 MSG_IOC_FACTS_REPLY facts; 1026 MSG_PORT_FACTS_REPLY pfp; 1027 u_int32_t pptr; 1028 int val; 1029 1030 /* Put all request buffers (back) on the free list */ 1031 SLIST_INIT(&mpt->request_free_list); 1032 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) { 1033 mpt_free_request(mpt, &mpt->request_pool[val]); 1034 } 1035 1036 if (mpt->verbose > 1) { 1037 mpt_prt(mpt, "doorbell req = %s", 1038 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL))); 1039 } 1040 1041 /* 1042 * Start by making sure we're not at FAULT or RESET state 1043 */ 1044 switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) { 1045 case MPT_DB_STATE_RESET: 1046 case MPT_DB_STATE_FAULT: 1047 if (mpt_reset(mpt) != MPT_OK) { 1048 return (EIO); 1049 } 1050 default: 1051 break; 1052 } 1053 1054 for (try = 0; try < MPT_MAX_TRYS; try++) { 1055 /* 1056 * No need to reset if the IOC is already in the READY state. 1057 * 1058 * Force reset if initialization failed previously. 1059 * Note that a hard_reset of the second channel of a '929 1060 * will stop operation of the first channel. Hopefully, if the 1061 * first channel is ok, the second will not require a hard 1062 * reset. 1063 */ 1064 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) != 1065 MPT_DB_STATE_READY) { 1066 if (mpt_reset(mpt) != MPT_OK) { 1067 DELAY(10000); 1068 continue; 1069 } 1070 } 1071 1072 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) { 1073 mpt_prt(mpt, "mpt_get_iocfacts failed"); 1074 continue; 1075 } 1076 1077 if (mpt->verbose > 1) { 1078 mpt_prt(mpt, 1079 "IOCFACTS: GlobalCredits=%d BlockSize=%u " 1080 "Request Frame Size %u\n", facts.GlobalCredits, 1081 facts.BlockSize, facts.RequestFrameSize); 1082 } 1083 mpt->mpt_global_credits = facts.GlobalCredits; 1084 mpt->request_frame_size = facts.RequestFrameSize; 1085 1086 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) { 1087 mpt_prt(mpt, "mpt_get_portfacts failed"); 1088 continue; 1089 } 1090 1091 if (mpt->verbose > 1) { 1092 mpt_prt(mpt, 1093 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n", 1094 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID, 1095 pfp.MaxDevices); 1096 } 1097 1098 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI && 1099 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) { 1100 mpt_prt(mpt, "Unsupported Port Type (%x)", 1101 pfp.PortType); 1102 return (ENXIO); 1103 } 1104 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) { 1105 mpt_prt(mpt, "initiator role unsupported"); 1106 return (ENXIO); 1107 } 1108 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) { 1109 mpt->is_fc = 1; 1110 } else { 1111 mpt->is_fc = 0; 1112 } 1113 mpt->mpt_ini_id = pfp.PortSCSIID; 1114 1115 if (mpt_send_ioc_init(mpt, who) != MPT_OK) { 1116 mpt_prt(mpt, "mpt_send_ioc_init failed"); 1117 continue; 1118 } 1119 1120 if (mpt->verbose > 1) { 1121 mpt_prt(mpt, "mpt_send_ioc_init ok"); 1122 } 1123 1124 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) { 1125 mpt_prt(mpt, "IOC failed to go to run state"); 1126 continue; 1127 } 1128 if (mpt->verbose > 1) { 1129 mpt_prt(mpt, "IOC now at RUNSTATE"); 1130 } 1131 1132 /* 1133 * Give it reply buffers 1134 * 1135 * Do *not* except global credits. 1136 */ 1137 for (val = 0, pptr = mpt->reply_phys; 1138 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE); 1139 pptr += MPT_REPLY_SIZE) { 1140 mpt_free_reply(mpt, pptr); 1141 if (++val == mpt->mpt_global_credits - 1) 1142 break; 1143 } 1144 1145 /* 1146 * Enable asynchronous event reporting 1147 */ 1148 mpt_send_event_request(mpt, 1); 1149 1150 1151 /* 1152 * Read set up initial configuration information 1153 * (SPI only for now) 1154 */ 1155 1156 if (mpt->is_fc == 0) { 1157 if (mpt_read_config_info_spi(mpt)) { 1158 return (EIO); 1159 } 1160 if (mpt_set_initial_config_spi(mpt)) { 1161 return (EIO); 1162 } 1163 } 1164 1165 /* 1166 * Now enable the port 1167 */ 1168 if (mpt_send_port_enable(mpt, 0) != MPT_OK) { 1169 mpt_prt(mpt, "failed to enable port 0"); 1170 continue; 1171 } 1172 1173 if (mpt->verbose > 1) { 1174 mpt_prt(mpt, "enabled port 0"); 1175 } 1176 1177 /* Everything worked */ 1178 break; 1179 } 1180 1181 if (try >= MPT_MAX_TRYS) { 1182 mpt_prt(mpt, "failed to initialize IOC"); 1183 return (EIO); 1184 } 1185 1186 if (mpt->verbose > 1) { 1187 mpt_prt(mpt, "enabling interrupts"); 1188 } 1189 1190 mpt_enable_ints(mpt); 1191 return (0); 1192 } 1193