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