Deleted Added
full compact
mpt.c (102304) mpt.c (102822)
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}