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