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