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