xref: /freebsd/sys/dev/ips/ips.c (revision 6af83ee0d2941d18880b6aaa2b4facd1d30c6106)
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 		mtx_unlock(&sc->queue_mtx);
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 	ts = time_second + command->timeout;
544 	while ((command->timeout != 0)
545 	 && (ips_morpheus_check_intr(command->sc) == 0)
546 	 && (ts > time_second))
547 		DELAY(1000);
548 }
549 
550 void ips_issue_morpheus_cmd(ips_command_t *command)
551 {
552 	/* hmmm, is there a cleaner way to do this? */
553 	if(command->sc->state & IPS_OFFLINE){
554 		command->status.value = IPS_ERROR_STATUS;
555 		command->callback(command);
556 		return;
557 	}
558 	command->timeout = 10;
559 	ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
560 }
561 
562 static void ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,int segnum, int error)
563 {
564 	ips_copper_queue_t *queue = queueptr;
565 	if(error){
566 		return;
567 	}
568 	queue->base_phys_addr = segments[0].ds_addr;
569 }
570 
571 static int ips_copperhead_queue_init(ips_softc_t *sc)
572 {
573 	int error;
574 	bus_dma_tag_t dmatag;
575 	bus_dmamap_t dmamap;
576        	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
577 				/* alignemnt */	1,
578 				/* boundary  */	0,
579 				/* lowaddr   */	BUS_SPACE_MAXADDR_32BIT,
580 				/* highaddr  */	BUS_SPACE_MAXADDR,
581 				/* filter    */	NULL,
582 				/* filterarg */	NULL,
583 				/* maxsize   */	sizeof(ips_copper_queue_t),
584 				/* numsegs   */	1,
585 				/* maxsegsize*/	sizeof(ips_copper_queue_t),
586 				/* flags     */	0,
587 				/* lockfunc  */ NULL,
588 				/* lockarg   */ NULL,
589 				&dmatag) != 0) {
590                 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
591 		error = ENOMEM;
592 		goto exit;
593         }
594 	if(bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
595 	   		    BUS_DMA_NOWAIT, &dmamap)){
596 		error = ENOMEM;
597 		goto exit;
598 	}
599 	bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
600 	sc->copper_queue->dmatag = dmatag;
601 	sc->copper_queue->dmamap = dmamap;
602 	sc->copper_queue->nextstatus = 1;
603 	bus_dmamap_load(dmatag, dmamap,
604 			&(sc->copper_queue->status[0]), IPS_MAX_CMD_NUM * 4,
605 			ips_copperhead_queue_callback, sc->copper_queue,
606 			BUS_DMA_NOWAIT);
607 	if(sc->copper_queue->base_phys_addr == 0){
608 		error = ENOMEM;
609 		goto exit;
610 	}
611 	ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
612 	ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
613 		    IPS_MAX_CMD_NUM * 4);
614 	ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
615 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
616 
617 
618 	return 0;
619 exit:
620 	bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
621 	bus_dma_tag_destroy(dmatag);
622 	return error;
623 }
624 
625 /* see if we should reinitialize the card and wait for it to timeout or complete initialization FIXME */
626 int ips_copperhead_reinit(ips_softc_t *sc, int force)
627 {
628 	int i, j;
629 	u_int32_t postcode = 0, configstatus = 0;
630 	ips_write_1(sc, COPPER_REG_SCPR, 0x80);
631 	ips_write_1(sc, COPPER_REG_SCPR, 0);
632 	device_printf(sc->dev, "reinitializing adapter, this could take several minutes.\n");
633 	for(j = 0; j < 2; j++){
634 		postcode <<= 8;
635 		for(i = 0; i < 45; i++){
636 			if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
637 				postcode |= ips_read_1(sc, COPPER_REG_ISPR);
638 				ips_write_1(sc, COPPER_REG_HISR,
639 					    COPPER_GHI_BIT);
640 				break;
641 			} else
642 				DELAY(1000000);
643 		}
644 		if(i == 45)
645 			return 1;
646 	}
647 	for(j = 0; j < 2; j++){
648 		configstatus <<= 8;
649 		for(i = 0; i < 240; i++){
650 			if(ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT){
651 				configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
652 				ips_write_1(sc, COPPER_REG_HISR,
653 					    COPPER_GHI_BIT);
654 				break;
655 			} else
656 				DELAY(1000000);
657 		}
658 		if(i == 240)
659 			return 1;
660 	}
661 	for(i = 0; i < 240; i++){
662 		if(!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT)){
663 			break;
664 		} else
665 			DELAY(1000000);
666 	}
667 	if(i == 240)
668 		return 1;
669 	ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
670 	ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
671 	ips_copperhead_queue_init(sc);
672 	ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
673 	i = ips_read_1(sc, COPPER_REG_SCPR);
674 	ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
675 	if(!configstatus){
676 		device_printf(sc->dev, "adapter initialization failed\n");
677 		return 1;
678 	}
679 	if(force && ips_clear_adapter(sc)){
680 		device_printf(sc->dev, "adapter clear failed\n");
681 		return 1;
682 	}
683 	return 0;
684 }
685 static u_int32_t ips_copperhead_cmd_status(ips_softc_t *sc)
686 {
687 	u_int32_t value;
688 	int statnum = sc->copper_queue->nextstatus++;
689 	if(sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
690 		sc->copper_queue->nextstatus = 0;
691 	value = sc->copper_queue->status[statnum];
692 	ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
693 		    4 * statnum);
694 	return value;
695 }
696 
697 
698 void ips_copperhead_intr(void *void_sc)
699 {
700         ips_softc_t *sc = (ips_softc_t *)void_sc;
701 	int cmdnumber;
702 	ips_cmd_status_t status;
703 
704 	mtx_lock(&sc->queue_mtx);
705 	while(ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT){
706 		status.value = ips_copperhead_cmd_status(sc);
707 		cmdnumber = status.fields.command_id;
708 		sc->commandarray[cmdnumber].status.value = status.value;
709 		sc->commandarray[cmdnumber].timeout = 0;
710 		sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
711 		PRINTF(9, "ips: got command %d\n", cmdnumber);
712 	}
713 	mtx_unlock(&sc->queue_mtx);
714         return;
715 }
716 
717 void ips_issue_copperhead_cmd(ips_command_t *command)
718 {
719 	int i;
720 	/* hmmm, is there a cleaner way to do this? */
721 	if(command->sc->state & IPS_OFFLINE){
722 		command->status.value = IPS_ERROR_STATUS;
723 		command->callback(command);
724 		return;
725 	}
726 	command->timeout = 10;
727 	for(i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
728 	    i++ ){
729 		if( i == 20){
730 printf("sem bit still set, can't send a command\n");
731 			return;
732 		}
733 		DELAY(500);/* need to do a delay here */
734 	}
735 	ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
736 	ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
737 }
738 
739 void ips_copperhead_poll(ips_command_t *command)
740 {
741 
742 	printf("ips: cmd polling not implemented for copperhead devices\n");
743 }
744