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