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