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