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