Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / disk / mpt / mpt.c
CommitLineData
984263bc
MD
1/* $FreeBSD: src/sys/dev/mpt/mpt.c,v 1.3.2.3 2002/09/24 21:37:24 mjacob Exp $ */
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->request_pool[req->index]) {
231 panic("mpt_free_request bad req ptr\n");
232 return;
233 }
234 req->sequence = 0;
235 req->ccb = NULL;
236 req->debug = REQ_FREE;
237 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
238}
239
240/* Get a command buffer from the free queue */
241request_t *
242mpt_get_request(mpt_softc_t *mpt)
243{
244 request_t *req;
245 req = SLIST_FIRST(&mpt->request_free_list);
246 if (req != NULL) {
247 if (req != &mpt->request_pool[req->index]) {
248 panic("mpt_get_request: corrupted request free list\n");
249 }
250 if (req->ccb != NULL) {
251 panic("mpt_get_request: corrupted request free list (ccb)\n");
252 }
253 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
254 req->debug = REQ_IN_PROGRESS;
255 }
256 return req;
257}
258
259/* Pass the command to the IOC */
260void
261mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
262{
263 req->sequence = mpt->sequence++;
264 if (mpt->verbose > 1) {
265 u_int32_t *pReq;
266 pReq = req->req_vbuf;
267 device_printf(mpt->dev, "Send Request %d (0x%lx):\n",
268 req->index, (long) req->req_pbuf);
269 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
270 pReq[0], pReq[1], pReq[2], pReq[3]);
271 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
272 pReq[4], pReq[5], pReq[6], pReq[7]);
273 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
274 pReq[8], pReq[9], pReq[10], pReq[11]);
275 device_printf(mpt->dev, "%08X %08X %08X %08X\n",
276 pReq[12], pReq[13], pReq[14], pReq[15]);
277 }
278 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
279 BUS_DMASYNC_PREWRITE);
280 req->debug = REQ_ON_CHIP;
281 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
282}
283
284/*
285 * Give the reply buffer back to the IOC after we have
286 * finished processing it.
287 */
288void
289mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
290{
291 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
292}
293
294/* Get a reply from the IOC */
295u_int32_t
296mpt_pop_reply_queue(mpt_softc_t *mpt)
297{
298 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
299}
300
301/*
302 * Send a command to the IOC via the handshake register.
303 *
304 * Only done at initialization time and for certain unusual
305 * commands such as device/bus reset as specified by LSI.
306 */
307int
308mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
309{
310 int i;
311 u_int32_t data, *data32;
312
313 /* Check condition of the IOC */
314 data = mpt_rd_db(mpt);
315 if (((MPT_STATE(data) != MPT_DB_STATE_READY) &&
316 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) &&
317 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) ||
318 ( MPT_DB_IS_IN_USE(data) )) {
319 device_printf(mpt->dev,
320 "handshake aborted due to invalid doorbell state\n");
321 mpt_print_db(data);
322 return(EBUSY);
323 }
324
325 /* We move things in 32 bit chunks */
326 len = (len + 3) >> 2;
327 data32 = cmd;
328
329 /* Clear any left over pending doorbell interupts */
330 if (MPT_DB_INTR(mpt_rd_intr(mpt)))
331 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
332
333 /*
334 * Tell the handshake reg. we are going to send a command
335 * and how long it is going to be.
336 */
337 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
338 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
339 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
340
341 /* Wait for the chip to notice */
342 if (mpt_wait_db_int(mpt) != MPT_OK) {
343 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout1!\n");
344 return ETIMEDOUT;
345 }
346
347 /* Clear the interrupt */
348 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
349
350 if (mpt_wait_db_ack(mpt) != MPT_OK) {
351 device_printf(mpt->dev, "mpt_send_handshake_cmd timeout2!\n");
352 return ETIMEDOUT;
353 }
354
355 /* Send the command */
356 for (i = 0; i < len; i++) {
357 mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
358 if (mpt_wait_db_ack(mpt) != MPT_OK) {
359 device_printf(mpt->dev,
360 "mpt_send_handshake_cmd timeout! index = %d\n", i);
361 return ETIMEDOUT;
362 }
363 }
364 return MPT_OK;
365}
366
367/* Get the response from the handshake register */
368int
369mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
370{
371 int left, reply_left;
372 u_int16_t *data16;
373 MSG_DEFAULT_REPLY *hdr;
374
375 /* We move things out in 16 bit chunks */
376 reply_len >>= 1;
377 data16 = (u_int16_t *)reply;
378
379 hdr = (MSG_DEFAULT_REPLY *)reply;
380
381 /* Get first word */
382 if (mpt_wait_db_int(mpt) != MPT_OK) {
383 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout1!\n");
384 return ETIMEDOUT;
385 }
386 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
387 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
388
389 /* Get Second Word */
390 if (mpt_wait_db_int(mpt) != MPT_OK) {
391 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout2!\n");
392 return ETIMEDOUT;
393 }
394 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
395 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
396
397 /* With the second word, we can now look at the length */
398 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
399 device_printf(mpt->dev,
400 "reply length does not match message length: "
401 "got 0x%02x, expected 0x%02lx\n",
402 hdr->MsgLength << 2, (long) (reply_len << 1));
403 }
404
405 /* Get rest of the reply; but don't overflow the provided buffer */
406 left = (hdr->MsgLength << 1) - 2;
407 reply_left = reply_len - 2;
408 while (left--) {
409 u_int16_t datum;
410
411 if (mpt_wait_db_int(mpt) != MPT_OK) {
412 device_printf(mpt->dev,
413 "mpt_recv_handshake_cmd timeout3!\n");
414 return ETIMEDOUT;
415 }
416 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
417
418 if (reply_left-- > 0)
419 *data16++ = datum & MPT_DB_DATA_MASK;
420
421 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
422 }
423
424 /* One more wait & clear at the end */
425 if (mpt_wait_db_int(mpt) != MPT_OK) {
426 device_printf(mpt->dev, "mpt_recv_handshake_cmd timeout4!\n");
427 return ETIMEDOUT;
428 }
429 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
430
431 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
432 if (mpt->verbose > 1)
433 mpt_print_reply(hdr);
434 return (MPT_FAIL | hdr->IOCStatus);
435 }
436
437 return (0);
438}
439
440static int
441mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
442{
443 MSG_IOC_FACTS f_req;
444 int error;
445
446 bzero(&f_req, sizeof f_req);
447 f_req.Function = MPI_FUNCTION_IOC_FACTS;
448 f_req.MsgContext = 0x12071942;
449 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
450 if (error)
451 return(error);
452 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
453 return (error);
454}
455
456static int
457mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
458{
459 MSG_PORT_FACTS f_req;
460 int error;
461
462 /* XXX: Only getting PORT FACTS for Port 0 */
463 bzero(&f_req, sizeof f_req);
464 f_req.Function = MPI_FUNCTION_PORT_FACTS;
465 f_req.MsgContext = 0x12071943;
466 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
467 if (error)
468 return(error);
469 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
470 return (error);
471}
472
473/*
474 * Send the initialization request. This is where we specify how many
475 * SCSI busses and how many devices per bus we wish to emulate.
476 * This is also the command that specifies the max size of the reply
477 * frames from the IOC that we will be allocating.
478 */
479static int
480mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
481{
482 int error = 0;
483 MSG_IOC_INIT init;
484 MSG_IOC_INIT_REPLY reply;
485
486 bzero(&init, sizeof init);
487 init.WhoInit = who;
488 init.Function = MPI_FUNCTION_IOC_INIT;
489 if (mpt->is_fc) {
490 init.MaxDevices = 255;
491 } else {
492 init.MaxDevices = 16;
493 }
494 init.MaxBuses = 1;
495 init.ReplyFrameSize = MPT_REPLY_SIZE;
496 init.MsgContext = 0x12071941;
497
498 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
499 return(error);
500 }
501
502 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
503 return (error);
504}
505
506
507/*
508 * Utiltity routine to read configuration headers and pages
509 */
510
511static int
512mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
513
514static int
515mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
516 int PageAddress, fCONFIG_PAGE_HEADER *rslt)
517{
518 int count;
519 request_t *req;
520 MSG_CONFIG *cfgp;
521 MSG_CONFIG_REPLY *reply;
522
523 req = mpt_get_request(mpt);
524
525 cfgp = req->req_vbuf;
526 bzero(cfgp, sizeof *cfgp);
527
528 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
529 cfgp->Function = MPI_FUNCTION_CONFIG;
530 cfgp->Header.PageNumber = (U8) PageNumber;
531 cfgp->Header.PageType = (U8) PageType;
532 cfgp->PageAddress = PageAddress;
533 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
534 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
535 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
536 cfgp->MsgContext = req->index | 0x80000000;
537
538 mpt_check_doorbell(mpt);
539 mpt_send_cmd(mpt, req);
540 count = 0;
541 do {
542 DELAY(500);
543 mpt_intr(mpt);
544 if (++count == 1000) {
545 device_printf(mpt->dev, "read_cfg_header timed out\n");
546 return (-1);
547 }
548 } while (req->debug == REQ_ON_CHIP);
549
550 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
551 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
552 device_printf(mpt->dev,
553 "mpt_read_cfg_header: Config Info Status %x\n",
554 reply->IOCStatus);
555 mpt_free_reply(mpt, (req->sequence << 1));
556 return (-1);
557 }
558 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
559 mpt_free_reply(mpt, (req->sequence << 1));
560 mpt_free_request(mpt, req);
561 return (0);
562}
563
564#define CFG_DATA_OFF 128
565
566int
567mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
568{
569 int count;
570 request_t *req;
571 SGE_SIMPLE32 *se;
572 MSG_CONFIG *cfgp;
573 size_t amt;
574 MSG_CONFIG_REPLY *reply;
575
576 req = mpt_get_request(mpt);
577
578 cfgp = req->req_vbuf;
579 bzero(cfgp, MPT_REQUEST_AREA);
580 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
581 cfgp->Function = MPI_FUNCTION_CONFIG;
582 cfgp->Header = *hdr;
583 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
584 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
585 cfgp->PageAddress = PageAddress;
586 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
587 se->Address = req->req_pbuf + CFG_DATA_OFF;
588 MPI_pSGE_SET_LENGTH(se, amt);
589 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
590 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
591 MPI_SGE_FLAGS_END_OF_LIST));
592
593 cfgp->MsgContext = req->index | 0x80000000;
594
595 mpt_check_doorbell(mpt);
596 mpt_send_cmd(mpt, req);
597 count = 0;
598 do {
599 DELAY(500);
600 mpt_intr(mpt);
601 if (++count == 1000) {
602 device_printf(mpt->dev, "read_cfg_page timed out\n");
603 return (-1);
604 }
605 } while (req->debug == REQ_ON_CHIP);
606
607 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
608 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
609 device_printf(mpt->dev,
610 "mpt_read_cfg_page: Config Info Status %x\n",
611 reply->IOCStatus);
612 mpt_free_reply(mpt, (req->sequence << 1));
613 return (-1);
614 }
615 mpt_free_reply(mpt, (req->sequence << 1));
616 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
617 BUS_DMASYNC_POSTREAD);
618 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
619 cfgp->Header.PageNumber == 0) {
620 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
621 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
622 cfgp->Header.PageNumber == 1) {
623 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
624 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
625 cfgp->Header.PageNumber == 2) {
626 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
627 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
628 cfgp->Header.PageNumber == 0) {
629 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
630 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
631 cfgp->Header.PageNumber == 1) {
632 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
633 }
634 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
635 mpt_free_request(mpt, req);
636 return (0);
637}
638
639int
640mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
641{
642 int count, hdr_attr;
643 request_t *req;
644 SGE_SIMPLE32 *se;
645 MSG_CONFIG *cfgp;
646 size_t amt;
647 MSG_CONFIG_REPLY *reply;
648
649 req = mpt_get_request(mpt);
650
651 cfgp = req->req_vbuf;
652 bzero(cfgp, sizeof *cfgp);
653
654 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
655 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
656 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
657 device_printf(mpt->dev, "page type 0x%x not changeable\n",
658 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
659 return (-1);
660 }
661 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
662
663 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
664 cfgp->Function = MPI_FUNCTION_CONFIG;
665 cfgp->Header = *hdr;
666 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
667 cfgp->PageAddress = PageAddress;
668
669 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
670 se->Address = req->req_pbuf + CFG_DATA_OFF;
671 MPI_pSGE_SET_LENGTH(se, amt);
672 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
673 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
674 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
675
676 cfgp->MsgContext = req->index | 0x80000000;
677
678 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
679 cfgp->Header.PageNumber == 0) {
680 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
681 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
682 cfgp->Header.PageNumber == 1) {
683 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
684 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
685 cfgp->Header.PageNumber == 2) {
686 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
687 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
688 cfgp->Header.PageNumber == 0) {
689 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
690 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
691 cfgp->Header.PageNumber == 1) {
692 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
693 }
694 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
695 /* Restore stripped out attributes */
696 hdr->PageType |= hdr_attr;
697
698 mpt_check_doorbell(mpt);
699 mpt_send_cmd(mpt, req);
700 count = 0;
701 do {
702 DELAY(500);
703 mpt_intr(mpt);
704 if (++count == 1000) {
705 hdr->PageType |= hdr_attr;
706 device_printf(mpt->dev,
707 "mpt_write_cfg_page timed out\n");
708 return (-1);
709 }
710 } while (req->debug == REQ_ON_CHIP);
711
712 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
713 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
714 device_printf(mpt->dev,
715 "mpt_write_cfg_page: Config Info Status %x\n",
716 reply->IOCStatus);
717 mpt_free_reply(mpt, (req->sequence << 1));
718 return (-1);
719 }
720 mpt_free_reply(mpt, (req->sequence << 1));
721
722 mpt_free_request(mpt, req);
723 return (0);
724}
725
726/*
727 * Read SCSI configuration information
728 */
729static int
730mpt_read_config_info_spi(mpt_softc_t *mpt)
731{
732 int rv, i;
733
734 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
735 0, &mpt->mpt_port_page0.Header);
736 if (rv) {
737 return (-1);
738 }
739 if (mpt->verbose > 1) {
740 device_printf(mpt->dev, "SPI Port Page 0 Header: %x %x %x %x\n",
741 mpt->mpt_port_page0.Header.PageVersion,
742 mpt->mpt_port_page0.Header.PageLength,
743 mpt->mpt_port_page0.Header.PageNumber,
744 mpt->mpt_port_page0.Header.PageType);
745 }
746
747 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
748 0, &mpt->mpt_port_page1.Header);
749 if (rv) {
750 return (-1);
751 }
752 if (mpt->verbose > 1) {
753 device_printf(mpt->dev, "SPI Port Page 1 Header: %x %x %x %x\n",
754 mpt->mpt_port_page1.Header.PageVersion,
755 mpt->mpt_port_page1.Header.PageLength,
756 mpt->mpt_port_page1.Header.PageNumber,
757 mpt->mpt_port_page1.Header.PageType);
758 }
759
760 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
761 0, &mpt->mpt_port_page2.Header);
762 if (rv) {
763 return (-1);
764 }
765
766 if (mpt->verbose > 1) {
767 device_printf(mpt->dev, "SPI Port Page 2 Header: %x %x %x %x\n",
768 mpt->mpt_port_page1.Header.PageVersion,
769 mpt->mpt_port_page1.Header.PageLength,
770 mpt->mpt_port_page1.Header.PageNumber,
771 mpt->mpt_port_page1.Header.PageType);
772 }
773
774 for (i = 0; i < 16; i++) {
775 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
776 0, i, &mpt->mpt_dev_page0[i].Header);
777 if (rv) {
778 return (-1);
779 }
780 if (mpt->verbose > 1) {
781 device_printf(mpt->dev,
782 "SPI Target %d Device Page 0 Header: %x %x %x %x\n",
783 i, mpt->mpt_dev_page0[i].Header.PageVersion,
784 mpt->mpt_dev_page0[i].Header.PageLength,
785 mpt->mpt_dev_page0[i].Header.PageNumber,
786 mpt->mpt_dev_page0[i].Header.PageType);
787 }
788
789 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
790 1, i, &mpt->mpt_dev_page1[i].Header);
791 if (rv) {
792 return (-1);
793 }
794 if (mpt->verbose > 1) {
795 device_printf(mpt->dev,
796 "SPI Target %d Device Page 1 Header: %x %x %x %x\n",
797 i, mpt->mpt_dev_page1[i].Header.PageVersion,
798 mpt->mpt_dev_page1[i].Header.PageLength,
799 mpt->mpt_dev_page1[i].Header.PageNumber,
800 mpt->mpt_dev_page1[i].Header.PageType);
801 }
802 }
803
804 /*
805 * At this point, we don't *have* to fail. As long as we have
806 * valid config header information, we can (barely) lurch
807 * along.
808 */
809
810 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
811 if (rv) {
812 device_printf(mpt->dev, "failed to read SPI Port Page 0\n");
813 } else if (mpt->verbose > 1) {
814 device_printf(mpt->dev,
815 "SPI Port Page 0: Capabilities %x PhysicalInterface %x\n",
816 mpt->mpt_port_page0.Capabilities,
817 mpt->mpt_port_page0.PhysicalInterface);
818 }
819
820 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
821 if (rv) {
822 device_printf(mpt->dev, "failed to read SPI Port Page 1\n");
823 } else if (mpt->verbose > 1) {
824 device_printf(mpt->dev,
825 "SPI Port Page 1: Configuration %x OnBusTimerValue %x\n",
826 mpt->mpt_port_page1.Configuration,
827 mpt->mpt_port_page1.OnBusTimerValue);
828 }
829
830 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
831 if (rv) {
832 device_printf(mpt->dev, "failed to read SPI Port Page 2\n");
833 } else if (mpt->verbose > 1) {
834 device_printf(mpt->dev,
835 "SPI Port Page 2: Flags %x Settings %x\n",
836 mpt->mpt_port_page2.PortFlags,
837 mpt->mpt_port_page2.PortSettings);
838 for (i = 0; i < 16; i++) {
839 device_printf(mpt->dev,
840 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x\n",
841 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
842 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
843 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
844 }
845 }
846
847 for (i = 0; i < 16; i++) {
848 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
849 if (rv) {
850 device_printf(mpt->dev,
851 "cannot read SPI Tgt %d Device Page 0\n", i);
852 continue;
853 }
854 if (mpt->verbose > 1) {
855 device_printf(mpt->dev,
856 "SPI Tgt %d Page 0: NParms %x Information %x\n",
857 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
858 mpt->mpt_dev_page0[i].Information);
859 }
860 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
861 if (rv) {
862 device_printf(mpt->dev,
863 "cannot read SPI Tgt %d Device Page 1\n", i);
864 continue;
865 }
866 if (mpt->verbose > 1) {
867 device_printf(mpt->dev,
868 "SPI Tgt %d Page 1: RParms %x Configuration %x\n",
869 i, mpt->mpt_dev_page1[i].RequestedParameters,
870 mpt->mpt_dev_page1[i].Configuration);
871 }
872 }
873 return (0);
874}
875
876/*
877 * Validate SPI configuration information.
878 *
879 * In particular, validate SPI Port Page 1.
880 */
881static int
882mpt_set_initial_config_spi(mpt_softc_t *mpt)
883{
884 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
885
886 mpt->mpt_disc_enable = 0xff;
887 mpt->mpt_tag_enable = 0;
888
889 if (mpt->mpt_port_page1.Configuration != pp1val) {
890 fCONFIG_PAGE_SCSI_PORT_1 tmp;
891 device_printf(mpt->dev,
892 "SPI Port Page 1 Config value bad (%x)- should be %x\n",
893 mpt->mpt_port_page1.Configuration, pp1val);
894 tmp = mpt->mpt_port_page1;
895 tmp.Configuration = pp1val;
896 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
897 return (-1);
898 }
899 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
900 return (-1);
901 }
902 if (tmp.Configuration != pp1val) {
903 device_printf(mpt->dev,
904 "failed to reset SPI Port Page 1 Config value\n");
905 return (-1);
906 }
907 mpt->mpt_port_page1 = tmp;
908 }
909
910 for (i = 0; i < 16; i++) {
911 fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
912 tmp = mpt->mpt_dev_page1[i];
913 tmp.RequestedParameters = 0;
914 tmp.Configuration = 0;
915 if (mpt->verbose > 1) {
916 device_printf(mpt->dev,
917 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x\n",
918 i, tmp.RequestedParameters, tmp.Configuration);
919 }
920 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
921 return (-1);
922 }
923 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
924 return (-1);
925 }
926 mpt->mpt_dev_page1[i] = tmp;
927 if (mpt->verbose > 1) {
928 device_printf(mpt->dev,
929 "SPI Tgt %d Page 1: RParm %x Configuration %x\n", i,
930 mpt->mpt_dev_page1[i].RequestedParameters,
931 mpt->mpt_dev_page1[i].Configuration);
932 }
933 }
934 return (0);
935}
936
937/*
938 * Enable IOC port
939 */
940static int
941mpt_send_port_enable(mpt_softc_t *mpt, int port)
942{
943 int count;
944 request_t *req;
945 MSG_PORT_ENABLE *enable_req;
946
947 req = mpt_get_request(mpt);
948
949 enable_req = req->req_vbuf;
950 bzero(enable_req, sizeof *enable_req);
951
952 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
953 enable_req->MsgContext = req->index | 0x80000000;
954 enable_req->PortNumber = port;
955
956 mpt_check_doorbell(mpt);
957 if (mpt->verbose > 1) {
958 device_printf(mpt->dev, "enabling port %d\n", port);
959 }
960 mpt_send_cmd(mpt, req);
961
962 count = 0;
963 do {
964 DELAY(500);
965 mpt_intr(mpt);
966 if (++count == 100000) {
967 device_printf(mpt->dev, "port enable timed out\n");
968 return (-1);
969 }
970 } while (req->debug == REQ_ON_CHIP);
971 mpt_free_request(mpt, req);
972 return (0);
973}
974
975/*
976 * Enable/Disable asynchronous event reporting.
977 *
978 * NB: this is the first command we send via shared memory
979 * instead of the handshake register.
980 */
981static int
982mpt_send_event_request(mpt_softc_t *mpt, int onoff)
983{
984 request_t *req;
985 MSG_EVENT_NOTIFY *enable_req;
986
987 req = mpt_get_request(mpt);
988
989 enable_req = req->req_vbuf;
990 bzero(enable_req, sizeof *enable_req);
991
992 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
993 enable_req->MsgContext = req->index | 0x80000000;
994 enable_req->Switch = onoff;
995
996 mpt_check_doorbell(mpt);
997 if (mpt->verbose > 1) {
998 device_printf(mpt->dev, "%sabling async events\n",
999 onoff? "en" : "dis");
1000 }
1001 mpt_send_cmd(mpt, req);
1002
1003 return (0);
1004}
1005
1006/*
1007 * Un-mask the interupts on the chip.
1008 */
1009void
1010mpt_enable_ints(mpt_softc_t *mpt)
1011{
1012 /* Unmask every thing except door bell int */
1013 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1014}
1015
1016/*
1017 * Mask the interupts on the chip.
1018 */
1019void
1020mpt_disable_ints(mpt_softc_t *mpt)
1021{
1022 /* Mask all interrupts */
1023 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1024 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1025}
1026
1027/* (Re)Initialize the chip for use */
1028int
1029mpt_init(mpt_softc_t *mpt, u_int32_t who)
1030{
1031 int try;
1032 MSG_IOC_FACTS_REPLY facts;
1033 MSG_PORT_FACTS_REPLY pfp;
1034 u_int32_t pptr;
1035 int val;
1036
1037 /* Put all request buffers (back) on the free list */
1038 SLIST_INIT(&mpt->request_free_list);
1039 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1040 mpt_free_request(mpt, &mpt->request_pool[val]);
1041 }
1042
1043 if (mpt->verbose > 1) {
1044 device_printf(mpt->dev, "doorbell req = %s\n",
1045 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1046 }
1047
1048 /*
1049 * Start by making sure we're not at FAULT or RESET state
1050 */
1051 switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1052 case MPT_DB_STATE_RESET:
1053 case MPT_DB_STATE_FAULT:
1054 if (mpt_reset(mpt) != MPT_OK) {
1055 return (EIO);
1056 }
1057 default:
1058 break;
1059 }
1060
1061 for (try = 0; try < MPT_MAX_TRYS; try++) {
1062 /*
1063 * No need to reset if the IOC is already in the READY state.
1064 *
1065 * Force reset if initialization failed previously.
1066 * Note that a hard_reset of the second channel of a '929
1067 * will stop operation of the first channel. Hopefully, if the
1068 * first channel is ok, the second will not require a hard
1069 * reset.
1070 */
1071 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1072 MPT_DB_STATE_READY) {
1073 if (mpt_reset(mpt) != MPT_OK) {
1074 DELAY(10000);
1075 continue;
1076 }
1077 }
1078
1079 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1080 device_printf(mpt->dev, "mpt_get_iocfacts failed\n");
1081 continue;
1082 }
1083
1084 if (mpt->verbose > 1) {
1085 device_printf(mpt->dev,
1086 "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1087 "Request Frame Size %u\n", facts.GlobalCredits,
1088 facts.BlockSize, facts.RequestFrameSize);
1089 }
1090 mpt->mpt_global_credits = facts.GlobalCredits;
1091 mpt->request_frame_size = facts.RequestFrameSize;
1092
1093 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1094 device_printf(mpt->dev, "mpt_get_portfacts failed\n");
1095 continue;
1096 }
1097
1098 if (mpt->verbose > 1) {
1099 device_printf(mpt->dev,
1100 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n",
1101 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1102 pfp.MaxDevices);
1103 }
1104
1105 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1106 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1107 device_printf(mpt->dev, "Unsupported Port Type (%x)\n",
1108 pfp.PortType);
1109 return (ENXIO);
1110 }
1111 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1112 device_printf(mpt->dev, "initiator role unsupported\n");
1113 return (ENXIO);
1114 }
1115 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1116 mpt->is_fc = 1;
1117 } else {
1118 mpt->is_fc = 0;
1119 }
1120 mpt->mpt_ini_id = pfp.PortSCSIID;
1121
1122 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1123 device_printf(mpt->dev, "mpt_send_ioc_init failed\n");
1124 continue;
1125 }
1126
1127 if (mpt->verbose > 1) {
1128 device_printf(mpt->dev, "mpt_send_ioc_init ok\n");
1129 }
1130
1131 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1132 device_printf(mpt->dev,
1133 "IOC failed to go to run state\n");
1134 continue;
1135 }
1136 if (mpt->verbose > 1) {
1137 device_printf(mpt->dev, "IOC now at RUNSTATE\n");
1138 }
1139
1140 /*
1141 * Give it reply buffers
1142 *
1143 * Do *not* except global credits.
1144 */
1145 for (val = 0, pptr = mpt->reply_phys;
1146 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1147 pptr += MPT_REPLY_SIZE) {
1148 mpt_free_reply(mpt, pptr);
1149 if (++val == mpt->mpt_global_credits - 1)
1150 break;
1151 }
1152
1153 /*
1154 * Enable asynchronous event reporting
1155 */
1156 mpt_send_event_request(mpt, 1);
1157
1158
1159 /*
1160 * Read set up initial configuration information
1161 * (SPI only for now)
1162 */
1163
1164 if (mpt->is_fc == 0) {
1165 if (mpt_read_config_info_spi(mpt)) {
1166 return (EIO);
1167 }
1168 if (mpt_set_initial_config_spi(mpt)) {
1169 return (EIO);
1170 }
1171 }
1172
1173 /*
1174 * Now enable the port
1175 */
1176 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1177 device_printf(mpt->dev, "failed to enable port 0\n");
1178 continue;
1179 }
1180
1181 if (mpt->verbose > 1) {
1182 device_printf(mpt->dev, "enabled port 0\n");
1183 }
1184
1185 /* Everything worked */
1186 break;
1187 }
1188
1189 if (try >= MPT_MAX_TRYS) {
1190 device_printf(mpt->dev, "failed to initialize IOC\n");
1191 return (EIO);
1192 }
1193
1194 if (mpt->verbose > 1) {
1195 device_printf(mpt->dev, "enabling interrupts\n");
1196 }
1197
1198 mpt_enable_ints(mpt);
1199 return (0);
1200}