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