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