]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - 6/sys/dev/hfa/fore_stats.c
Clone Kip's Xen on stable/6 tree so that I can work on improving FreeBSD/amd64
[FreeBSD/FreeBSD.git] / 6 / sys / dev / hfa / fore_stats.c
1 /*-
2  * ===================================
3  * HARP  |  Host ATM Research Platform
4  * ===================================
5  *
6  * This Host ATM Research Platform ("HARP") file (the "Software") is
7  * made available by Network Computing Services, Inc. ("NetworkCS")
8  * "AS IS".  NetworkCS does not provide maintenance, improvements or
9  * support of any kind.
10  *
11  * NETWORKCS MAKES NO WARRANTIES OR REPRESENTATIONS, EXPRESS OR IMPLIED,
12  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY
13  * AND FITNESS FOR A PARTICULAR PURPOSE, AS TO ANY ELEMENT OF THE
14  * SOFTWARE OR ANY SUPPORT PROVIDED IN CONNECTION WITH THIS SOFTWARE.
15  * In no event shall NetworkCS be responsible for any damages, including
16  * but not limited to consequential damages, arising from or relating to
17  * any use of the Software or related support.
18  *
19  * Copyright 1994-1998 Network Computing Services, Inc.
20  *
21  * Copies of this Software may be made, however, the above copyright
22  * notice must be reproduced on all copies.
23  */
24
25 #include <sys/cdefs.h>
26 __FBSDID("$FreeBSD$");
27
28 /*
29  * FORE Systems 200-Series Adapter Support
30  * ---------------------------------------
31  *
32  * Device statistics routines
33  *
34  */
35
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/socket.h>
39 #include <sys/socketvar.h>
40 #include <vm/vm.h>
41 #include <vm/pmap.h>
42 #include <net/if.h>
43 #include <netatm/port.h>
44 #include <netatm/queue.h>
45 #include <netatm/atm.h>
46 #include <netatm/atm_sys.h>
47 #include <netatm/atm_sap.h>
48 #include <netatm/atm_cm.h>
49 #include <netatm/atm_if.h>
50 #include <netatm/atm_stack.h>
51 #include <netatm/atm_pcb.h>
52 #include <netatm/atm_var.h>
53 #include <dev/pci/pcivar.h>
54 #include <dev/hfa/fore.h>
55 #include <dev/hfa/fore_aali.h>
56 #include <dev/hfa/fore_slave.h>
57 #include <dev/hfa/fore_stats.h>
58 #include <dev/hfa/fore_var.h>
59 #include <dev/hfa/fore_include.h>
60
61 #ifndef lint
62 __RCSID("@(#) $FreeBSD$");
63 #endif
64
65
66 /*
67  * Get device statistics from CP
68  * 
69  * This function will issue a GET_STATS command to the CP in order to
70  * initiate the DMA transfer of the CP's statistics structure to the host.
71  * We will then sleep pending command completion.  This must only be called
72  * from the ioctl system call handler.
73  *
74  * Called at splnet.
75  *
76  * Arguments:
77  *      fup     pointer to device unit structure
78  *
79  * Returns:
80  *      0       stats retrieval successful
81  *      errno   stats retrieval failed - reason indicated
82  *
83  */
84 int
85 fore_get_stats(fup)
86         Fore_unit       *fup;
87 {
88         H_cmd_queue     *hcp;
89         Cmd_queue       *cqp;
90         int             s, sst;
91
92         ATM_DEBUG1("fore_get_stats: fup=%p\n", fup);
93
94         /*
95          * Make sure device has been initialized
96          */
97         if ((fup->fu_flags & CUF_INITED) == 0) {
98                 return (EIO);
99         }
100
101         /*
102          * If someone has already initiated a stats request, we'll
103          * just wait for that one to complete
104          */
105         s = splimp();
106         if (fup->fu_flags & FUF_STATCMD) {
107
108 #if (defined(BSD) && (BSD >= 199103))
109                 sst = tsleep((caddr_t)&fup->fu_stats, PWAIT|PCATCH, "fore", 0);
110 #else
111                 sst = sleep((caddr_t)&fup->fu_stats, PWAIT|PCATCH);
112                 if (sst != 0)
113                         sst = EINTR;
114 #endif
115                 (void) splx(s);
116                 return (sst ? sst : fup->fu_stats_ret);
117         }
118
119         /*
120          * Limit stats gathering to once a second or so
121          */
122         if (time_second == fup->fu_stats_time) {
123                 (void) splx(s);
124                 return (0);
125         } else
126                 fup->fu_stats_time = time_second;
127
128         /*
129          * Queue command at end of command queue
130          */
131         hcp = fup->fu_cmd_tail;
132         if ((*hcp->hcq_status) & QSTAT_FREE) {
133                 vm_paddr_t      dma;
134
135                 /*
136                  * Queue entry available, so set our view of things up
137                  */
138                 hcp->hcq_code = CMD_GET_STATS;
139                 hcp->hcq_arg = NULL;
140                 fup->fu_cmd_tail = hcp->hcq_next;
141
142                 /*
143                  * Now set the CP-resident queue entry - the CP will grab
144                  * the command when the op-code is set.
145                  */
146                 cqp = hcp->hcq_cpelem;
147                 (*hcp->hcq_status) = QSTAT_PENDING;
148
149                 dma = vtophys(fup->fu_stats);
150                 if (dma == 0) {
151                         fup->fu_stats->st_drv.drv_cm_nodma++;
152                         (void) splx(s);
153                         return (EIO);
154                 }
155                 fup->fu_statsd = dma;
156                 cqp->cmdq_stats.stats_buffer = (CP_dma) CP_WRITE(dma);
157
158                 fup->fu_flags |= FUF_STATCMD;
159                 cqp->cmdq_stats.stats_cmd = 
160                         CP_WRITE(CMD_GET_STATS | CMD_INTR_REQ);
161
162                 /*
163                  * Now wait for command to finish
164                  */
165 #if (defined(BSD) && (BSD >= 199103))
166                 sst = tsleep((caddr_t)&fup->fu_stats, PWAIT|PCATCH, "fore", 0);
167 #else
168                 sst = sleep((caddr_t)&fup->fu_stats, PWAIT|PCATCH);
169                 if (sst != 0)
170                         sst = EINTR;
171 #endif
172                 (void) splx(s);
173                 return (sst ? sst : fup->fu_stats_ret);
174
175         } else {
176                 /*
177                  * Command queue full
178                  */
179                 fup->fu_stats->st_drv.drv_cm_full++;
180                 (void) splx(s);
181                 return (EIO);
182         }
183 }
184