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