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