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