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