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