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