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