xref: /freebsd/sys/dev/ips/ips.c (revision b52f49a9a0f22207ad5130ad8faba08de3ed23d8)
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 *) 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         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 				&sc->command_dmatag) != 0) {
340                 device_printf(sc->dev, "can't alloc command dma tag\n");
341 		goto error;
342         }
343 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
344 				/* alignemnt */	1,
345 				/* boundary  */	0,
346 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
347 				/* highaddr  */	BUS_SPACE_MAXADDR,
348 				/* filter    */	NULL,
349 				/* filterarg */	NULL,
350 				/* maxsize   */	IPS_MAX_IOBUF_SIZE,
351 				/* numsegs   */	IPS_MAX_SG_ELEMENTS,
352 				/* maxsegsize*/	IPS_MAX_IOBUF_SIZE,
353 				/* flags     */	0,
354 				&sc->sg_dmatag) != 0) {
355 		device_printf(sc->dev, "can't alloc SG dma tag\n");
356 		goto error;
357 	}
358 	/* create one command buffer until we know how many commands this card
359            can handle */
360 	sc->max_cmds = 1;
361 	ips_cmdqueue_init(sc);
362 
363 	if(sc->ips_adapter_reinit(sc, 0))
364 		goto error;
365 
366 	mtx_init(&sc->cmd_mtx, "ips command mutex", NULL, MTX_DEF);
367 	if(ips_get_adapter_info(sc) || ips_get_drive_info(sc)){
368 		device_printf(sc->dev, "failed to get configuration data from device\n");
369 		goto error;
370 	}
371 	ips_update_nvram(sc); /* no error check as failure doesn't matter */
372 
373         ips_cmdqueue_free(sc);
374 	if(sc->adapter_info.max_concurrent_cmds)
375         	sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
376 	else
377 		sc->max_cmds = 32;
378         if(ips_cmdqueue_init(sc)){
379 		device_printf(sc->dev, "failed to initialize command buffers\n");
380 		goto error;
381 	}
382         sc->device_file = make_dev(&ips_cdevsw, device_get_unit(sc->dev), UID_ROOT, GID_OPERATOR,
383                                         S_IRUSR | S_IWUSR, "ips%d", device_get_unit(sc->dev));
384 	sc->device_file->si_drv1 = sc;
385 	ips_diskdev_init(sc);
386 	sc->timer = timeout(ips_timeout, sc, 10*hz);
387         return 0;
388 
389 error:
390 	ips_adapter_free(sc);
391 	return ENXIO;
392 }
393 
394 /* see if we should reinitialize the card and wait for it to timeout or complete initialization */
395 int ips_morpheus_reinit(ips_softc_t *sc, int force)
396 {
397         u_int32_t tmp;
398 	int i;
399 
400 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
401 	if(!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
402 	    (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp){
403 		ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
404 		return 0;
405 	}
406 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
407 	ips_read_4(sc, MORPHEUS_REG_OIMR);
408 
409 	device_printf(sc->dev, "resetting adapter, this may take up to 5 minutes\n");
410 	ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
411 	DELAY(5000000);
412 	pci_read_config(sc->dev, 0, 4);
413 
414 	tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
415 	for(i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++){
416 		DELAY(1000000);
417 		DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
418 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
419 	}
420 	if(tmp & MORPHEUS_BIT_POST1)
421 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
422 
423         if( i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK){
424                 device_printf(sc->dev,"Adapter error during initialization.\n");
425 		return 1;
426         }
427 	for(i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++){
428 		DELAY(1000000);
429 		DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
430 		tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
431 	}
432 	if(tmp & MORPHEUS_BIT_POST2)
433 		ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
434 
435 	if(i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)){
436 		device_printf(sc->dev, "adapter failed config check\n");
437 		return 1;
438         }
439 	ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
440 	if(force && ips_clear_adapter(sc)){
441 		device_printf(sc->dev, "adapter clear failed\n");
442 		return 1;
443 	}
444 	return 0;
445 }
446 
447 /* clean up so we can unload the driver. */
448 int ips_adapter_free(ips_softc_t *sc)
449 {
450 	int error = 0;
451 	intrmask_t mask;
452 	if(sc->state & IPS_DEV_OPEN)
453 		return EBUSY;
454 	if((error = ips_diskdev_free(sc)))
455 		return error;
456 	if(ips_cmdqueue_free(sc)){
457 		device_printf(sc->dev,
458 		     "trying to exit when command queue is not empty!\n");
459 		return EBUSY;
460 	}
461 	DEVICE_PRINTF(1, sc->dev, "free\n");
462 	mask = splbio();
463 	untimeout(ips_timeout, sc, sc->timer);
464 	splx(mask);
465 	if (mtx_initialized(&sc->cmd_mtx))
466 		mtx_destroy(&sc->cmd_mtx);
467 
468 	if(sc->sg_dmatag)
469 		bus_dma_tag_destroy(sc->sg_dmatag);
470 	if(sc->command_dmatag)
471 		bus_dma_tag_destroy(sc->command_dmatag);
472 	if(sc->device_file)
473 	        destroy_dev(sc->device_file);
474         return 0;
475 }
476 
477 void ips_morpheus_intr(void *void_sc)
478 {
479         ips_softc_t *sc = (ips_softc_t *)void_sc;
480 	u_int32_t oisr, iisr;
481 	int cmdnumber;
482 	ips_cmd_status_t status;
483 
484 	iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
485 	oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
486         PRINTF(9,"interrupt registers in:%x out:%x\n",iisr, oisr);
487 	if(!(oisr & MORPHEUS_BIT_CMD_IRQ)){
488 		DEVICE_PRINTF(2,sc->dev, "got a non-command irq\n");
489 		return;
490 	}
491 	while((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR)) != 0xffffffff){
492 		cmdnumber = status.fields.command_id;
493 		sc->commandarray[cmdnumber].status.value = status.value;
494 		sc->commandarray[cmdnumber].timeout = 0;
495 		sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
496 
497 
498 		DEVICE_PRINTF(9,sc->dev, "got command %d\n", cmdnumber);
499 	}
500         return;
501 }
502 
503 void ips_issue_morpheus_cmd(ips_command_t *command)
504 {
505 	intrmask_t mask = splbio();
506 	/* hmmm, is there a cleaner way to do this? */
507 	if(command->sc->state & IPS_OFFLINE){
508 		splx(mask);
509 		command->status.value = IPS_ERROR_STATUS;
510 		command->callback(command);
511 		return;
512 	}
513 	command->timeout = 10;
514 	ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
515 	splx(mask);
516 }
517 
518 static void ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,int segnum, int error)
519 {
520 	ips_copper_queue_t *queue = queueptr;
521 	if(error){
522 		return;
523 	}
524 	queue->base_phys_addr = segments[0].ds_addr;
525 }
526 
527 static int ips_copperhead_queue_init(ips_softc_t *sc)
528 {
529 	int error;
530 	bus_dma_tag_t dmatag;
531 	bus_dmamap_t dmamap;
532        	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
533 				/* alignemnt */	1,
534 				/* boundary  */	0,
535 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
536 				/* highaddr  */	BUS_SPACE_MAXADDR,
537 				/* filter    */	NULL,
538 				/* filterarg */	NULL,
539 				/* maxsize   */	sizeof(ips_copper_queue_t),
540 				/* numsegs   */	1,
541 				/* maxsegsize*/	sizeof(ips_copper_queue_t),
542 				/* flags     */	0,
543 				&dmatag) != 0) {
544                 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
545 		error = ENOMEM;
546 		goto exit;
547         }
548 	if(bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
549 	   		    BUS_DMA_NOWAIT, &dmamap)){
550 		error = ENOMEM;
551 		goto exit;
552 	}
553 	bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
554 	sc->copper_queue->dmatag = dmatag;
555 	sc->copper_queue->dmamap = dmamap;
556 	sc->copper_queue->nextstatus = 1;
557 	bus_dmamap_load(dmatag, dmamap,
558 			&(sc->copper_queue->status[0]), IPS_MAX_CMD_NUM * 4,
559 			ips_copperhead_queue_callback, sc->copper_queue,
560 			BUS_DMA_NOWAIT);
561 	if(sc->copper_queue->base_phys_addr == 0){
562 		error = ENOMEM;
563 		goto exit;
564 	}
565 	ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
566 	ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
567 		    IPS_MAX_CMD_NUM * 4);
568 	ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
569 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
570 
571 
572 	return 0;
573 exit:
574 	bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
575 	bus_dma_tag_destroy(dmatag);
576 	return error;
577 }
578 
579 /* see if we should reinitialize the card and wait for it to timeout or complete initialization FIXME */
580 int ips_copperhead_reinit(ips_softc_t *sc, int force)
581 {
582 	int i, j;
583 	u_int32_t postcode = 0, configstatus = 0;
584 	ips_write_1(sc, COPPER_REG_SCPR, 0x80);
585 	ips_write_1(sc, COPPER_REG_SCPR, 0);
586 	device_printf(sc->dev, "reinitializing adapter, this could take several minutes.\n");
587 	for(j = 0; j < 2; j++){
588 		postcode <<= 8;
589 		for(i = 0; i < 45; i++){
590 			if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
591 				postcode |= ips_read_1(sc, COPPER_REG_ISPR);
592 				ips_write_1(sc, COPPER_REG_HISR,
593 					    COPPER_GHI_BIT);
594 				break;
595 			} else
596 				DELAY(1000000);
597 		}
598 		if(i == 45)
599 			return 1;
600 	}
601 	for(j = 0; j < 2; j++){
602 		configstatus <<= 8;
603 		for(i = 0; i < 240; i++){
604 			if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
605 				configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
606 				ips_write_1(sc, COPPER_REG_HISR,
607 					    COPPER_GHI_BIT);
608 				break;
609 			} else
610 				DELAY(1000000);
611 		}
612 		if(i == 240)
613 			return 1;
614 	}
615 	for(i = 0; i < 240; i++){
616 		if(!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT)){
617 			break;
618 		} else
619 			DELAY(1000000);
620 	}
621 	if(i == 240)
622 		return 1;
623 	ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
624 	ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
625 	ips_copperhead_queue_init(sc);
626 	ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
627 	i = ips_read_1(sc, COPPER_REG_SCPR);
628 	ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
629 	if(!configstatus){
630 		device_printf(sc->dev, "adapter initialization failed\n");
631 		return 1;
632 	}
633 	if(force && ips_clear_adapter(sc)){
634 		device_printf(sc->dev, "adapter clear failed\n");
635 		return 1;
636 	}
637 	return 0;
638 }
639 static u_int32_t ips_copperhead_cmd_status(ips_softc_t *sc)
640 {
641 	intrmask_t mask;
642 	u_int32_t value;
643 	int statnum = sc->copper_queue->nextstatus++;
644 	if(sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
645 		sc->copper_queue->nextstatus = 0;
646 	mask = splbio();
647 	value = sc->copper_queue->status[statnum];
648 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
649 		    4 * statnum);
650 	splx(mask);
651 	return value;
652 }
653 
654 
655 void ips_copperhead_intr(void *void_sc)
656 {
657         ips_softc_t *sc = (ips_softc_t *)void_sc;
658 	int cmdnumber;
659 	ips_cmd_status_t status;
660 
661 	while(ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT){
662 		status.value = ips_copperhead_cmd_status(sc);
663 		cmdnumber = status.fields.command_id;
664 		sc->commandarray[cmdnumber].status.value = status.value;
665 		sc->commandarray[cmdnumber].timeout = 0;
666 		sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
667 		PRINTF(9, "ips: got command %d\n", cmdnumber);
668 	}
669         return;
670 }
671 
672 void ips_issue_copperhead_cmd(ips_command_t *command)
673 {
674 	int i;
675 	intrmask_t mask = splbio();
676 	/* hmmm, is there a cleaner way to do this? */
677 	if(command->sc->state & IPS_OFFLINE){
678 		splx(mask);
679 		command->status.value = IPS_ERROR_STATUS;
680 		command->callback(command);
681 		return;
682 	}
683 	command->timeout = 10;
684 	for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
685 	    i++ ){
686 		if( i == 20){
687 printf("sem bit still set, can't send a command\n");
688 			splx(mask);
689 			return;
690 		}
691 		DELAY(500);/* need to do a delay here */
692 	}
693 	ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
694 	ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
695 	splx(mask);
696 }
697 
698