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