Merge from vendor branch SENDMAIL:
[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.10 2004/12/10 04:09:46 y0netan1 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         /* initialize ffdc values */
458         microtime(&sc->ffdc_resettime);
459         sc->ffdc_resetcount = 1;
460         if ((i = ips_ffdc_reset(sc)) != 0) {
461                 device_printf(sc->dev,
462                     "failed to send ffdc reset to device (%d)\n", i);
463                 goto error;
464         }
465         if ((i = ips_get_adapter_info(sc)) != 0) {
466                 device_printf(sc->dev, "failed to get adapter configuration "
467                     "data from device (%d)\n", i);
468                 goto error;
469         }
470         /* no error check as failure doesn't matter */
471         ips_update_nvram(sc);
472         if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
473                 device_printf(sc->dev, "adapter type: %s\n",
474                     ips_adapter_name[sc->adapter_type]);
475         }
476         if ((i = ips_get_drive_info(sc)) != 0) {
477                 device_printf(sc->dev, "failed to get drive "
478                     "configuration data from device (%d)\n", i);
479                 goto error;
480         }
481         ips_cmdqueue_free(sc);
482         if (sc->adapter_info.max_concurrent_cmds)
483                 sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
484         else
485                 sc->max_cmds = 32;
486         if (ips_cmdqueue_init(sc)) {
487                 device_printf(sc->dev,
488                     "failed to initialize command buffers\n");
489                 goto error;
490         }
491         cdevsw_add(&ips_cdevsw, -1, device_get_unit(sc->dev));
492         dev = make_dev(&ips_cdevsw, device_get_unit(sc->dev),
493                                    UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
494                                    "ips%d", device_get_unit(sc->dev));
495         dev->si_drv1 = sc;
496         ips_diskdev_init(sc);
497         callout_reset(&sc->timer, 10 * hz, ips_timeout, sc);
498         return 0;
499 error:
500         ips_adapter_free(sc);
501         return ENXIO;
502 }
503
504 /*
505  * see if we should reinitialize the card and wait for it to timeout
506  * or complete initialization
507  */
508 int
509 ips_morpheus_reinit(ips_softc_t *sc, int force)
510 {
511         u_int32_t tmp;
512         int i;
513
514         tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
515         if (!force && (ips_read_4(sc, MORPHEUS_REG_OMR0) >= IPS_POST1_OK) &&
516             (ips_read_4(sc, MORPHEUS_REG_OMR1) != 0xdeadbeef) && !tmp) {
517                 ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
518                 return 0;
519         }
520         ips_write_4(sc, MORPHEUS_REG_OIMR, 0xff);
521         ips_read_4(sc, MORPHEUS_REG_OIMR);
522         device_printf(sc->dev,
523             "resetting adapter, this may take up to 5 minutes\n");
524         ips_write_4(sc, MORPHEUS_REG_IDR, 0x80000000);
525         DELAY(5000000);
526         pci_read_config(sc->dev, 0, 4);
527         tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
528         for (i = 0; i < 45 && !(tmp & MORPHEUS_BIT_POST1); i++) {
529                 DELAY(1000000);
530                 DEVICE_PRINTF(2, sc->dev, "post1: %d\n", i);
531                 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
532         }
533         if (tmp & MORPHEUS_BIT_POST1)
534                 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST1);
535
536         if (i == 45 || ips_read_4(sc, MORPHEUS_REG_OMR0) < IPS_POST1_OK) {
537                 device_printf(sc->dev,
538                     "Adapter error during initialization.\n");
539                 return 1;
540         }
541         for (i = 0; i < 240 && !(tmp & MORPHEUS_BIT_POST2); i++) {
542                 DELAY(1000000);
543                 DEVICE_PRINTF(2, sc->dev, "post2: %d\n", i);
544                 tmp = ips_read_4(sc, MORPHEUS_REG_OISR);
545         }
546         if (tmp & MORPHEUS_BIT_POST2)
547                 ips_write_4(sc, MORPHEUS_REG_OISR, MORPHEUS_BIT_POST2);
548
549         if (i == 240 || !ips_read_4(sc, MORPHEUS_REG_OMR1)) {
550                 device_printf(sc->dev, "adapter failed config check\n");
551                 return 1;
552         }
553         ips_write_4(sc, MORPHEUS_REG_OIMR, 0);
554         if (force && ips_clear_adapter(sc)) {
555                 device_printf(sc->dev, "adapter clear failed\n");
556                 return 1;
557         }
558         return 0;
559 }
560
561 /* clean up so we can unload the driver. */
562 int
563 ips_adapter_free(ips_softc_t *sc)
564 {
565         int error = 0;
566         intrmask_t mask;
567         if (sc->state & IPS_DEV_OPEN)
568                 return EBUSY;
569         if ((error = ips_diskdev_free(sc)))
570                 return error;
571         if (ips_cmdqueue_free(sc)) {
572                 device_printf(sc->dev,
573                     "trying to exit when command queue is not empty!\n");
574                 return EBUSY;
575         }
576         DEVICE_PRINTF(1, sc->dev, "free\n");
577         mask = splbio();
578         callout_stop(&sc->timer);
579         splx(mask);
580         if (sc->sg_dmatag)
581                 bus_dma_tag_destroy(sc->sg_dmatag);
582         if (sc->command_dmatag)
583                 bus_dma_tag_destroy(sc->command_dmatag);
584         cdevsw_remove(&ips_cdevsw, -1, device_get_unit(sc->dev));
585         return 0;
586 }
587
588 void
589 ips_morpheus_intr(void *void_sc)
590 {
591         ips_softc_t *sc = (ips_softc_t *)void_sc;
592         u_int32_t oisr, iisr;
593         ips_cmd_status_t status;
594         ips_command_t *command;
595         int cmdnumber;
596
597         iisr =ips_read_4(sc, MORPHEUS_REG_IISR);
598         oisr =ips_read_4(sc, MORPHEUS_REG_OISR);
599         PRINTF(9, "interrupt registers in:%x out:%x\n", iisr, oisr);
600         if (!(oisr & MORPHEUS_BIT_CMD_IRQ)) {
601                 DEVICE_PRINTF(2, sc->dev, "got a non-command irq\n");
602                 return;
603         }
604         while ((status.value = ips_read_4(sc, MORPHEUS_REG_OQPR))
605                != 0xffffffff) {
606                 cmdnumber = status.fields.command_id;
607                 command = &sc->commandarray[cmdnumber];
608                 command->status.value = status.value;
609                 command->timeout = 0;
610                 command->callback(command);
611                 DEVICE_PRINTF(9, sc->dev, "got command %d\n", cmdnumber);
612         }
613         return;
614 }
615
616 void
617 ips_issue_morpheus_cmd(ips_command_t *command)
618 {
619         intrmask_t mask;
620
621         mask = splbio();
622         /* hmmm, is there a cleaner way to do this? */
623         if (command->sc->state & IPS_OFFLINE) {
624                 splx(mask);
625                 command->status.value = IPS_ERROR_STATUS;
626                 command->callback(command);
627                 return;
628         }
629         command->timeout = 10;
630         ips_write_4(command->sc, MORPHEUS_REG_IQPR, command->command_phys_addr);
631         splx(mask);
632 }
633
634 static void
635 ips_copperhead_queue_callback(void *queueptr, bus_dma_segment_t *segments,
636                               int segnum, int error)
637 {
638         ips_copper_queue_t *queue = queueptr;
639
640         if (error)
641                 return;
642         queue->base_phys_addr = segments[0].ds_addr;
643 }
644
645 static int
646 ips_copperhead_queue_init(ips_softc_t *sc)
647 {
648         bus_dma_tag_t dmatag;
649         bus_dmamap_t dmamap;
650         int error;
651
652         if (bus_dma_tag_create( /* parent    */ sc->adapter_dmatag,
653                                 /* alignemnt */ 1,
654                                 /* boundary  */ 0,
655                                 /* lowaddr   */ BUS_SPACE_MAXADDR_32BIT,
656                                 /* highaddr  */ BUS_SPACE_MAXADDR,
657                                 /* filter    */ NULL,
658                                 /* filterarg */ NULL,
659                                 /* maxsize   */ sizeof(ips_copper_queue_t),
660                                 /* numsegs   */ 1,
661                                 /* maxsegsize*/ sizeof(ips_copper_queue_t),
662                                 /* flags     */ 0,
663                                 &dmatag) != 0) {
664                 device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
665                 error = ENOMEM;
666                 goto exit;
667         }
668         if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
669             BUS_DMA_NOWAIT, &dmamap)) {
670                 error = ENOMEM;
671                 goto exit;
672         }
673         bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
674         sc->copper_queue->dmatag = dmatag;
675         sc->copper_queue->dmamap = dmamap;
676         sc->copper_queue->nextstatus = 1;
677         bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
678             IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
679             sc->copper_queue, BUS_DMA_NOWAIT);
680         if (sc->copper_queue->base_phys_addr == 0) {
681                 error = ENOMEM;
682                 goto exit;
683         }
684         ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
685         ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
686             IPS_MAX_CMD_NUM * 4);
687         ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
688         ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
689         return 0;
690 exit:
691         bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
692         bus_dma_tag_destroy(dmatag);
693         return error;
694 }
695
696 /*
697  * see if we should reinitialize the card and wait for it to timeout or
698  * complete initialization FIXME
699  */
700 int
701 ips_copperhead_reinit(ips_softc_t *sc, int force)
702 {
703         u_int32_t postcode = 0, configstatus = 0;
704         int       i, j;
705
706         ips_write_1(sc, COPPER_REG_SCPR, 0x80);
707         ips_write_1(sc, COPPER_REG_SCPR, 0);
708         device_printf(sc->dev,
709             "reinitializing adapter, this could take several minutes.\n");
710         for (j = 0; j < 2; j++) {
711                 postcode <<= 8;
712                 for (i = 0; i < 45; i++) {
713                         if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
714                                 postcode |= ips_read_1(sc, COPPER_REG_ISPR);
715                                 ips_write_1(sc, COPPER_REG_HISR,
716                                     COPPER_GHI_BIT);
717                                 break;
718                         } else
719                                 DELAY(1000000);
720                 }
721                 if (i == 45)
722                         return 1;
723         }
724         for (j = 0; j < 2; j++) {
725                 configstatus <<= 8;
726                 for (i = 0; i < 240; i++) {
727                         if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
728                                 configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
729                                 ips_write_1(sc, COPPER_REG_HISR,
730                                     COPPER_GHI_BIT);
731                                 break;
732                         } else
733                                 DELAY(1000000);
734                 }
735                 if (i == 240)
736                         return 1;
737         }
738         for (i = 0; i < 240; i++) {
739                 if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
740                         break;
741                 else
742                         DELAY(1000000);
743         }
744         if (i == 240)
745                 return 1;
746         ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
747         ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
748         ips_copperhead_queue_init(sc);
749         ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
750         i = ips_read_1(sc, COPPER_REG_SCPR);
751         ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
752         if (configstatus == 0) {
753                 device_printf(sc->dev, "adapter initialization failed\n");
754                 return 1;
755         }
756         if (force && ips_clear_adapter(sc)) {
757                 device_printf(sc->dev, "adapter clear failed\n");
758                 return 1;
759         }
760         return 0;
761 }
762
763 static u_int32_t
764 ips_copperhead_cmd_status(ips_softc_t *sc)
765 {
766         intrmask_t mask;
767         u_int32_t value;
768         int statnum;
769
770         statnum = sc->copper_queue->nextstatus++;
771         if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
772                 sc->copper_queue->nextstatus = 0;
773         mask = splbio();
774         value = sc->copper_queue->status[statnum];
775         ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
776             4 * statnum);
777         splx(mask);
778         return value;
779 }
780
781 void
782 ips_copperhead_intr(void *void_sc)
783 {
784         ips_softc_t *sc = (ips_softc_t *)void_sc;
785         ips_cmd_status_t status;
786         int cmdnumber;
787
788         while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
789                 status.value = ips_copperhead_cmd_status(sc);
790                 cmdnumber = status.fields.command_id;
791                 sc->commandarray[cmdnumber].status.value = status.value;
792                 sc->commandarray[cmdnumber].timeout = 0;
793                 sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
794                 PRINTF(9, "ips: got command %d\n", cmdnumber);
795         }
796         return;
797 }
798
799 void
800 ips_issue_copperhead_cmd(ips_command_t *command)
801 {
802         intrmask_t mask;
803         int i;
804
805         mask = splbio();
806         /* hmmm, is there a cleaner way to do this? */
807         if (command->sc->state & IPS_OFFLINE) {
808                 splx(mask);
809                 command->status.value = IPS_ERROR_STATUS;
810                 command->callback(command);
811                 return;
812         }
813         command->timeout = 10;
814         for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
815             i++) {
816                 if (i == 20) {
817                         printf("sem bit still set, can't send a command\n");
818                         splx(mask);
819                         return;
820                 }
821                 DELAY(500);     /* need to do a delay here */
822         }
823         ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
824         ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
825         splx(mask);
826 }