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