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