Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / atm / hfa / fore_if.c
1 /*
2  *
3  * ===================================
4  * HARP  |  Host ATM Research Platform
5  * ===================================
6  *
7  *
8  * This Host ATM Research Platform ("HARP") file (the "Software") is
9  * made available by Network Computing Services, Inc. ("NetworkCS")
10  * "AS IS".  NetworkCS does not provide maintenance, improvements or
11  * support of any kind.
12  *
13  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
14  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
15  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
16  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
17  * In no event shall NetworkCS be responsible for any damages, including
18  * but not limited to consequential damages, arising from or relating to
19  * any use of the Software or related support.
20  *
21  * Copyright 1994-1998 Network Computing Services, Inc.
22  *
23  * Copies of this Software may be made, however, the above copyright
24  * notice must be reproduced on all copies.
25  *
26  *      @(#) $FreeBSD: src/sys/dev/hfa/fore_if.c,v 1.5 1999/08/28 00:41:49 peter Exp $
27  *
28  */
29
30 /*
31  * FORE Systems 200-Series Adapter Support
32  * ---------------------------------------
33  *
34  * Network interface layer support
35  *
36  */
37
38 #include <dev/hfa/fore_include.h>
39
40 #ifndef lint
41 __RCSID("@(#) $FreeBSD: src/sys/dev/hfa/fore_if.c,v 1.5 1999/08/28 00:41:49 peter Exp $");
42 #endif
43
44
45 /*
46  * Handle netatm core service interface ioctl requests 
47  *
48  * Called at splnet.
49  *
50  * Arguments:
51  *      code            ioctl function (sub)code
52  *      data            data to/from ioctl
53  *      arg             optional code-specific argument
54  *
55  * Returns:
56  *      0               request processed successfully
57  *      error           request failed - reason code
58  */
59 int
60 fore_atm_ioctl(code, data, arg)
61         int     code;
62         caddr_t data;
63         caddr_t arg;
64 {
65         struct atminfreq        *aip = (struct atminfreq *)data;
66         struct atm_pif          *pip;
67         Fore_unit               *fup;
68         caddr_t                 buf = aip->air_buf_addr;
69         struct air_vinfo_rsp    *avr;
70         int                     count, len, buf_len = aip->air_buf_len;
71         int                     err = 0;
72         char                    ifname[2*IFNAMSIZ];
73  
74
75         ATM_DEBUG2("fore_atm_ioctl: code=%d, opcode=%d\n", 
76                 code, aip->air_opcode);
77
78         switch ( aip->air_opcode ) {
79
80         case AIOCS_INF_VST:
81                 /*
82                  * Get vendor statistics
83                  */
84                 pip = (struct atm_pif *)arg;
85                 fup = (Fore_unit *)pip;
86                 if ( pip == NULL )
87                         return ( ENXIO );
88                 snprintf ( ifname, sizeof(ifname),
89                     "%s%d", pip->pif_name, pip->pif_unit );
90
91                 /*
92                  * Cast response structure onto user's buffer
93                  */
94                 avr = (struct air_vinfo_rsp *)buf;
95
96                 /*
97                  * How large is the response structure?
98                  */
99                 len = sizeof(struct air_vinfo_rsp);
100
101                 /*
102                  * Sanity check - enough room for response structure?
103                  */
104                 if ( buf_len < len )
105                         return ( ENOSPC );
106
107                 /*
108                  * Copy interface name into response structure
109                  */
110                 if ((err = copyout ( ifname, avr->avsp_intf, IFNAMSIZ)) != 0)
111                         break;
112
113                 /*
114                  * Advance the buffer address and decrement the size
115                  */
116                 buf += len;
117                 buf_len -= len;
118
119                 /*
120                  * Get the vendor stats from the hardware
121                  */
122                 count = 0;
123                 if ( ( err = fore_get_stats ( fup ) ) == 0 )
124                 {
125                         /*
126                          * Stick as much of it as we have room for 
127                          * into the response
128                          */
129                         count = min ( sizeof(Fore_stats), buf_len );
130
131                         /*
132                          * Copy stats into user's buffer. Return value is
133                          * amount of data copied.
134                          */
135                         if ((err = copyout((caddr_t)fup->fu_stats, buf, count)) != 0)
136                                 break;
137                         buf += count;
138                         buf_len -= count;
139                         if ( count < sizeof(Fore_stats) )
140                                 err = ENOSPC;
141                 }
142
143                 /*
144                  * Record amount we're returning as vendor info...
145                  */
146                 if ((err = copyout(&count, &avr->avsp_len, sizeof(int))) != 0)
147                         break;
148
149                 /*
150                  * Update the reply pointers and lengths
151                  */
152                 aip->air_buf_addr = buf;
153                 aip->air_buf_len = buf_len;
154                 break;
155
156         default:
157                 err = ENOSYS;           /* Operation not supported */
158                 break;
159         }
160
161         return (err);
162 }
163
164
165 /*
166  * Free Fore-specific device resources
167  * 
168  * Frees all dynamically acquired resources for a device unit.  Before
169  * this function is called, the CP will have been reset and our interrupt
170  * vectors removed.
171  *
172  * Arguments:
173  *      fup     pointer to device unit structure
174  *
175  * Returns:
176  *      none
177  *
178  */
179 void
180 fore_interface_free(fup)
181         Fore_unit       *fup;
182 {
183
184         /*
185          * Free up all of our allocated memory
186          */
187         fore_xmit_free(fup);
188         fore_recv_free(fup);
189         fore_buf_free(fup);
190         fore_cmd_free(fup);
191
192         /*
193          * Clear device initialized
194          */
195         if (fup->fu_flags & CUF_INITED) {
196                 fup->fu_flags &= ~CUF_INITED;
197         }
198
199         if (fup->fu_flags & FUF_STATCMD) {
200                 DMA_FREE_ADDR(fup->fu_stats, fup->fu_statsd,
201                         sizeof(Fore_cp_stats), 0);
202                 fup->fu_flags &= ~FUF_STATCMD;
203         }
204         return;
205 }
206