timeout/untimeout ==> callout_*
[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.12 2004/05/30 04:01:29 scottl Exp $
28  * $DragonFly: src/sys/dev/raid/ips/ips.c,v 1.9 2004/09/15 15:22:02 joerg Exp $
29  */
30
31 #include <dev/raid/ips/ips.h>
32 #include <sys/stat.h>
33 #include <sys/time.h>
34 #include <machine/clock.h>
35
36 static d_open_t ips_open;
37 static d_close_t ips_close;
38 static d_ioctl_t ips_ioctl;
39
40 MALLOC_DEFINE(M_IPSBUF, "ipsbuf", "IPS driver buffer");
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         ips_command_t *command;
119         intrmask_t mask;
120
121         mask = splbio();
122         if (sc->used_commands == 0) {
123                 for (i = 0; i < sc->max_cmds; i++) {
124                         command = &sc->commandarray[i];
125                         if (command->command_phys_addr == 0)
126                                 continue;
127                         bus_dmamap_unload(sc->command_dmatag,
128                             command->command_dmamap);
129                         bus_dmamem_free(sc->command_dmatag,
130                             command->command_buffer,
131                             command->command_dmamap);
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 */
142 static __inline__ int
143 ips_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);
150         for (i = 0; i < sc->max_cmds; i++) {
151                 command = &sc->commandarray[i];
152                 command->id = i;
153                 command->sc = sc;
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                 }
166                 SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
167         }
168         sc->state &= ~IPS_OFFLINE;
169         return 0;
170 error:
171         ips_cmdqueue_free(sc);
172         return ENOMEM;
173 }
174
175 static int
176 ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *),
177     void *data)
178 {
179         intrmask_t mask;
180         ips_command_t *command;
181         ips_wait_list_t *waiter;
182
183         waiter = malloc(sizeof(ips_wait_list_t), M_IPSBUF, M_INTWAIT);
184         mask = splbio();
185         if (sc->state & IPS_OFFLINE) {
186                 splx(mask);
187                 free(waiter, M_IPSBUF);
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);
197                 free(waiter, M_IPSBUF);
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
209 static void
210 ips_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;
233         free(waiter, M_IPSBUF);
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  */
244 int
245 ips_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;
261                 return ips_add_waiting_command(sc, callback, data);
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 */
273 void
274 ips_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 }
285 static const char *
286 ips_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
314 static int
315 ips_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
337 static int
338 ips_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  */
363 static void
364 ips_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)
404                 callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
405         splx(mask);
406 }
407
408 /* check card and initialize it */
409 int
410 ips_adapter_init(ips_softc_t *sc)
411 {
412         int i;
413         dev_t dev;
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);
454         callout_init(&sc->timer);
455         if (sc->ips_adapter_reinit(sc, 0))
456                 goto error;
457         IPS_LOCK_INIT(sc);
458         /* initialize ffdc values */
459         microtime(&sc->ffdc_resettime);
460         sc->ffdc_resetcount = 1;
461         if ((i = ips_ffdc_reset(sc)) != 0) {
462                 device_printf(sc->dev,
463                     "failed to send ffdc reset to device (%d)\n", i);
464                 goto error;
465         }
466         if ((i = ips_get_adapter_info(sc)) != 0) {
467                 device_printf(sc->dev, "failed to get adapter configuration "
468                     "data from device (%d)\n", i);
469                 goto error;
470         }
471         /* no error check as failure doesn't matter */
472         ips_update_nvram(sc);
473         if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
474                 device_printf(sc->dev, "adapter type: %s\n",
475                     ips_adapter_name[sc->adapter_type]);
476         }
477         if ((i = ips_get_drive_info(sc)) != 0) {
478                 device_printf(sc->dev, "failed to get drive "
479                     "configuration data from device (%d)\n", i);
480                 goto error;
481         }
482         ips_cmdqueue_free(sc);
483         if (sc->adapter_info.max_concurrent_cmds)
484                 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
485         else
486                 sc->max_cmds = 32;
487         if (ips_cmdqueue_init(sc)) {
488                 device_printf(sc->dev,
489                     "failed to initialize command buffers\n");
490                 goto error;
491         }
492         cdevsw_add(&ips_cdevsw, -1, device_get_unit(sc->dev));
493         dev = make_dev(&ips_cdevsw, device_get_unit(sc->dev),
494                                    UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
495                                    "ips%d", device_get_unit(sc->dev));
496         dev->si_drv1 = sc;
497         ips_diskdev_init(sc);
498         callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
499         return 0;
500 error:
501         ips_adapter_free(sc);
502         return ENXIO;
503 }
504
505 /*
506  * see if we should reinitialize the card and wait for it to timeout
507  * or complete initialization
508  */
509 int
510 ips_morpheus_reinit(ips_softc_t *sc, int force)
511 {
512         u_int32_t tmp;
513         int i;
514
515         tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
516         if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
517             (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
518                 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
519                 return 0;
520         }
521         ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
522         ips_read_4(sc, MORPHEUS_REG_OIMR);
523         device_printf(sc->dev,
524             "resetting adapter, this may take up to 5 minutes\n");
525         ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
526         DELAY(5000000);
527         pci_read_config(sc->dev, 0, 4);
528         tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
529         for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
530                 DELAY(1000000);
531                 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
532                 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
533         }
534         if (tmp & MORPHEUS_BIT_POST1)
535                 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
536
537         if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
538                 device_printf(sc->dev,
539                     "Adapter error during initialization.\n");
540                 return 1;
541         }
542         for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
543                 DELAY(1000000);
544                 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
545                 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
546         }
547         if (tmp & MORPHEUS_BIT_POST2)
548                 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
549
550         if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
551                 device_printf(sc->dev, "adapter failed config check\n");
552                 return 1;
553         }
554         ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
555         if (force && ips_clear_adapter(sc)) {
556                 device_printf(sc->dev, "adapter clear failed\n");
557                 return 1;
558         }
559         return 0;
560 }
561
562 /* clean up so we can unload the driver. */
563 int
564 ips_adapter_free(ips_softc_t *sc)
565 {
566         int error = 0;
567         intrmask_t mask;
568         if (sc->state & IPS_DEV_OPEN)
569                 return EBUSY;
570         if ((error = ips_diskdev_free(sc)))
571                 return error;
572         if (ips_cmdqueue_free(sc)) {
573                 device_printf(sc->dev,
574                     "trying to exit when command queue is not empty!\n");
575                 return EBUSY;
576         }
577         DEVICE_PRINTF(1, sc->dev, "free\n");
578         mask = splbio();
579         callout_stop(&sc->timer);
580         splx(mask);
581         IPS_LOCK_FREE(sc);
582         if (sc->sg_dmatag)
583                 bus_dma_tag_destroy(sc->sg_dmatag);
584         if (sc->command_dmatag)
585                 bus_dma_tag_destroy(sc->command_dmatag);
586         cdevsw_remove(&ips_cdevsw, -1, device_get_unit(sc->dev));
587         return 0;
588 }
589
590 void
591 ips_morpheus_intr(void *void_sc)
592 {
593         ips_softc_t *sc = (ips_softc_t *)void_sc;
594         u_int32_t oisr, iisr;
595         ips_cmd_status_t status;
596         ips_command_t *command;
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                 command = &sc->commandarray[cmdnumber];
610                 command->status.value = status.value;
611                 command->timeout = 0;
612                 command->callback(command);
613                 DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
614         }
615         return;
616 }
617
618 void
619 ips_issue_morpheus_cmd(ips_command_t *command)
620 {
621         intrmask_t mask;
622
623         mask = splbio();
624         /* hmmm, is there a cleaner way to do this? */
625         if (command->sc->state & IPS_OFFLINE) {
626                 splx(mask);
627                 command->status.value = IPS_ERROR_STATUS;
628                 command->callback(command);
629                 return;
630         }
631         command->timeout = 10;
632         ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
633         splx(mask);
634 }
635
636 static void
637 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
638                               int segnum, int error)
639 {
640         ips_copper_queue_t *queue = queueptr;
641
642         if (error)
643                 return;
644         queue->base_phys_addr = segments[0].ds_addr;
645 }
646
647 static int
648 ips_copperhead_queue_init(ips_softc_t *sc)
649 {
650         bus_dma_tag_t dmatag;
651         bus_dmamap_t dmamap;
652         int error;
653
654         if (bus_dma_tag_create( /* parent    */ sc->adapter_dmatag,
655                                 /* alignemnt */ 1,
656                                 /* boundary  */ 0,
657                                 /* lowaddr   */ BUS_SPACE_MAXADDR_32BIT,
658                                 /* highaddr  */ BUS_SPACE_MAXADDR,
659                                 /* filter    */ NULL,
660                                 /* filterarg */ NULL,
661                                 /* maxsize   */ sizeof(ips_copper_queue_t),
662                                 /* numsegs   */ 1,
663                                 /* maxsegsize*/ sizeof(ips_copper_queue_t),
664                                 /* flags     */ 0,
665                                 &dmatag) != 0) {
666                 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
667                 error = ENOMEM;
668                 goto exit;
669         }
670         if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
671             BUS_DMA_NOWAIT, &dmamap)) {
672                 error = ENOMEM;
673                 goto exit;
674         }
675         bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
676         sc->copper_queue->dmatag = dmatag;
677         sc->copper_queue->dmamap = dmamap;
678         sc->copper_queue->nextstatus = 1;
679         bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
680             IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
681             sc->copper_queue, BUS_DMA_NOWAIT);
682         if (sc->copper_queue->base_phys_addr == 0) {
683                 error = ENOMEM;
684                 goto exit;
685         }
686         ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
687         ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
688             IPS_MAX_CMD_NUM * 4);
689         ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
690         ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
691         return 0;
692 exit:
693         bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
694         bus_dma_tag_destroy(dmatag);
695         return error;
696 }
697
698 /*
699  * see if we should reinitialize the card and wait for it to timeout or
700  * complete initialization FIXME
701  */
702 int
703 ips_copperhead_reinit(ips_softc_t *sc, int force)
704 {
705         u_int32_t postcode = 0, configstatus = 0;
706         int       i, j;
707
708         ips_write_1(sc, COPPER_REG_SCPR, 0x80);
709         ips_write_1(sc, COPPER_REG_SCPR, 0);
710         device_printf(sc->dev,
711             "reinitializing adapter, this could take several minutes.\n");
712         for (j = 0; j < 2; j++) {
713                 postcode <<= 8;
714                 for (i = 0; i < 45; i++) {
715                         if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
716                                 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
717                                 ips_write_1(sc, COPPER_REG_HISR,
718                                     COPPER_GHI_BIT);
719                                 break;
720                         } else
721                                 DELAY(1000000);
722                 }
723                 if (i == 45)
724                         return 1;
725         }
726         for (j = 0; j < 2; j++) {
727                 configstatus <<= 8;
728                 for (i = 0; i < 240; i++) {
729                         if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
730                                 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
731                                 ips_write_1(sc, COPPER_REG_HISR,
732                                     COPPER_GHI_BIT);
733                                 break;
734                         } else
735                                 DELAY(1000000);
736                 }
737                 if (i == 240)
738                         return 1;
739         }
740         for (i = 0; i < 240; i++) {
741                 if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
742                         break;
743                 else
744                         DELAY(1000000);
745         }
746         if (i == 240)
747                 return 1;
748         ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
749         ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
750         ips_copperhead_queue_init(sc);
751         ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
752         i = ips_read_1(sc, COPPER_REG_SCPR);
753         ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
754         if (configstatus == 0) {
755                 device_printf(sc->dev, "adapter initialization failed\n");
756                 return 1;
757         }
758         if (force && ips_clear_adapter(sc)) {
759                 device_printf(sc->dev, "adapter clear failed\n");
760                 return 1;
761         }
762         return 0;
763 }
764
765 static u_int32_t
766 ips_copperhead_cmd_status(ips_softc_t *sc)
767 {
768         intrmask_t mask;
769         u_int32_t value;
770         int statnum;
771
772         statnum = sc->copper_queue->nextstatus++;
773         if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
774                 sc->copper_queue->nextstatus = 0;
775         mask = splbio();
776         value = sc->copper_queue->status[statnum];
777         ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
778             4 * statnum);
779         splx(mask);
780         return value;
781 }
782
783 void
784 ips_copperhead_intr(void *void_sc)
785 {
786         ips_softc_t *sc = (ips_softc_t *)void_sc;
787         ips_cmd_status_t status;
788         int cmdnumber;
789
790         while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
791                 status.value = ips_copperhead_cmd_status(sc);
792                 cmdnumber = status.fields.command_id;
793                 sc->commandarray[cmdnumber].status.value = status.value;
794                 sc->commandarray[cmdnumber].timeout = 0;
795                 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
796                 PRINTF(9, "ips: got command %d\n", cmdnumber);
797         }
798         return;
799 }
800
801 void
802 ips_issue_copperhead_cmd(ips_command_t *command)
803 {
804         intrmask_t mask;
805         int i;
806
807         mask = splbio();
808         /* hmmm, is there a cleaner way to do this? */
809         if (command->sc->state & IPS_OFFLINE) {
810                 splx(mask);
811                 command->status.value = IPS_ERROR_STATUS;
812                 command->callback(command);
813                 return;
814         }
815         command->timeout = 10;
816         for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
817             i++) {
818                 if (i == 20) {
819                         printf("sem bit still set, can't send a command\n");
820                         splx(mask);
821                         return;
822                 }
823                 DELAY(500);     /* need to do a delay here */
824         }
825         ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
826         ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
827         splx(mask);
828 }