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