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