xref: /dragonfly/sys/dev/raid/ips/ips.c (revision 030b0c8c4cf27c560ccec70410c8e21934ae677d)
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  */
29 
30 #include <dev/raid/ips/ips.h>
31 #include <sys/stat.h>
32 #include <sys/time.h>
33 #include <sys/thread2.h>
34 #include <sys/udev.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", 0, 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           "ServeRAID 7t",
68           "ServeRAID 7k",
69           "ServeRAID 7M",
70 };
71 
72 
73 static int
ips_open(struct dev_open_args * ap)74 ips_open(struct dev_open_args *ap)
75 {
76           cdev_t dev = ap->a_head.a_dev;
77           ips_softc_t *sc = dev->si_drv1;
78 
79           sc->state |= IPS_DEV_OPEN;
80           return 0;
81 }
82 
83 static int
ips_close(struct dev_close_args * ap)84 ips_close(struct dev_close_args *ap)
85 {
86           cdev_t dev = ap->a_head.a_dev;
87           ips_softc_t *sc = dev->si_drv1;
88 
89           sc->state &= ~IPS_DEV_OPEN;
90           return 0;
91 }
92 
93 static int
ips_ioctl(struct dev_ioctl_args * ap)94 ips_ioctl(struct dev_ioctl_args *ap)
95 {
96           ips_softc_t *sc;
97 
98           sc = ap->a_head.a_dev->si_drv1;
99           return ips_ioctl_request(sc, ap->a_cmd, ap->a_data, ap->a_fflag);
100 }
101 
102 static void
ips_cmd_dmaload(void * cmdptr,bus_dma_segment_t * segments,int segnum,int error)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
ips_cmdqueue_free(ips_softc_t * sc)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           kfree(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
ips_cmdqueue_init(ips_softc_t * sc)152 ips_cmdqueue_init(ips_softc_t *sc)
153 {
154           int i;
155           ips_command_t *command;
156 
157           sc->commandarray = kmalloc(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
ips_get_free_cmd(ips_softc_t * sc,ips_command_t ** cmd,unsigned long flags)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
ips_insert_free_cmd(ips_softc_t * sc,ips_command_t * command)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 *
ips_diskdev_statename(u_int8_t state)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           ksprintf(statebuf, "UNKNOWN(0x%02x)", state);
278           return (statebuf);
279 }
280 
281 static int
ips_diskdev_init(ips_softc_t * sc)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
ips_diskdev_free(ips_softc_t * sc)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
ips_timeout(void * arg)331 ips_timeout(void *arg)
332 {
333           ips_command_t *command;
334           ips_softc_t *sc = arg;
335           int i, state = 0;
336 
337           lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
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           lockmgr(&sc->queue_lock, LK_RELEASE);
371 }
372 
373 /* check card and initialize it */
374 int
ips_adapter_init(ips_softc_t * sc)375 ips_adapter_init(ips_softc_t *sc)
376 {
377           int i;
378           cdev_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                                         /* maxsize   */     IPS_COMMAND_LEN +
387                                                                 IPS_MAX_SG_LEN,
388                                         /* numsegs   */     1,
389                                         /* maxsegsize*/     IPS_COMMAND_LEN +
390                                                                 IPS_MAX_SG_LEN,
391                                         /* flags     */     0,
392                                         &sc->command_dmatag) != 0) {
393                     device_printf(sc->dev, "can't alloc command dma tag\n");
394                     goto error;
395           }
396           if (bus_dma_tag_create(       /* parent    */     sc->adapter_dmatag,
397                                         /* alignemnt */     1,
398                                         /* boundary  */     0,
399                                         /* lowaddr   */     BUS_SPACE_MAXADDR_32BIT,
400                                         /* highaddr  */     BUS_SPACE_MAXADDR,
401                                         /* maxsize   */     IPS_MAX_IOBUF_SIZE,
402                                         /* numsegs   */     IPS_MAX_SG_ELEMENTS,
403                                         /* maxsegsize*/     IPS_MAX_IOBUF_SIZE,
404                                         /* flags     */     0,
405                                         &sc->sg_dmatag) != 0) {
406                     device_printf(sc->dev, "can't alloc SG dma tag\n");
407                     goto error;
408           }
409           /*
410            * create one command buffer until we know how many commands this card
411            * can handle
412            */
413           sc->max_cmds = 1;
414           ips_cmdqueue_init(sc);
415           callout_init(&sc->timer);
416           if (sc->ips_adapter_reinit(sc, 0))
417                     goto error;
418           /* initialize ffdc values */
419           microtime(&sc->ffdc_resettime);
420           sc->ffdc_resetcount = 1;
421           if ((i = ips_ffdc_reset(sc)) != 0) {
422                     device_printf(sc->dev,
423                         "failed to send ffdc reset to device (%d)\n", i);
424                     goto error;
425           }
426           if ((i = ips_get_adapter_info(sc)) != 0) {
427                     device_printf(sc->dev, "failed to get adapter configuration "
428                         "data from device (%d)\n", i);
429                     goto error;
430           }
431           /* no error check as failure doesn't matter */
432           ips_update_nvram(sc);
433           if (sc->adapter_type > 0 && sc->adapter_type <= IPS_ADAPTER_MAX_T) {
434                     device_printf(sc->dev, "adapter type: %s\n",
435                         ips_adapter_name[sc->adapter_type]);
436           }
437           if ((i = ips_get_drive_info(sc)) != 0) {
438                     device_printf(sc->dev, "failed to get drive "
439                         "configuration data from device (%d)\n", i);
440                     goto error;
441           }
442           ips_cmdqueue_free(sc);
443           if (sc->adapter_info.max_concurrent_cmds)
444                     sc->max_cmds = min(128, sc->adapter_info.max_concurrent_cmds);
445           else
446                     sc->max_cmds = 32;
447           if (ips_cmdqueue_init(sc)) {
448                     device_printf(sc->dev,
449                         "failed to initialize command buffers\n");
450                     goto error;
451           }
452           dev = make_dev(&ips_ops, device_get_unit(sc->dev),
453                            UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
454                            "ips%d", device_get_unit(sc->dev));
455           dev->si_drv1 = sc;
456           udev_dict_set_cstr(dev, "subsystem", "raid");
457           udev_dict_set_cstr(dev, "disk-type", "raid");
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
ips_morpheus_reinit(ips_softc_t * sc,int force)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
ips_adapter_free(ips_softc_t * sc)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_minor(&ips_ops, device_get_unit(sc->dev));
547           return 0;
548 }
549 
550 static int
ips_morpheus_check_intr(void * void_sc)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
ips_morpheus_intr(void * void_sc)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
ips_issue_morpheus_cmd(ips_command_t * command)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
ips_morpheus_poll(ips_command_t * command)607 ips_morpheus_poll(ips_command_t *command)
608 {
609           uint32_t ts;
610 
611           ts = time_uptime + command->timeout;
612           while (command->timeout != 0 &&
613               ips_morpheus_check_intr(command->sc) == 0 &&
614               (ts > time_uptime))
615                     DELAY(1000);
616  }
617 
618 static void
ips_copperhead_queue_callback(void * queueptr,bus_dma_segment_t * segments,int segnum,int error)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
ips_copperhead_queue_init(ips_softc_t * sc)630 ips_copperhead_queue_init(ips_softc_t *sc)
631 {
632           bus_dma_tag_t dmatag = NULL;
633           bus_dmamap_t dmamap = NULL;
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                                         /* maxsize   */     sizeof(ips_copper_queue_t),
642                                         /* numsegs   */     1,
643                                         /* maxsegsize*/     sizeof(ips_copper_queue_t),
644                                         /* flags     */     0,
645                                         &dmatag) != 0) {
646                     device_printf(sc->dev, "can't alloc dma tag for statue queue\n");
647                     error = ENOMEM;
648                     goto exit;
649           }
650           if (bus_dmamem_alloc(dmatag, (void *)&(sc->copper_queue),
651               BUS_DMA_NOWAIT, &dmamap)) {
652                     error = ENOMEM;
653                     goto exit;
654           }
655           bzero(sc->copper_queue, sizeof(ips_copper_queue_t));
656           sc->copper_queue->dmatag = dmatag;
657           sc->copper_queue->dmamap = dmamap;
658           sc->copper_queue->nextstatus = 1;
659           bus_dmamap_load(dmatag, dmamap, &(sc->copper_queue->status[0]),
660               IPS_MAX_CMD_NUM * 4, ips_copperhead_queue_callback,
661               sc->copper_queue, BUS_DMA_NOWAIT);
662           if (sc->copper_queue->base_phys_addr == 0) {
663                     error = ENOMEM;
664                     goto exit;
665           }
666           ips_write_4(sc, COPPER_REG_SQSR, sc->copper_queue->base_phys_addr);
667           ips_write_4(sc, COPPER_REG_SQER, sc->copper_queue->base_phys_addr +
668               IPS_MAX_CMD_NUM * 4);
669           ips_write_4(sc, COPPER_REG_SQHR, sc->copper_queue->base_phys_addr + 4);
670           ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr);
671           return 0;
672 exit:
673           bus_dmamem_free(dmatag, sc->copper_queue, dmamap);
674           bus_dma_tag_destroy(dmatag);
675           return error;
676 }
677 
678 /*
679  * see if we should reinitialize the card and wait for it to timeout or
680  * complete initialization FIXME
681  */
682 int
ips_copperhead_reinit(ips_softc_t * sc,int force)683 ips_copperhead_reinit(ips_softc_t *sc, int force)
684 {
685           u_int32_t postcode = 0, configstatus = 0;
686           int         i, j;
687 
688           ips_write_1(sc, COPPER_REG_SCPR, 0x80);
689           ips_write_1(sc, COPPER_REG_SCPR, 0);
690           device_printf(sc->dev,
691               "reinitializing adapter, this could take several minutes.\n");
692           for (j = 0; j < 2; j++) {
693                     postcode <<= 8;
694                     for (i = 0; i < 45; i++) {
695                               if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
696                                         postcode |= ips_read_1(sc, COPPER_REG_ISPR);
697                                         ips_write_1(sc, COPPER_REG_HISR,
698                                             COPPER_GHI_BIT);
699                                         break;
700                               } else
701                                         DELAY(1000000);
702                     }
703                     if (i == 45)
704                               return 1;
705           }
706           for (j = 0; j < 2; j++) {
707                     configstatus <<= 8;
708                     for (i = 0; i < 240; i++) {
709                               if (ips_read_1(sc, COPPER_REG_HISR) & COPPER_GHI_BIT) {
710                                         configstatus |= ips_read_1(sc, COPPER_REG_ISPR);
711                                         ips_write_1(sc, COPPER_REG_HISR,
712                                             COPPER_GHI_BIT);
713                                         break;
714                               } else
715                                         DELAY(1000000);
716                     }
717                     if (i == 240)
718                               return 1;
719           }
720           for (i = 0; i < 240; i++) {
721                     if (!(ips_read_1(sc, COPPER_REG_CBSP) & COPPER_OP_BIT))
722                               break;
723                     else
724                               DELAY(1000000);
725           }
726           if (i == 240)
727                     return 1;
728           ips_write_2(sc, COPPER_REG_CCCR, 0x1000 | COPPER_ILE_BIT);
729           ips_write_1(sc, COPPER_REG_SCPR, COPPER_EBM_BIT);
730           ips_copperhead_queue_init(sc);
731           ips_write_1(sc, COPPER_REG_HISR, COPPER_GHI_BIT);
732           i = ips_read_1(sc, COPPER_REG_SCPR);
733           ips_write_1(sc, COPPER_REG_HISR, COPPER_EI_BIT);
734           if (configstatus == 0) {
735                     device_printf(sc->dev, "adapter initialization failed\n");
736                     return 1;
737           }
738           if (force && ips_clear_adapter(sc)) {
739                     device_printf(sc->dev, "adapter clear failed\n");
740                     return 1;
741           }
742           return 0;
743 }
744 
745 static u_int32_t
ips_copperhead_cmd_status(ips_softc_t * sc)746 ips_copperhead_cmd_status(ips_softc_t *sc)
747 {
748           u_int32_t value;
749           int statnum;
750 
751           statnum = sc->copper_queue->nextstatus++;
752           if (sc->copper_queue->nextstatus == IPS_MAX_CMD_NUM)
753                     sc->copper_queue->nextstatus = 0;
754           crit_enter();
755           value = sc->copper_queue->status[statnum];
756           ips_write_4(sc, COPPER_REG_SQTR, sc->copper_queue->base_phys_addr +
757               4 * statnum);
758           crit_exit();
759           return value;
760 }
761 
762 void
ips_copperhead_intr(void * void_sc)763 ips_copperhead_intr(void *void_sc)
764 {
765           ips_softc_t *sc = (ips_softc_t *)void_sc;
766           ips_cmd_status_t status;
767           int cmdnumber;
768 
769           lockmgr(&sc->queue_lock, LK_EXCLUSIVE|LK_RETRY);
770           while (ips_read_1(sc, COPPER_REG_HISR) & COPPER_SCE_BIT) {
771                     status.value = ips_copperhead_cmd_status(sc);
772                     cmdnumber = status.fields.command_id;
773                     sc->commandarray[cmdnumber].status.value = status.value;
774                     sc->commandarray[cmdnumber].timeout = 0;
775                     sc->commandarray[cmdnumber].callback(&(sc->commandarray[cmdnumber]));
776                     PRINTF(9, "ips: got command %d\n", cmdnumber);
777           }
778           lockmgr(&sc->queue_lock, LK_RELEASE);
779           return;
780 }
781 
782 void
ips_issue_copperhead_cmd(ips_command_t * command)783 ips_issue_copperhead_cmd(ips_command_t *command)
784 {
785           int i;
786 
787           crit_enter();
788           /* hmmm, is there a cleaner way to do this? */
789           if (command->sc->state & IPS_OFFLINE) {
790                     crit_exit();
791                     command->status.value = IPS_ERROR_STATUS;
792                     command->callback(command);
793                     return;
794           }
795           command->timeout = 10;
796           for (i = 0; ips_read_4(command->sc, COPPER_REG_CCCR) & COPPER_SEM_BIT;
797               i++) {
798                     if (i == 20) {
799                               kprintf("sem bit still set, can't send a command\n");
800                               crit_exit();
801                               return;
802                     }
803                     DELAY(500);         /* need to do a delay here */
804           }
805           ips_write_4(command->sc, COPPER_REG_CCSAR, command->command_phys_addr);
806           ips_write_2(command->sc, COPPER_REG_CCCR, COPPER_CMD_START);
807           crit_exit();
808 }
809 
810 void
ips_copperhead_poll(ips_command_t * command)811 ips_copperhead_poll(ips_command_t *command)
812 {
813           kprintf("ips: cmd polling not implemented for copperhead devices\n");
814 }
815