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