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