xref: /dragonfly/sys/dev/raid/ips/ips.c (revision d5f516c3)
1 /*-
2  * Written by: David Jeffery
3  * Copyright (c) 2002 Adaptec Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD: src/sys/dev/ips/ips.c,v 1.12 2004/05/30 04:01:29 scottl Exp $
28  * $DragonFly: src/sys/dev/raid/ips/ips.c,v 1.9 2004/09/15 15:22:02 joerg Exp $
29  */
30 
31 #include <dev/raid/ips/ips.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <machine/clock.h>
35 
36 static d_open_t ips_open;
37 static d_close_t ips_close;
38 static d_ioctl_t ips_ioctl;
39 
40 MALLOC_DEFINE(M_IPSBUF, "ipsbuf", "IPS driver buffer");
41 
42 static struct cdevsw ips_cdevsw = {
43 	.d_name		= "ips",
44 	.d_maj		= IPS_CDEV_MAJOR,
45 	.d_flags	= D_DISK,
46 	.d_port		= NULL,
47 	.d_clone	= NULL,
48 	.old_open	= ips_open,
49 	.old_close	= ips_close,
50 	.old_ioctl	= ips_ioctl,
51 };
52 
53 static const char *ips_adapter_name[] = {
54 	"N/A",
55 	"ServeRAID (copperhead)",
56 	"ServeRAID II (copperhead refresh)",
57 	"ServeRAID onboard (copperhead)",
58 	"ServeRAID onboard (copperhead)",
59 	"ServeRAID 3H (clarinet)",
60 	"ServeRAID 3L (clarinet lite)",
61 	"ServeRAID 4H (trombone)",
62 	"ServeRAID 4M (morpheus)",
63 	"ServeRAID 4L (morpheus lite)",
64 	"ServeRAID 4Mx (neo)",
65 	"ServeRAID 4Lx (neo lite)",
66 	"ServeRAID 5i II (sarasota)",
67 	"ServeRAID 5i (sarasota)",
68 	"ServeRAID 6M (marco)",
69 	"ServeRAID 6i (sebring)"
70 };
71 
72 
73 static int
74 ips_open(dev_t dev, int flags, int fmt, d_thread_t *td)
75 {
76 	ips_softc_t *sc = dev->si_drv1;
77 
78 	sc->state |= IPS_DEV_OPEN;
79 	return 0;
80 }
81 
82 static int
83 ips_close(dev_t dev, int flags, int fmt, d_thread_t *td)
84 {
85 	ips_softc_t *sc = dev->si_drv1;
86 
87 	sc->state &= ~IPS_DEV_OPEN;
88 	return 0;
89 }
90 
91 static int
92 ips_ioctl(dev_t dev, u_long command, caddr_t addr, int32_t flags,
93     d_thread_t *td)
94 {
95 	ips_softc_t *sc;
96 
97 	sc = dev->si_drv1;
98 	return ips_ioctl_request(sc, command, addr, flags);
99 }
100 
101 static void
102 ips_cmd_dmaload(void *cmdptr, bus_dma_segment_t *segments, int segnum,
103     int error)
104 {
105 	ips_command_t *command = cmdptr;
106 
107 	PRINTF(10, "ips: in ips_cmd_dmaload\n");
108 	if (!error)
109 		command->command_phys_addr = segments[0].ds_addr;
110 
111 }
112 
113 /* is locking needed? what locking guarentees are there on removal? */
114 static __inline__ int
115 ips_cmdqueue_free(ips_softc_t *sc)
116 {
117 	int i, error = -1;
118 	ips_command_t *command;
119 	intrmask_t mask;
120 
121 	mask = splbio();
122 	if (sc->used_commands == 0) {
123 		for (i = 0; i < sc->max_cmds; i++) {
124 			command = &sc->commandarray[i];
125 			if (command->command_phys_addr == 0)
126 				continue;
127 			bus_dmamap_unload(sc->command_dmatag,
128 			    command->command_dmamap);
129 			bus_dmamem_free(sc->command_dmatag,
130 			    command->command_buffer,
131 			    command->command_dmamap);
132 		}
133 		error = 0;
134 		sc->state |= IPS_OFFLINE;
135 	}
136 	splx(mask);
137 	return error;
138 }
139 
140 /* places all ips command structs on the free command queue.  No locking as if someone else tries
141  * to access this during init, we have bigger problems */
142 static __inline__ int
143 ips_cmdqueue_init(ips_softc_t *sc)
144 {
145 	int i;
146 	ips_command_t *command;
147 
148 	SLIST_INIT(&sc->free_cmd_list);
149 	STAILQ_INIT(&sc->cmd_wait_list);
150 	for (i = 0; i < sc->max_cmds; i++) {
151 		command = &sc->commandarray[i];
152 		command->id = i;
153 		command->sc = sc;
154 		if (bus_dmamem_alloc(sc->command_dmatag,
155 		    &command->command_buffer, BUS_DMA_NOWAIT,
156 		    &command->command_dmamap))
157 			goto error;
158 		bus_dmamap_load(sc->command_dmatag, command->command_dmamap,
159 		    command->command_buffer, IPS_COMMAND_LEN, ips_cmd_dmaload,
160 		    command, BUS_DMA_NOWAIT);
161 		if (command->command_phys_addr == 0) {
162 			bus_dmamem_free(sc->command_dmatag,
163 			    command->command_buffer, command->command_dmamap);
164 			goto error;
165 		}
166 		SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
167 	}
168 	sc->state &= ~IPS_OFFLINE;
169 	return 0;
170 error:
171 	ips_cmdqueue_free(sc);
172 	return ENOMEM;
173 }
174 
175 static int
176 ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *),
177     void *data)
178 {
179 	intrmask_t mask;
180 	ips_command_t *command;
181 	ips_wait_list_t *waiter;
182 
183 	waiter = malloc(sizeof(ips_wait_list_t), M_IPSBUF, M_INTWAIT);
184 	mask = splbio();
185 	if (sc->state & IPS_OFFLINE) {
186 		splx(mask);
187 		free(waiter, M_IPSBUF);
188 		return EIO;
189 	}
190 	command = SLIST_FIRST(&sc->free_cmd_list);
191 	if (command && !(sc->state & IPS_TIMEOUT)) {
192 		SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
193 		sc->used_commands++;
194 		splx(mask);
195 		clear_ips_command(command);
196 		bzero(command->command_buffer, IPS_COMMAND_LEN);
197 		free(waiter, M_IPSBUF);
198 		command->arg = data;
199 		return callback(command);
200 	}
201 	DEVICE_PRINTF(1, sc->dev, "adding command to the wait queue\n");
202 	waiter->callback = callback;
203 	waiter->data = data;
204 	STAILQ_INSERT_TAIL(&sc->cmd_wait_list, waiter, next);
205 	splx(mask);
206 	return 0;
207 }
208 
209 static void
210 ips_run_waiting_command(ips_softc_t *sc)
211 {
212 	ips_wait_list_t *waiter;
213 	ips_command_t	*command;
214 	int (*callback)(ips_command_t*);
215 	intrmask_t mask;
216 
217 	mask = splbio();
218 	waiter = STAILQ_FIRST(&sc->cmd_wait_list);
219 	command = SLIST_FIRST(&sc->free_cmd_list);
220 	if (waiter == NULL || command == NULL) {
221 		splx(mask);
222 		return;
223 	}
224 	DEVICE_PRINTF(1, sc->dev, "removing command from wait queue\n");
225 	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
226 	STAILQ_REMOVE_HEAD(&sc->cmd_wait_list, next);
227 	sc->used_commands++;
228 	splx(mask);
229 	clear_ips_command(command);
230 	bzero(command->command_buffer, IPS_COMMAND_LEN);
231 	command->arg = waiter->data;
232 	callback = waiter->callback;
233 	free(waiter, M_IPSBUF);
234 	callback(command);
235 	return;
236 }
237 
238 /*
239  * returns a free command struct if one is available.
240  * It also blanks out anything that may be a wild pointer/value.
241  * Also, command buffers are not freed.  They are
242  * small so they are saved and kept dmamapped and loaded.
243  */
244 int
245 ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data,
246     unsigned long flags)
247 {
248 	ips_command_t *command;
249 	intrmask_t mask;
250 
251 	mask = splbio();
252 	if (sc->state & IPS_OFFLINE) {
253 		splx(mask);
254 		return EIO;
255 	}
256 	command = SLIST_FIRST(&sc->free_cmd_list);
257 	if (!command || (sc->state & IPS_TIMEOUT)) {
258 		splx(mask);
259 		if (flags & IPS_NOWAIT_FLAG)
260 			return EAGAIN;
261 		return ips_add_waiting_command(sc, callback, data);
262 	}
263 	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
264 	sc->used_commands++;
265 	splx(mask);
266 	clear_ips_command(command);
267 	bzero(command->command_buffer, IPS_COMMAND_LEN);
268 	command->arg = data;
269 	return callback(command);
270 }
271 
272 /* adds a command back to the free command queue */
273 void
274 ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command)
275 {
276 	intrmask_t mask;
277 
278 	mask = splbio();
279 	SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
280 	sc->used_commands--;
281 	splx(mask);
282 	if (!(sc->state & IPS_TIMEOUT))
283 		ips_run_waiting_command(sc);
284 }
285 static const char *
286 ips_diskdev_statename(u_int8_t state)
287 {
288 	static char statebuf[20];
289 
290 	switch(state) {
291 	case IPS_LD_OFFLINE:
292 		return("OFFLINE");
293 		break;
294 	case IPS_LD_OKAY:
295 		return("OK");
296 		break;
297 	case IPS_LD_DEGRADED:
298 		return("DEGRADED");
299 		break;
300 	case IPS_LD_FREE:
301 		return("FREE");
302 		break;
303 	case IPS_LD_SYS:
304 		return("SYS");
305 		break;
306 	case IPS_LD_CRS:
307 		return("CRS");
308 		break;
309 	}
310 	sprintf(statebuf, "UNKNOWN(0x%02x)", state);
311 	return (statebuf);
312 }
313 
314 static int
315 ips_diskdev_init(ips_softc_t *sc)
316 {
317 	int i;
318 
319 	for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
320 		if (sc->drives[i].state == IPS_LD_FREE)
321 			continue;
322 		device_printf(sc->dev,
323 		    "Logical Drive %d: RAID%d sectors: %u, state %s\n", i,
324 		    sc->drives[i].raid_lvl, sc->drives[i].sector_count,
325 		    ips_diskdev_statename(sc->drives[i].state));
326 		if (sc->drives[i].state == IPS_LD_OKAY ||
327 		    sc->drives[i].state == IPS_LD_DEGRADED) {
328 			sc->diskdev[i] = device_add_child(sc->dev, NULL, -1);
329 			device_set_ivars(sc->diskdev[i], (void *)(uintptr_t)i);
330 		}
331 	}
332 	if (bus_generic_attach(sc->dev))
333 		device_printf(sc->dev, "Attaching bus failed\n");
334 	return 0;
335 }
336 
337 static int
338 ips_diskdev_free(ips_softc_t *sc)
339 {
340 	int i;
341 	int error = 0;
342 
343 	for (i = 0; i < IPS_MAX_NUM_DRIVES; i++) {
344 		if (sc->diskdev[i] != NULL) {
345 			error = device_delete_child(sc->dev, sc->diskdev[i]);
346 			if (error)
347 				return error;
348 		}
349 	}
350 	bus_generic_detach(sc->dev);
351 	return 0;
352 }
353 
354 /*
355  * ips_timeout is periodically called to make sure no commands sent
356  * to the card have become stuck.  If it finds a stuck command, it
357  * sets a flag so the driver won't start any more commands and then
358  * is periodically called to see if all outstanding commands have
359  * either finished or timed out.  Once timed out, an attempt to
360  * reinitialize the card is made.  If that fails, the driver gives
361  * up and declares the card dead.
362  */
363 static void
364 ips_timeout(void *arg)
365 {
366 	ips_command_t *command;
367 	ips_softc_t *sc = arg;
368 	intrmask_t mask;
369 	int i, state = 0;
370 
371 	command = &sc->commandarray[0];
372 	mask = splbio();
373 	for (i = 0; i < sc->max_cmds; i++) {
374 		if (!command[i].timeout)
375 			continue;
376 		command[i].timeout--;
377 		if (command[i].timeout == 0) {
378 			if (!(sc->state & IPS_TIMEOUT)) {
379 				sc->state |= IPS_TIMEOUT;
380 				device_printf(sc->dev, "WARNING: command timeout. Adapter is in toaster mode, resetting to known state\n");
381 			}
382 			command[i].status.value = IPS_ERROR_STATUS;
383 			command[i].callback(&command[i]);
384 			/* hmm, this should be enough cleanup */
385 		} else
386 			state = 1;
387 	}
388 	if (!state && (sc->state & IPS_TIMEOUT)) {
389 		if (sc->ips_adapter_reinit(sc, 1)) {
390 			device_printf(sc->dev, "AIEE! adapter reset failed, "
391 			    "giving up and going home! Have a nice day.\n");
392 			sc->state |= IPS_OFFLINE;
393 			sc->state &= ~IPS_TIMEOUT;
394 			/*
395 			 * Grr, I hate this solution. I run waiting commands
396 			 * one at a time and error them out just before they
397 			 * would go to the card. This sucks.
398 			 */
399 		} else
400 			sc->state &= ~IPS_TIMEOUT;
401 		ips_run_waiting_command(sc);
402 	}
403 	if (sc->state != IPS_OFFLINE)
404 		callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
405 	splx(mask);
406 }
407 
408 /* check card and initialize it */
409 int
410 ips_adapter_init(ips_softc_t *sc)
411 {
412 	int i;
413 	dev_t dev;
414 
415 	DEVICE_PRINTF(1, sc->dev, "initializing\n");
416 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
417 				/* alignemnt */	1,
418 				/* boundary  */	0,
419 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
420 				/* highaddr  */	BUS_SPACE_MAXADDR,
421 				/* filter    */	NULL,
422 				/* filterarg */	NULL,
423 				/* maxsize   */	IPS_COMMAND_LEN +
424 						    IPS_MAX_SG_LEN,
425 				/* numsegs   */	1,
426 				/* maxsegsize*/	IPS_COMMAND_LEN +
427 						    IPS_MAX_SG_LEN,
428 				/* flags     */	0,
429 				&sc->command_dmatag) != 0) {
430 		device_printf(sc->dev, "can't alloc command dma tag\n");
431 		goto error;
432 	}
433 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
434 				/* alignemnt */	1,
435 				/* boundary  */	0,
436 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
437 				/* highaddr  */	BUS_SPACE_MAXADDR,
438 				/* filter    */	NULL,
439 				/* filterarg */	NULL,
440 				/* maxsize   */	IPS_MAX_IOBUF_SIZE,
441 				/* numsegs   */	IPS_MAX_SG_ELEMENTS,
442 				/* maxsegsize*/	IPS_MAX_IOBUF_SIZE,
443 				/* flags     */	0,
444 				&sc->sg_dmatag) != 0) {
445 		device_printf(sc->dev, "can't alloc SG dma tag\n");
446 		goto error;
447 	}
448 	/*
449 	 * create one command buffer until we know how many commands this card
450 	 * can handle
451 	 */
452 	sc->max_cmds = 1;
453 	ips_cmdqueue_init(sc);
454 	callout_init(&sc->timer);
455 	if (sc->ips_adapter_reinit(sc, 0))
456 		goto error;
457 	IPS_LOCK_INIT(sc);
458 	/* initialize ffdc values */
459 	microtime(&sc->ffdc_resettime);
460 	sc->ffdc_resetcount = 1;
461 	if ((i = ips_ffdc_reset(sc)) != 0) {
462 		device_printf(sc->dev,
463 		    "failed to send ffdc reset to device (%d)\n", i);
464 		goto error;
465 	}
466 	if ((i = ips_get_adapter_info(sc)) != 0) {
467 		device_printf(sc->dev, "failed to get adapter configuration "
468 		    "data from device (%d)\n", i);
469 		goto error;
470 	}
471 	/* no error check as failure doesn't matter */
472 	ips_update_nvram(sc);
473 	if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
474 		device_printf(sc->dev, "adapter type: %s\n",
475 		    ips_adapter_name[sc->adapter_type]);
476 	}
477 	if ((i = ips_get_drive_info(sc)) != 0) {
478 		device_printf(sc->dev, "failed to get drive "
479 		    "configuration data from device (%d)\n", i);
480 		goto error;
481 	}
482 	ips_cmdqueue_free(sc);
483 	if (sc->adapter_info.max_concurrent_cmds)
484 		sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
485 	else
486 		sc->max_cmds = 32;
487 	if (ips_cmdqueue_init(sc)) {
488 		device_printf(sc->dev,
489 		    "failed to initialize command buffers\n");
490 		goto error;
491 	}
492 	cdevsw_add(&ips_cdevsw, -1, device_get_unit(sc->dev));
493 	dev = make_dev(&ips_cdevsw, device_get_unit(sc->dev),
494 				   UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
495 				   "ips%d", device_get_unit(sc->dev));
496 	dev->si_drv1 = sc;
497 	ips_diskdev_init(sc);
498 	callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
499 	return 0;
500 error:
501 	ips_adapter_free(sc);
502 	return ENXIO;
503 }
504 
505 /*
506  * see if we should reinitialize the card and wait for it to timeout
507  * or complete initialization
508  */
509 int
510 ips_morpheus_reinit(ips_softc_t *sc, int force)
511 {
512 	u_int32_t tmp;
513 	int i;
514 
515 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
516 	if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
517 	    (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
518 		ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
519 		return 0;
520 	}
521 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
522 	ips_read_4(sc, MORPHEUS_REG_OIMR);
523 	device_printf(sc->dev,
524 	    "resetting adapter, this may take up to 5 minutes\n");
525 	ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
526 	DELAY(5000000);
527 	pci_read_config(sc->dev, 0, 4);
528 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
529 	for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
530 		DELAY(1000000);
531 		DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
532 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
533 	}
534 	if (tmp & MORPHEUS_BIT_POST1)
535 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
536 
537 	if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
538 		device_printf(sc->dev,
539 		    "Adapter error during initialization.\n");
540 		return 1;
541 	}
542 	for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
543 		DELAY(1000000);
544 		DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
545 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
546 	}
547 	if (tmp & MORPHEUS_BIT_POST2)
548 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
549 
550 	if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
551 		device_printf(sc->dev, "adapter failed config check\n");
552 		return 1;
553 	}
554 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
555 	if (force && ips_clear_adapter(sc)) {
556 		device_printf(sc->dev, "adapter clear failed\n");
557 		return 1;
558 	}
559 	return 0;
560 }
561 
562 /* clean up so we can unload the driver. */
563 int
564 ips_adapter_free(ips_softc_t *sc)
565 {
566 	int error = 0;
567 	intrmask_t mask;
568 	if (sc->state & IPS_DEV_OPEN)
569 		return EBUSY;
570 	if ((error = ips_diskdev_free(sc)))
571 		return error;
572 	if (ips_cmdqueue_free(sc)) {
573 		device_printf(sc->dev,
574 		    "trying to exit when command queue is not empty!\n");
575 		return EBUSY;
576 	}
577 	DEVICE_PRINTF(1, sc->dev, "free\n");
578 	mask = splbio();
579 	callout_stop(&sc->timer);
580 	splx(mask);
581 	IPS_LOCK_FREE(sc);
582 	if (sc->sg_dmatag)
583 		bus_dma_tag_destroy(sc->sg_dmatag);
584 	if (sc->command_dmatag)
585 		bus_dma_tag_destroy(sc->command_dmatag);
586 	cdevsw_remove(&ips_cdevsw, -1, device_get_unit(sc->dev));
587 	return 0;
588 }
589 
590 void
591 ips_morpheus_intr(void *void_sc)
592 {
593 	ips_softc_t *sc = (ips_softc_t *)void_sc;
594 	u_int32_t oisr, iisr;
595 	ips_cmd_status_t status;
596 	ips_command_t *command;
597 	int cmdnumber;
598 
599 	iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
600 	oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
601 	PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
602 	if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
603 		DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
604 		return;
605 	}
606 	while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
607 	       != 0xffffffff) {
608 		cmdnumber = status.fields.command_id;
609 		command = &sc->commandarray[cmdnumber];
610 		command->status.value = status.value;
611 		command->timeout = 0;
612 		command->callback(command);
613 		DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
614 	}
615 	return;
616 }
617 
618 void
619 ips_issue_morpheus_cmd(ips_command_t *command)
620 {
621 	intrmask_t mask;
622 
623 	mask = splbio();
624 	/* hmmm, is there a cleaner way to do this? */
625 	if (command->sc->state & IPS_OFFLINE) {
626 		splx(mask);
627 		command->status.value = IPS_ERROR_STATUS;
628 		command->callback(command);
629 		return;
630 	}
631 	command->timeout = 10;
632 	ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
633 	splx(mask);
634 }
635 
636 static void
637 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
638 			      int segnum, int error)
639 {
640 	ips_copper_queue_t *queue = queueptr;
641 
642 	if (error)
643 		return;
644 	queue->base_phys_addr = segments[0].ds_addr;
645 }
646 
647 static int
648 ips_copperhead_queue_init(ips_softc_t *sc)
649 {
650 	bus_dma_tag_t dmatag;
651 	bus_dmamap_t dmamap;
652 	int error;
653 
654 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
655 				/* alignemnt */	1,
656 				/* boundary  */	0,
657 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
658 				/* highaddr  */	BUS_SPACE_MAXADDR,
659 				/* filter    */	NULL,
660 				/* filterarg */	NULL,
661 				/* maxsize   */	sizeof(ips_copper_queue_t),
662 				/* numsegs   */	1,
663 				/* maxsegsize*/	sizeof(ips_copper_queue_t),
664 				/* flags     */	0,
665 				&dmatag) != 0) {
666 		device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
667 		error = ENOMEM;
668 		goto exit;
669 	}
670 	if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
671 	    BUS_DMA_NOWAIT, &dmamap)) {
672 		error = ENOMEM;
673 		goto exit;
674 	}
675 	bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
676 	sc->copper_queue->dmatag = dmatag;
677 	sc->copper_queue->dmamap = dmamap;
678 	sc->copper_queue->nextstatus = 1;
679 	bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
680 	    IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
681 	    sc->copper_queue, BUS_DMA_NOWAIT);
682 	if (sc->copper_queue->base_phys_addr == 0) {
683 		error = ENOMEM;
684 		goto exit;
685 	}
686 	ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
687 	ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
688 	    IPS_MAX_CMD_NUM * 4);
689 	ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
690 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
691 	return 0;
692 exit:
693 	bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
694 	bus_dma_tag_destroy(dmatag);
695 	return error;
696 }
697 
698 /*
699  * see if we should reinitialize the card and wait for it to timeout or
700  * complete initialization FIXME
701  */
702 int
703 ips_copperhead_reinit(ips_softc_t *sc, int force)
704 {
705 	u_int32_t postcode = 0, configstatus = 0;
706 	int	  i, j;
707 
708 	ips_write_1(sc, COPPER_REG_SCPR, 0x80);
709 	ips_write_1(sc, COPPER_REG_SCPR, 0);
710 	device_printf(sc->dev,
711 	    "reinitializing adapter, this could take several minutes.\n");
712 	for (j = 0; j < 2; j++) {
713 		postcode <<= 8;
714 		for (i = 0; i < 45; i++) {
715 			if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
716 				postcode |= ips_read_1(sc, COPPER_REG_ISPR);
717 				ips_write_1(sc, COPPER_REG_HISR,
718 				    COPPER_GHI_BIT);
719 				break;
720 			} else
721 				DELAY(1000000);
722 		}
723 		if (i == 45)
724 			return 1;
725 	}
726 	for (j = 0; j < 2; j++) {
727 		configstatus <<= 8;
728 		for (i = 0; i < 240; i++) {
729 			if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
730 				configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
731 				ips_write_1(sc, COPPER_REG_HISR,
732 				    COPPER_GHI_BIT);
733 				break;
734 			} else
735 				DELAY(1000000);
736 		}
737 		if (i == 240)
738 			return 1;
739 	}
740 	for (i = 0; i < 240; i++) {
741 		if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
742 			break;
743 		else
744 			DELAY(1000000);
745 	}
746 	if (i == 240)
747 		return 1;
748 	ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
749 	ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
750 	ips_copperhead_queue_init(sc);
751 	ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
752 	i = ips_read_1(sc, COPPER_REG_SCPR);
753 	ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
754 	if (configstatus == 0) {
755 		device_printf(sc->dev, "adapter initialization failed\n");
756 		return 1;
757 	}
758 	if (force && ips_clear_adapter(sc)) {
759 		device_printf(sc->dev, "adapter clear failed\n");
760 		return 1;
761 	}
762 	return 0;
763 }
764 
765 static u_int32_t
766 ips_copperhead_cmd_status(ips_softc_t *sc)
767 {
768 	intrmask_t mask;
769 	u_int32_t value;
770 	int statnum;
771 
772 	statnum = sc->copper_queue->nextstatus++;
773 	if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
774 		sc->copper_queue->nextstatus = 0;
775 	mask = splbio();
776 	value = sc->copper_queue->status[statnum];
777 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
778 	    4 * statnum);
779 	splx(mask);
780 	return value;
781 }
782 
783 void
784 ips_copperhead_intr(void *void_sc)
785 {
786 	ips_softc_t *sc = (ips_softc_t *)void_sc;
787 	ips_cmd_status_t status;
788 	int cmdnumber;
789 
790 	while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
791 		status.value = ips_copperhead_cmd_status(sc);
792 		cmdnumber = status.fields.command_id;
793 		sc->commandarray[cmdnumber].status.value = status.value;
794 		sc->commandarray[cmdnumber].timeout = 0;
795 		sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
796 		PRINTF(9, "ips: got command %d\n", cmdnumber);
797 	}
798 	return;
799 }
800 
801 void
802 ips_issue_copperhead_cmd(ips_command_t *command)
803 {
804 	intrmask_t mask;
805 	int i;
806 
807 	mask = splbio();
808 	/* hmmm, is there a cleaner way to do this? */
809 	if (command->sc->state & IPS_OFFLINE) {
810 		splx(mask);
811 		command->status.value = IPS_ERROR_STATUS;
812 		command->callback(command);
813 		return;
814 	}
815 	command->timeout = 10;
816 	for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
817 	    i++) {
818 		if (i == 20) {
819 			printf("sem bit still set, can't send a command\n");
820 			splx(mask);
821 			return;
822 		}
823 		DELAY(500);	/* need to do a delay here */
824 	}
825 	ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
826 	ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
827 	splx(mask);
828 }
829