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