1 /* $OpenBSD: mpt.c,v 1.6 2004/04/28 01:45:48 marco Exp $ */
2 /* $NetBSD: mpt.c,v 1.4 2003/11/02 11:07:45 wiz Exp $ */
3
4 /*
5 * Copyright (c) 2000, 2001 by Greg Ansley
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice immediately at the beginning of the file, without modification,
12 * this list of conditions, and the following disclaimer.
13 * 2. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
20 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28 /*
29 * Additional Copyright (c) 2002 by Matthew Jacob under same license.
30 */
31
32 /*
33 * mpt.c:
34 *
35 * Generic routines for LSI Fusion adapters.
36 *
37 * Adapted from the FreeBSD "mpt" driver by Jason R. Thorpe for
38 * Wasabi Systems, Inc.
39 */
40
41 #include <sys/cdefs.h>
42 /* __KERNEL_RCSID(0, "$NetBSD: mpt.c,v 1.4 2003/11/02 11:07:45 wiz Exp $"); */
43
44 #include <dev/ic/mpt.h>
45
46 #define MPT_MAX_TRYS 3
47 #define MPT_MAX_WAIT 300000
48
49 static int maxwait_ack = 0;
50 static int maxwait_int = 0;
51 static int maxwait_state = 0;
52
53 static __inline u_int32_t
mpt_rd_db(mpt_softc_t * mpt)54 mpt_rd_db(mpt_softc_t *mpt)
55 {
56 return mpt_read(mpt, MPT_OFFSET_DOORBELL);
57 }
58
59 static __inline u_int32_t
mpt_rd_intr(mpt_softc_t * mpt)60 mpt_rd_intr(mpt_softc_t *mpt)
61 {
62 return mpt_read(mpt, MPT_OFFSET_INTR_STATUS);
63 }
64
65 /* Busy wait for a door bell to be read by IOC */
66 static int
mpt_wait_db_ack(mpt_softc_t * mpt)67 mpt_wait_db_ack(mpt_softc_t *mpt)
68 {
69 int i;
70 for (i=0; i < MPT_MAX_WAIT; i++) {
71 if (!MPT_DB_IS_BUSY(mpt_rd_intr(mpt))) {
72 maxwait_ack = i > maxwait_ack ? i : maxwait_ack;
73 return MPT_OK;
74 }
75
76 DELAY(100);
77 }
78 return MPT_FAIL;
79 }
80
81 /* Busy wait for a door bell interrupt */
82 static int
mpt_wait_db_int(mpt_softc_t * mpt)83 mpt_wait_db_int(mpt_softc_t *mpt)
84 {
85 int i;
86 for (i=0; i < MPT_MAX_WAIT; i++) {
87 if (MPT_DB_INTR(mpt_rd_intr(mpt))) {
88 maxwait_int = i > maxwait_int ? i : maxwait_int;
89 return MPT_OK;
90 }
91 DELAY(100);
92 }
93 return MPT_FAIL;
94 }
95
96 /* Wait for IOC to transition to a give state */
97 void
mpt_check_doorbell(mpt_softc_t * mpt)98 mpt_check_doorbell(mpt_softc_t *mpt)
99 {
100 u_int32_t db = mpt_rd_db(mpt);
101
102 /* prepare this function for error path */
103 /* if (MPT_STATE(db) != MPT_DB_STATE_RUNNING) { */
104 switch (MPT_STATE(db)) {
105 case MPT_DB_STATE_FAULT:
106 case MPT_DB_STATE_READY:
107 /* 1030 needs reset, issue IOC_INIT */
108 /* FIXME */
109 if (mpt_init(mpt, MPT_DB_INIT_HOST) != 0)
110 panic("%s: Can't get MPT IOC operational",
111 mpt->mpt_dev.dv_xname);
112 break;
113
114 default:
115 /* nothing done for now */
116 break;
117 }
118 }
119
120 /* Wait for IOC to transition to a give state */
121 static int
mpt_wait_state(mpt_softc_t * mpt,enum DB_STATE_BITS state)122 mpt_wait_state(mpt_softc_t *mpt, enum DB_STATE_BITS state)
123 {
124 int i;
125
126 for (i = 0; i < MPT_MAX_WAIT; i++) {
127 u_int32_t db = mpt_rd_db(mpt);
128 if (MPT_STATE(db) == state) {
129 maxwait_state = i > maxwait_state ? i : maxwait_state;
130 return (MPT_OK);
131 }
132 DELAY(100);
133 }
134 return (MPT_FAIL);
135 }
136
137
138 /* Issue the reset COMMAND to the IOC */
139 int
mpt_soft_reset(mpt_softc_t * mpt)140 mpt_soft_reset(mpt_softc_t *mpt)
141 {
142 if (mpt->verbose) {
143 mpt_prt(mpt, "soft reset");
144 }
145
146 /* Have to use hard reset if we are not in Running state */
147 if (MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_RUNNING) {
148 mpt_prt(mpt, "soft reset failed: device not running");
149 return MPT_FAIL;
150 }
151
152 /* If door bell is in use we don't have a chance of getting
153 * a word in since the IOC probably crashed in message
154 * processing. So don't waste our time.
155 */
156 if (MPT_DB_IS_IN_USE(mpt_rd_db(mpt))) {
157 mpt_prt(mpt, "soft reset failed: doorbell wedged");
158 return MPT_FAIL;
159 }
160
161 /* Send the reset request to the IOC */
162 mpt_write(mpt, MPT_OFFSET_DOORBELL,
163 MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET << MPI_DOORBELL_FUNCTION_SHIFT);
164 if (mpt_wait_db_ack(mpt) != MPT_OK) {
165 mpt_prt(mpt, "soft reset failed: ack timeout");
166 return MPT_FAIL;
167 }
168
169 /* Wait for the IOC to reload and come out of reset state */
170 if (mpt_wait_state(mpt, MPT_DB_STATE_READY) != MPT_OK) {
171 mpt_prt(mpt, "soft reset failed: device did not start running");
172 return MPT_FAIL;
173 }
174
175 return MPT_OK;
176 }
177
178 /* This is a magic diagnostic reset that resets all the ARM
179 * processors in the chip.
180 */
181 void
mpt_hard_reset(mpt_softc_t * mpt)182 mpt_hard_reset(mpt_softc_t *mpt)
183 {
184 u_int32_t diag0;
185 int count;
186
187 /* This extra read comes for the Linux source
188 * released by LSI. It's function is undocumented!
189 */
190 if (mpt->verbose) {
191 mpt_prt(mpt, "hard reset");
192 }
193 mpt_read(mpt, MPT_OFFSET_FUBAR);
194
195 /* Enable diagnostic registers */
196 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
197 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2);
198 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3);
199 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4);
200 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5);
201
202 /* Diag. port is now active so we can now hit the reset bit */
203 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, MPT_DIAG_RESET_IOC);
204
205 DELAY(10000);
206
207 /* Disable Diagnostic Register */
208 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
209
210 /* Restore the config register values */
211 /* Hard resets are known to screw up the BAR for diagnostic
212 memory accesses (Mem1). */
213 mpt_set_config_regs(mpt);
214 if (mpt->mpt2 != NULL) {
215 mpt_set_config_regs(mpt->mpt2);
216 }
217
218 /* Note that if there is no valid firmware to run, the doorbell will
219 remain in the reset state (0x00000000) */
220
221 /* try to download firmware, if available */
222 if (mpt->fw) {
223 /* wait for the adapter to finish the reset */
224 for (count = 0; count < 30; count++) {
225 diag0 = mpt_read(mpt, MPI_DIAGNOSTIC_OFFSET);
226 mpt_prt(mpt, "diag0=%08x", diag0);
227 if (!(diag0 & MPI_DIAG_RESET_ADAPTER)) {
228 break;
229 }
230
231 /* wait 1 second */
232 DELAY(1000);
233 }
234 count = mpt_downloadboot(mpt);
235 if (count < 0) {
236 panic("firmware downloadboot failure (%d)!", count);
237 }
238 }
239 }
240
241 /*
242 * Reset the IOC when needed. Try software command first then if needed
243 * poke at the magic diagnostic reset. Note that a hard reset resets
244 * *both* IOCs on dual function chips (FC929 && LSI1030) as well as
245 * fouls up the PCI configuration registers.
246 */
247 int
mpt_reset(mpt_softc_t * mpt)248 mpt_reset(mpt_softc_t *mpt)
249 {
250 int ret;
251
252 /* Try a soft reset */
253 if ((ret = mpt_soft_reset(mpt)) != MPT_OK) {
254 /* Failed; do a hard reset */
255 mpt_hard_reset(mpt);
256
257 /* Wait for the IOC to reload and come out of reset state */
258 ret = mpt_wait_state(mpt, MPT_DB_STATE_READY);
259 if (ret != MPT_OK) {
260 mpt_prt(mpt, "failed to reset device");
261 }
262 }
263
264 return ret;
265 }
266
267 /* Return a command buffer to the free queue */
268 void
mpt_free_request(mpt_softc_t * mpt,request_t * req)269 mpt_free_request(mpt_softc_t *mpt, request_t *req)
270 {
271 if (req == NULL || req != &mpt->request_pool[req->index]) {
272 panic("mpt_free_request bad req ptr");
273 return;
274 }
275 if (req->debug == REQ_FREE) {
276 /*
277 * XXX MU this should not happen but do not corrupt the free
278 * list if it does
279 */
280 mpt_prt(mpt, "request %d already free", req->index);
281 return;
282 }
283 req->sequence = 0;
284 req->xfer = NULL;
285 req->debug = REQ_FREE;
286 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
287 }
288
289 /* Initialize command buffer */
290 void
mpt_init_request(mpt_softc_t * mpt,request_t * req)291 mpt_init_request(mpt_softc_t *mpt, request_t *req)
292 {
293 if (req == NULL || req != &mpt->request_pool[req->index]) {
294 panic("mpt_init_request bad req ptr");
295 return;
296 }
297 req->sequence = 0;
298 req->xfer = NULL;
299 req->debug = REQ_FREE;
300 SLIST_INSERT_HEAD(&mpt->request_free_list, req, link);
301 }
302 /* Get a command buffer from the free queue */
303 request_t *
mpt_get_request(mpt_softc_t * mpt)304 mpt_get_request(mpt_softc_t *mpt)
305 {
306 request_t *req;
307 req = SLIST_FIRST(&mpt->request_free_list);
308 if (req != NULL) {
309 if (req != &mpt->request_pool[req->index]) {
310 panic("mpt_get_request: corrupted request free list");
311 }
312 if (req->xfer != NULL) {
313 panic("mpt_get_request: corrupted request free list "
314 "(xfer)");
315 }
316 SLIST_REMOVE_HEAD(&mpt->request_free_list, link);
317 req->debug = REQ_IN_PROGRESS;
318 }
319 return req;
320 }
321
322 /* Pass the command to the IOC */
323 void
mpt_send_cmd(mpt_softc_t * mpt,request_t * req)324 mpt_send_cmd(mpt_softc_t *mpt, request_t *req)
325 {
326 req->sequence = mpt->sequence++;
327 if (mpt->verbose > 1) {
328 u_int32_t *pReq;
329 pReq = req->req_vbuf;
330 mpt_prt(mpt, "Send Request %d (0x%x):",
331 req->index, req->req_pbuf);
332 mpt_prt(mpt, "%08x %08x %08x %08x",
333 pReq[0], pReq[1], pReq[2], pReq[3]);
334 mpt_prt(mpt, "%08x %08x %08x %08x",
335 pReq[4], pReq[5], pReq[6], pReq[7]);
336 mpt_prt(mpt, "%08x %08x %08x %08x",
337 pReq[8], pReq[9], pReq[10], pReq[11]);
338 mpt_prt(mpt, "%08x %08x %08x %08x",
339 pReq[12], pReq[13], pReq[14], pReq[15]);
340 }
341 MPT_SYNC_REQ(mpt, req, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
342 req->debug = REQ_ON_CHIP;
343 mpt_write(mpt, MPT_OFFSET_REQUEST_Q, (u_int32_t) req->req_pbuf);
344 }
345
346 /*
347 * Give the reply buffer back to the IOC after we have
348 * finished processing it.
349 */
350 void
mpt_free_reply(mpt_softc_t * mpt,u_int32_t ptr)351 mpt_free_reply(mpt_softc_t *mpt, u_int32_t ptr)
352 {
353 mpt_write(mpt, MPT_OFFSET_REPLY_Q, ptr);
354 }
355
356 /* Get a reply from the IOC */
357 u_int32_t
mpt_pop_reply_queue(mpt_softc_t * mpt)358 mpt_pop_reply_queue(mpt_softc_t *mpt)
359 {
360 return mpt_read(mpt, MPT_OFFSET_REPLY_Q);
361 }
362
363 /*
364 * Send a command to the IOC via the handshake register.
365 *
366 * Only done at initialization time and for certain unusual
367 * commands such as device/bus reset as specified by LSI.
368 */
369 int
mpt_send_handshake_cmd(mpt_softc_t * mpt,size_t len,void * cmd)370 mpt_send_handshake_cmd(mpt_softc_t *mpt, size_t len, void *cmd)
371 {
372 int i;
373 u_int32_t data, *data32;
374
375 /* Check condition of the IOC */
376 data = mpt_rd_db(mpt);
377 if (((MPT_STATE(data) != MPT_DB_STATE_READY) &&
378 (MPT_STATE(data) != MPT_DB_STATE_RUNNING) &&
379 (MPT_STATE(data) != MPT_DB_STATE_FAULT)) ||
380 ( MPT_DB_IS_IN_USE(data) )) {
381 mpt_prt(mpt, "handshake aborted due to invalid doorbell state");
382 mpt_print_db(data);
383 return(EBUSY);
384 }
385
386 /* We move things in 32 bit chunks */
387 len = (len + 3) >> 2;
388 data32 = cmd;
389
390 /* Clear any left over pending doorbell interrupts */
391 if (MPT_DB_INTR(mpt_rd_intr(mpt)))
392 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
393
394 /*
395 * Tell the handshake reg. we are going to send a command
396 * and how long it is going to be.
397 */
398 data = (MPI_FUNCTION_HANDSHAKE << MPI_DOORBELL_FUNCTION_SHIFT) |
399 (len << MPI_DOORBELL_ADD_DWORDS_SHIFT);
400 mpt_write(mpt, MPT_OFFSET_DOORBELL, data);
401
402 /* Wait for the chip to notice */
403 if (mpt_wait_db_int(mpt) != MPT_OK) {
404 mpt_prt(mpt, "mpt_send_handshake_cmd timeout1");
405 return ETIMEDOUT;
406 }
407
408 /* Clear the interrupt */
409 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
410
411 if (mpt_wait_db_ack(mpt) != MPT_OK) {
412 mpt_prt(mpt, "mpt_send_handshake_cmd timeout2");
413 return ETIMEDOUT;
414 }
415
416 /* Send the command */
417 for (i = 0; i < len; i++) {
418 mpt_write(mpt, MPT_OFFSET_DOORBELL, *data32++);
419 if (mpt_wait_db_ack(mpt) != MPT_OK) {
420 mpt_prt(mpt,
421 "mpt_send_handshake_cmd timeout! index = %d", i);
422 return ETIMEDOUT;
423 }
424 }
425 return MPT_OK;
426 }
427
428 /* Get the response from the handshake register */
429 int
mpt_recv_handshake_reply(mpt_softc_t * mpt,size_t reply_len,void * reply)430 mpt_recv_handshake_reply(mpt_softc_t *mpt, size_t reply_len, void *reply)
431 {
432 int left, reply_left;
433 u_int16_t *data16;
434 MSG_DEFAULT_REPLY *hdr;
435
436 /* We move things out in 16 bit chunks */
437 reply_len >>= 1;
438 data16 = (u_int16_t *)reply;
439
440 hdr = (MSG_DEFAULT_REPLY *)reply;
441
442 /* Get first word */
443 if (mpt_wait_db_int(mpt) != MPT_OK) {
444 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout1");
445 return ETIMEDOUT;
446 }
447 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
448 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
449
450 /* Get Second Word */
451 if (mpt_wait_db_int(mpt) != MPT_OK) {
452 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout2");
453 return ETIMEDOUT;
454 }
455 *data16++ = mpt_read(mpt, MPT_OFFSET_DOORBELL) & MPT_DB_DATA_MASK;
456 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
457
458 /* With the second word, we can now look at the length */
459 if (mpt->verbose > 1 && ((reply_len >> 1) != hdr->MsgLength)) {
460 mpt_prt(mpt, "reply length does not match message length: "
461 "got 0x%02x, expected 0x%02x",
462 hdr->MsgLength << 2, reply_len << 1);
463 }
464
465 /* Get rest of the reply; but don't overflow the provided buffer */
466 left = (hdr->MsgLength << 1) - 2;
467 reply_left = reply_len - 2;
468 while (left--) {
469 u_int16_t datum;
470
471 if (mpt_wait_db_int(mpt) != MPT_OK) {
472 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout3");
473 return ETIMEDOUT;
474 }
475 datum = mpt_read(mpt, MPT_OFFSET_DOORBELL);
476
477 if (reply_left-- > 0)
478 *data16++ = datum & MPT_DB_DATA_MASK;
479
480 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
481 }
482
483 /* One more wait & clear at the end */
484 if (mpt_wait_db_int(mpt) != MPT_OK) {
485 mpt_prt(mpt, "mpt_recv_handshake_cmd timeout4");
486 return ETIMEDOUT;
487 }
488 mpt_write(mpt, MPT_OFFSET_INTR_STATUS, 0);
489
490 if ((hdr->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
491 if (mpt->verbose > 1)
492 mpt_print_reply(hdr);
493 return (MPT_FAIL | hdr->IOCStatus);
494 }
495
496 return (0);
497 }
498
499 static int
mpt_get_iocfacts(mpt_softc_t * mpt,MSG_IOC_FACTS_REPLY * freplp)500 mpt_get_iocfacts(mpt_softc_t *mpt, MSG_IOC_FACTS_REPLY *freplp)
501 {
502 MSG_IOC_FACTS f_req;
503 int error;
504
505 bzero(&f_req, sizeof f_req);
506 f_req.Function = MPI_FUNCTION_IOC_FACTS;
507 f_req.MsgContext = 0x12071942;
508 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
509 if (error)
510 return(error);
511 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
512 return (error);
513 }
514
515 static int
mpt_get_portfacts(mpt_softc_t * mpt,MSG_PORT_FACTS_REPLY * freplp)516 mpt_get_portfacts(mpt_softc_t *mpt, MSG_PORT_FACTS_REPLY *freplp)
517 {
518 MSG_PORT_FACTS f_req;
519 int error;
520
521 /* XXX: Only getting PORT FACTS for Port 0 */
522 bzero(&f_req, sizeof f_req);
523 f_req.Function = MPI_FUNCTION_PORT_FACTS;
524 f_req.MsgContext = 0x12071943;
525 error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req);
526 if (error)
527 return(error);
528 error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp);
529 return (error);
530 }
531
532 /*
533 * Send the initialization request. This is where we specify how many
534 * SCSI busses and how many devices per bus we wish to emulate.
535 * This is also the command that specifies the max size of the reply
536 * frames from the IOC that we will be allocating.
537 */
538 static int
mpt_send_ioc_init(mpt_softc_t * mpt,u_int32_t who)539 mpt_send_ioc_init(mpt_softc_t *mpt, u_int32_t who)
540 {
541 int error = 0;
542 MSG_IOC_INIT init;
543 MSG_IOC_INIT_REPLY reply;
544
545 bzero(&init, sizeof init);
546 init.WhoInit = who;
547 init.Function = MPI_FUNCTION_IOC_INIT;
548 if (mpt->is_fc) {
549 init.MaxDevices = 255;
550 } else {
551 init.MaxDevices = 16;
552 }
553 init.MaxBuses = 1;
554 init.ReplyFrameSize = MPT_REPLY_SIZE;
555 init.MsgContext = 0x12071941;
556
557 /*
558 * If we are in a recovery mode and we uploaded the FW image,
559 * then the fw pointer is not NULL. Skip the upload a second time
560 * Set this flag if fw set for IOC.
561 */
562 mpt->upload_fw = 0;
563
564 if (mpt->fw_download_boot) {
565 if (mpt->fw) {
566 init.Flags = MPI_IOCINIT_FLAGS_DISCARD_FW_IMAGE;
567 }
568 else {
569 mpt->upload_fw = 1;
570 }
571 }
572 if (mpt->verbose > 1) {
573 mpt_prt(mpt, "flags %d, upload_fw %d", init.Flags,
574 mpt->upload_fw);
575 }
576
577 if ((error = mpt_send_handshake_cmd(mpt, sizeof init, &init)) != 0) {
578 return(error);
579 }
580
581 error = mpt_recv_handshake_reply(mpt, sizeof reply, &reply);
582 return (error);
583 }
584
585
586 /*
587 * Utiltity routine to read configuration headers and pages
588 */
589
590 static int
591 mpt_read_cfg_header(mpt_softc_t *, int, int, int, fCONFIG_PAGE_HEADER *);
592
593 static int
mpt_read_cfg_header(mpt_softc_t * mpt,int PageType,int PageNumber,int PageAddress,fCONFIG_PAGE_HEADER * rslt)594 mpt_read_cfg_header(mpt_softc_t *mpt, int PageType, int PageNumber,
595 int PageAddress, fCONFIG_PAGE_HEADER *rslt)
596 {
597 int count;
598 request_t *req;
599 MSG_CONFIG *cfgp;
600 MSG_CONFIG_REPLY *reply;
601
602 req = mpt_get_request(mpt);
603
604 cfgp = req->req_vbuf;
605 bzero(cfgp, sizeof *cfgp);
606
607 cfgp->Action = MPI_CONFIG_ACTION_PAGE_HEADER;
608 cfgp->Function = MPI_FUNCTION_CONFIG;
609 cfgp->Header.PageNumber = (U8) PageNumber;
610 cfgp->Header.PageType = (U8) PageType;
611 cfgp->PageAddress = PageAddress;
612 MPI_pSGE_SET_FLAGS(((SGE_SIMPLE32 *) &cfgp->PageBufferSGE),
613 (MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
614 MPI_SGE_FLAGS_SIMPLE_ELEMENT | MPI_SGE_FLAGS_END_OF_LIST));
615 cfgp->MsgContext = req->index | 0x80000000;
616
617 mpt_check_doorbell(mpt);
618 mpt_send_cmd(mpt, req);
619 count = 0;
620 do {
621 DELAY(500);
622 mpt_intr(mpt);
623 if (++count == 1000) {
624 mpt_prt(mpt, "read_cfg_header timed out");
625 return (-1);
626 }
627 } while (req->debug == REQ_ON_CHIP);
628
629 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
630 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
631 mpt_prt(mpt, "mpt_read_cfg_header: Config Info Status %x",
632 reply->IOCStatus);
633 mpt_free_reply(mpt, (req->sequence << 1));
634 return (-1);
635 }
636 bcopy(&reply->Header, rslt, sizeof (fCONFIG_PAGE_HEADER));
637 mpt_free_reply(mpt, (req->sequence << 1));
638 mpt_free_request(mpt, req);
639 return (0);
640 }
641
642 #define CFG_DATA_OFF 128
643
644 int
mpt_read_cfg_page(mpt_softc_t * mpt,int PageAddress,fCONFIG_PAGE_HEADER * hdr)645 mpt_read_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
646 {
647 int count;
648 request_t *req;
649 SGE_SIMPLE32 *se;
650 MSG_CONFIG *cfgp;
651 size_t amt;
652 MSG_CONFIG_REPLY *reply;
653
654 req = mpt_get_request(mpt);
655
656 cfgp = req->req_vbuf;
657 bzero(cfgp, MPT_REQUEST_AREA);
658 cfgp->Action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
659 cfgp->Function = MPI_FUNCTION_CONFIG;
660 cfgp->Header = *hdr;
661 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
662 cfgp->Header.PageType &= MPI_CONFIG_PAGETYPE_MASK;
663 cfgp->PageAddress = PageAddress;
664 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
665 se->Address = req->req_pbuf + CFG_DATA_OFF;
666 MPI_pSGE_SET_LENGTH(se, amt);
667 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
668 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
669 MPI_SGE_FLAGS_END_OF_LIST));
670
671 cfgp->MsgContext = req->index | 0x80000000;
672
673 mpt_check_doorbell(mpt);
674 mpt_send_cmd(mpt, req);
675 count = 0;
676 do {
677 DELAY(500);
678 mpt_intr(mpt);
679 if (++count == 1000) {
680 mpt_prt(mpt, "read_cfg_page timed out");
681 return (-1);
682 }
683 } while (req->debug == REQ_ON_CHIP);
684
685 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
686 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
687 mpt_prt(mpt, "mpt_read_cfg_page: Config Info Status %x",
688 reply->IOCStatus);
689 mpt_free_reply(mpt, (req->sequence << 1));
690 return (-1);
691 }
692 mpt_free_reply(mpt, (req->sequence << 1));
693 #if 0 /* XXXJRT */
694 bus_dmamap_sync(mpt->request_dmat, mpt->request_dmap,
695 BUS_DMASYNC_POSTREAD);
696 #endif
697 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
698 cfgp->Header.PageNumber == 0) {
699 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
700 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
701 cfgp->Header.PageNumber == 1) {
702 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
703 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
704 cfgp->Header.PageNumber == 2) {
705 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
706 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
707 cfgp->Header.PageNumber == 0) {
708 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
709 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
710 cfgp->Header.PageNumber == 1) {
711 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
712 }
713 bcopy(((caddr_t)req->req_vbuf)+CFG_DATA_OFF, hdr, amt);
714 mpt_free_request(mpt, req);
715 return (0);
716 }
717
718 int
mpt_write_cfg_page(mpt_softc_t * mpt,int PageAddress,fCONFIG_PAGE_HEADER * hdr)719 mpt_write_cfg_page(mpt_softc_t *mpt, int PageAddress, fCONFIG_PAGE_HEADER *hdr)
720 {
721 int count, hdr_attr;
722 request_t *req;
723 SGE_SIMPLE32 *se;
724 MSG_CONFIG *cfgp;
725 size_t amt;
726 MSG_CONFIG_REPLY *reply;
727
728 req = mpt_get_request(mpt);
729
730 cfgp = req->req_vbuf;
731 bzero(cfgp, sizeof *cfgp);
732
733 hdr_attr = hdr->PageType & MPI_CONFIG_PAGEATTR_MASK;
734 if (hdr_attr != MPI_CONFIG_PAGEATTR_CHANGEABLE &&
735 hdr_attr != MPI_CONFIG_PAGEATTR_PERSISTENT) {
736 mpt_prt(mpt, "page type 0x%x not changeable",
737 hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
738 return (-1);
739 }
740 hdr->PageType &= MPI_CONFIG_PAGETYPE_MASK;
741
742 cfgp->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
743 cfgp->Function = MPI_FUNCTION_CONFIG;
744 cfgp->Header = *hdr;
745 amt = (cfgp->Header.PageLength * sizeof (u_int32_t));
746 cfgp->PageAddress = PageAddress;
747
748 se = (SGE_SIMPLE32 *) &cfgp->PageBufferSGE;
749 se->Address = req->req_pbuf + CFG_DATA_OFF;
750 MPI_pSGE_SET_LENGTH(se, amt);
751 MPI_pSGE_SET_FLAGS(se, (MPI_SGE_FLAGS_SIMPLE_ELEMENT |
752 MPI_SGE_FLAGS_LAST_ELEMENT | MPI_SGE_FLAGS_END_OF_BUFFER |
753 MPI_SGE_FLAGS_END_OF_LIST | MPI_SGE_FLAGS_HOST_TO_IOC));
754
755 cfgp->MsgContext = req->index | 0x80000000;
756
757 if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
758 cfgp->Header.PageNumber == 0) {
759 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_0);
760 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
761 cfgp->Header.PageNumber == 1) {
762 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_1);
763 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_PORT &&
764 cfgp->Header.PageNumber == 2) {
765 amt = sizeof (fCONFIG_PAGE_SCSI_PORT_2);
766 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
767 cfgp->Header.PageNumber == 0) {
768 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_0);
769 } else if (cfgp->Header.PageType == MPI_CONFIG_PAGETYPE_SCSI_DEVICE &&
770 cfgp->Header.PageNumber == 1) {
771 amt = sizeof (fCONFIG_PAGE_SCSI_DEVICE_1);
772 }
773 bcopy(hdr, ((caddr_t)req->req_vbuf)+CFG_DATA_OFF, amt);
774 /* Restore stripped out attributes */
775 hdr->PageType |= hdr_attr;
776
777 mpt_check_doorbell(mpt);
778 mpt_send_cmd(mpt, req);
779 count = 0;
780 do {
781 DELAY(500);
782 mpt_intr(mpt);
783 if (++count == 1000) {
784 hdr->PageType |= hdr_attr;
785 mpt_prt(mpt, "mpt_write_cfg_page timed out");
786 return (-1);
787 }
788 } while (req->debug == REQ_ON_CHIP);
789
790 reply = (MSG_CONFIG_REPLY *) MPT_REPLY_PTOV(mpt, req->sequence);
791 if ((reply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
792 mpt_prt(mpt, "mpt_write_cfg_page: Config Info Status %x",
793 reply->IOCStatus);
794 mpt_free_reply(mpt, (req->sequence << 1));
795 return (-1);
796 }
797 mpt_free_reply(mpt, (req->sequence << 1));
798
799 mpt_free_request(mpt, req);
800 return (0);
801 }
802
803 /*
804 * Read SCSI configuration information
805 */
806 static int
mpt_read_config_info_spi(mpt_softc_t * mpt)807 mpt_read_config_info_spi(mpt_softc_t *mpt)
808 {
809 int rv, i;
810
811 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 0,
812 0, &mpt->mpt_port_page0.Header);
813 if (rv) {
814 return (-1);
815 }
816 if (mpt->verbose > 1) {
817 mpt_prt(mpt, "SPI Port Page 0 Header: %x %x %x %x",
818 mpt->mpt_port_page0.Header.PageVersion,
819 mpt->mpt_port_page0.Header.PageLength,
820 mpt->mpt_port_page0.Header.PageNumber,
821 mpt->mpt_port_page0.Header.PageType);
822 }
823
824 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 1,
825 0, &mpt->mpt_port_page1.Header);
826 if (rv) {
827 return (-1);
828 }
829 if (mpt->verbose > 1) {
830 mpt_prt(mpt, "SPI Port Page 1 Header: %x %x %x %x",
831 mpt->mpt_port_page1.Header.PageVersion,
832 mpt->mpt_port_page1.Header.PageLength,
833 mpt->mpt_port_page1.Header.PageNumber,
834 mpt->mpt_port_page1.Header.PageType);
835 }
836
837 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_PORT, 2,
838 0, &mpt->mpt_port_page2.Header);
839 if (rv) {
840 return (-1);
841 }
842
843 if (mpt->verbose > 1) {
844 mpt_prt(mpt, "SPI Port Page 2 Header: %x %x %x %x",
845 mpt->mpt_port_page1.Header.PageVersion,
846 mpt->mpt_port_page1.Header.PageLength,
847 mpt->mpt_port_page1.Header.PageNumber,
848 mpt->mpt_port_page1.Header.PageType);
849 }
850
851 for (i = 0; i < 16; i++) {
852 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
853 0, i, &mpt->mpt_dev_page0[i].Header);
854 if (rv) {
855 return (-1);
856 }
857 if (mpt->verbose > 1) {
858 mpt_prt(mpt,
859 "SPI Target %d Device Page 0 Header: %x %x %x %x",
860 i, mpt->mpt_dev_page0[i].Header.PageVersion,
861 mpt->mpt_dev_page0[i].Header.PageLength,
862 mpt->mpt_dev_page0[i].Header.PageNumber,
863 mpt->mpt_dev_page0[i].Header.PageType);
864 }
865
866 rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_SCSI_DEVICE,
867 1, i, &mpt->mpt_dev_page1[i].Header);
868 if (rv) {
869 return (-1);
870 }
871 if (mpt->verbose > 1) {
872 mpt_prt(mpt,
873 "SPI Target %d Device Page 1 Header: %x %x %x %x",
874 i, mpt->mpt_dev_page1[i].Header.PageVersion,
875 mpt->mpt_dev_page1[i].Header.PageLength,
876 mpt->mpt_dev_page1[i].Header.PageNumber,
877 mpt->mpt_dev_page1[i].Header.PageType);
878 }
879 }
880
881 /*
882 * At this point, we don't *have* to fail. As long as we have
883 * valid config header information, we can (barely) lurch
884 * along.
885 */
886
887 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page0.Header);
888 if (rv) {
889 mpt_prt(mpt, "failed to read SPI Port Page 0");
890 } else if (mpt->verbose > 1) {
891 mpt_prt(mpt,
892 "SPI Port Page 0: Capabilities %x PhysicalInterface %x",
893 mpt->mpt_port_page0.Capabilities,
894 mpt->mpt_port_page0.PhysicalInterface);
895 }
896
897 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page1.Header);
898 if (rv) {
899 mpt_prt(mpt, "failed to read SPI Port Page 1");
900 } else if (mpt->verbose > 1) {
901 mpt_prt(mpt,
902 "SPI Port Page 1: Configuration %x OnBusTimerValue %x",
903 mpt->mpt_port_page1.Configuration,
904 mpt->mpt_port_page1.OnBusTimerValue);
905 }
906
907 rv = mpt_read_cfg_page(mpt, 0, &mpt->mpt_port_page2.Header);
908 if (rv) {
909 mpt_prt(mpt, "failed to read SPI Port Page 2");
910 } else if (mpt->verbose > 1) {
911 mpt_prt(mpt,
912 "SPI Port Page 2: Flags %x Settings %x",
913 mpt->mpt_port_page2.PortFlags,
914 mpt->mpt_port_page2.PortSettings);
915 for (i = 0; i < 16; i++) {
916 mpt_prt(mpt,
917 "SPI Port Page 2 Tgt %d: timo %x SF %x Flags %x",
918 i, mpt->mpt_port_page2.DeviceSettings[i].Timeout,
919 mpt->mpt_port_page2.DeviceSettings[i].SyncFactor,
920 mpt->mpt_port_page2.DeviceSettings[i].DeviceFlags);
921 }
922 }
923
924 for (i = 0; i < 16; i++) {
925 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page0[i].Header);
926 if (rv) {
927 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 0", i);
928 continue;
929 }
930 if (mpt->verbose > 1) {
931 mpt_prt(mpt,
932 "SPI Tgt %d Page 0: NParms %x Information %x",
933 i, mpt->mpt_dev_page0[i].NegotiatedParameters,
934 mpt->mpt_dev_page0[i].Information);
935 }
936 rv = mpt_read_cfg_page(mpt, i, &mpt->mpt_dev_page1[i].Header);
937 if (rv) {
938 mpt_prt(mpt, "cannot read SPI Tgt %d Device Page 1", i);
939 continue;
940 }
941 if (mpt->verbose > 1) {
942 mpt_prt(mpt,
943 "SPI Tgt %d Page 1: RParms %x Configuration %x",
944 i, mpt->mpt_dev_page1[i].RequestedParameters,
945 mpt->mpt_dev_page1[i].Configuration);
946 }
947 }
948 return (0);
949 }
950
951 /*
952 * Validate SPI configuration information.
953 *
954 * In particular, validate SPI Port Page 1.
955 */
956 static int
mpt_set_initial_config_spi(mpt_softc_t * mpt)957 mpt_set_initial_config_spi(mpt_softc_t *mpt)
958 {
959 int i, pp1val = ((1 << mpt->mpt_ini_id) << 16) | mpt->mpt_ini_id;
960
961 mpt->mpt_disc_enable = 0xff;
962 mpt->mpt_tag_enable = 0;
963
964 if (mpt->mpt_port_page1.Configuration != pp1val) {
965 fCONFIG_PAGE_SCSI_PORT_1 tmp;
966 mpt_prt(mpt,
967 "SPI Port Page 1 Config value bad (%x)- should be %x",
968 mpt->mpt_port_page1.Configuration, pp1val);
969 tmp = mpt->mpt_port_page1;
970 tmp.Configuration = pp1val;
971 if (mpt_write_cfg_page(mpt, 0, &tmp.Header)) {
972 return (-1);
973 }
974 if (mpt_read_cfg_page(mpt, 0, &tmp.Header)) {
975 return (-1);
976 }
977 if (tmp.Configuration != pp1val) {
978 mpt_prt(mpt,
979 "failed to reset SPI Port Page 1 Config value");
980 return (-1);
981 }
982 mpt->mpt_port_page1 = tmp;
983 }
984
985 for (i = 0; i < 16; i++) {
986 fCONFIG_PAGE_SCSI_DEVICE_1 tmp;
987 tmp = mpt->mpt_dev_page1[i];
988 tmp.RequestedParameters = 0;
989 tmp.Configuration = 0;
990 if (mpt->verbose > 1) {
991 mpt_prt(mpt,
992 "Set Tgt %d SPI DevicePage 1 values to %x 0 %x",
993 i, tmp.RequestedParameters, tmp.Configuration);
994 }
995 if (mpt_write_cfg_page(mpt, i, &tmp.Header)) {
996 return (-1);
997 }
998 if (mpt_read_cfg_page(mpt, i, &tmp.Header)) {
999 return (-1);
1000 }
1001 mpt->mpt_dev_page1[i] = tmp;
1002 if (mpt->verbose > 1) {
1003 mpt_prt(mpt,
1004 "SPI Tgt %d Page 1: RParm %x Configuration %x", i,
1005 mpt->mpt_dev_page1[i].RequestedParameters,
1006 mpt->mpt_dev_page1[i].Configuration);
1007 }
1008 }
1009 return (0);
1010 }
1011
1012 /*
1013 * Enable IOC port
1014 */
1015 static int
mpt_send_port_enable(mpt_softc_t * mpt,int port)1016 mpt_send_port_enable(mpt_softc_t *mpt, int port)
1017 {
1018 int count;
1019 request_t *req;
1020 MSG_PORT_ENABLE *enable_req;
1021
1022 req = mpt_get_request(mpt);
1023
1024 enable_req = req->req_vbuf;
1025 bzero(enable_req, sizeof *enable_req);
1026
1027 enable_req->Function = MPI_FUNCTION_PORT_ENABLE;
1028 enable_req->MsgContext = req->index | 0x80000000;
1029 enable_req->PortNumber = port;
1030
1031 mpt_check_doorbell(mpt);
1032 if (mpt->verbose > 1) {
1033 mpt_prt(mpt, "enabling port %d", port);
1034 }
1035 mpt_send_cmd(mpt, req);
1036
1037 count = 0;
1038 do {
1039 DELAY(500);
1040 mpt_intr(mpt);
1041 if (++count == 100000) {
1042 mpt_prt(mpt, "port enable timed out");
1043 return (-1);
1044 }
1045 } while (req->debug == REQ_ON_CHIP);
1046 mpt_free_request(mpt, req);
1047 return (0);
1048 }
1049
1050 /*
1051 * Enable/Disable asynchronous event reporting.
1052 *
1053 * NB: this is the first command we send via shared memory
1054 * instead of the handshake register.
1055 */
1056 static int
mpt_send_event_request(mpt_softc_t * mpt,int onoff)1057 mpt_send_event_request(mpt_softc_t *mpt, int onoff)
1058 {
1059 request_t *req;
1060 MSG_EVENT_NOTIFY *enable_req;
1061
1062 req = mpt_get_request(mpt);
1063
1064 enable_req = req->req_vbuf;
1065 bzero(enable_req, sizeof *enable_req);
1066
1067 enable_req->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
1068 enable_req->MsgContext = req->index | 0x80000000;
1069 enable_req->Switch = onoff;
1070
1071 mpt_check_doorbell(mpt);
1072 if (mpt->verbose > 1) {
1073 mpt_prt(mpt, "%sabling async events", onoff? "en" : "dis");
1074 }
1075 mpt_send_cmd(mpt, req);
1076
1077 return (0);
1078 }
1079
1080 /*
1081 * Un-mask the interrupts on the chip.
1082 */
1083 void
mpt_enable_ints(mpt_softc_t * mpt)1084 mpt_enable_ints(mpt_softc_t *mpt)
1085 {
1086 /* Unmask every thing except door bell int */
1087 mpt_write(mpt, MPT_OFFSET_INTR_MASK, MPT_INTR_DB_MASK);
1088 }
1089
1090 /*
1091 * Mask the interrupts on the chip.
1092 */
1093 void
mpt_disable_ints(mpt_softc_t * mpt)1094 mpt_disable_ints(mpt_softc_t *mpt)
1095 {
1096 /* Mask all interrupts */
1097 mpt_write(mpt, MPT_OFFSET_INTR_MASK,
1098 MPT_INTR_REPLY_MASK | MPT_INTR_DB_MASK);
1099 }
1100
1101 /* (Re)Initialize the chip for use */
1102 int
mpt_init(mpt_softc_t * mpt,u_int32_t who)1103 mpt_init(mpt_softc_t *mpt, u_int32_t who)
1104 {
1105 int try;
1106 MSG_IOC_FACTS_REPLY facts;
1107 MSG_PORT_FACTS_REPLY pfp;
1108 u_int32_t pptr;
1109 int val;
1110
1111 /* Put all request buffers (back) on the free list */
1112 SLIST_INIT(&mpt->request_free_list);
1113 for (val = 0; val < MPT_MAX_REQUESTS(mpt); val++) {
1114 mpt_init_request(mpt, &mpt->request_pool[val]);
1115 }
1116
1117 if (mpt->verbose > 1) {
1118 mpt_prt(mpt, "doorbell req = %s",
1119 mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL)));
1120 }
1121
1122 /*
1123 * Start by making sure we're not at FAULT or RESET state
1124 */
1125 switch (mpt_rd_db(mpt) & MPT_DB_STATE_MASK) {
1126 case MPT_DB_STATE_RESET:
1127 case MPT_DB_STATE_FAULT:
1128 if (mpt_reset(mpt) != MPT_OK) {
1129 return (EIO);
1130 }
1131 default:
1132 break;
1133 }
1134
1135 for (try = 0; try < MPT_MAX_TRYS; try++) {
1136 /*
1137 * No need to reset if the IOC is already in the READY state.
1138 *
1139 * Force reset if initialization failed previously.
1140 * Note that a hard_reset of the second channel of a '929
1141 * will stop operation of the first channel. Hopefully, if the
1142 * first channel is ok, the second will not require a hard
1143 * reset.
1144 */
1145 if ((mpt_rd_db(mpt) & MPT_DB_STATE_MASK) !=
1146 MPT_DB_STATE_READY) {
1147 if (mpt_reset(mpt) != MPT_OK) {
1148 DELAY(10000);
1149 continue;
1150 }
1151 }
1152
1153 if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) {
1154 mpt_prt(mpt, "mpt_get_iocfacts failed");
1155 continue;
1156 }
1157
1158 if (mpt->verbose > 1) {
1159 mpt_prt(mpt,
1160 "IOCFACTS: GlobalCredits=%d BlockSize=%u "
1161 "Request Frame Size %u", facts.GlobalCredits,
1162 facts.BlockSize, facts.RequestFrameSize);
1163 }
1164 mpt->mpt_global_credits = facts.GlobalCredits;
1165 mpt->request_frame_size = facts.RequestFrameSize;
1166
1167 /* save the firmware upload required flag */
1168 mpt->fw_download_boot = facts.Flags
1169 & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT;
1170
1171 mpt->fw_image_size = facts.FWImageSize;
1172
1173 if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) {
1174 mpt_prt(mpt, "mpt_get_portfacts failed");
1175 continue;
1176 }
1177
1178 if (mpt->verbose > 1) {
1179 mpt_prt(mpt,
1180 "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d",
1181 pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID,
1182 pfp.MaxDevices);
1183 }
1184
1185 if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI &&
1186 pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) {
1187 mpt_prt(mpt, "Unsupported Port Type (%x)",
1188 pfp.PortType);
1189 return (ENXIO);
1190 }
1191 if (!(pfp.ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR)) {
1192 mpt_prt(mpt, "initiator role unsupported");
1193 return (ENXIO);
1194 }
1195 if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) {
1196 mpt->is_fc = 1;
1197 } else {
1198 mpt->is_fc = 0;
1199 }
1200 mpt->mpt_ini_id = pfp.PortSCSIID;
1201
1202 if (mpt_send_ioc_init(mpt, who) != MPT_OK) {
1203 mpt_prt(mpt, "mpt_send_ioc_init failed");
1204 continue;
1205 }
1206
1207 if (mpt->verbose > 1) {
1208 mpt_prt(mpt, "mpt_send_ioc_init ok");
1209 }
1210
1211 if (mpt_wait_state(mpt, MPT_DB_STATE_RUNNING) != MPT_OK) {
1212 mpt_prt(mpt, "IOC failed to go to run state");
1213 continue;
1214 }
1215 if (mpt->verbose > 1) {
1216 mpt_prt(mpt, "IOC now at RUNSTATE");
1217 }
1218
1219 /*
1220 * Give it reply buffers
1221 *
1222 * Do *not* except global credits.
1223 */
1224 for (val = 0, pptr = mpt->reply_phys;
1225 (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE);
1226 pptr += MPT_REPLY_SIZE) {
1227 mpt_free_reply(mpt, pptr);
1228 if (++val == mpt->mpt_global_credits - 1)
1229 break;
1230 }
1231
1232 /* XXX MU correct place the call to fw_upload? */
1233 if (mpt->upload_fw) {
1234 if (mpt->verbose > 1) {
1235 mpt_prt(mpt, "firmware upload required.");
1236 }
1237
1238 if (mpt_do_upload(mpt)) {
1239 /* XXX MP should we panic? */
1240 mpt_prt(mpt, "firmware upload failure!");
1241 }
1242 /* continue; */
1243 }
1244 else {
1245 if (mpt->verbose > 1) {
1246 mpt_prt(mpt, "firmware upload not required.");
1247 }
1248 }
1249
1250 /*
1251 * Enable asynchronous event reporting
1252 */
1253 mpt_send_event_request(mpt, 1);
1254
1255
1256 /*
1257 * Read set up initial configuration information
1258 * (SPI only for now)
1259 */
1260
1261 if (mpt->is_fc == 0) {
1262 if (mpt_read_config_info_spi(mpt)) {
1263 return (EIO);
1264 }
1265 if (mpt_set_initial_config_spi(mpt)) {
1266 return (EIO);
1267 }
1268 }
1269
1270 /*
1271 * Now enable the port
1272 */
1273 if (mpt_send_port_enable(mpt, 0) != MPT_OK) {
1274 mpt_prt(mpt, "failed to enable port 0");
1275 continue;
1276 }
1277
1278 if (mpt->verbose > 1) {
1279 mpt_prt(mpt, "enabled port 0");
1280 }
1281
1282 /* Everything worked */
1283 break;
1284 }
1285
1286 if (try >= MPT_MAX_TRYS) {
1287 mpt_prt(mpt, "failed to initialize IOC");
1288 return (EIO);
1289 }
1290
1291 if (mpt->verbose > 1) {
1292 mpt_prt(mpt, "enabling interrupts");
1293 }
1294
1295 mpt_enable_ints(mpt);
1296 return (0);
1297 }
1298
1299 /*
1300 * mpt_do_upload - create and send FWUpload request to MPT adapter port.
1301 *
1302 * Returns 0 for success, error for failure
1303 */
1304 int
mpt_do_upload(mpt_softc_t * mpt)1305 mpt_do_upload(mpt_softc_t *mpt)
1306 {
1307 u_int8_t request[MPT_RQSL(mpt)];
1308 FWUploadReply_t reply;
1309 FWUpload_t *prequest;
1310 FWUploadReply_t *preply;
1311 FWUploadTCSGE_t *ptcsge = NULL;
1312 SGE_SIMPLE32 *se;
1313 int maxsgl;
1314 int sgeoffset;
1315 int i, error;
1316 uint32_t flags;
1317
1318 if (mpt->fw_image_size == 0 || mpt->fw != NULL) {
1319 return 0;
1320 }
1321
1322 /* compute the maximum number of elements in the SG list */
1323 maxsgl = (MPT_RQSL(mpt) - sizeof(MSG_FW_UPLOAD) +
1324 sizeof(SGE_MPI_UNION) - sizeof(FWUploadTCSGE_t))
1325 / sizeof(SGE_SIMPLE32);
1326
1327 error = mpt_alloc_fw_mem(mpt, mpt->fw_image_size, maxsgl);
1328 if (error) {
1329 mpt_prt(mpt,"mpt_alloc_fw_mem error: %d", error);
1330 return error;
1331 }
1332
1333 if (mpt->fw_dmap->dm_nsegs > maxsgl) {
1334 mpt_prt(mpt,"nsegs > maxsgl");
1335 return 1; /* XXX */
1336 }
1337
1338 prequest = (FWUpload_t *)&request;
1339 preply = (FWUploadReply_t *)&reply;
1340
1341 memset(prequest, 0, MPT_RQSL(mpt));
1342 memset(preply, 0, sizeof(reply));
1343
1344 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
1345 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
1346 prequest->MsgContext = 0;
1347
1348 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
1349 ptcsge->Reserved = 0;
1350 ptcsge->ContextSize = 0;
1351 ptcsge->DetailsLength = 12;
1352 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
1353 ptcsge->Reserved1 = 0;
1354 ptcsge->ImageOffset = 0;
1355 ptcsge->ImageSize = mpt->fw_image_size; /* XXX MU check endianess */
1356
1357 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) +
1358 sizeof(FWUploadTCSGE_t);
1359
1360 se = (SGE_SIMPLE32 *) &request[sgeoffset];
1361
1362 flags = MPI_SGE_FLAGS_SIMPLE_ELEMENT;
1363
1364 if (mpt->verbose > 1) {
1365 mpt_prt(mpt, "assembling SG list (%d entries)",
1366 mpt->fw_dmap->dm_nsegs);
1367 }
1368
1369 for (i = 0; i < mpt->fw_dmap->dm_nsegs; i++, se++) {
1370 if (i == mpt->fw_dmap->dm_nsegs - 1) {
1371 /* XXX MU okay? */
1372 flags |= MPI_SGE_FLAGS_LAST_ELEMENT |
1373 MPI_SGE_FLAGS_END_OF_BUFFER |
1374 MPI_SGE_FLAGS_END_OF_LIST;
1375 }
1376
1377 se->Address = mpt->fw_dmap->dm_segs[i].ds_addr;
1378 MPI_pSGE_SET_LENGTH(se, mpt->fw_dmap->dm_segs[i].ds_len);
1379 MPI_pSGE_SET_FLAGS(se, flags);
1380 sgeoffset += sizeof(*se);
1381 }
1382
1383 mpt_prt(mpt, "sending FW Upload request to IOC (size: %d, "
1384 "img size: %d)", sgeoffset, mpt->fw_image_size);
1385
1386 if ((error = mpt_send_handshake_cmd(mpt, sgeoffset, prequest)) != 0) {
1387 return(error);
1388 }
1389
1390 error = mpt_recv_handshake_reply(mpt, sizeof(reply), &reply);
1391
1392 if (error == 0) {
1393 /*
1394 * Handshake transfer was complete and successfull.
1395 * Check the Reply Frame
1396 */
1397 int status, transfer_sz;
1398
1399 status = preply->IOCStatus;
1400 if (mpt->verbose > 1) {
1401 mpt_prt(mpt, "fw_upload reply status %d", status);
1402 }
1403
1404 if (status == MPI_IOCSTATUS_SUCCESS) {
1405 transfer_sz = preply->ActualImageSize;
1406 if (transfer_sz != mpt->fw_image_size)
1407 error = EFAULT;
1408 }
1409 else {
1410 error = EFAULT;
1411 }
1412 }
1413
1414 if (error == 0) {
1415 mpt->upload_fw = 0;
1416 }
1417 else {
1418 mpt_prt(mpt, "freeing image memory");
1419 mpt_free_fw_mem(mpt);
1420 mpt->fw = NULL;
1421 }
1422
1423 return error;
1424 }
1425
1426 /*
1427 * mpt_downloadboot - DownloadBoot code
1428 * Returns 0 for success, <0 for failure
1429 */
1430 int
mpt_downloadboot(mpt_softc_t * mpt)1431 mpt_downloadboot(mpt_softc_t *mpt)
1432 {
1433 MpiFwHeader_t *fwhdr = NULL;
1434 MpiExtImageHeader_t *exthdr = NULL;
1435 int fw_size;
1436 u_int32_t diag0;
1437 #if MPT_DEBUG
1438 u_int32_t diag1;
1439 #endif
1440 int count = 0;
1441 u_int32_t *ptr = NULL;
1442 u_int32_t nextimg;
1443 u_int32_t load_addr;
1444 u_int32_t diagrw_data;
1445
1446 #ifdef MPT_DEBUG
1447 diag0 = mpt_read(mpt, MPT_OFFSET_DIAGNOSTIC);
1448 if (mpt->mpt2)
1449 diag1 = mpt_read(mpt->mpt2, MPT_OFFSET_DIAGNOSTIC);
1450 mpt_prt(mpt, "diag0=%08x, diag1=%08x", diag0, diag1);
1451 #endif
1452 mpt_prt(mpt, "fw size 0x%x, ioc FW ptr %p", mpt->fw_image_size,
1453 mpt->fw);
1454 if (mpt->mpt2)
1455 mpt_prt(mpt->mpt2, "ioc FW ptr %p", mpt->mpt2->fw);
1456
1457 fw_size = mpt->fw_image_size;
1458
1459 if (fw_size == 0)
1460 return -1;
1461
1462 mpt_prt(mpt, "FW Image @ %p", mpt->fw);
1463
1464 if (!mpt->fw)
1465 return -2;
1466
1467 /*
1468 * Write magic sequence to WriteSequence register
1469 * until enter diagnostic mode
1470 */
1471 diag0 = mpt_read(mpt, MPT_OFFSET_DIAGNOSTIC);
1472 while ((diag0 & MPI_DIAG_DRWE) == 0) {
1473 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
1474 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_1);
1475 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_2);
1476 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_3);
1477 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_4);
1478 mpt_write(mpt, MPT_OFFSET_SEQUENCE, MPT_DIAG_SEQUENCE_5);
1479
1480 /* wait 100msec */
1481 DELAY(100);
1482
1483 count++;
1484 if (count > 20) {
1485 mpt_prt(mpt, "enable diagnostic mode FAILED! (%02xh)",
1486 diag0);
1487 return -EFAULT;
1488 }
1489
1490 diag0 = mpt_read(mpt, MPT_OFFSET_DIAGNOSTIC);
1491 #ifdef MPT_DEBUG
1492 if (mpt->mpt2)
1493 diag1 = mpt_read(mpt->mpt2, MPT_OFFSET_DIAGNOSTIC);
1494 mpt_prt(mpt, "diag0=%08x, diag1=%08x", diag0, diag1);
1495 #endif
1496 mpt_prt(mpt, "wrote magic DiagWriteEn sequence (%x)", diag0);
1497 }
1498
1499 /* Set the DiagRwEn and Disable ARM bits */
1500 diag0 |= (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM);
1501 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, diag0);
1502
1503 #ifdef MPT_DEBUG
1504 if (mpt->mpt2)
1505 diag1 = mpt_read(mpt->mpt2, MPT_OFFSET_DIAGNOSTIC);
1506 mpt_prt(mpt, "diag0=%08x, diag1=%08x", diag0, diag1);
1507 #endif
1508
1509 fwhdr = (MpiFwHeader_t *) mpt->fw;
1510 ptr = (u_int32_t *) fwhdr;
1511 count = (fwhdr->ImageSize + 3)/4;
1512 nextimg = fwhdr->NextImageHeaderOffset;
1513
1514 /*
1515 * write the LoadStartAddress to the DiagRw Address Register
1516 * XXX linux is using programmed IO for the RWADDR and RWDATA
1517 */
1518 mpt_write(mpt, MPT_OFFSET_RWADDR, fwhdr->LoadStartAddress);
1519
1520 mpt_prt(mpt, "LoadStart addr written 0x%x", fwhdr->LoadStartAddress);
1521 mpt_prt(mpt, "writing file image: 0x%x u32's @ %p", count, ptr);
1522
1523 while (count--) {
1524 mpt_write(mpt, MPT_OFFSET_RWDATA, *ptr);
1525 ptr++;
1526 }
1527
1528 while (nextimg) {
1529 ptr = (u_int32_t *) (mpt->fw + nextimg);
1530 exthdr = (MpiExtImageHeader_t *) ptr;
1531 count = (exthdr->ImageSize +3)/4;
1532 nextimg = exthdr->NextImageHeaderOffset;
1533 load_addr = exthdr->LoadStartAddress;
1534
1535 mpt_prt(mpt, "write ext image: 0x%x u32's @ %p", count, ptr);
1536
1537 mpt_write(mpt, MPT_OFFSET_RWADDR, load_addr);
1538
1539 while (count--) {
1540 mpt_write(mpt, MPT_OFFSET_RWDATA, *ptr);
1541 ptr++;
1542 }
1543 }
1544
1545 /* write the IopResetVectorRegAddr */
1546 mpt_prt(mpt, "write IopResetVector addr!");
1547 mpt_write(mpt, MPT_OFFSET_RWADDR, fwhdr->IopResetRegAddr);
1548
1549 /* write the IopResetVectorValue */
1550 mpt_prt(mpt, "write IopResetVector value!");
1551 mpt_write(mpt, MPT_OFFSET_RWDATA, fwhdr->IopResetVectorValue);
1552
1553 /*
1554 * clear the internal flash bad bit - autoincrementing register,
1555 * so must do two writes.
1556 */
1557 mpt_write(mpt, MPT_OFFSET_RWADDR, 0x3F000000);
1558 diagrw_data = mpt_read(mpt, MPT_OFFSET_RWDATA);
1559 diagrw_data |= 0x4000000;
1560 mpt_write(mpt, MPT_OFFSET_RWADDR, 0x3F000000);
1561 mpt_write(mpt, MPT_OFFSET_RWDATA, diagrw_data);
1562
1563 /* clear the RW enable and DISARM bits */
1564 diag0 = mpt_read(mpt, MPT_OFFSET_DIAGNOSTIC);
1565 diag0 &= ~(MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE
1566 | MPI_DIAG_FLASH_BAD_SIG);
1567 mpt_write(mpt, MPT_OFFSET_DIAGNOSTIC, diag0);
1568
1569 /* write 0xFF to reset the sequencer */
1570 mpt_write(mpt, MPT_OFFSET_SEQUENCE, 0xFF);
1571
1572 return 0;
1573 }
1574