1 /*- 2 * Copyright (c) 2009 Yahoo! Inc. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 /* Communications core for LSI MPT2 */ 31 32 #include <sys/types.h> 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/kernel.h> 36 #include <sys/selinfo.h> 37 #include <sys/lock.h> 38 #include <sys/mutex.h> 39 #include <sys/module.h> 40 #include <sys/bus.h> 41 #include <sys/conf.h> 42 #include <sys/bio.h> 43 #include <sys/malloc.h> 44 #include <sys/uio.h> 45 #include <sys/sysctl.h> 46 #include <sys/endian.h> 47 48 #include <machine/bus.h> 49 #include <machine/resource.h> 50 #include <sys/rman.h> 51 52 #include <cam/scsi/scsi_all.h> 53 54 #include <dev/mps/mpi/mpi2_type.h> 55 #include <dev/mps/mpi/mpi2.h> 56 #include <dev/mps/mpi/mpi2_ioc.h> 57 #include <dev/mps/mpi/mpi2_cnfg.h> 58 #include <dev/mps/mpsvar.h> 59 #include <dev/mps/mps_table.h> 60 61 static void mps_startup(void *arg); 62 static void mps_startup_complete(struct mps_softc *sc, struct mps_command *cm); 63 static int mps_send_iocinit(struct mps_softc *sc); 64 static int mps_attach_log(struct mps_softc *sc); 65 static void mps_dispatch_event(struct mps_softc *sc, uintptr_t data, MPI2_EVENT_NOTIFICATION_REPLY *reply); 66 static void mps_config_complete(struct mps_softc *sc, struct mps_command *cm); 67 static void mps_periodic(void *); 68 69 SYSCTL_NODE(_hw, OID_AUTO, mps, CTLFLAG_RD, 0, "MPS Driver Parameters"); 70 71 MALLOC_DEFINE(M_MPT2, "mps", "mpt2 driver memory"); 72 73 /* 74 * Do a "Diagnostic Reset" aka a hard reset. This should get the chip out of 75 * any state and back to its initialization state machine. 76 */ 77 static char mpt2_reset_magic[] = { 0x00, 0x0f, 0x04, 0x0b, 0x02, 0x07, 0x0d }; 78 79 static int 80 mps_hard_reset(struct mps_softc *sc) 81 { 82 uint32_t reg; 83 int i, error, tries = 0; 84 85 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 86 87 /* Clear any pending interrupts */ 88 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 89 90 /* Push the magic sequence */ 91 error = ETIMEDOUT; 92 while (tries++ < 20) { 93 for (i = 0; i < sizeof(mpt2_reset_magic); i++) 94 mps_regwrite(sc, MPI2_WRITE_SEQUENCE_OFFSET, 95 mpt2_reset_magic[i]); 96 97 DELAY(100 * 1000); 98 99 reg = mps_regread(sc, MPI2_HOST_DIAGNOSTIC_OFFSET); 100 if (reg & MPI2_DIAG_DIAG_WRITE_ENABLE) { 101 error = 0; 102 break; 103 } 104 } 105 if (error) 106 return (error); 107 108 /* Send the actual reset. XXX need to refresh the reg? */ 109 mps_regwrite(sc, MPI2_HOST_DIAGNOSTIC_OFFSET, 110 reg | MPI2_DIAG_RESET_ADAPTER); 111 112 /* Wait up to 300 seconds in 50ms intervals */ 113 error = ETIMEDOUT; 114 for (i = 0; i < 60000; i++) { 115 DELAY(50000); 116 reg = mps_regread(sc, MPI2_DOORBELL_OFFSET); 117 if ((reg & MPI2_IOC_STATE_MASK) != MPI2_IOC_STATE_RESET) { 118 error = 0; 119 break; 120 } 121 } 122 if (error) 123 return (error); 124 125 mps_regwrite(sc, MPI2_WRITE_SEQUENCE_OFFSET, 0x0); 126 127 return (0); 128 } 129 130 static int 131 mps_soft_reset(struct mps_softc *sc) 132 { 133 134 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 135 136 mps_regwrite(sc, MPI2_DOORBELL_OFFSET, 137 MPI2_FUNCTION_IOC_MESSAGE_UNIT_RESET << 138 MPI2_DOORBELL_FUNCTION_SHIFT); 139 DELAY(50000); 140 141 return (0); 142 } 143 144 static int 145 mps_transition_ready(struct mps_softc *sc) 146 { 147 uint32_t reg, state; 148 int error, tries = 0; 149 150 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 151 152 error = 0; 153 while (tries++ < 5) { 154 reg = mps_regread(sc, MPI2_DOORBELL_OFFSET); 155 mps_dprint(sc, MPS_INFO, "Doorbell= 0x%x\n", reg); 156 157 /* 158 * Ensure the IOC is ready to talk. If it's not, try 159 * resetting it. 160 */ 161 if (reg & MPI2_DOORBELL_USED) { 162 mps_hard_reset(sc); 163 DELAY(50000); 164 continue; 165 } 166 167 /* Is the adapter owned by another peer? */ 168 if ((reg & MPI2_DOORBELL_WHO_INIT_MASK) == 169 (MPI2_WHOINIT_PCI_PEER << MPI2_DOORBELL_WHO_INIT_SHIFT)) { 170 device_printf(sc->mps_dev, "IOC is under the control " 171 "of another peer host, aborting initialization.\n"); 172 return (ENXIO); 173 } 174 175 state = reg & MPI2_IOC_STATE_MASK; 176 if (state == MPI2_IOC_STATE_READY) { 177 /* Ready to go! */ 178 error = 0; 179 break; 180 } else if (state == MPI2_IOC_STATE_FAULT) { 181 mps_dprint(sc, MPS_INFO, "IOC in fault state 0x%x\n", 182 state & MPI2_DOORBELL_FAULT_CODE_MASK); 183 mps_hard_reset(sc); 184 } else if (state == MPI2_IOC_STATE_OPERATIONAL) { 185 /* Need to take ownership */ 186 mps_soft_reset(sc); 187 } else if (state == MPI2_IOC_STATE_RESET) { 188 /* Wait a bit, IOC might be in transition */ 189 mps_dprint(sc, MPS_FAULT, 190 "IOC in unexpected reset state\n"); 191 } else { 192 mps_dprint(sc, MPS_FAULT, 193 "IOC in unknown state 0x%x\n", state); 194 error = EINVAL; 195 break; 196 } 197 198 /* Wait 50ms for things to settle down. */ 199 DELAY(50000); 200 } 201 202 if (error) 203 device_printf(sc->mps_dev, "Cannot transition IOC to ready\n"); 204 205 return (error); 206 } 207 208 static int 209 mps_transition_operational(struct mps_softc *sc) 210 { 211 uint32_t reg, state; 212 int error; 213 214 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 215 216 error = 0; 217 reg = mps_regread(sc, MPI2_DOORBELL_OFFSET); 218 mps_dprint(sc, MPS_INFO, "Doorbell= 0x%x\n", reg); 219 220 state = reg & MPI2_IOC_STATE_MASK; 221 if (state != MPI2_IOC_STATE_READY) { 222 if ((error = mps_transition_ready(sc)) != 0) 223 return (error); 224 } 225 226 error = mps_send_iocinit(sc); 227 return (error); 228 } 229 230 /* Wait for the chip to ACK a word that we've put into its FIFO */ 231 static int 232 mps_wait_db_ack(struct mps_softc *sc) 233 { 234 int retry; 235 236 for (retry = 0; retry < MPS_DB_MAX_WAIT; retry++) { 237 if ((mps_regread(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET) & 238 MPI2_HIS_SYS2IOC_DB_STATUS) == 0) 239 return (0); 240 DELAY(2000); 241 } 242 return (ETIMEDOUT); 243 } 244 245 /* Wait for the chip to signal that the next word in its FIFO can be fetched */ 246 static int 247 mps_wait_db_int(struct mps_softc *sc) 248 { 249 int retry; 250 251 for (retry = 0; retry < MPS_DB_MAX_WAIT; retry++) { 252 if ((mps_regread(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET) & 253 MPI2_HIS_IOC2SYS_DB_STATUS) != 0) 254 return (0); 255 DELAY(2000); 256 } 257 return (ETIMEDOUT); 258 } 259 260 /* Step through the synchronous command state machine, i.e. "Doorbell mode" */ 261 static int 262 mps_request_sync(struct mps_softc *sc, void *req, MPI2_DEFAULT_REPLY *reply, 263 int req_sz, int reply_sz, int timeout) 264 { 265 uint32_t *data32; 266 uint16_t *data16; 267 int i, count, ioc_sz, residual; 268 269 /* Step 1 */ 270 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 271 272 /* Step 2 */ 273 if (mps_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_USED) 274 return (EBUSY); 275 276 /* Step 3 277 * Announce that a message is coming through the doorbell. Messages 278 * are pushed at 32bit words, so round up if needed. 279 */ 280 count = (req_sz + 3) / 4; 281 mps_regwrite(sc, MPI2_DOORBELL_OFFSET, 282 (MPI2_FUNCTION_HANDSHAKE << MPI2_DOORBELL_FUNCTION_SHIFT) | 283 (count << MPI2_DOORBELL_ADD_DWORDS_SHIFT)); 284 285 /* Step 4 */ 286 if (mps_wait_db_int(sc) || 287 (mps_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_USED) == 0) { 288 mps_dprint(sc, MPS_FAULT, "Doorbell failed to activate\n"); 289 return (ENXIO); 290 } 291 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 292 if (mps_wait_db_ack(sc) != 0) { 293 mps_dprint(sc, MPS_FAULT, "Doorbell handshake failed\n"); 294 return (ENXIO); 295 } 296 297 /* Step 5 */ 298 /* Clock out the message data synchronously in 32-bit dwords*/ 299 data32 = (uint32_t *)req; 300 for (i = 0; i < count; i++) { 301 mps_regwrite(sc, MPI2_DOORBELL_OFFSET, data32[i]); 302 if (mps_wait_db_ack(sc) != 0) { 303 mps_dprint(sc, MPS_FAULT, 304 "Timeout while writing doorbell\n"); 305 return (ENXIO); 306 } 307 } 308 309 /* Step 6 */ 310 /* Clock in the reply in 16-bit words. The total length of the 311 * message is always in the 4th byte, so clock out the first 2 words 312 * manually, then loop the rest. 313 */ 314 data16 = (uint16_t *)reply; 315 if (mps_wait_db_int(sc) != 0) { 316 mps_dprint(sc, MPS_FAULT, "Timeout reading doorbell 0\n"); 317 return (ENXIO); 318 } 319 data16[0] = 320 mps_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_DATA_MASK; 321 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 322 if (mps_wait_db_int(sc) != 0) { 323 mps_dprint(sc, MPS_FAULT, "Timeout reading doorbell 1\n"); 324 return (ENXIO); 325 } 326 data16[1] = 327 mps_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_DATA_MASK; 328 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 329 330 /* Number of 32bit words in the message */ 331 ioc_sz = reply->MsgLength; 332 333 /* 334 * Figure out how many 16bit words to clock in without overrunning. 335 * The precision loss with dividing reply_sz can safely be 336 * ignored because the messages can only be multiples of 32bits. 337 */ 338 residual = 0; 339 count = MIN((reply_sz / 4), ioc_sz) * 2; 340 if (count < ioc_sz * 2) { 341 residual = ioc_sz * 2 - count; 342 mps_dprint(sc, MPS_FAULT, "Driver error, throwing away %d " 343 "residual message words\n", residual); 344 } 345 346 for (i = 2; i < count; i++) { 347 if (mps_wait_db_int(sc) != 0) { 348 mps_dprint(sc, MPS_FAULT, 349 "Timeout reading doorbell %d\n", i); 350 return (ENXIO); 351 } 352 data16[i] = mps_regread(sc, MPI2_DOORBELL_OFFSET) & 353 MPI2_DOORBELL_DATA_MASK; 354 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 355 } 356 357 /* 358 * Pull out residual words that won't fit into the provided buffer. 359 * This keeps the chip from hanging due to a driver programming 360 * error. 361 */ 362 while (residual--) { 363 if (mps_wait_db_int(sc) != 0) { 364 mps_dprint(sc, MPS_FAULT, 365 "Timeout reading doorbell\n"); 366 return (ENXIO); 367 } 368 (void)mps_regread(sc, MPI2_DOORBELL_OFFSET); 369 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 370 } 371 372 /* Step 7 */ 373 if (mps_wait_db_int(sc) != 0) { 374 mps_dprint(sc, MPS_FAULT, "Timeout waiting to exit doorbell\n"); 375 return (ENXIO); 376 } 377 if (mps_regread(sc, MPI2_DOORBELL_OFFSET) & MPI2_DOORBELL_USED) 378 mps_dprint(sc, MPS_FAULT, "Warning, doorbell still active\n"); 379 mps_regwrite(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET, 0x0); 380 381 return (0); 382 } 383 384 void 385 mps_enqueue_request(struct mps_softc *sc, struct mps_command *cm) 386 { 387 388 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 389 390 mps_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_LOW_OFFSET, 391 cm->cm_desc.Words.Low); 392 mps_regwrite(sc, MPI2_REQUEST_DESCRIPTOR_POST_HIGH_OFFSET, 393 cm->cm_desc.Words.High); 394 } 395 396 int 397 mps_request_polled(struct mps_softc *sc, struct mps_command *cm) 398 { 399 int error, timeout = 0; 400 401 error = 0; 402 403 cm->cm_flags |= MPS_CM_FLAGS_POLLED; 404 cm->cm_complete = NULL; 405 mps_map_command(sc, cm); 406 407 while ((cm->cm_flags & MPS_CM_FLAGS_COMPLETE) == 0) { 408 mps_intr(sc); 409 DELAY(50 * 1000); 410 if (timeout++ > 1000) { 411 mps_dprint(sc, MPS_FAULT, "polling failed\n"); 412 error = ETIMEDOUT; 413 break; 414 } 415 } 416 417 return (error); 418 } 419 420 /* 421 * Just the FACTS, ma'am. 422 */ 423 static int 424 mps_get_iocfacts(struct mps_softc *sc, MPI2_IOC_FACTS_REPLY *facts) 425 { 426 MPI2_DEFAULT_REPLY *reply; 427 MPI2_IOC_FACTS_REQUEST request; 428 int error, req_sz, reply_sz; 429 430 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 431 432 req_sz = sizeof(MPI2_IOC_FACTS_REQUEST); 433 reply_sz = sizeof(MPI2_IOC_FACTS_REPLY); 434 reply = (MPI2_DEFAULT_REPLY *)facts; 435 436 bzero(&request, req_sz); 437 request.Function = MPI2_FUNCTION_IOC_FACTS; 438 error = mps_request_sync(sc, &request, reply, req_sz, reply_sz, 5); 439 440 return (error); 441 } 442 443 static int 444 mps_get_portfacts(struct mps_softc *sc, MPI2_PORT_FACTS_REPLY *facts, int port) 445 { 446 MPI2_PORT_FACTS_REQUEST *request; 447 MPI2_PORT_FACTS_REPLY *reply; 448 struct mps_command *cm; 449 int error; 450 451 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 452 453 if ((cm = mps_alloc_command(sc)) == NULL) 454 return (EBUSY); 455 request = (MPI2_PORT_FACTS_REQUEST *)cm->cm_req; 456 request->Function = MPI2_FUNCTION_PORT_FACTS; 457 request->PortNumber = port; 458 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 459 cm->cm_data = NULL; 460 error = mps_request_polled(sc, cm); 461 reply = (MPI2_PORT_FACTS_REPLY *)cm->cm_reply; 462 if ((reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) 463 error = ENXIO; 464 bcopy(reply, facts, sizeof(MPI2_PORT_FACTS_REPLY)); 465 mps_free_command(sc, cm); 466 467 return (error); 468 } 469 470 static int 471 mps_send_iocinit(struct mps_softc *sc) 472 { 473 MPI2_IOC_INIT_REQUEST init; 474 MPI2_DEFAULT_REPLY reply; 475 int req_sz, reply_sz, error; 476 477 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 478 479 req_sz = sizeof(MPI2_IOC_INIT_REQUEST); 480 reply_sz = sizeof(MPI2_IOC_INIT_REPLY); 481 bzero(&init, req_sz); 482 bzero(&reply, reply_sz); 483 484 /* 485 * Fill in the init block. Note that most addresses are 486 * deliberately in the lower 32bits of memory. This is a micro- 487 * optimzation for PCI/PCIX, though it's not clear if it helps PCIe. 488 */ 489 init.Function = MPI2_FUNCTION_IOC_INIT; 490 init.WhoInit = MPI2_WHOINIT_HOST_DRIVER; 491 init.MsgVersion = MPI2_VERSION; 492 init.HeaderVersion = MPI2_HEADER_VERSION; 493 init.SystemRequestFrameSize = sc->facts->IOCRequestFrameSize; 494 init.ReplyDescriptorPostQueueDepth = sc->pqdepth; 495 init.ReplyFreeQueueDepth = sc->fqdepth; 496 init.SenseBufferAddressHigh = 0; 497 init.SystemReplyAddressHigh = 0; 498 init.SystemRequestFrameBaseAddress.High = 0; 499 init.SystemRequestFrameBaseAddress.Low = (uint32_t)sc->req_busaddr; 500 init.ReplyDescriptorPostQueueAddress.High = 0; 501 init.ReplyDescriptorPostQueueAddress.Low = (uint32_t)sc->post_busaddr; 502 init.ReplyFreeQueueAddress.High = 0; 503 init.ReplyFreeQueueAddress.Low = (uint32_t)sc->free_busaddr; 504 init.TimeStamp.High = 0; 505 init.TimeStamp.Low = (uint32_t)time_uptime; 506 507 error = mps_request_sync(sc, &init, &reply, req_sz, reply_sz, 5); 508 if ((reply.IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) 509 error = ENXIO; 510 511 mps_dprint(sc, MPS_INFO, "IOCInit status= 0x%x\n", reply.IOCStatus); 512 return (error); 513 } 514 515 static int 516 mps_send_portenable(struct mps_softc *sc) 517 { 518 MPI2_PORT_ENABLE_REQUEST *request; 519 struct mps_command *cm; 520 521 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 522 523 if ((cm = mps_alloc_command(sc)) == NULL) 524 return (EBUSY); 525 request = (MPI2_PORT_ENABLE_REQUEST *)cm->cm_req; 526 request->Function = MPI2_FUNCTION_PORT_ENABLE; 527 request->MsgFlags = 0; 528 request->VP_ID = 0; 529 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 530 cm->cm_complete = mps_startup_complete; 531 532 mps_enqueue_request(sc, cm); 533 return (0); 534 } 535 536 static int 537 mps_send_mur(struct mps_softc *sc) 538 { 539 540 /* Placeholder */ 541 return (0); 542 } 543 544 void 545 mps_memaddr_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 546 { 547 bus_addr_t *addr; 548 549 addr = arg; 550 *addr = segs[0].ds_addr; 551 } 552 553 static int 554 mps_alloc_queues(struct mps_softc *sc) 555 { 556 bus_addr_t queues_busaddr; 557 uint8_t *queues; 558 int qsize, fqsize, pqsize; 559 560 /* 561 * The reply free queue contains 4 byte entries in multiples of 16 and 562 * aligned on a 16 byte boundary. There must always be an unused entry. 563 * This queue supplies fresh reply frames for the firmware to use. 564 * 565 * The reply descriptor post queue contains 8 byte entries in 566 * multiples of 16 and aligned on a 16 byte boundary. This queue 567 * contains filled-in reply frames sent from the firmware to the host. 568 * 569 * These two queues are allocated together for simplicity. 570 */ 571 sc->fqdepth = roundup2((sc->num_replies + 1), 16); 572 sc->pqdepth = roundup2((sc->num_replies + 1), 16); 573 fqsize= sc->fqdepth * 4; 574 pqsize = sc->pqdepth * 8; 575 qsize = fqsize + pqsize; 576 577 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 578 16, 0, /* algnmnt, boundary */ 579 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 580 BUS_SPACE_MAXADDR, /* highaddr */ 581 NULL, NULL, /* filter, filterarg */ 582 qsize, /* maxsize */ 583 1, /* nsegments */ 584 qsize, /* maxsegsize */ 585 0, /* flags */ 586 NULL, NULL, /* lockfunc, lockarg */ 587 &sc->queues_dmat)) { 588 device_printf(sc->mps_dev, "Cannot allocate queues DMA tag\n"); 589 return (ENOMEM); 590 } 591 if (bus_dmamem_alloc(sc->queues_dmat, (void **)&queues, BUS_DMA_NOWAIT, 592 &sc->queues_map)) { 593 device_printf(sc->mps_dev, "Cannot allocate queues memory\n"); 594 return (ENOMEM); 595 } 596 bzero(queues, qsize); 597 bus_dmamap_load(sc->queues_dmat, sc->queues_map, queues, qsize, 598 mps_memaddr_cb, &queues_busaddr, 0); 599 600 sc->free_queue = (uint32_t *)queues; 601 sc->free_busaddr = queues_busaddr; 602 sc->post_queue = (MPI2_REPLY_DESCRIPTORS_UNION *)(queues + fqsize); 603 sc->post_busaddr = queues_busaddr + fqsize; 604 605 return (0); 606 } 607 608 static int 609 mps_alloc_replies(struct mps_softc *sc) 610 { 611 int rsize, num_replies; 612 613 /* 614 * sc->num_replies should be one less than sc->fqdepth. We need to 615 * allocate space for sc->fqdepth replies, but only sc->num_replies 616 * replies can be used at once. 617 */ 618 num_replies = max(sc->fqdepth, sc->num_replies); 619 620 rsize = sc->facts->ReplyFrameSize * num_replies * 4; 621 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 622 4, 0, /* algnmnt, boundary */ 623 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 624 BUS_SPACE_MAXADDR, /* highaddr */ 625 NULL, NULL, /* filter, filterarg */ 626 rsize, /* maxsize */ 627 1, /* nsegments */ 628 rsize, /* maxsegsize */ 629 0, /* flags */ 630 NULL, NULL, /* lockfunc, lockarg */ 631 &sc->reply_dmat)) { 632 device_printf(sc->mps_dev, "Cannot allocate replies DMA tag\n"); 633 return (ENOMEM); 634 } 635 if (bus_dmamem_alloc(sc->reply_dmat, (void **)&sc->reply_frames, 636 BUS_DMA_NOWAIT, &sc->reply_map)) { 637 device_printf(sc->mps_dev, "Cannot allocate replies memory\n"); 638 return (ENOMEM); 639 } 640 bzero(sc->reply_frames, rsize); 641 bus_dmamap_load(sc->reply_dmat, sc->reply_map, sc->reply_frames, rsize, 642 mps_memaddr_cb, &sc->reply_busaddr, 0); 643 644 return (0); 645 } 646 647 static int 648 mps_alloc_requests(struct mps_softc *sc) 649 { 650 struct mps_command *cm; 651 struct mps_chain *chain; 652 int i, rsize, nsegs; 653 654 rsize = sc->facts->IOCRequestFrameSize * sc->num_reqs * 4; 655 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 656 16, 0, /* algnmnt, boundary */ 657 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 658 BUS_SPACE_MAXADDR, /* highaddr */ 659 NULL, NULL, /* filter, filterarg */ 660 rsize, /* maxsize */ 661 1, /* nsegments */ 662 rsize, /* maxsegsize */ 663 0, /* flags */ 664 NULL, NULL, /* lockfunc, lockarg */ 665 &sc->req_dmat)) { 666 device_printf(sc->mps_dev, "Cannot allocate request DMA tag\n"); 667 return (ENOMEM); 668 } 669 if (bus_dmamem_alloc(sc->req_dmat, (void **)&sc->req_frames, 670 BUS_DMA_NOWAIT, &sc->req_map)) { 671 device_printf(sc->mps_dev, "Cannot allocate request memory\n"); 672 return (ENOMEM); 673 } 674 bzero(sc->req_frames, rsize); 675 bus_dmamap_load(sc->req_dmat, sc->req_map, sc->req_frames, rsize, 676 mps_memaddr_cb, &sc->req_busaddr, 0); 677 678 rsize = sc->facts->IOCRequestFrameSize * MPS_CHAIN_FRAMES * 4; 679 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 680 16, 0, /* algnmnt, boundary */ 681 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 682 BUS_SPACE_MAXADDR, /* highaddr */ 683 NULL, NULL, /* filter, filterarg */ 684 rsize, /* maxsize */ 685 1, /* nsegments */ 686 rsize, /* maxsegsize */ 687 0, /* flags */ 688 NULL, NULL, /* lockfunc, lockarg */ 689 &sc->chain_dmat)) { 690 device_printf(sc->mps_dev, "Cannot allocate chain DMA tag\n"); 691 return (ENOMEM); 692 } 693 if (bus_dmamem_alloc(sc->chain_dmat, (void **)&sc->chain_frames, 694 BUS_DMA_NOWAIT, &sc->chain_map)) { 695 device_printf(sc->mps_dev, "Cannot allocate chain memory\n"); 696 return (ENOMEM); 697 } 698 bzero(sc->chain_frames, rsize); 699 bus_dmamap_load(sc->chain_dmat, sc->chain_map, sc->chain_frames, rsize, 700 mps_memaddr_cb, &sc->chain_busaddr, 0); 701 702 rsize = MPS_SENSE_LEN * sc->num_reqs; 703 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 704 1, 0, /* algnmnt, boundary */ 705 BUS_SPACE_MAXADDR_32BIT,/* lowaddr */ 706 BUS_SPACE_MAXADDR, /* highaddr */ 707 NULL, NULL, /* filter, filterarg */ 708 rsize, /* maxsize */ 709 1, /* nsegments */ 710 rsize, /* maxsegsize */ 711 0, /* flags */ 712 NULL, NULL, /* lockfunc, lockarg */ 713 &sc->sense_dmat)) { 714 device_printf(sc->mps_dev, "Cannot allocate sense DMA tag\n"); 715 return (ENOMEM); 716 } 717 if (bus_dmamem_alloc(sc->sense_dmat, (void **)&sc->sense_frames, 718 BUS_DMA_NOWAIT, &sc->sense_map)) { 719 device_printf(sc->mps_dev, "Cannot allocate sense memory\n"); 720 return (ENOMEM); 721 } 722 bzero(sc->sense_frames, rsize); 723 bus_dmamap_load(sc->sense_dmat, sc->sense_map, sc->sense_frames, rsize, 724 mps_memaddr_cb, &sc->sense_busaddr, 0); 725 726 sc->chains = malloc(sizeof(struct mps_chain) * MPS_CHAIN_FRAMES, 727 M_MPT2, M_WAITOK | M_ZERO); 728 for (i = 0; i < MPS_CHAIN_FRAMES; i++) { 729 chain = &sc->chains[i]; 730 chain->chain = (MPI2_SGE_IO_UNION *)(sc->chain_frames + 731 i * sc->facts->IOCRequestFrameSize * 4); 732 chain->chain_busaddr = sc->chain_busaddr + 733 i * sc->facts->IOCRequestFrameSize * 4; 734 mps_free_chain(sc, chain); 735 } 736 737 /* XXX Need to pick a more precise value */ 738 nsegs = (MAXPHYS / PAGE_SIZE) + 1; 739 if (bus_dma_tag_create( sc->mps_parent_dmat, /* parent */ 740 1, 0, /* algnmnt, boundary */ 741 BUS_SPACE_MAXADDR, /* lowaddr */ 742 BUS_SPACE_MAXADDR, /* highaddr */ 743 NULL, NULL, /* filter, filterarg */ 744 BUS_SPACE_MAXSIZE_32BIT,/* maxsize */ 745 nsegs, /* nsegments */ 746 BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */ 747 BUS_DMA_ALLOCNOW, /* flags */ 748 busdma_lock_mutex, /* lockfunc */ 749 &sc->mps_mtx, /* lockarg */ 750 &sc->buffer_dmat)) { 751 device_printf(sc->mps_dev, "Cannot allocate sense DMA tag\n"); 752 return (ENOMEM); 753 } 754 755 /* 756 * SMID 0 cannot be used as a free command per the firmware spec. 757 * Just drop that command instead of risking accounting bugs. 758 */ 759 sc->commands = malloc(sizeof(struct mps_command) * sc->num_reqs, 760 M_MPT2, M_WAITOK | M_ZERO); 761 for (i = 1; i < sc->num_reqs; i++) { 762 cm = &sc->commands[i]; 763 cm->cm_req = sc->req_frames + 764 i * sc->facts->IOCRequestFrameSize * 4; 765 cm->cm_req_busaddr = sc->req_busaddr + 766 i * sc->facts->IOCRequestFrameSize * 4; 767 cm->cm_sense = &sc->sense_frames[i]; 768 cm->cm_sense_busaddr = sc->sense_busaddr + i * MPS_SENSE_LEN; 769 cm->cm_desc.Default.SMID = i; 770 cm->cm_sc = sc; 771 TAILQ_INIT(&cm->cm_chain_list); 772 callout_init(&cm->cm_callout, 1 /*MPSAFE*/); 773 774 /* XXX Is a failure here a critical problem? */ 775 if (bus_dmamap_create(sc->buffer_dmat, 0, &cm->cm_dmamap) == 0) 776 mps_free_command(sc, cm); 777 else { 778 sc->num_reqs = i; 779 break; 780 } 781 } 782 783 return (0); 784 } 785 786 static int 787 mps_init_queues(struct mps_softc *sc) 788 { 789 int i; 790 791 memset((uint8_t *)sc->post_queue, 0xff, sc->pqdepth * 8); 792 793 /* 794 * According to the spec, we need to use one less reply than we 795 * have space for on the queue. So sc->num_replies (the number we 796 * use) should be less than sc->fqdepth (allocated size). 797 */ 798 if (sc->num_replies >= sc->fqdepth) 799 return (EINVAL); 800 801 /* 802 * Initialize all of the free queue entries. 803 */ 804 for (i = 0; i < sc->fqdepth; i++) 805 sc->free_queue[i] = sc->reply_busaddr + (i * sc->facts->ReplyFrameSize * 4); 806 sc->replyfreeindex = sc->num_replies; 807 808 return (0); 809 } 810 811 int 812 mps_attach(struct mps_softc *sc) 813 { 814 int i, error; 815 char tmpstr[80], tmpstr2[80]; 816 817 /* 818 * Grab any tunable-set debug level so that tracing works as early 819 * as possible. 820 */ 821 snprintf(tmpstr, sizeof(tmpstr), "hw.mps.%d.debug_level", 822 device_get_unit(sc->mps_dev)); 823 TUNABLE_INT_FETCH(tmpstr, &sc->mps_debug); 824 snprintf(tmpstr, sizeof(tmpstr), "hw.mps.%d.allow_multiple_tm_cmds", 825 device_get_unit(sc->mps_dev)); 826 TUNABLE_INT_FETCH(tmpstr, &sc->allow_multiple_tm_cmds); 827 828 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 829 830 mtx_init(&sc->mps_mtx, "MPT2SAS lock", NULL, MTX_DEF); 831 callout_init_mtx(&sc->periodic, &sc->mps_mtx, 0); 832 TAILQ_INIT(&sc->event_list); 833 834 /* 835 * Setup the sysctl variable so the user can change the debug level 836 * on the fly. 837 */ 838 snprintf(tmpstr, sizeof(tmpstr), "MPS controller %d", 839 device_get_unit(sc->mps_dev)); 840 snprintf(tmpstr2, sizeof(tmpstr2), "%d", device_get_unit(sc->mps_dev)); 841 842 sysctl_ctx_init(&sc->sysctl_ctx); 843 sc->sysctl_tree = SYSCTL_ADD_NODE(&sc->sysctl_ctx, 844 SYSCTL_STATIC_CHILDREN(_hw_mps), OID_AUTO, tmpstr2, CTLFLAG_RD, 845 0, tmpstr); 846 if (sc->sysctl_tree == NULL) 847 return (ENOMEM); 848 849 SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 850 OID_AUTO, "debug_level", CTLFLAG_RW, &sc->mps_debug, 0, 851 "mps debug level"); 852 853 SYSCTL_ADD_UINT(&sc->sysctl_ctx, SYSCTL_CHILDREN(sc->sysctl_tree), 854 OID_AUTO, "allow_multiple_tm_cmds", CTLFLAG_RW, 855 &sc->allow_multiple_tm_cmds, 0, 856 "allow multiple simultaneous task management cmds"); 857 858 if ((error = mps_transition_ready(sc)) != 0) 859 return (error); 860 861 sc->facts = malloc(sizeof(MPI2_IOC_FACTS_REPLY), M_MPT2, 862 M_ZERO|M_NOWAIT); 863 if ((error = mps_get_iocfacts(sc, sc->facts)) != 0) 864 return (error); 865 866 mps_print_iocfacts(sc, sc->facts); 867 868 mps_printf(sc, "Firmware: %02d.%02d.%02d.%02d\n", 869 sc->facts->FWVersion.Struct.Major, 870 sc->facts->FWVersion.Struct.Minor, 871 sc->facts->FWVersion.Struct.Unit, 872 sc->facts->FWVersion.Struct.Dev); 873 mps_printf(sc, "IOCCapabilities: %b\n", sc->facts->IOCCapabilities, 874 "\20" "\3ScsiTaskFull" "\4DiagTrace" "\5SnapBuf" "\6ExtBuf" 875 "\7EEDP" "\10BiDirTarg" "\11Multicast" "\14TransRetry" "\15IR" 876 "\16EventReplay" "\17RaidAccel" "\20MSIXIndex" "\21HostDisc"); 877 878 /* 879 * If the chip doesn't support event replay then a hard reset will be 880 * required to trigger a full discovery. Do the reset here then 881 * retransition to Ready. A hard reset might have already been done, 882 * but it doesn't hurt to do it again. 883 */ 884 if ((sc->facts->IOCCapabilities & 885 MPI2_IOCFACTS_CAPABILITY_EVENT_REPLAY) == 0) { 886 mps_hard_reset(sc); 887 if ((error = mps_transition_ready(sc)) != 0) 888 return (error); 889 } 890 891 /* 892 * Size the queues. Since the reply queues always need one free entry, 893 * we'll just deduct one reply message here. 894 */ 895 sc->num_reqs = MIN(MPS_REQ_FRAMES, sc->facts->RequestCredit); 896 sc->num_replies = MIN(MPS_REPLY_FRAMES + MPS_EVT_REPLY_FRAMES, 897 sc->facts->MaxReplyDescriptorPostQueueDepth) - 1; 898 TAILQ_INIT(&sc->req_list); 899 TAILQ_INIT(&sc->chain_list); 900 TAILQ_INIT(&sc->tm_list); 901 902 if (((error = mps_alloc_queues(sc)) != 0) || 903 ((error = mps_alloc_replies(sc)) != 0) || 904 ((error = mps_alloc_requests(sc)) != 0)) { 905 mps_free(sc); 906 return (error); 907 } 908 909 if (((error = mps_init_queues(sc)) != 0) || 910 ((error = mps_transition_operational(sc)) != 0)) { 911 mps_free(sc); 912 return (error); 913 } 914 915 /* 916 * Finish the queue initialization. 917 * These are set here instead of in mps_init_queues() because the 918 * IOC resets these values during the state transition in 919 * mps_transition_operational(). The free index is set to 1 920 * because the corresponding index in the IOC is set to 0, and the 921 * IOC treats the queues as full if both are set to the same value. 922 * Hence the reason that the queue can't hold all of the possible 923 * replies. 924 */ 925 sc->replypostindex = 0; 926 mps_regwrite(sc, MPI2_REPLY_FREE_HOST_INDEX_OFFSET, sc->replyfreeindex); 927 mps_regwrite(sc, MPI2_REPLY_POST_HOST_INDEX_OFFSET, 0); 928 929 sc->pfacts = malloc(sizeof(MPI2_PORT_FACTS_REPLY) * 930 sc->facts->NumberOfPorts, M_MPT2, M_ZERO|M_WAITOK); 931 for (i = 0; i < sc->facts->NumberOfPorts; i++) { 932 if ((error = mps_get_portfacts(sc, &sc->pfacts[i], i)) != 0) { 933 mps_free(sc); 934 return (error); 935 } 936 mps_print_portfacts(sc, &sc->pfacts[i]); 937 } 938 939 /* Attach the subsystems so they can prepare their event masks. */ 940 /* XXX Should be dynamic so that IM/IR and user modules can attach */ 941 if (((error = mps_attach_log(sc)) != 0) || 942 ((error = mps_attach_sas(sc)) != 0) || 943 ((error = mps_attach_user(sc)) != 0)) { 944 mps_printf(sc, "%s failed to attach all subsystems: error %d\n", 945 __func__, error); 946 mps_free(sc); 947 return (error); 948 } 949 950 if ((error = mps_pci_setup_interrupts(sc)) != 0) { 951 mps_free(sc); 952 return (error); 953 } 954 955 /* Start the periodic watchdog check on the IOC Doorbell */ 956 mps_periodic(sc); 957 958 /* 959 * The portenable will kick off discovery events that will drive the 960 * rest of the initialization process. The CAM/SAS module will 961 * hold up the boot sequence until discovery is complete. 962 */ 963 sc->mps_ich.ich_func = mps_startup; 964 sc->mps_ich.ich_arg = sc; 965 if (config_intrhook_establish(&sc->mps_ich) != 0) { 966 mps_dprint(sc, MPS_FAULT, "Cannot establish MPS config hook\n"); 967 error = EINVAL; 968 } 969 970 return (error); 971 } 972 973 static void 974 mps_startup(void *arg) 975 { 976 struct mps_softc *sc; 977 978 sc = (struct mps_softc *)arg; 979 980 mps_lock(sc); 981 mps_unmask_intr(sc); 982 mps_send_portenable(sc); 983 mps_unlock(sc); 984 } 985 986 /* Periodic watchdog. Is called with the driver lock already held. */ 987 static void 988 mps_periodic(void *arg) 989 { 990 struct mps_softc *sc; 991 uint32_t db; 992 993 sc = (struct mps_softc *)arg; 994 if (sc->mps_flags & MPS_FLAGS_SHUTDOWN) 995 return; 996 997 db = mps_regread(sc, MPI2_DOORBELL_OFFSET); 998 if ((db & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 999 device_printf(sc->mps_dev, "IOC Fault 0x%08x, Resetting\n", db); 1000 /* XXX Need to broaden this to re-initialize the chip */ 1001 mps_hard_reset(sc); 1002 db = mps_regread(sc, MPI2_DOORBELL_OFFSET); 1003 if ((db & MPI2_IOC_STATE_MASK) == MPI2_IOC_STATE_FAULT) { 1004 device_printf(sc->mps_dev, "Second IOC Fault 0x%08x, " 1005 "Giving up!\n", db); 1006 return; 1007 } 1008 } 1009 1010 callout_reset(&sc->periodic, MPS_PERIODIC_DELAY * hz, mps_periodic, sc); 1011 } 1012 1013 static void 1014 mps_startup_complete(struct mps_softc *sc, struct mps_command *cm) 1015 { 1016 MPI2_PORT_ENABLE_REPLY *reply; 1017 1018 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1019 1020 reply = (MPI2_PORT_ENABLE_REPLY *)cm->cm_reply; 1021 if ((reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) 1022 mps_dprint(sc, MPS_FAULT, "Portenable failed\n"); 1023 1024 mps_free_command(sc, cm); 1025 config_intrhook_disestablish(&sc->mps_ich); 1026 1027 } 1028 1029 static void 1030 mps_log_evt_handler(struct mps_softc *sc, uintptr_t data, 1031 MPI2_EVENT_NOTIFICATION_REPLY *event) 1032 { 1033 MPI2_EVENT_DATA_LOG_ENTRY_ADDED *entry; 1034 1035 mps_print_event(sc, event); 1036 1037 switch (event->Event) { 1038 case MPI2_EVENT_LOG_DATA: 1039 device_printf(sc->mps_dev, "MPI2_EVENT_LOG_DATA:\n"); 1040 hexdump(event->EventData, event->EventDataLength, NULL, 0); 1041 break; 1042 case MPI2_EVENT_LOG_ENTRY_ADDED: 1043 entry = (MPI2_EVENT_DATA_LOG_ENTRY_ADDED *)event->EventData; 1044 mps_dprint(sc, MPS_INFO, "MPI2_EVENT_LOG_ENTRY_ADDED event " 1045 "0x%x Sequence %d:\n", entry->LogEntryQualifier, 1046 entry->LogSequence); 1047 break; 1048 default: 1049 break; 1050 } 1051 return; 1052 } 1053 1054 static int 1055 mps_attach_log(struct mps_softc *sc) 1056 { 1057 uint8_t events[16]; 1058 1059 bzero(events, 16); 1060 setbit(events, MPI2_EVENT_LOG_DATA); 1061 setbit(events, MPI2_EVENT_LOG_ENTRY_ADDED); 1062 1063 mps_register_events(sc, events, mps_log_evt_handler, NULL, 1064 &sc->mps_log_eh); 1065 1066 return (0); 1067 } 1068 1069 static int 1070 mps_detach_log(struct mps_softc *sc) 1071 { 1072 1073 if (sc->mps_log_eh != NULL) 1074 mps_deregister_events(sc, sc->mps_log_eh); 1075 return (0); 1076 } 1077 1078 /* 1079 * Free all of the driver resources and detach submodules. Should be called 1080 * without the lock held. 1081 */ 1082 int 1083 mps_free(struct mps_softc *sc) 1084 { 1085 struct mps_command *cm; 1086 int i, error; 1087 1088 /* Turn off the watchdog */ 1089 mps_lock(sc); 1090 sc->mps_flags |= MPS_FLAGS_SHUTDOWN; 1091 mps_unlock(sc); 1092 /* Lock must not be held for this */ 1093 callout_drain(&sc->periodic); 1094 1095 if (((error = mps_detach_log(sc)) != 0) || 1096 ((error = mps_detach_sas(sc)) != 0)) 1097 return (error); 1098 1099 /* Put the IOC back in the READY state. */ 1100 mps_lock(sc); 1101 if ((error = mps_send_mur(sc)) != 0) { 1102 mps_unlock(sc); 1103 return (error); 1104 } 1105 mps_unlock(sc); 1106 1107 if (sc->facts != NULL) 1108 free(sc->facts, M_MPT2); 1109 1110 if (sc->pfacts != NULL) 1111 free(sc->pfacts, M_MPT2); 1112 1113 if (sc->post_busaddr != 0) 1114 bus_dmamap_unload(sc->queues_dmat, sc->queues_map); 1115 if (sc->post_queue != NULL) 1116 bus_dmamem_free(sc->queues_dmat, sc->post_queue, 1117 sc->queues_map); 1118 if (sc->queues_dmat != NULL) 1119 bus_dma_tag_destroy(sc->queues_dmat); 1120 1121 if (sc->chain_busaddr != 0) 1122 bus_dmamap_unload(sc->chain_dmat, sc->chain_map); 1123 if (sc->chain_frames != NULL) 1124 bus_dmamem_free(sc->chain_dmat, sc->chain_frames,sc->chain_map); 1125 if (sc->chain_dmat != NULL) 1126 bus_dma_tag_destroy(sc->chain_dmat); 1127 1128 if (sc->sense_busaddr != 0) 1129 bus_dmamap_unload(sc->sense_dmat, sc->sense_map); 1130 if (sc->sense_frames != NULL) 1131 bus_dmamem_free(sc->sense_dmat, sc->sense_frames,sc->sense_map); 1132 if (sc->sense_dmat != NULL) 1133 bus_dma_tag_destroy(sc->sense_dmat); 1134 1135 if (sc->reply_busaddr != 0) 1136 bus_dmamap_unload(sc->reply_dmat, sc->reply_map); 1137 if (sc->reply_frames != NULL) 1138 bus_dmamem_free(sc->reply_dmat, sc->reply_frames,sc->reply_map); 1139 if (sc->reply_dmat != NULL) 1140 bus_dma_tag_destroy(sc->reply_dmat); 1141 1142 if (sc->req_busaddr != 0) 1143 bus_dmamap_unload(sc->req_dmat, sc->req_map); 1144 if (sc->req_frames != NULL) 1145 bus_dmamem_free(sc->req_dmat, sc->req_frames, sc->req_map); 1146 if (sc->req_dmat != NULL) 1147 bus_dma_tag_destroy(sc->req_dmat); 1148 1149 if (sc->chains != NULL) 1150 free(sc->chains, M_MPT2); 1151 if (sc->commands != NULL) { 1152 for (i = 1; i < sc->num_reqs; i++) { 1153 cm = &sc->commands[i]; 1154 bus_dmamap_destroy(sc->buffer_dmat, cm->cm_dmamap); 1155 } 1156 free(sc->commands, M_MPT2); 1157 } 1158 if (sc->buffer_dmat != NULL) 1159 bus_dma_tag_destroy(sc->buffer_dmat); 1160 1161 if (sc->sysctl_tree != NULL) 1162 sysctl_ctx_free(&sc->sysctl_ctx); 1163 1164 mtx_destroy(&sc->mps_mtx); 1165 1166 return (0); 1167 } 1168 1169 void 1170 mps_intr(void *data) 1171 { 1172 struct mps_softc *sc; 1173 uint32_t status; 1174 1175 sc = (struct mps_softc *)data; 1176 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1177 1178 /* 1179 * Check interrupt status register to flush the bus. This is 1180 * needed for both INTx interrupts and driver-driven polling 1181 */ 1182 status = mps_regread(sc, MPI2_HOST_INTERRUPT_STATUS_OFFSET); 1183 if ((status & MPI2_HIS_REPLY_DESCRIPTOR_INTERRUPT) == 0) 1184 return; 1185 1186 mps_lock(sc); 1187 mps_intr_locked(data); 1188 mps_unlock(sc); 1189 return; 1190 } 1191 1192 /* 1193 * In theory, MSI/MSIX interrupts shouldn't need to read any registers on the 1194 * chip. Hopefully this theory is correct. 1195 */ 1196 void 1197 mps_intr_msi(void *data) 1198 { 1199 struct mps_softc *sc; 1200 1201 sc = (struct mps_softc *)data; 1202 mps_lock(sc); 1203 mps_intr_locked(data); 1204 mps_unlock(sc); 1205 return; 1206 } 1207 1208 /* 1209 * The locking is overly broad and simplistic, but easy to deal with for now. 1210 */ 1211 void 1212 mps_intr_locked(void *data) 1213 { 1214 MPI2_REPLY_DESCRIPTORS_UNION *desc; 1215 struct mps_softc *sc; 1216 struct mps_command *cm = NULL; 1217 uint8_t flags; 1218 u_int pq; 1219 1220 sc = (struct mps_softc *)data; 1221 1222 pq = sc->replypostindex; 1223 1224 for ( ;; ) { 1225 cm = NULL; 1226 desc = &sc->post_queue[pq]; 1227 flags = desc->Default.ReplyFlags & 1228 MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; 1229 if ((flags == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) 1230 || (desc->Words.High == 0xffffffff)) 1231 break; 1232 1233 switch (flags) { 1234 case MPI2_RPY_DESCRIPT_FLAGS_SCSI_IO_SUCCESS: 1235 cm = &sc->commands[desc->SCSIIOSuccess.SMID]; 1236 cm->cm_reply = NULL; 1237 break; 1238 case MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY: 1239 { 1240 uint32_t baddr; 1241 uint8_t *reply; 1242 1243 /* 1244 * Re-compose the reply address from the address 1245 * sent back from the chip. The ReplyFrameAddress 1246 * is the lower 32 bits of the physical address of 1247 * particular reply frame. Convert that address to 1248 * host format, and then use that to provide the 1249 * offset against the virtual address base 1250 * (sc->reply_frames). 1251 */ 1252 baddr = le32toh(desc->AddressReply.ReplyFrameAddress); 1253 reply = sc->reply_frames + 1254 (baddr - ((uint32_t)sc->reply_busaddr)); 1255 /* 1256 * Make sure the reply we got back is in a valid 1257 * range. If not, go ahead and panic here, since 1258 * we'll probably panic as soon as we deference the 1259 * reply pointer anyway. 1260 */ 1261 if ((reply < sc->reply_frames) 1262 || (reply > (sc->reply_frames + 1263 (sc->fqdepth * sc->facts->ReplyFrameSize * 4)))) { 1264 printf("%s: WARNING: reply %p out of range!\n", 1265 __func__, reply); 1266 printf("%s: reply_frames %p, fqdepth %d, " 1267 "frame size %d\n", __func__, 1268 sc->reply_frames, sc->fqdepth, 1269 sc->facts->ReplyFrameSize * 4); 1270 printf("%s: baddr %#x,\n", __func__, baddr); 1271 panic("Reply address out of range"); 1272 } 1273 if (desc->AddressReply.SMID == 0) { 1274 mps_dispatch_event(sc, baddr, 1275 (MPI2_EVENT_NOTIFICATION_REPLY *) reply); 1276 } else { 1277 cm = &sc->commands[desc->AddressReply.SMID]; 1278 cm->cm_reply = reply; 1279 cm->cm_reply_data = 1280 desc->AddressReply.ReplyFrameAddress; 1281 } 1282 break; 1283 } 1284 case MPI2_RPY_DESCRIPT_FLAGS_TARGETASSIST_SUCCESS: 1285 case MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER: 1286 case MPI2_RPY_DESCRIPT_FLAGS_RAID_ACCELERATOR_SUCCESS: 1287 default: 1288 /* Unhandled */ 1289 device_printf(sc->mps_dev, "Unhandled reply 0x%x\n", 1290 desc->Default.ReplyFlags); 1291 cm = NULL; 1292 break; 1293 } 1294 1295 if (cm != NULL) { 1296 if (cm->cm_flags & MPS_CM_FLAGS_POLLED) 1297 cm->cm_flags |= MPS_CM_FLAGS_COMPLETE; 1298 1299 if (cm->cm_complete != NULL) 1300 cm->cm_complete(sc, cm); 1301 1302 if (cm->cm_flags & MPS_CM_FLAGS_WAKEUP) 1303 wakeup(cm); 1304 } 1305 1306 desc->Words.Low = 0xffffffff; 1307 desc->Words.High = 0xffffffff; 1308 if (++pq >= sc->pqdepth) 1309 pq = 0; 1310 } 1311 1312 if (pq != sc->replypostindex) { 1313 mps_dprint(sc, MPS_INFO, "writing postindex %d\n", pq); 1314 mps_regwrite(sc, MPI2_REPLY_POST_HOST_INDEX_OFFSET, pq); 1315 sc->replypostindex = pq; 1316 } 1317 1318 return; 1319 } 1320 1321 static void 1322 mps_dispatch_event(struct mps_softc *sc, uintptr_t data, 1323 MPI2_EVENT_NOTIFICATION_REPLY *reply) 1324 { 1325 struct mps_event_handle *eh; 1326 int event, handled = 0; 1327 1328 event = reply->Event; 1329 TAILQ_FOREACH(eh, &sc->event_list, eh_list) { 1330 if (isset(eh->mask, event)) { 1331 eh->callback(sc, data, reply); 1332 handled++; 1333 } 1334 } 1335 1336 if (handled == 0) 1337 device_printf(sc->mps_dev, "Unhandled event 0x%x\n", event); 1338 } 1339 1340 /* 1341 * For both register_events and update_events, the caller supplies a bitmap 1342 * of events that it _wants_. These functions then turn that into a bitmask 1343 * suitable for the controller. 1344 */ 1345 int 1346 mps_register_events(struct mps_softc *sc, uint8_t *mask, 1347 mps_evt_callback_t *cb, void *data, struct mps_event_handle **handle) 1348 { 1349 struct mps_event_handle *eh; 1350 int error = 0; 1351 1352 eh = malloc(sizeof(struct mps_event_handle), M_MPT2, M_WAITOK|M_ZERO); 1353 eh->callback = cb; 1354 eh->data = data; 1355 TAILQ_INSERT_TAIL(&sc->event_list, eh, eh_list); 1356 if (mask != NULL) 1357 error = mps_update_events(sc, eh, mask); 1358 *handle = eh; 1359 1360 return (error); 1361 } 1362 1363 int 1364 mps_update_events(struct mps_softc *sc, struct mps_event_handle *handle, 1365 uint8_t *mask) 1366 { 1367 MPI2_EVENT_NOTIFICATION_REQUEST *evtreq; 1368 MPI2_EVENT_NOTIFICATION_REPLY *reply; 1369 struct mps_command *cm; 1370 struct mps_event_handle *eh; 1371 int error, i; 1372 1373 mps_dprint(sc, MPS_TRACE, "%s\n", __func__); 1374 1375 if ((mask != NULL) && (handle != NULL)) 1376 bcopy(mask, &handle->mask[0], 16); 1377 memset(sc->event_mask, 0xff, 16); 1378 1379 TAILQ_FOREACH(eh, &sc->event_list, eh_list) { 1380 for (i = 0; i < 16; i++) 1381 sc->event_mask[i] &= ~eh->mask[i]; 1382 } 1383 1384 if ((cm = mps_alloc_command(sc)) == NULL) 1385 return (EBUSY); 1386 evtreq = (MPI2_EVENT_NOTIFICATION_REQUEST *)cm->cm_req; 1387 evtreq->Function = MPI2_FUNCTION_EVENT_NOTIFICATION; 1388 evtreq->MsgFlags = 0; 1389 evtreq->SASBroadcastPrimitiveMasks = 0; 1390 #ifdef MPS_DEBUG_ALL_EVENTS 1391 { 1392 u_char fullmask[16]; 1393 memset(fullmask, 0x00, 16); 1394 bcopy(fullmask, (uint8_t *)&evtreq->EventMasks, 16); 1395 } 1396 #else 1397 bcopy(sc->event_mask, (uint8_t *)&evtreq->EventMasks, 16); 1398 #endif 1399 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1400 cm->cm_data = NULL; 1401 1402 error = mps_request_polled(sc, cm); 1403 reply = (MPI2_EVENT_NOTIFICATION_REPLY *)cm->cm_reply; 1404 if ((reply->IOCStatus & MPI2_IOCSTATUS_MASK) != MPI2_IOCSTATUS_SUCCESS) 1405 error = ENXIO; 1406 mps_print_event(sc, reply); 1407 1408 mps_free_command(sc, cm); 1409 return (error); 1410 } 1411 1412 int 1413 mps_deregister_events(struct mps_softc *sc, struct mps_event_handle *handle) 1414 { 1415 1416 TAILQ_REMOVE(&sc->event_list, handle, eh_list); 1417 free(handle, M_MPT2); 1418 return (mps_update_events(sc, NULL, NULL)); 1419 } 1420 1421 /* 1422 * Add a chain element as the next SGE for the specified command. 1423 * Reset cm_sge and cm_sgesize to indicate all the available space. 1424 */ 1425 static int 1426 mps_add_chain(struct mps_command *cm) 1427 { 1428 MPI2_SGE_CHAIN32 *sgc; 1429 struct mps_chain *chain; 1430 int space; 1431 1432 if (cm->cm_sglsize < MPS_SGC_SIZE) 1433 panic("MPS: Need SGE Error Code\n"); 1434 1435 chain = mps_alloc_chain(cm->cm_sc); 1436 if (chain == NULL) 1437 return (ENOBUFS); 1438 1439 space = (int)cm->cm_sc->facts->IOCRequestFrameSize * 4; 1440 1441 /* 1442 * Note: a double-linked list is used to make it easier to 1443 * walk for debugging. 1444 */ 1445 TAILQ_INSERT_TAIL(&cm->cm_chain_list, chain, chain_link); 1446 1447 sgc = (MPI2_SGE_CHAIN32 *)&cm->cm_sge->MpiChain; 1448 sgc->Length = space; 1449 sgc->NextChainOffset = 0; 1450 sgc->Flags = MPI2_SGE_FLAGS_CHAIN_ELEMENT; 1451 sgc->Address = chain->chain_busaddr; 1452 1453 cm->cm_sge = (MPI2_SGE_IO_UNION *)&chain->chain->MpiSimple; 1454 cm->cm_sglsize = space; 1455 return (0); 1456 } 1457 1458 /* 1459 * Add one scatter-gather element (chain, simple, transaction context) 1460 * to the scatter-gather list for a command. Maintain cm_sglsize and 1461 * cm_sge as the remaining size and pointer to the next SGE to fill 1462 * in, respectively. 1463 */ 1464 int 1465 mps_push_sge(struct mps_command *cm, void *sgep, size_t len, int segsleft) 1466 { 1467 MPI2_SGE_TRANSACTION_UNION *tc = sgep; 1468 MPI2_SGE_SIMPLE64 *sge = sgep; 1469 int error, type; 1470 1471 type = (tc->Flags & MPI2_SGE_FLAGS_ELEMENT_MASK); 1472 1473 #ifdef INVARIANTS 1474 switch (type) { 1475 case MPI2_SGE_FLAGS_TRANSACTION_ELEMENT: { 1476 if (len != tc->DetailsLength + 4) 1477 panic("TC %p length %u or %zu?", tc, 1478 tc->DetailsLength + 4, len); 1479 } 1480 break; 1481 case MPI2_SGE_FLAGS_CHAIN_ELEMENT: 1482 /* Driver only uses 32-bit chain elements */ 1483 if (len != MPS_SGC_SIZE) 1484 panic("CHAIN %p length %u or %zu?", sgep, 1485 MPS_SGC_SIZE, len); 1486 break; 1487 case MPI2_SGE_FLAGS_SIMPLE_ELEMENT: 1488 /* Driver only uses 64-bit SGE simple elements */ 1489 sge = sgep; 1490 if (len != MPS_SGE64_SIZE) 1491 panic("SGE simple %p length %u or %zu?", sge, 1492 MPS_SGE64_SIZE, len); 1493 if (((sge->FlagsLength >> MPI2_SGE_FLAGS_SHIFT) & 1494 MPI2_SGE_FLAGS_ADDRESS_SIZE) == 0) 1495 panic("SGE simple %p flags %02x not marked 64-bit?", 1496 sge, sge->FlagsLength >> MPI2_SGE_FLAGS_SHIFT); 1497 1498 break; 1499 default: 1500 panic("Unexpected SGE %p, flags %02x", tc, tc->Flags); 1501 } 1502 #endif 1503 1504 /* 1505 * case 1: 1 more segment, enough room for it 1506 * case 2: 2 more segments, enough room for both 1507 * case 3: >=2 more segments, only enough room for 1 and a chain 1508 * case 4: >=1 more segment, enough room for only a chain 1509 * case 5: >=1 more segment, no room for anything (error) 1510 */ 1511 1512 /* 1513 * There should be room for at least a chain element, or this 1514 * code is buggy. Case (5). 1515 */ 1516 if (cm->cm_sglsize < MPS_SGC_SIZE) 1517 panic("MPS: Need SGE Error Code\n"); 1518 1519 if (segsleft >= 2 && 1520 cm->cm_sglsize < len + MPS_SGC_SIZE + MPS_SGE64_SIZE) { 1521 /* 1522 * There are 2 or more segments left to add, and only 1523 * enough room for 1 and a chain. Case (3). 1524 * 1525 * Mark as last element in this chain if necessary. 1526 */ 1527 if (type == MPI2_SGE_FLAGS_SIMPLE_ELEMENT) { 1528 sge->FlagsLength |= 1529 (MPI2_SGE_FLAGS_LAST_ELEMENT << MPI2_SGE_FLAGS_SHIFT); 1530 } 1531 1532 /* 1533 * Add the item then a chain. Do the chain now, 1534 * rather than on the next iteration, to simplify 1535 * understanding the code. 1536 */ 1537 cm->cm_sglsize -= len; 1538 bcopy(sgep, cm->cm_sge, len); 1539 cm->cm_sge = (MPI2_SGE_IO_UNION *)((uintptr_t)cm->cm_sge + len); 1540 return (mps_add_chain(cm)); 1541 } 1542 1543 if (segsleft >= 1 && cm->cm_sglsize < len + MPS_SGC_SIZE) { 1544 /* 1545 * 1 or more segment, enough room for only a chain. 1546 * Hope the previous element wasn't a Simple entry 1547 * that needed to be marked with 1548 * MPI2_SGE_FLAGS_LAST_ELEMENT. Case (4). 1549 */ 1550 if ((error = mps_add_chain(cm)) != 0) 1551 return (error); 1552 } 1553 1554 #ifdef INVARIANTS 1555 /* Case 1: 1 more segment, enough room for it. */ 1556 if (segsleft == 1 && cm->cm_sglsize < len) 1557 panic("1 seg left and no room? %u versus %zu", 1558 cm->cm_sglsize, len); 1559 1560 /* Case 2: 2 more segments, enough room for both */ 1561 if (segsleft == 2 && cm->cm_sglsize < len + MPS_SGE64_SIZE) 1562 panic("2 segs left and no room? %u versus %zu", 1563 cm->cm_sglsize, len); 1564 #endif 1565 1566 if (segsleft == 1 && type == MPI2_SGE_FLAGS_SIMPLE_ELEMENT) { 1567 /* 1568 * Last element of the last segment of the entire 1569 * buffer. 1570 */ 1571 sge->FlagsLength |= ((MPI2_SGE_FLAGS_LAST_ELEMENT | 1572 MPI2_SGE_FLAGS_END_OF_BUFFER | 1573 MPI2_SGE_FLAGS_END_OF_LIST) << MPI2_SGE_FLAGS_SHIFT); 1574 } 1575 1576 cm->cm_sglsize -= len; 1577 bcopy(sgep, cm->cm_sge, len); 1578 cm->cm_sge = (MPI2_SGE_IO_UNION *)((uintptr_t)cm->cm_sge + len); 1579 return (0); 1580 } 1581 1582 /* 1583 * Add one dma segment to the scatter-gather list for a command. 1584 */ 1585 int 1586 mps_add_dmaseg(struct mps_command *cm, vm_paddr_t pa, size_t len, u_int flags, 1587 int segsleft) 1588 { 1589 MPI2_SGE_SIMPLE64 sge; 1590 1591 /* 1592 * This driver always uses 64-bit address elements for 1593 * simplicity. 1594 */ 1595 flags |= MPI2_SGE_FLAGS_SIMPLE_ELEMENT | MPI2_SGE_FLAGS_ADDRESS_SIZE; 1596 sge.FlagsLength = len | (flags << MPI2_SGE_FLAGS_SHIFT); 1597 mps_from_u64(pa, &sge.Address); 1598 1599 return (mps_push_sge(cm, &sge, sizeof sge, segsleft)); 1600 } 1601 1602 static void 1603 mps_data_cb(void *arg, bus_dma_segment_t *segs, int nsegs, int error) 1604 { 1605 struct mps_softc *sc; 1606 struct mps_command *cm; 1607 u_int i, dir, sflags; 1608 1609 cm = (struct mps_command *)arg; 1610 sc = cm->cm_sc; 1611 1612 /* 1613 * In this case, just print out a warning and let the chip tell the 1614 * user they did the wrong thing. 1615 */ 1616 if ((cm->cm_max_segs != 0) && (nsegs > cm->cm_max_segs)) { 1617 mps_printf(sc, "%s: warning: busdma returned %d segments, " 1618 "more than the %d allowed\n", __func__, nsegs, 1619 cm->cm_max_segs); 1620 } 1621 1622 /* 1623 * Set up DMA direction flags. Note that we don't support 1624 * bi-directional transfers, with the exception of SMP passthrough. 1625 */ 1626 sflags = 0; 1627 if (cm->cm_flags & MPS_CM_FLAGS_SMP_PASS) { 1628 /* 1629 * We have to add a special case for SMP passthrough, there 1630 * is no easy way to generically handle it. The first 1631 * S/G element is used for the command (therefore the 1632 * direction bit needs to be set). The second one is used 1633 * for the reply. We'll leave it to the caller to make 1634 * sure we only have two buffers. 1635 */ 1636 /* 1637 * Even though the busdma man page says it doesn't make 1638 * sense to have both direction flags, it does in this case. 1639 * We have one s/g element being accessed in each direction. 1640 */ 1641 dir = BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD; 1642 1643 /* 1644 * Set the direction flag on the first buffer in the SMP 1645 * passthrough request. We'll clear it for the second one. 1646 */ 1647 sflags |= MPI2_SGE_FLAGS_DIRECTION | 1648 MPI2_SGE_FLAGS_END_OF_BUFFER; 1649 } else if (cm->cm_flags & MPS_CM_FLAGS_DATAOUT) { 1650 sflags |= MPI2_SGE_FLAGS_DIRECTION; 1651 dir = BUS_DMASYNC_PREWRITE; 1652 } else 1653 dir = BUS_DMASYNC_PREREAD; 1654 1655 for (i = 0; i < nsegs; i++) { 1656 if ((cm->cm_flags & MPS_CM_FLAGS_SMP_PASS) 1657 && (i != 0)) { 1658 sflags &= ~MPI2_SGE_FLAGS_DIRECTION; 1659 } 1660 error = mps_add_dmaseg(cm, segs[i].ds_addr, segs[i].ds_len, 1661 sflags, nsegs - i); 1662 if (error != 0) { 1663 /* Resource shortage, roll back! */ 1664 mps_printf(sc, "out of chain frames\n"); 1665 return; 1666 } 1667 } 1668 1669 bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, dir); 1670 mps_enqueue_request(sc, cm); 1671 1672 return; 1673 } 1674 1675 static void 1676 mps_data_cb2(void *arg, bus_dma_segment_t *segs, int nsegs, bus_size_t mapsize, 1677 int error) 1678 { 1679 mps_data_cb(arg, segs, nsegs, error); 1680 } 1681 1682 /* 1683 * Note that the only error path here is from bus_dmamap_load(), which can 1684 * return EINPROGRESS if it is waiting for resources. 1685 */ 1686 int 1687 mps_map_command(struct mps_softc *sc, struct mps_command *cm) 1688 { 1689 MPI2_SGE_SIMPLE32 *sge; 1690 int error = 0; 1691 1692 if (cm->cm_flags & MPS_CM_FLAGS_USE_UIO) { 1693 error = bus_dmamap_load_uio(sc->buffer_dmat, cm->cm_dmamap, 1694 &cm->cm_uio, mps_data_cb2, cm, 0); 1695 } else if ((cm->cm_data != NULL) && (cm->cm_length != 0)) { 1696 error = bus_dmamap_load(sc->buffer_dmat, cm->cm_dmamap, 1697 cm->cm_data, cm->cm_length, mps_data_cb, cm, 0); 1698 } else { 1699 /* Add a zero-length element as needed */ 1700 if (cm->cm_sge != NULL) { 1701 sge = (MPI2_SGE_SIMPLE32 *)cm->cm_sge; 1702 sge->FlagsLength = (MPI2_SGE_FLAGS_LAST_ELEMENT | 1703 MPI2_SGE_FLAGS_END_OF_BUFFER | 1704 MPI2_SGE_FLAGS_END_OF_LIST | 1705 MPI2_SGE_FLAGS_SIMPLE_ELEMENT) << 1706 MPI2_SGE_FLAGS_SHIFT; 1707 sge->Address = 0; 1708 } 1709 mps_enqueue_request(sc, cm); 1710 } 1711 1712 return (error); 1713 } 1714 1715 /* 1716 * The MPT driver had a verbose interface for config pages. In this driver, 1717 * reduce it to much simplier terms, similar to the Linux driver. 1718 */ 1719 int 1720 mps_read_config_page(struct mps_softc *sc, struct mps_config_params *params) 1721 { 1722 MPI2_CONFIG_REQUEST *req; 1723 struct mps_command *cm; 1724 int error; 1725 1726 if (sc->mps_flags & MPS_FLAGS_BUSY) { 1727 return (EBUSY); 1728 } 1729 1730 cm = mps_alloc_command(sc); 1731 if (cm == NULL) { 1732 return (EBUSY); 1733 } 1734 1735 req = (MPI2_CONFIG_REQUEST *)cm->cm_req; 1736 req->Function = MPI2_FUNCTION_CONFIG; 1737 req->Action = params->action; 1738 req->SGLFlags = 0; 1739 req->ChainOffset = 0; 1740 req->PageAddress = params->page_address; 1741 if (params->hdr.Ext.ExtPageType != 0) { 1742 MPI2_CONFIG_EXTENDED_PAGE_HEADER *hdr; 1743 1744 hdr = ¶ms->hdr.Ext; 1745 req->ExtPageType = hdr->ExtPageType; 1746 req->ExtPageLength = hdr->ExtPageLength; 1747 req->Header.PageType = MPI2_CONFIG_PAGETYPE_EXTENDED; 1748 req->Header.PageLength = 0; /* Must be set to zero */ 1749 req->Header.PageNumber = hdr->PageNumber; 1750 req->Header.PageVersion = hdr->PageVersion; 1751 } else { 1752 MPI2_CONFIG_PAGE_HEADER *hdr; 1753 1754 hdr = ¶ms->hdr.Struct; 1755 req->Header.PageType = hdr->PageType; 1756 req->Header.PageNumber = hdr->PageNumber; 1757 req->Header.PageLength = hdr->PageLength; 1758 req->Header.PageVersion = hdr->PageVersion; 1759 } 1760 1761 cm->cm_data = params->buffer; 1762 cm->cm_length = params->length; 1763 cm->cm_sge = &req->PageBufferSGE; 1764 cm->cm_sglsize = sizeof(MPI2_SGE_IO_UNION); 1765 cm->cm_flags = MPS_CM_FLAGS_SGE_SIMPLE | MPS_CM_FLAGS_DATAIN; 1766 cm->cm_desc.Default.RequestFlags = MPI2_REQ_DESCRIPT_FLAGS_DEFAULT_TYPE; 1767 1768 cm->cm_complete_data = params; 1769 if (params->callback != NULL) { 1770 cm->cm_complete = mps_config_complete; 1771 return (mps_map_command(sc, cm)); 1772 } else { 1773 cm->cm_complete = NULL; 1774 cm->cm_flags |= MPS_CM_FLAGS_WAKEUP; 1775 if ((error = mps_map_command(sc, cm)) != 0) 1776 return (error); 1777 msleep(cm, &sc->mps_mtx, 0, "mpswait", 0); 1778 mps_config_complete(sc, cm); 1779 } 1780 1781 return (0); 1782 } 1783 1784 int 1785 mps_write_config_page(struct mps_softc *sc, struct mps_config_params *params) 1786 { 1787 return (EINVAL); 1788 } 1789 1790 static void 1791 mps_config_complete(struct mps_softc *sc, struct mps_command *cm) 1792 { 1793 MPI2_CONFIG_REPLY *reply; 1794 struct mps_config_params *params; 1795 1796 params = cm->cm_complete_data; 1797 1798 if (cm->cm_data != NULL) { 1799 bus_dmamap_sync(sc->buffer_dmat, cm->cm_dmamap, 1800 BUS_DMASYNC_POSTREAD); 1801 bus_dmamap_unload(sc->buffer_dmat, cm->cm_dmamap); 1802 } 1803 1804 reply = (MPI2_CONFIG_REPLY *)cm->cm_reply; 1805 params->status = reply->IOCStatus; 1806 if (params->hdr.Ext.ExtPageType != 0) { 1807 params->hdr.Ext.ExtPageType = reply->ExtPageType; 1808 params->hdr.Ext.ExtPageLength = reply->ExtPageLength; 1809 } else { 1810 params->hdr.Struct.PageType = reply->Header.PageType; 1811 params->hdr.Struct.PageNumber = reply->Header.PageNumber; 1812 params->hdr.Struct.PageLength = reply->Header.PageLength; 1813 params->hdr.Struct.PageVersion = reply->Header.PageVersion; 1814 } 1815 1816 mps_free_command(sc, cm); 1817 if (params->callback != NULL) 1818 params->callback(sc, params); 1819 1820 return; 1821 } 1822