2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2012 Gary Mills
23 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2012 Garrett D'Amore <garrett@damore.org>. All rights reserved.
25 */
26
27 /*
28 * ISA bus nexus driver
29 */
30
31 #include <sys/types.h>
32 #include <sys/cmn_err.h>
33 #include <sys/conf.h>
34 #include <sys/modctl.h>
35 #include <sys/autoconf.h>
36 #include <sys/errno.h>
37 #include <sys/debug.h>
38 #include <sys/kmem.h>
39 #include <sys/psm.h>
40 #include <sys/ddidmareq.h>
41 #include <sys/ddi_impldefs.h>
42 #include <sys/ddi_subrdefs.h>
43 #include <sys/dma_engine.h>
44 #include <sys/ddi.h>
109 #define MAX_EXTRA_RESOURCE 7
110 static struct regspec isa_extra_resource[MAX_EXTRA_RESOURCE];
111 static int isa_extra_count = 0;
112
113 /* Register definitions for COM1 to COM4. */
114 static struct regspec asy_regs[] = {
115 {1, 0x3f8, 0x8},
116 {1, 0x2f8, 0x8},
117 {1, 0x3e8, 0x8},
118 {1, 0x2e8, 0x8}
119 };
120
121 /* Serial port interrupt vectors for COM1 to COM4. */
122 static int asy_intrs[] = {0x4, 0x3, 0x4, 0x3};
123 /* Bitfield indicating which interrupts are overridden by eeprom config */
124 static uchar_t asy_intr_override = 0;
125
126 /*
127 * Local data
128 */
129 static ddi_dma_lim_t ISA_dma_limits = {
130 0, /* address low */
131 0x00ffffff, /* address high */
132 0, /* counter max */
133 1, /* burstsize */
134 DMA_UNIT_8, /* minimum xfer */
135 0, /* dma speed */
136 (uint_t)DMALIM_VER0, /* version */
137 0x0000ffff, /* address register */
138 0x0000ffff, /* counter register */
139 1, /* sector size */
140 0x00000001, /* scatter/gather list length */
141 (uint_t)0xffffffff /* request size */
142 };
143
144 static ddi_dma_attr_t ISA_dma_attr = {
145 DMA_ATTR_V0,
146 (unsigned long long)0,
147 (unsigned long long)0x00ffffff,
148 0x0000ffff,
149 1,
150 1,
151 1,
152 (unsigned long long)0xffffffff,
153 (unsigned long long)0x0000ffff,
154 1,
155 1,
156 0
157 };
158
159
160 /*
161 * Config information
162 */
561 * Call my parents bus_map function with modified values...
562 */
563
564 return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
565 }
566
567 static int
568 isa_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *dma_attr,
569 int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
570 {
571 ddi_dma_attr_merge(dma_attr, &ISA_dma_attr);
572 return (ddi_dma_allochdl(dip, rdip, dma_attr, waitfp, arg, handlep));
573 }
574
575 static int
576 isa_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
577 ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
578 off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
579 {
580 int rval;
581 ddi_dma_lim_t defalt;
582 int arg = (int)(uintptr_t)objp;
583
584 switch (request) {
585
586 case DDI_DMA_E_PROG:
587 return (i_dmae_prog(rdip, (struct ddi_dmae_req *)offp,
588 (ddi_dma_cookie_t *)lenp, arg));
589
590 case DDI_DMA_E_ACQUIRE:
591 return (i_dmae_acquire(rdip, arg, (int(*)(caddr_t))offp,
592 (caddr_t)lenp));
593
594 case DDI_DMA_E_FREE:
595 return (i_dmae_free(rdip, arg));
596
597 case DDI_DMA_E_STOP:
598 i_dmae_stop(rdip, arg);
599 return (DDI_SUCCESS);
600
601 case DDI_DMA_E_ENABLE:
602 i_dmae_enable(rdip, arg);
603 return (DDI_SUCCESS);
604
605 case DDI_DMA_E_DISABLE:
606 i_dmae_disable(rdip, arg);
607 return (DDI_SUCCESS);
608
609 case DDI_DMA_E_GETCNT:
610 i_dmae_get_chan_stat(rdip, arg, NULL, (int *)lenp);
611 return (DDI_SUCCESS);
612
613 case DDI_DMA_E_SWSETUP:
614 return (i_dmae_swsetup(rdip, (struct ddi_dmae_req *)offp,
615 (ddi_dma_cookie_t *)lenp, arg));
616
617 case DDI_DMA_E_SWSTART:
618 i_dmae_swstart(rdip, arg);
619 return (DDI_SUCCESS);
620
621 case DDI_DMA_E_GETLIM:
622 bcopy(&ISA_dma_limits, objp, sizeof (ddi_dma_lim_t));
623 return (DDI_SUCCESS);
624
625 case DDI_DMA_E_GETATTR:
626 bcopy(&ISA_dma_attr, objp, sizeof (ddi_dma_attr_t));
627 return (DDI_SUCCESS);
628
629 case DDI_DMA_E_1STPTY:
630 {
631 struct ddi_dmae_req req1stpty =
632 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
633 if (arg == 0) {
634 req1stpty.der_command = DMAE_CMD_TRAN;
635 req1stpty.der_trans = DMAE_TRANS_DMND;
636 } else {
637 req1stpty.der_trans = DMAE_TRANS_CSCD;
638 }
639 return (i_dmae_prog(rdip, &req1stpty, NULL, arg));
640 }
641
642 case DDI_DMA_IOPB_ALLOC: /* get contiguous DMA-able memory */
643 case DDI_DMA_SMEM_ALLOC:
644 if (!offp) {
645 defalt = ISA_dma_limits;
646 offp = (off_t *)&defalt;
647 }
648 /*FALLTHROUGH*/
649 default:
650 rval = ddi_dma_mctl(dip, rdip, handle, request, offp,
651 lenp, objp, flags);
652 }
653 return (rval);
654 }
655
656 /*
657 * Check if driver should be treated as an old pre 2.6 driver
658 */
659 static int
660 old_driver(dev_info_t *dip)
661 {
662 extern int ignore_hardware_nodes; /* force flag from ddi_impl.c */
663
664 if (ndi_dev_is_persistent_node(dip)) {
665 if (ignore_hardware_nodes)
666 return (1);
667 if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
668 "ignore-hardware-nodes", -1) != -1)
669 return (1);
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright 2014 Garrett D'Amore <garrett@damore.org>
23 * Copyright (c) 2012 Gary Mills
24 * Copyright (c) 1992, 2010, Oracle and/or its affiliates. All rights reserved.
25 */
26
27 /*
28 * ISA bus nexus driver
29 */
30
31 #include <sys/types.h>
32 #include <sys/cmn_err.h>
33 #include <sys/conf.h>
34 #include <sys/modctl.h>
35 #include <sys/autoconf.h>
36 #include <sys/errno.h>
37 #include <sys/debug.h>
38 #include <sys/kmem.h>
39 #include <sys/psm.h>
40 #include <sys/ddidmareq.h>
41 #include <sys/ddi_impldefs.h>
42 #include <sys/ddi_subrdefs.h>
43 #include <sys/dma_engine.h>
44 #include <sys/ddi.h>
109 #define MAX_EXTRA_RESOURCE 7
110 static struct regspec isa_extra_resource[MAX_EXTRA_RESOURCE];
111 static int isa_extra_count = 0;
112
113 /* Register definitions for COM1 to COM4. */
114 static struct regspec asy_regs[] = {
115 {1, 0x3f8, 0x8},
116 {1, 0x2f8, 0x8},
117 {1, 0x3e8, 0x8},
118 {1, 0x2e8, 0x8}
119 };
120
121 /* Serial port interrupt vectors for COM1 to COM4. */
122 static int asy_intrs[] = {0x4, 0x3, 0x4, 0x3};
123 /* Bitfield indicating which interrupts are overridden by eeprom config */
124 static uchar_t asy_intr_override = 0;
125
126 /*
127 * Local data
128 */
129
130 static ddi_dma_attr_t ISA_dma_attr = {
131 DMA_ATTR_V0,
132 (unsigned long long)0,
133 (unsigned long long)0x00ffffff,
134 0x0000ffff,
135 1,
136 1,
137 1,
138 (unsigned long long)0xffffffff,
139 (unsigned long long)0x0000ffff,
140 1,
141 1,
142 0
143 };
144
145
146 /*
147 * Config information
148 */
547 * Call my parents bus_map function with modified values...
548 */
549
550 return (ddi_map(dip, mp, (off_t)0, (off_t)0, vaddrp));
551 }
552
553 static int
554 isa_dma_allochdl(dev_info_t *dip, dev_info_t *rdip, ddi_dma_attr_t *dma_attr,
555 int (*waitfp)(caddr_t), caddr_t arg, ddi_dma_handle_t *handlep)
556 {
557 ddi_dma_attr_merge(dma_attr, &ISA_dma_attr);
558 return (ddi_dma_allochdl(dip, rdip, dma_attr, waitfp, arg, handlep));
559 }
560
561 static int
562 isa_dma_mctl(dev_info_t *dip, dev_info_t *rdip,
563 ddi_dma_handle_t handle, enum ddi_dma_ctlops request,
564 off_t *offp, size_t *lenp, caddr_t *objp, uint_t flags)
565 {
566 int rval;
567 int arg = (int)(uintptr_t)objp;
568
569 switch (request) {
570
571 case DDI_DMA_E_PROG:
572 return (i_dmae_prog(rdip, (struct ddi_dmae_req *)offp,
573 (ddi_dma_cookie_t *)lenp, arg));
574
575 case DDI_DMA_E_ACQUIRE:
576 return (i_dmae_acquire(rdip, arg, (int(*)(caddr_t))offp,
577 (caddr_t)lenp));
578
579 case DDI_DMA_E_FREE:
580 return (i_dmae_free(rdip, arg));
581
582 case DDI_DMA_E_STOP:
583 i_dmae_stop(rdip, arg);
584 return (DDI_SUCCESS);
585
586 case DDI_DMA_E_ENABLE:
587 i_dmae_enable(rdip, arg);
588 return (DDI_SUCCESS);
589
590 case DDI_DMA_E_DISABLE:
591 i_dmae_disable(rdip, arg);
592 return (DDI_SUCCESS);
593
594 case DDI_DMA_E_GETCNT:
595 i_dmae_get_chan_stat(rdip, arg, NULL, (int *)lenp);
596 return (DDI_SUCCESS);
597
598 case DDI_DMA_E_SWSETUP:
599 return (i_dmae_swsetup(rdip, (struct ddi_dmae_req *)offp,
600 (ddi_dma_cookie_t *)lenp, arg));
601
602 case DDI_DMA_E_SWSTART:
603 i_dmae_swstart(rdip, arg);
604 return (DDI_SUCCESS);
605
606 case DDI_DMA_E_GETATTR:
607 bcopy(&ISA_dma_attr, objp, sizeof (ddi_dma_attr_t));
608 return (DDI_SUCCESS);
609
610 case DDI_DMA_E_1STPTY:
611 {
612 struct ddi_dmae_req req1stpty =
613 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
614 if (arg == 0) {
615 req1stpty.der_command = DMAE_CMD_TRAN;
616 req1stpty.der_trans = DMAE_TRANS_DMND;
617 } else {
618 req1stpty.der_trans = DMAE_TRANS_CSCD;
619 }
620 return (i_dmae_prog(rdip, &req1stpty, NULL, arg));
621 }
622
623 default:
624 /*
625 * We pass to rootnex, but it turns out that rootnex will just
626 * return failure, as we don't use ddi_dma_mctl() except
627 * for DMA engine (ISA) and DVMA (SPARC). Arguably we could
628 * just return an error direclty here, instead.
629 */
630 rval = ddi_dma_mctl(dip, rdip, handle, request, offp,
631 lenp, objp, flags);
632 }
633 return (rval);
634 }
635
636 /*
637 * Check if driver should be treated as an old pre 2.6 driver
638 */
639 static int
640 old_driver(dev_info_t *dip)
641 {
642 extern int ignore_hardware_nodes; /* force flag from ddi_impl.c */
643
644 if (ndi_dev_is_persistent_node(dip)) {
645 if (ignore_hardware_nodes)
646 return (1);
647 if (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
648 "ignore-hardware-nodes", -1) != -1)
649 return (1);
|