xref: /dragonfly/sys/dev/raid/ips/ips.c (revision 611395e5)
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.10 2004/12/10 04:09:46 y0netan1 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 	/* initialize ffdc values */
458 	microtime(&sc->ffdc_resettime);
459 	sc->ffdc_resetcount = 1;
460 	if ((i = ips_ffdc_reset(sc)) != 0) {
461 		device_printf(sc->dev,
462 		    "failed to send ffdc reset to device (%d)\n", i);
463 		goto error;
464 	}
465 	if ((i = ips_get_adapter_info(sc)) != 0) {
466 		device_printf(sc->dev, "failed to get adapter configuration "
467 		    "data from device (%d)\n", i);
468 		goto error;
469 	}
470 	/* no error check as failure doesn't matter */
471 	ips_update_nvram(sc);
472 	if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
473 		device_printf(sc->dev, "adapter type: %s\n",
474 		    ips_adapter_name[sc->adapter_type]);
475 	}
476 	if ((i = ips_get_drive_info(sc)) != 0) {
477 		device_printf(sc->dev, "failed to get drive "
478 		    "configuration data from device (%d)\n", i);
479 		goto error;
480 	}
481 	ips_cmdqueue_free(sc);
482 	if (sc->adapter_info.max_concurrent_cmds)
483 		sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
484 	else
485 		sc->max_cmds = 32;
486 	if (ips_cmdqueue_init(sc)) {
487 		device_printf(sc->dev,
488 		    "failed to initialize command buffers\n");
489 		goto error;
490 	}
491 	cdevsw_add(&ips_cdevsw, -1, device_get_unit(sc->dev));
492 	dev = make_dev(&ips_cdevsw, device_get_unit(sc->dev),
493 				   UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
494 				   "ips%d", device_get_unit(sc->dev));
495 	dev->si_drv1 = sc;
496 	ips_diskdev_init(sc);
497 	callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
498 	return 0;
499 error:
500 	ips_adapter_free(sc);
501 	return ENXIO;
502 }
503 
504 /*
505  * see if we should reinitialize the card and wait for it to timeout
506  * or complete initialization
507  */
508 int
509 ips_morpheus_reinit(ips_softc_t *sc, int force)
510 {
511 	u_int32_t tmp;
512 	int i;
513 
514 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
515 	if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
516 	    (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
517 		ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
518 		return 0;
519 	}
520 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
521 	ips_read_4(sc, MORPHEUS_REG_OIMR);
522 	device_printf(sc->dev,
523 	    "resetting adapter, this may take up to 5 minutes\n");
524 	ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
525 	DELAY(5000000);
526 	pci_read_config(sc->dev, 0, 4);
527 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
528 	for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
529 		DELAY(1000000);
530 		DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
531 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
532 	}
533 	if (tmp & MORPHEUS_BIT_POST1)
534 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
535 
536 	if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
537 		device_printf(sc->dev,
538 		    "Adapter error during initialization.\n");
539 		return 1;
540 	}
541 	for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
542 		DELAY(1000000);
543 		DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
544 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
545 	}
546 	if (tmp & MORPHEUS_BIT_POST2)
547 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
548 
549 	if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
550 		device_printf(sc->dev, "adapter failed config check\n");
551 		return 1;
552 	}
553 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
554 	if (force && ips_clear_adapter(sc)) {
555 		device_printf(sc->dev, "adapter clear failed\n");
556 		return 1;
557 	}
558 	return 0;
559 }
560 
561 /* clean up so we can unload the driver. */
562 int
563 ips_adapter_free(ips_softc_t *sc)
564 {
565 	int error = 0;
566 	intrmask_t mask;
567 	if (sc->state & IPS_DEV_OPEN)
568 		return EBUSY;
569 	if ((error = ips_diskdev_free(sc)))
570 		return error;
571 	if (ips_cmdqueue_free(sc)) {
572 		device_printf(sc->dev,
573 		    "trying to exit when command queue is not empty!\n");
574 		return EBUSY;
575 	}
576 	DEVICE_PRINTF(1, sc->dev, "free\n");
577 	mask = splbio();
578 	callout_stop(&sc->timer);
579 	splx(mask);
580 	if (sc->sg_dmatag)
581 		bus_dma_tag_destroy(sc->sg_dmatag);
582 	if (sc->command_dmatag)
583 		bus_dma_tag_destroy(sc->command_dmatag);
584 	cdevsw_remove(&ips_cdevsw, -1, device_get_unit(sc->dev));
585 	return 0;
586 }
587 
588 void
589 ips_morpheus_intr(void *void_sc)
590 {
591 	ips_softc_t *sc = (ips_softc_t *)void_sc;
592 	u_int32_t oisr, iisr;
593 	ips_cmd_status_t status;
594 	ips_command_t *command;
595 	int cmdnumber;
596 
597 	iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
598 	oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
599 	PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
600 	if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
601 		DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
602 		return;
603 	}
604 	while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
605 	       != 0xffffffff) {
606 		cmdnumber = status.fields.command_id;
607 		command = &sc->commandarray[cmdnumber];
608 		command->status.value = status.value;
609 		command->timeout = 0;
610 		command->callback(command);
611 		DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
612 	}
613 	return;
614 }
615 
616 void
617 ips_issue_morpheus_cmd(ips_command_t *command)
618 {
619 	intrmask_t mask;
620 
621 	mask = splbio();
622 	/* hmmm, is there a cleaner way to do this? */
623 	if (command->sc->state & IPS_OFFLINE) {
624 		splx(mask);
625 		command->status.value = IPS_ERROR_STATUS;
626 		command->callback(command);
627 		return;
628 	}
629 	command->timeout = 10;
630 	ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
631 	splx(mask);
632 }
633 
634 static void
635 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
636 			      int segnum, int error)
637 {
638 	ips_copper_queue_t *queue = queueptr;
639 
640 	if (error)
641 		return;
642 	queue->base_phys_addr = segments[0].ds_addr;
643 }
644 
645 static int
646 ips_copperhead_queue_init(ips_softc_t *sc)
647 {
648 	bus_dma_tag_t dmatag;
649 	bus_dmamap_t dmamap;
650 	int error;
651 
652 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
653 				/* alignemnt */	1,
654 				/* boundary  */	0,
655 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
656 				/* highaddr  */	BUS_SPACE_MAXADDR,
657 				/* filter    */	NULL,
658 				/* filterarg */	NULL,
659 				/* maxsize   */	sizeof(ips_copper_queue_t),
660 				/* numsegs   */	1,
661 				/* maxsegsize*/	sizeof(ips_copper_queue_t),
662 				/* flags     */	0,
663 				&dmatag) != 0) {
664 		device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
665 		error = ENOMEM;
666 		goto exit;
667 	}
668 	if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
669 	    BUS_DMA_NOWAIT, &dmamap)) {
670 		error = ENOMEM;
671 		goto exit;
672 	}
673 	bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
674 	sc->copper_queue->dmatag = dmatag;
675 	sc->copper_queue->dmamap = dmamap;
676 	sc->copper_queue->nextstatus = 1;
677 	bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
678 	    IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
679 	    sc->copper_queue, BUS_DMA_NOWAIT);
680 	if (sc->copper_queue->base_phys_addr == 0) {
681 		error = ENOMEM;
682 		goto exit;
683 	}
684 	ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
685 	ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
686 	    IPS_MAX_CMD_NUM * 4);
687 	ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
688 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
689 	return 0;
690 exit:
691 	bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
692 	bus_dma_tag_destroy(dmatag);
693 	return error;
694 }
695 
696 /*
697  * see if we should reinitialize the card and wait for it to timeout or
698  * complete initialization FIXME
699  */
700 int
701 ips_copperhead_reinit(ips_softc_t *sc, int force)
702 {
703 	u_int32_t postcode = 0, configstatus = 0;
704 	int	  i, j;
705 
706 	ips_write_1(sc, COPPER_REG_SCPR, 0x80);
707 	ips_write_1(sc, COPPER_REG_SCPR, 0);
708 	device_printf(sc->dev,
709 	    "reinitializing adapter, this could take several minutes.\n");
710 	for (j = 0; j < 2; j++) {
711 		postcode <<= 8;
712 		for (i = 0; i < 45; i++) {
713 			if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
714 				postcode |= ips_read_1(sc, COPPER_REG_ISPR);
715 				ips_write_1(sc, COPPER_REG_HISR,
716 				    COPPER_GHI_BIT);
717 				break;
718 			} else
719 				DELAY(1000000);
720 		}
721 		if (i == 45)
722 			return 1;
723 	}
724 	for (j = 0; j < 2; j++) {
725 		configstatus <<= 8;
726 		for (i = 0; i < 240; i++) {
727 			if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
728 				configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
729 				ips_write_1(sc, COPPER_REG_HISR,
730 				    COPPER_GHI_BIT);
731 				break;
732 			} else
733 				DELAY(1000000);
734 		}
735 		if (i == 240)
736 			return 1;
737 	}
738 	for (i = 0; i < 240; i++) {
739 		if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
740 			break;
741 		else
742 			DELAY(1000000);
743 	}
744 	if (i == 240)
745 		return 1;
746 	ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
747 	ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
748 	ips_copperhead_queue_init(sc);
749 	ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
750 	i = ips_read_1(sc, COPPER_REG_SCPR);
751 	ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
752 	if (configstatus == 0) {
753 		device_printf(sc->dev, "adapter initialization failed\n");
754 		return 1;
755 	}
756 	if (force && ips_clear_adapter(sc)) {
757 		device_printf(sc->dev, "adapter clear failed\n");
758 		return 1;
759 	}
760 	return 0;
761 }
762 
763 static u_int32_t
764 ips_copperhead_cmd_status(ips_softc_t *sc)
765 {
766 	intrmask_t mask;
767 	u_int32_t value;
768 	int statnum;
769 
770 	statnum = sc->copper_queue->nextstatus++;
771 	if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
772 		sc->copper_queue->nextstatus = 0;
773 	mask = splbio();
774 	value = sc->copper_queue->status[statnum];
775 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
776 	    4 * statnum);
777 	splx(mask);
778 	return value;
779 }
780 
781 void
782 ips_copperhead_intr(void *void_sc)
783 {
784 	ips_softc_t *sc = (ips_softc_t *)void_sc;
785 	ips_cmd_status_t status;
786 	int cmdnumber;
787 
788 	while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
789 		status.value = ips_copperhead_cmd_status(sc);
790 		cmdnumber = status.fields.command_id;
791 		sc->commandarray[cmdnumber].status.value = status.value;
792 		sc->commandarray[cmdnumber].timeout = 0;
793 		sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
794 		PRINTF(9, "ips: got command %d\n", cmdnumber);
795 	}
796 	return;
797 }
798 
799 void
800 ips_issue_copperhead_cmd(ips_command_t *command)
801 {
802 	intrmask_t mask;
803 	int i;
804 
805 	mask = splbio();
806 	/* hmmm, is there a cleaner way to do this? */
807 	if (command->sc->state & IPS_OFFLINE) {
808 		splx(mask);
809 		command->status.value = IPS_ERROR_STATUS;
810 		command->callback(command);
811 		return;
812 	}
813 	command->timeout = 10;
814 	for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
815 	    i++) {
816 		if (i == 20) {
817 			printf("sem bit still set, can't send a command\n");
818 			splx(mask);
819 			return;
820 		}
821 		DELAY(500);	/* need to do a delay here */
822 	}
823 	ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
824 	ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
825 	splx(mask);
826 }
827