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