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