diff options
author | Andrew Morton <akpm@osdl.org> | 2006-01-11 15:17:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-11 21:42:14 -0500 |
commit | 8d8706e2f86d28814c1b40a116ffdeca35e4c949 (patch) | |
tree | 146567d7a807feb37a5368fbb4a6ee76d9d7bc7e /drivers/char/rio/rioctrl.c | |
parent | a9415644583ef344e02f84faf5fe24bfadb2af8e (diff) |
[PATCH] lindent rio drivers
Run all rio files through indent -kr -i8 -bri0 -l255, as requested by Alan.
rioboot.c and rioinit.c were skipped due to worrisome lindent warnings.
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/char/rio/rioctrl.c')
-rw-r--r-- | drivers/char/rio/rioctrl.c | 3119 |
1 files changed, 1501 insertions, 1618 deletions
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c index b4d1a23e27e4..0b7700d2f049 100644 --- a/drivers/char/rio/rioctrl.c +++ b/drivers/char/rio/rioctrl.c | |||
@@ -82,16 +82,16 @@ static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3"; | |||
82 | #include "rioioctl.h" | 82 | #include "rioioctl.h" |
83 | 83 | ||
84 | 84 | ||
85 | static struct LpbReq LpbReq; | 85 | static struct LpbReq LpbReq; |
86 | static struct RupReq RupReq; | 86 | static struct RupReq RupReq; |
87 | static struct PortReq PortReq; | 87 | static struct PortReq PortReq; |
88 | static struct HostReq HostReq; | 88 | static struct HostReq HostReq; |
89 | static struct HostDpRam HostDpRam; | 89 | static struct HostDpRam HostDpRam; |
90 | static struct DebugCtrl DebugCtrl; | 90 | static struct DebugCtrl DebugCtrl; |
91 | static struct Map MapEnt; | 91 | static struct Map MapEnt; |
92 | static struct PortSetup PortSetup; | 92 | static struct PortSetup PortSetup; |
93 | static struct DownLoad DownLoad; | 93 | static struct DownLoad DownLoad; |
94 | static struct SendPack SendPack; | 94 | static struct SendPack SendPack; |
95 | /* static struct StreamInfo StreamInfo; */ | 95 | /* static struct StreamInfo StreamInfo; */ |
96 | /* static char modemtable[RIO_PORTS]; */ | 96 | /* static char modemtable[RIO_PORTS]; */ |
97 | static struct SpecialRupCmd SpecialRupCmd; | 97 | static struct SpecialRupCmd SpecialRupCmd; |
@@ -99,18 +99,18 @@ static struct PortParams PortParams; | |||
99 | static struct portStats portStats; | 99 | static struct portStats portStats; |
100 | 100 | ||
101 | static struct SubCmdStruct { | 101 | static struct SubCmdStruct { |
102 | ushort Host; | 102 | ushort Host; |
103 | ushort Rup; | 103 | ushort Rup; |
104 | ushort Port; | 104 | ushort Port; |
105 | ushort Addr; | 105 | ushort Addr; |
106 | } SubCmd; | 106 | } SubCmd; |
107 | 107 | ||
108 | struct PortTty { | 108 | struct PortTty { |
109 | uint port; | 109 | uint port; |
110 | struct ttystatics Tty; | 110 | struct ttystatics Tty; |
111 | }; | 111 | }; |
112 | 112 | ||
113 | static struct PortTty PortTty; | 113 | static struct PortTty PortTty; |
114 | typedef struct ttystatics TERMIO; | 114 | typedef struct ttystatics TERMIO; |
115 | 115 | ||
116 | /* | 116 | /* |
@@ -121,267 +121,264 @@ typedef struct ttystatics TERMIO; | |||
121 | ** The RIOBootCodeUNKNOWN entry is there to politely tell the calling | 121 | ** The RIOBootCodeUNKNOWN entry is there to politely tell the calling |
122 | ** process to bog off. | 122 | ** process to bog off. |
123 | */ | 123 | */ |
124 | static int | 124 | static int |
125 | (*RIOBootTable[MAX_PRODUCT])(struct rio_info *, struct DownLoad *) = | 125 | (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = { |
126 | { | 126 | /* 0 */ RIOBootCodeHOST, |
127 | /* 0 */ RIOBootCodeHOST, /* Host Card */ | 127 | /* Host Card */ |
128 | /* 1 */ RIOBootCodeRTA, /* RTA */ | 128 | /* 1 */ RIOBootCodeRTA, |
129 | /* RTA */ | ||
129 | }; | 130 | }; |
130 | 131 | ||
131 | #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) | 132 | #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff)) |
132 | 133 | ||
133 | int copyin (int arg, caddr_t dp, int siz) | 134 | int copyin(int arg, caddr_t dp, int siz) |
134 | { | 135 | { |
135 | int rv; | 136 | int rv; |
136 | 137 | ||
137 | rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *)arg, dp); | 138 | rio_dprintk(RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *) arg, dp); |
138 | rv = copy_from_user (dp, (void *)arg, siz); | 139 | rv = copy_from_user(dp, (void *) arg, siz); |
139 | if (rv) return COPYFAIL; | 140 | if (rv) |
140 | else return rv; | 141 | return COPYFAIL; |
142 | else | ||
143 | return rv; | ||
141 | } | 144 | } |
142 | 145 | ||
143 | static int copyout (caddr_t dp, int arg, int siz) | 146 | static int copyout(caddr_t dp, int arg, int siz) |
144 | { | 147 | { |
145 | int rv; | 148 | int rv; |
146 | 149 | ||
147 | rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *)arg, dp); | 150 | rio_dprintk(RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *) arg, dp); |
148 | rv = copy_to_user ((void *)arg, dp, siz); | 151 | rv = copy_to_user((void *) arg, dp, siz); |
149 | if (rv) return COPYFAIL; | 152 | if (rv) |
150 | else return rv; | 153 | return COPYFAIL; |
154 | else | ||
155 | return rv; | ||
151 | } | 156 | } |
152 | 157 | ||
153 | int | 158 | int riocontrol(p, dev, cmd, arg, su) |
154 | riocontrol(p, dev, cmd, arg, su) | 159 | struct rio_info *p; |
155 | struct rio_info * p; | 160 | dev_t dev; |
156 | dev_t dev; | 161 | int cmd; |
157 | int cmd; | 162 | caddr_t arg; |
158 | caddr_t arg; | 163 | int su; |
159 | int su; | ||
160 | { | 164 | { |
161 | uint Host; /* leave me unsigned! */ | 165 | uint Host; /* leave me unsigned! */ |
162 | uint port; /* and me! */ | 166 | uint port; /* and me! */ |
163 | struct Host *HostP; | 167 | struct Host *HostP; |
164 | ushort loop; | 168 | ushort loop; |
165 | int Entry; | 169 | int Entry; |
166 | struct Port *PortP; | 170 | struct Port *PortP; |
167 | PKT *PacketP; | 171 | PKT *PacketP; |
168 | int retval = 0; | 172 | int retval = 0; |
169 | unsigned long flags; | 173 | unsigned long flags; |
170 | 174 | ||
171 | func_enter (); | 175 | func_enter(); |
172 | 176 | ||
173 | /* Confuse the compiler to think that we've initialized these */ | 177 | /* Confuse the compiler to think that we've initialized these */ |
174 | Host=0; | 178 | Host = 0; |
175 | PortP = NULL; | 179 | PortP = NULL; |
176 | 180 | ||
177 | rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg); | 181 | rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int) arg); |
178 | 182 | ||
179 | switch (cmd) { | 183 | switch (cmd) { |
180 | /* | 184 | /* |
181 | ** RIO_SET_TIMER | 185 | ** RIO_SET_TIMER |
182 | ** | 186 | ** |
183 | ** Change the value of the host card interrupt timer. | 187 | ** Change the value of the host card interrupt timer. |
184 | ** If the host card number is -1 then all host cards are changed | 188 | ** If the host card number is -1 then all host cards are changed |
185 | ** otherwise just the specified host card will be changed. | 189 | ** otherwise just the specified host card will be changed. |
186 | */ | 190 | */ |
187 | case RIO_SET_TIMER: | 191 | case RIO_SET_TIMER: |
188 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint)arg); | 192 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint) arg); |
189 | { | 193 | { |
190 | int host, value; | 194 | int host, value; |
191 | host = (uint)arg >> 16; | 195 | host = (uint) arg >> 16; |
192 | value = (uint)arg & 0x0000ffff; | 196 | value = (uint) arg & 0x0000ffff; |
193 | if (host == -1) { | 197 | if (host == -1) { |
194 | for (host = 0; host < p->RIONumHosts; host++) { | 198 | for (host = 0; host < p->RIONumHosts; host++) { |
195 | if (p->RIOHosts[host].Flags == RC_RUNNING) { | 199 | if (p->RIOHosts[host].Flags == RC_RUNNING) { |
196 | WWORD(p->RIOHosts[host].ParmMapP->timer , value); | 200 | WWORD(p->RIOHosts[host].ParmMapP->timer, value); |
197 | } | ||
198 | } | ||
199 | } else if (host >= p->RIONumHosts) { | ||
200 | return -EINVAL; | ||
201 | } else { | ||
202 | if ( p->RIOHosts[host].Flags == RC_RUNNING ) { | ||
203 | WWORD(p->RIOHosts[host].ParmMapP->timer , value); | ||
204 | } | 201 | } |
205 | } | 202 | } |
206 | } | 203 | } else if (host >= p->RIONumHosts) { |
207 | return 0; | 204 | return -EINVAL; |
208 | 205 | } else { | |
209 | case RIO_IDENTIFY_DRIVER: | 206 | if (p->RIOHosts[host].Flags == RC_RUNNING) { |
210 | /* | 207 | WWORD(p->RIOHosts[host].ParmMapP->timer, value); |
211 | ** 15.10.1998 ARG - ESIL 0760 part fix | ||
212 | ** Added driver ident string output. | ||
213 | ** | ||
214 | #ifndef __THIS_RELEASE__ | ||
215 | #warning Driver Version string not defined ! | ||
216 | #endif | ||
217 | cprintf("%s %s %s %s\n", | ||
218 | RIO_DRV_STR, | ||
219 | __THIS_RELEASE__, | ||
220 | __DATE__, __TIME__ ); | ||
221 | |||
222 | return 0; | ||
223 | |||
224 | case RIO_DISPLAY_HOST_CFG: | ||
225 | ** | ||
226 | ** 15.10.1998 ARG - ESIL 0760 part fix | ||
227 | ** Added driver host card ident string output. | ||
228 | ** | ||
229 | ** Note that the only types currently supported | ||
230 | ** are ISA and PCI. Also this driver does not | ||
231 | ** (yet) distinguish between the Old PCI card | ||
232 | ** and the Jet PCI card. In fact I think this | ||
233 | ** driver only supports JET PCI ! | ||
234 | ** | ||
235 | |||
236 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
237 | { | ||
238 | HostP = &(p->RIOHosts[Host]); | ||
239 | |||
240 | switch ( HostP->Type ) | ||
241 | { | ||
242 | case RIO_AT : | ||
243 | strcpy( host_type, RIO_AT_HOST_STR ); | ||
244 | break; | ||
245 | |||
246 | case RIO_PCI : | ||
247 | strcpy( host_type, RIO_PCI_HOST_STR ); | ||
248 | break; | ||
249 | |||
250 | default : | ||
251 | strcpy( host_type, "Unknown" ); | ||
252 | break; | ||
253 | } | 208 | } |
209 | } | ||
210 | } | ||
211 | return 0; | ||
254 | 212 | ||
255 | cprintf( | 213 | case RIO_IDENTIFY_DRIVER: |
256 | "RIO Host %d - Type:%s Addr:%X IRQ:%d\n", | 214 | /* |
257 | Host, host_type, | 215 | ** 15.10.1998 ARG - ESIL 0760 part fix |
258 | (uint)HostP->PaddrP, | 216 | ** Added driver ident string output. |
259 | (int)HostP->Ivec - 32 ); | 217 | ** |
218 | #ifndef __THIS_RELEASE__ | ||
219 | #warning Driver Version string not defined ! | ||
220 | #endif | ||
221 | cprintf("%s %s %s %s\n", | ||
222 | RIO_DRV_STR, | ||
223 | __THIS_RELEASE__, | ||
224 | __DATE__, __TIME__ ); | ||
225 | |||
226 | return 0; | ||
227 | |||
228 | case RIO_DISPLAY_HOST_CFG: | ||
229 | ** | ||
230 | ** 15.10.1998 ARG - ESIL 0760 part fix | ||
231 | ** Added driver host card ident string output. | ||
232 | ** | ||
233 | ** Note that the only types currently supported | ||
234 | ** are ISA and PCI. Also this driver does not | ||
235 | ** (yet) distinguish between the Old PCI card | ||
236 | ** and the Jet PCI card. In fact I think this | ||
237 | ** driver only supports JET PCI ! | ||
238 | ** | ||
239 | |||
240 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
241 | { | ||
242 | HostP = &(p->RIOHosts[Host]); | ||
243 | |||
244 | switch ( HostP->Type ) | ||
245 | { | ||
246 | case RIO_AT : | ||
247 | strcpy( host_type, RIO_AT_HOST_STR ); | ||
248 | break; | ||
249 | |||
250 | case RIO_PCI : | ||
251 | strcpy( host_type, RIO_PCI_HOST_STR ); | ||
252 | break; | ||
253 | |||
254 | default : | ||
255 | strcpy( host_type, "Unknown" ); | ||
256 | break; | ||
257 | } | ||
258 | |||
259 | cprintf( | ||
260 | "RIO Host %d - Type:%s Addr:%X IRQ:%d\n", | ||
261 | Host, host_type, | ||
262 | (uint)HostP->PaddrP, | ||
263 | (int)HostP->Ivec - 32 ); | ||
264 | } | ||
265 | return 0; | ||
266 | ** | ||
267 | */ | ||
268 | |||
269 | case RIO_FOAD_RTA: | ||
270 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); | ||
271 | return RIOCommandRta(p, (uint) arg, RIOFoadRta); | ||
272 | |||
273 | case RIO_ZOMBIE_RTA: | ||
274 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); | ||
275 | return RIOCommandRta(p, (uint) arg, RIOZombieRta); | ||
276 | |||
277 | case RIO_IDENTIFY_RTA: | ||
278 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); | ||
279 | return RIOIdentifyRta(p, arg); | ||
280 | |||
281 | case RIO_KILL_NEIGHBOUR: | ||
282 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); | ||
283 | return RIOKillNeighbour(p, arg); | ||
284 | |||
285 | case SPECIAL_RUP_CMD: | ||
286 | { | ||
287 | struct CmdBlk *CmdBlkP; | ||
288 | |||
289 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); | ||
290 | if (copyin((int) arg, (caddr_t) & SpecialRupCmd, sizeof(SpecialRupCmd)) == COPYFAIL) { | ||
291 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); | ||
292 | p->RIOError.Error = COPYIN_FAILED; | ||
293 | return -EFAULT; | ||
294 | } | ||
295 | CmdBlkP = RIOGetCmdBlk(); | ||
296 | if (!CmdBlkP) { | ||
297 | rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); | ||
298 | return -ENXIO; | ||
299 | } | ||
300 | CmdBlkP->Packet = SpecialRupCmd.Packet; | ||
301 | if (SpecialRupCmd.Host >= p->RIONumHosts) | ||
302 | SpecialRupCmd.Host = 0; | ||
303 | rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum); | ||
304 | if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { | ||
305 | cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n"); | ||
260 | } | 306 | } |
261 | return 0; | 307 | return 0; |
262 | ** | 308 | } |
263 | */ | ||
264 | |||
265 | case RIO_FOAD_RTA: | ||
266 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n"); | ||
267 | return RIOCommandRta(p, (uint)arg, RIOFoadRta); | ||
268 | |||
269 | case RIO_ZOMBIE_RTA: | ||
270 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n"); | ||
271 | return RIOCommandRta(p, (uint)arg, RIOZombieRta); | ||
272 | |||
273 | case RIO_IDENTIFY_RTA: | ||
274 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n"); | ||
275 | return RIOIdentifyRta(p, arg); | ||
276 | |||
277 | case RIO_KILL_NEIGHBOUR: | ||
278 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n"); | ||
279 | return RIOKillNeighbour(p, arg); | ||
280 | |||
281 | case SPECIAL_RUP_CMD: | ||
282 | { | ||
283 | struct CmdBlk *CmdBlkP; | ||
284 | |||
285 | rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n"); | ||
286 | if (copyin((int)arg, (caddr_t)&SpecialRupCmd, | ||
287 | sizeof(SpecialRupCmd)) == COPYFAIL ) { | ||
288 | rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n"); | ||
289 | p->RIOError.Error = COPYIN_FAILED; | ||
290 | return -EFAULT; | ||
291 | } | ||
292 | CmdBlkP = RIOGetCmdBlk(); | ||
293 | if ( !CmdBlkP ) { | ||
294 | rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n"); | ||
295 | return -ENXIO; | ||
296 | } | ||
297 | CmdBlkP->Packet = SpecialRupCmd.Packet; | ||
298 | if ( SpecialRupCmd.Host >= p->RIONumHosts ) | ||
299 | SpecialRupCmd.Host = 0; | ||
300 | rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", | ||
301 | SpecialRupCmd.Host, SpecialRupCmd.RupNum); | ||
302 | if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], | ||
303 | SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) { | ||
304 | cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n"); | ||
305 | } | ||
306 | return 0; | ||
307 | } | ||
308 | 309 | ||
309 | case RIO_DEBUG_MEM: | 310 | case RIO_DEBUG_MEM: |
310 | #ifdef DEBUG_MEM_SUPPORT | 311 | #ifdef DEBUG_MEM_SUPPORT |
311 | RIO_DEBUG_CTRL, if (su) | 312 | RIO_DEBUG_CTRL, if (su) |
312 | return rio_RIODebugMemory(RIO_DEBUG_CTRL, arg); | 313 | return rio_RIODebugMemory(RIO_DEBUG_CTRL, arg); |
313 | else | 314 | else |
314 | #endif | 315 | #endif |
315 | return -EPERM; | 316 | return -EPERM; |
316 | |||
317 | case RIO_ALL_MODEM: | ||
318 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); | ||
319 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; | ||
320 | return -EINVAL; | ||
321 | |||
322 | case RIO_GET_TABLE: | ||
323 | /* | ||
324 | ** Read the routing table from the device driver to user space | ||
325 | */ | ||
326 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); | ||
327 | 317 | ||
328 | if ((retval = RIOApel(p)) != 0) | 318 | case RIO_ALL_MODEM: |
329 | return retval; | 319 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n"); |
320 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; | ||
321 | return -EINVAL; | ||
330 | 322 | ||
331 | if (copyout((caddr_t)p->RIOConnectTable, (int)arg, | 323 | case RIO_GET_TABLE: |
332 | TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) { | 324 | /* |
333 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); | 325 | ** Read the routing table from the device driver to user space |
334 | p->RIOError.Error = COPYOUT_FAILED; | 326 | */ |
335 | return -EFAULT; | 327 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n"); |
336 | } | 328 | |
329 | if ((retval = RIOApel(p)) != 0) | ||
330 | return retval; | ||
331 | |||
332 | if (copyout((caddr_t) p->RIOConnectTable, (int) arg, TOTAL_MAP_ENTRIES * sizeof(struct Map)) == COPYFAIL) { | ||
333 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n"); | ||
334 | p->RIOError.Error = COPYOUT_FAILED; | ||
335 | return -EFAULT; | ||
336 | } | ||
337 | |||
338 | { | ||
339 | int entry; | ||
340 | rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); | ||
341 | for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) { | ||
342 | if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0)) | ||
343 | continue; | ||
344 | |||
345 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum); | ||
346 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum); | ||
347 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID); | ||
348 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2); | ||
349 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags); | ||
350 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort); | ||
351 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit); | ||
352 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link); | ||
353 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit); | ||
354 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link); | ||
355 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit); | ||
356 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link); | ||
357 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit); | ||
358 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link); | ||
359 | rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name); | ||
360 | } | ||
361 | rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); | ||
362 | } | ||
363 | p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ | ||
364 | return 0; | ||
337 | 365 | ||
338 | { | 366 | case RIO_PUT_TABLE: |
339 | int entry; | 367 | /* |
340 | rio_dprintk (RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n"); | 368 | ** Write the routing table to the device driver from user space |
341 | for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ ) | 369 | */ |
342 | { | 370 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); |
343 | if ((p->RIOConnectTable[entry].ID == 0) && | 371 | |
344 | (p->RIOConnectTable[entry].HostUniqueNum == 0) && | 372 | if (!su) { |
345 | (p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue; | 373 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); |
346 | 374 | p->RIOError.Error = NOT_SUPER_USER; | |
347 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ); | 375 | return -EPERM; |
348 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ); | 376 | } |
349 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ); | 377 | if (copyin((int) arg, (caddr_t) & p->RIOConnectTable[0], TOTAL_MAP_ENTRIES * sizeof(struct Map)) == COPYFAIL) { |
350 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ); | 378 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); |
351 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags ); | 379 | p->RIOError.Error = COPYIN_FAILED; |
352 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort ); | 380 | return -EFAULT; |
353 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ); | 381 | } |
354 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link ); | ||
355 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ); | ||
356 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link ); | ||
357 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ); | ||
358 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link ); | ||
359 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ); | ||
360 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link ); | ||
361 | rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ); | ||
362 | } | ||
363 | rio_dprintk (RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n"); | ||
364 | } | ||
365 | p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */ | ||
366 | return 0; | ||
367 | |||
368 | case RIO_PUT_TABLE: | ||
369 | /* | ||
370 | ** Write the routing table to the device driver from user space | ||
371 | */ | ||
372 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n"); | ||
373 | |||
374 | if ( !su ) { | ||
375 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n"); | ||
376 | p->RIOError.Error = NOT_SUPER_USER; | ||
377 | return -EPERM; | ||
378 | } | ||
379 | if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0], | ||
380 | TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) { | ||
381 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n"); | ||
382 | p->RIOError.Error = COPYIN_FAILED; | ||
383 | return -EFAULT; | ||
384 | } | ||
385 | /* | 382 | /* |
386 | *********************************** | 383 | *********************************** |
387 | { | 384 | { |
@@ -409,1353 +406,1244 @@ RIO_DEBUG_CTRL, if (su) | |||
409 | } | 406 | } |
410 | *********************************** | 407 | *********************************** |
411 | */ | 408 | */ |
412 | return RIONewTable(p); | 409 | return RIONewTable(p); |
413 | |||
414 | case RIO_GET_BINDINGS : | ||
415 | /* | ||
416 | ** Send bindings table, containing unique numbers of RTAs owned | ||
417 | ** by this system to user space | ||
418 | */ | ||
419 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); | ||
420 | 410 | ||
421 | if ( !su ) | 411 | case RIO_GET_BINDINGS: |
422 | { | 412 | /* |
423 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); | 413 | ** Send bindings table, containing unique numbers of RTAs owned |
424 | p->RIOError.Error = NOT_SUPER_USER; | 414 | ** by this system to user space |
425 | return -EPERM; | 415 | */ |
426 | } | 416 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n"); |
427 | if (copyout((caddr_t) p->RIOBindTab, (int)arg, | 417 | |
428 | (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) { | 418 | if (!su) { |
429 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); | 419 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n"); |
430 | p->RIOError.Error = COPYOUT_FAILED; | 420 | p->RIOError.Error = NOT_SUPER_USER; |
431 | return -EFAULT; | 421 | return -EPERM; |
432 | } | 422 | } |
433 | return 0; | 423 | if (copyout((caddr_t) p->RIOBindTab, (int) arg, (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) { |
434 | 424 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n"); | |
435 | case RIO_PUT_BINDINGS : | 425 | p->RIOError.Error = COPYOUT_FAILED; |
426 | return -EFAULT; | ||
427 | } | ||
428 | return 0; | ||
429 | |||
430 | case RIO_PUT_BINDINGS: | ||
431 | /* | ||
432 | ** Receive a bindings table, containing unique numbers of RTAs owned | ||
433 | ** by this system | ||
434 | */ | ||
435 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); | ||
436 | |||
437 | if (!su) { | ||
438 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); | ||
439 | p->RIOError.Error = NOT_SUPER_USER; | ||
440 | return -EPERM; | ||
441 | } | ||
442 | if (copyin((int) arg, (caddr_t) & p->RIOBindTab[0], (sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL) { | ||
443 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); | ||
444 | p->RIOError.Error = COPYIN_FAILED; | ||
445 | return -EFAULT; | ||
446 | } | ||
447 | return 0; | ||
448 | |||
449 | case RIO_BIND_RTA: | ||
450 | { | ||
451 | int EmptySlot = -1; | ||
436 | /* | 452 | /* |
437 | ** Receive a bindings table, containing unique numbers of RTAs owned | 453 | ** Bind this RTA to host, so that it will be booted by |
438 | ** by this system | 454 | ** host in 'boot owned RTAs' mode. |
439 | */ | 455 | */ |
440 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n"); | 456 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); |
441 | 457 | ||
442 | if ( !su ) | 458 | if (!su) { |
443 | { | 459 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); |
444 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n"); | 460 | p->RIOError.Error = NOT_SUPER_USER; |
445 | p->RIOError.Error = NOT_SUPER_USER; | 461 | return -EPERM; |
446 | return -EPERM; | 462 | } |
447 | } | 463 | for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { |
448 | if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0], | 464 | if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) |
449 | (sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) { | 465 | EmptySlot = Entry; |
450 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n"); | 466 | else if (p->RIOBindTab[Entry] == (int) arg) { |
451 | p->RIOError.Error = COPYIN_FAILED; | ||
452 | return -EFAULT; | ||
453 | } | ||
454 | return 0; | ||
455 | |||
456 | case RIO_BIND_RTA : | ||
457 | { | ||
458 | int EmptySlot = -1; | ||
459 | /* | ||
460 | ** Bind this RTA to host, so that it will be booted by | ||
461 | ** host in 'boot owned RTAs' mode. | ||
462 | */ | ||
463 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA\n"); | ||
464 | |||
465 | if ( !su ) { | ||
466 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n"); | ||
467 | p->RIOError.Error = NOT_SUPER_USER; | ||
468 | return -EPERM; | ||
469 | } | ||
470 | for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) { | ||
471 | if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L)) | ||
472 | EmptySlot = Entry; | ||
473 | else if (p->RIOBindTab[Entry] == (int) arg) { | ||
474 | /* | ||
475 | ** Already exists - delete | ||
476 | */ | ||
477 | p->RIOBindTab[Entry] = 0L; | ||
478 | rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n", | ||
479 | (int) arg); | ||
480 | return 0; | ||
481 | } | ||
482 | } | ||
483 | /* | 467 | /* |
484 | ** Dosen't exist - add | 468 | ** Already exists - delete |
485 | */ | 469 | */ |
486 | if (EmptySlot != -1) { | 470 | p->RIOBindTab[Entry] = 0L; |
487 | p->RIOBindTab[EmptySlot] = (int) arg; | 471 | rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n", (int) arg); |
488 | rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n", | ||
489 | (int) arg); | ||
490 | } | ||
491 | else { | ||
492 | rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n", | ||
493 | (int) arg); | ||
494 | return -ENOMEM; | ||
495 | } | ||
496 | return 0; | 472 | return 0; |
497 | } | 473 | } |
498 | 474 | } | |
499 | case RIO_RESUME : | 475 | /* |
500 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME\n"); | 476 | ** Dosen't exist - add |
501 | port = (uint) arg; | 477 | */ |
502 | if ((port < 0) || (port > 511)) { | 478 | if (EmptySlot != -1) { |
503 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); | 479 | p->RIOBindTab[EmptySlot] = (int) arg; |
504 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 480 | rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n", (int) arg); |
505 | return -EINVAL; | 481 | } else { |
506 | } | 482 | rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n", (int) arg); |
507 | PortP = p->RIOPortp[port]; | 483 | return -ENOMEM; |
508 | if (!PortP->Mapped) { | 484 | } |
509 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); | 485 | return 0; |
510 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; | 486 | } |
511 | return -EINVAL; | 487 | |
512 | } | 488 | case RIO_RESUME: |
513 | if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { | 489 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n"); |
514 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); | 490 | port = (uint) arg; |
515 | return -EINVAL; | 491 | if ((port < 0) || (port > 511)) { |
516 | } | 492 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port); |
517 | 493 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | |
518 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 494 | return -EINVAL; |
519 | if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == | 495 | } |
520 | RIO_FAIL) { | 496 | PortP = p->RIOPortp[port]; |
521 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); | 497 | if (!PortP->Mapped) { |
522 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 498 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port); |
523 | return -EBUSY; | 499 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; |
524 | } | 500 | return -EINVAL; |
525 | else { | 501 | } |
526 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); | 502 | if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) { |
527 | PortP->State |= RIO_BUSY; | 503 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port); |
528 | } | 504 | return -EINVAL; |
529 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 505 | } |
530 | return retval; | 506 | |
531 | 507 | rio_spin_lock_irqsave(&PortP->portSem, flags); | |
532 | case RIO_ASSIGN_RTA: | 508 | if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == RIO_FAIL) { |
533 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); | 509 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n"); |
534 | if ( !su ) { | 510 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
535 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); | 511 | return -EBUSY; |
536 | p->RIOError.Error = NOT_SUPER_USER; | 512 | } else { |
537 | return -EPERM; | 513 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port); |
538 | } | 514 | PortP->State |= RIO_BUSY; |
539 | if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt)) | 515 | } |
540 | == COPYFAIL) { | 516 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
541 | rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n"); | 517 | return retval; |
542 | p->RIOError.Error = COPYIN_FAILED; | 518 | |
543 | return -EFAULT; | 519 | case RIO_ASSIGN_RTA: |
544 | } | 520 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n"); |
545 | return RIOAssignRta(p, &MapEnt); | 521 | if (!su) { |
546 | 522 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n"); | |
547 | case RIO_CHANGE_NAME: | 523 | p->RIOError.Error = NOT_SUPER_USER; |
548 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); | 524 | return -EPERM; |
549 | if ( !su ) { | 525 | } |
550 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); | 526 | if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt)) |
551 | p->RIOError.Error = NOT_SUPER_USER; | 527 | == COPYFAIL) { |
552 | return -EPERM; | 528 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); |
553 | } | 529 | p->RIOError.Error = COPYIN_FAILED; |
554 | if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt)) | 530 | return -EFAULT; |
555 | == COPYFAIL) { | 531 | } |
556 | rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n"); | 532 | return RIOAssignRta(p, &MapEnt); |
557 | p->RIOError.Error = COPYIN_FAILED; | 533 | |
558 | return -EFAULT; | 534 | case RIO_CHANGE_NAME: |
559 | } | 535 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n"); |
560 | return RIOChangeName(p, &MapEnt); | 536 | if (!su) { |
561 | 537 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n"); | |
562 | case RIO_DELETE_RTA: | 538 | p->RIOError.Error = NOT_SUPER_USER; |
563 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); | 539 | return -EPERM; |
564 | if ( !su ) { | 540 | } |
565 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); | 541 | if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt)) |
566 | p->RIOError.Error = NOT_SUPER_USER; | 542 | == COPYFAIL) { |
567 | return -EPERM; | 543 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n"); |
568 | } | 544 | p->RIOError.Error = COPYIN_FAILED; |
569 | if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt)) | 545 | return -EFAULT; |
570 | == COPYFAIL ) { | 546 | } |
571 | rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failed\n"); | 547 | return RIOChangeName(p, &MapEnt); |
572 | p->RIOError.Error = COPYIN_FAILED; | 548 | |
573 | return -EFAULT; | 549 | case RIO_DELETE_RTA: |
574 | } | 550 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n"); |
575 | return RIODeleteRta(p, &MapEnt); | 551 | if (!su) { |
576 | 552 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n"); | |
577 | case RIO_QUICK_CHECK: | 553 | p->RIOError.Error = NOT_SUPER_USER; |
578 | /* | 554 | return -EPERM; |
579 | ** 09.12.1998 ARG - ESIL 0776 part fix | 555 | } |
580 | ** A customer was using this to get the RTAs | 556 | if (copyin((int) arg, (caddr_t) & MapEnt, sizeof(MapEnt)) |
581 | ** connect/disconnect status. | 557 | == COPYFAIL) { |
582 | ** RIOConCon() had been botched use RIOHalted | 558 | rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n"); |
583 | ** to keep track of RTA connections and | 559 | p->RIOError.Error = COPYIN_FAILED; |
584 | ** disconnections. That has been changed and | 560 | return -EFAULT; |
585 | ** RIORtaDisCons in the rio_info struct now | 561 | } |
586 | ** does the job. So we need to return the value | 562 | return RIODeleteRta(p, &MapEnt); |
587 | ** of RIORtaCons instead of RIOHalted. | 563 | |
588 | ** | 564 | case RIO_QUICK_CHECK: |
589 | if (copyout((caddr_t)&p->RIOHalted,(int)arg, | 565 | /* |
590 | sizeof(uint))==COPYFAIL) { | 566 | ** 09.12.1998 ARG - ESIL 0776 part fix |
591 | ** | 567 | ** A customer was using this to get the RTAs |
592 | */ | 568 | ** connect/disconnect status. |
593 | 569 | ** RIOConCon() had been botched use RIOHalted | |
594 | if (copyout((caddr_t)&p->RIORtaDisCons,(int)arg, | 570 | ** to keep track of RTA connections and |
595 | sizeof(uint))==COPYFAIL) { | 571 | ** disconnections. That has been changed and |
596 | p->RIOError.Error = COPYOUT_FAILED; | 572 | ** RIORtaDisCons in the rio_info struct now |
597 | return -EFAULT; | 573 | ** does the job. So we need to return the value |
598 | } | 574 | ** of RIORtaCons instead of RIOHalted. |
599 | return 0; | 575 | ** |
600 | 576 | if (copyout((caddr_t)&p->RIOHalted,(int)arg, | |
601 | case RIO_LAST_ERROR: | 577 | sizeof(uint))==COPYFAIL) { |
602 | if (copyout((caddr_t)&p->RIOError, (int)arg, | 578 | ** |
603 | sizeof(struct Error)) ==COPYFAIL ) | 579 | */ |
604 | return -EFAULT; | 580 | |
605 | return 0; | 581 | if (copyout((caddr_t) & p->RIORtaDisCons, (int) arg, sizeof(uint)) == COPYFAIL) { |
606 | 582 | p->RIOError.Error = COPYOUT_FAILED; | |
607 | case RIO_GET_LOG: | 583 | return -EFAULT; |
608 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); | 584 | } |
585 | return 0; | ||
586 | |||
587 | case RIO_LAST_ERROR: | ||
588 | if (copyout((caddr_t) & p->RIOError, (int) arg, sizeof(struct Error)) == COPYFAIL) | ||
589 | return -EFAULT; | ||
590 | return 0; | ||
591 | |||
592 | case RIO_GET_LOG: | ||
593 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n"); | ||
609 | #ifdef LOGGING | 594 | #ifdef LOGGING |
610 | RIOGetLog(arg); | 595 | RIOGetLog(arg); |
611 | return 0; | 596 | return 0; |
612 | #else | 597 | #else |
613 | return -EINVAL; | 598 | return -EINVAL; |
614 | #endif | 599 | #endif |
615 | 600 | ||
616 | case RIO_GET_MODTYPE: | 601 | case RIO_GET_MODTYPE: |
617 | if ( copyin( (int)arg, (caddr_t)&port, | 602 | if (copyin((int) arg, (caddr_t) & port, sizeof(uint)) == COPYFAIL) { |
618 | sizeof(uint)) == COPYFAIL ) | 603 | p->RIOError.Error = COPYIN_FAILED; |
619 | { | 604 | return -EFAULT; |
620 | p->RIOError.Error = COPYIN_FAILED; | 605 | } |
621 | return -EFAULT; | 606 | rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port); |
622 | } | 607 | if (port < 0 || port > 511) { |
623 | rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %d\n", port); | 608 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); |
624 | if ( port < 0 || port > 511 ) | 609 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
625 | { | 610 | return -EINVAL; |
626 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port); | 611 | } |
627 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 612 | PortP = (p->RIOPortp[port]); |
628 | return -EINVAL; | 613 | if (!PortP->Mapped) { |
629 | } | 614 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); |
630 | PortP = (p->RIOPortp[port]); | 615 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; |
631 | if (!PortP->Mapped) | 616 | return -EINVAL; |
632 | { | 617 | } |
633 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port); | 618 | /* |
634 | p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM; | 619 | ** Return module type of port |
635 | return -EINVAL; | 620 | */ |
636 | } | 621 | port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; |
637 | /* | 622 | if (copyout((caddr_t) & port, (int) arg, sizeof(uint)) == COPYFAIL) { |
638 | ** Return module type of port | 623 | p->RIOError.Error = COPYOUT_FAILED; |
639 | */ | 624 | return -EFAULT; |
640 | port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes; | 625 | } |
641 | if (copyout((caddr_t)&port, (int)arg, | 626 | return (0); |
642 | sizeof(uint)) == COPYFAIL) { | 627 | /* |
643 | p->RIOError.Error = COPYOUT_FAILED; | 628 | ** 02.03.1999 ARG - ESIL 0820 fix |
644 | return -EFAULT; | 629 | ** We are no longer using "Boot Mode", so these ioctls |
645 | } | 630 | ** are not required : |
646 | return(0); | 631 | ** |
647 | /* | 632 | case RIO_GET_BOOT_MODE : |
648 | ** 02.03.1999 ARG - ESIL 0820 fix | 633 | rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %x\n", p->RIOBootMode)); |
649 | ** We are no longer using "Boot Mode", so these ioctls | 634 | ** |
650 | ** are not required : | 635 | ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE |
651 | ** | 636 | ** |
652 | case RIO_GET_BOOT_MODE : | 637 | if (copyout((caddr_t)&p->RIOBootMode, (int)arg, |
653 | rio_dprint(RIO_DEBUG_CTRL, ("Get boot mode - %x\n", p->RIOBootMode)); | 638 | sizeof(p->RIOBootMode)) == COPYFAIL) { |
654 | ** | 639 | p->RIOError.Error = COPYOUT_FAILED; |
655 | ** Return boot state of system - BOOT_ALL, BOOT_OWN or BOOT_NONE | 640 | return -EFAULT; |
656 | ** | 641 | } |
657 | if (copyout((caddr_t)&p->RIOBootMode, (int)arg, | 642 | return(0); |
658 | sizeof(p->RIOBootMode)) == COPYFAIL) { | 643 | |
659 | p->RIOError.Error = COPYOUT_FAILED; | 644 | case RIO_SET_BOOT_MODE : |
660 | return -EFAULT; | 645 | p->RIOBootMode = (uint) arg; |
661 | } | 646 | rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%x\n", p->RIOBootMode)); |
662 | return(0); | 647 | return(0); |
663 | 648 | ** | |
664 | case RIO_SET_BOOT_MODE : | 649 | ** End ESIL 0820 fix |
665 | p->RIOBootMode = (uint) arg; | 650 | */ |
666 | rio_dprint(RIO_DEBUG_CTRL, ("Set boot mode to 0x%x\n", p->RIOBootMode)); | 651 | |
667 | return(0); | 652 | case RIO_BLOCK_OPENS: |
668 | ** | 653 | rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n"); |
669 | ** End ESIL 0820 fix | 654 | for (Entry = 0; Entry < RIO_PORTS; Entry++) { |
670 | */ | 655 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
671 | 656 | p->RIOPortp[Entry]->WaitUntilBooted = 1; | |
672 | case RIO_BLOCK_OPENS: | 657 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
673 | rio_dprintk (RIO_DEBUG_CTRL, "Opens block until booted\n"); | 658 | } |
674 | for ( Entry=0; Entry < RIO_PORTS; Entry++ ) { | 659 | return 0; |
675 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 660 | |
676 | p->RIOPortp[Entry]->WaitUntilBooted = 1; | 661 | case RIO_SETUP_PORTS: |
677 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 662 | rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n"); |
678 | } | 663 | if (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup)) |
679 | return 0; | 664 | == COPYFAIL) { |
680 | 665 | p->RIOError.Error = COPYIN_FAILED; | |
681 | case RIO_SETUP_PORTS: | 666 | rio_dprintk(RIO_DEBUG_CTRL, "EFAULT"); |
682 | rio_dprintk (RIO_DEBUG_CTRL, "Setup ports\n"); | 667 | return -EFAULT; |
683 | if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) | 668 | } |
684 | == COPYFAIL ) { | 669 | if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) { |
685 | p->RIOError.Error = COPYIN_FAILED; | 670 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
686 | rio_dprintk (RIO_DEBUG_CTRL, "EFAULT"); | 671 | rio_dprintk(RIO_DEBUG_CTRL, "ENXIO"); |
687 | return -EFAULT; | 672 | return -ENXIO; |
688 | } | 673 | } |
689 | if ( PortSetup.From > PortSetup.To || | 674 | if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) { |
690 | PortSetup.To >= RIO_PORTS ) { | 675 | p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; |
691 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 676 | rio_dprintk(RIO_DEBUG_CTRL, "EINVAL"); |
692 | rio_dprintk (RIO_DEBUG_CTRL, "ENXIO"); | 677 | return -EINVAL; |
693 | return -ENXIO; | 678 | } |
694 | } | 679 | if (!p->RIOPortp) { |
695 | if ( PortSetup.XpCps > p->RIOConf.MaxXpCps || | 680 | cprintf("No p->RIOPortp array!\n"); |
696 | PortSetup.XpCps < p->RIOConf.MinXpCps ) { | 681 | rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); |
697 | p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE; | 682 | return -EIO; |
698 | rio_dprintk (RIO_DEBUG_CTRL, "EINVAL"); | 683 | } |
699 | return -EINVAL; | 684 | rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); |
700 | } | 685 | for (loop = PortSetup.From; loop <= PortSetup.To; loop++) { |
701 | if ( !p->RIOPortp ) { | 686 | rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); |
702 | cprintf("No p->RIOPortp array!\n"); | ||
703 | rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!\n"); | ||
704 | return -EIO; | ||
705 | } | ||
706 | rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To); | ||
707 | for (loop=PortSetup.From; loop<=PortSetup.To; loop++) { | ||
708 | rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!\n", loop); | ||
709 | #if 0 | 687 | #if 0 |
710 | PortP = p->RIOPortp[loop]; | 688 | PortP = p->RIOPortp[loop]; |
711 | if ( !PortP->TtyP ) | 689 | if (!PortP->TtyP) |
712 | PortP->TtyP = &p->channel[loop]; | 690 | PortP->TtyP = &p->channel[loop]; |
713 | 691 | ||
714 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 692 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
715 | if ( PortSetup.IxAny ) | 693 | if (PortSetup.IxAny) |
716 | PortP->Config |= RIO_IXANY; | 694 | PortP->Config |= RIO_IXANY; |
717 | else | 695 | else |
718 | PortP->Config &= ~RIO_IXANY; | 696 | PortP->Config &= ~RIO_IXANY; |
719 | if ( PortSetup.IxOn ) | 697 | if (PortSetup.IxOn) |
720 | PortP->Config |= RIO_IXON; | 698 | PortP->Config |= RIO_IXON; |
721 | else | 699 | else |
722 | PortP->Config &= ~RIO_IXON; | 700 | PortP->Config &= ~RIO_IXON; |
723 | |||
724 | /* | ||
725 | ** If the port needs to wait for all a processes output | ||
726 | ** to drain before closing then this flag will be set. | ||
727 | */ | ||
728 | if (PortSetup.Drain) { | ||
729 | PortP->Config |= RIO_WAITDRAIN; | ||
730 | } else { | ||
731 | PortP->Config &= ~RIO_WAITDRAIN; | ||
732 | } | ||
733 | /* | ||
734 | ** Store settings if locking or unlocking port or if the | ||
735 | ** port is not locked, when setting the store option. | ||
736 | */ | ||
737 | if (PortP->Mapped && | ||
738 | ((PortSetup.Lock && !PortP->Lock) || | ||
739 | (!PortP->Lock && | ||
740 | (PortSetup.Store && !PortP->Store)))) { | ||
741 | PortP->StoredTty.iflag = PortP->TtyP->tm.c_iflag; | ||
742 | PortP->StoredTty.oflag = PortP->TtyP->tm.c_oflag; | ||
743 | PortP->StoredTty.cflag = PortP->TtyP->tm.c_cflag; | ||
744 | PortP->StoredTty.lflag = PortP->TtyP->tm.c_lflag; | ||
745 | PortP->StoredTty.line = PortP->TtyP->tm.c_line; | ||
746 | bcopy(PortP->TtyP->tm.c_cc, PortP->StoredTty.cc, | ||
747 | NCC + 5); | ||
748 | } | ||
749 | PortP->Lock = PortSetup.Lock; | ||
750 | PortP->Store = PortSetup.Store; | ||
751 | PortP->Xprint.XpCps = PortSetup.XpCps; | ||
752 | bcopy(PortSetup.XpOn,PortP->Xprint.XpOn,MAX_XP_CTRL_LEN); | ||
753 | bcopy(PortSetup.XpOff,PortP->Xprint.XpOff,MAX_XP_CTRL_LEN); | ||
754 | PortP->Xprint.XpOn[MAX_XP_CTRL_LEN-1] = '\0'; | ||
755 | PortP->Xprint.XpOff[MAX_XP_CTRL_LEN-1] = '\0'; | ||
756 | PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn)+ | ||
757 | RIOStrlen(PortP->Xprint.XpOff); | ||
758 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | ||
759 | #endif | ||
760 | } | ||
761 | rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); | ||
762 | rio_dprintk (RIO_DEBUG_CTRL, "Retval:%x\n", retval); | ||
763 | return retval; | ||
764 | |||
765 | case RIO_GET_PORT_SETUP : | ||
766 | rio_dprintk (RIO_DEBUG_CTRL, "Get port setup\n"); | ||
767 | if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) | ||
768 | == COPYFAIL ) { | ||
769 | p->RIOError.Error = COPYIN_FAILED; | ||
770 | return -EFAULT; | ||
771 | } | ||
772 | if ( PortSetup.From >= RIO_PORTS ) { | ||
773 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
774 | return -ENXIO; | ||
775 | } | ||
776 | 701 | ||
777 | port = PortSetup.To = PortSetup.From; | 702 | /* |
778 | PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? | 703 | ** If the port needs to wait for all a processes output |
779 | 1 : 0; | 704 | ** to drain before closing then this flag will be set. |
780 | PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? | 705 | */ |
781 | 1 : 0; | 706 | if (PortSetup.Drain) { |
782 | PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? | 707 | PortP->Config |= RIO_WAITDRAIN; |
783 | 1 : 0; | 708 | } else { |
784 | PortSetup.Store = p->RIOPortp[port]->Store; | 709 | PortP->Config &= ~RIO_WAITDRAIN; |
785 | PortSetup.Lock = p->RIOPortp[port]->Lock; | 710 | } |
786 | PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; | 711 | /* |
787 | bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn, | 712 | ** Store settings if locking or unlocking port or if the |
788 | MAX_XP_CTRL_LEN); | 713 | ** port is not locked, when setting the store option. |
789 | bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff, | 714 | */ |
790 | MAX_XP_CTRL_LEN); | 715 | if (PortP->Mapped && ((PortSetup.Lock && !PortP->Lock) || (!PortP->Lock && (PortSetup.Store && !PortP->Store)))) { |
791 | PortSetup.XpOn[MAX_XP_CTRL_LEN-1] = '\0'; | 716 | PortP->StoredTty.iflag = PortP->TtyP->tm.c_iflag; |
792 | PortSetup.XpOff[MAX_XP_CTRL_LEN-1] = '\0'; | 717 | PortP->StoredTty.oflag = PortP->TtyP->tm.c_oflag; |
793 | 718 | PortP->StoredTty.cflag = PortP->TtyP->tm.c_cflag; | |
794 | if ( copyout((caddr_t)&PortSetup,(int)arg,sizeof(PortSetup)) | 719 | PortP->StoredTty.lflag = PortP->TtyP->tm.c_lflag; |
795 | ==COPYFAIL ) { | 720 | PortP->StoredTty.line = PortP->TtyP->tm.c_line; |
796 | p->RIOError.Error = COPYOUT_FAILED; | 721 | bcopy(PortP->TtyP->tm.c_cc, PortP->StoredTty.cc, NCC + 5); |
797 | return -EFAULT; | 722 | } |
798 | } | 723 | PortP->Lock = PortSetup.Lock; |
799 | return retval; | 724 | PortP->Store = PortSetup.Store; |
800 | 725 | PortP->Xprint.XpCps = PortSetup.XpCps; | |
801 | case RIO_GET_PORT_PARAMS : | 726 | bcopy(PortSetup.XpOn, PortP->Xprint.XpOn, MAX_XP_CTRL_LEN); |
802 | rio_dprintk (RIO_DEBUG_CTRL, "Get port params\n"); | 727 | bcopy(PortSetup.XpOff, PortP->Xprint.XpOff, MAX_XP_CTRL_LEN); |
803 | if (copyin( (int)arg, (caddr_t)&PortParams, | 728 | PortP->Xprint.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; |
804 | sizeof(struct PortParams)) == COPYFAIL) { | 729 | PortP->Xprint.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; |
805 | p->RIOError.Error = COPYIN_FAILED; | 730 | PortP->Xprint.XpLen = RIOStrlen(PortP->Xprint.XpOn) + RIOStrlen(PortP->Xprint.XpOff); |
806 | return -EFAULT; | 731 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
807 | } | 732 | #endif |
808 | if (PortParams.Port >= RIO_PORTS) { | 733 | } |
809 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 734 | rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop); |
810 | return -ENXIO; | 735 | rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval); |
811 | } | 736 | return retval; |
812 | PortP = (p->RIOPortp[PortParams.Port]); | 737 | |
813 | PortParams.Config = PortP->Config; | 738 | case RIO_GET_PORT_SETUP: |
814 | PortParams.State = PortP->State; | 739 | rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n"); |
815 | rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); | 740 | if (copyin((int) arg, (caddr_t) & PortSetup, sizeof(PortSetup)) |
816 | 741 | == COPYFAIL) { | |
817 | if (copyout((caddr_t)&PortParams, (int)arg, | 742 | p->RIOError.Error = COPYIN_FAILED; |
818 | sizeof(struct PortParams)) == COPYFAIL ) { | 743 | return -EFAULT; |
819 | p->RIOError.Error = COPYOUT_FAILED; | 744 | } |
820 | return -EFAULT; | 745 | if (PortSetup.From >= RIO_PORTS) { |
821 | } | 746 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
822 | return retval; | 747 | return -ENXIO; |
823 | 748 | } | |
824 | case RIO_GET_PORT_TTY : | 749 | |
825 | rio_dprintk (RIO_DEBUG_CTRL, "Get port tty\n"); | 750 | port = PortSetup.To = PortSetup.From; |
826 | if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty)) | 751 | PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0; |
827 | == COPYFAIL) { | 752 | PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0; |
828 | p->RIOError.Error = COPYIN_FAILED; | 753 | PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0; |
829 | return -EFAULT; | 754 | PortSetup.Store = p->RIOPortp[port]->Store; |
830 | } | 755 | PortSetup.Lock = p->RIOPortp[port]->Lock; |
831 | if ( PortTty.port >= RIO_PORTS ) { | 756 | PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps; |
832 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 757 | bcopy(p->RIOPortp[port]->Xprint.XpOn, PortSetup.XpOn, MAX_XP_CTRL_LEN); |
833 | return -ENXIO; | 758 | bcopy(p->RIOPortp[port]->Xprint.XpOff, PortSetup.XpOff, MAX_XP_CTRL_LEN); |
834 | } | 759 | PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0'; |
835 | 760 | PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0'; | |
836 | rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); | 761 | |
837 | PortP = (p->RIOPortp[PortTty.port]); | 762 | if (copyout((caddr_t) & PortSetup, (int) arg, sizeof(PortSetup)) |
763 | == COPYFAIL) { | ||
764 | p->RIOError.Error = COPYOUT_FAILED; | ||
765 | return -EFAULT; | ||
766 | } | ||
767 | return retval; | ||
768 | |||
769 | case RIO_GET_PORT_PARAMS: | ||
770 | rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n"); | ||
771 | if (copyin((int) arg, (caddr_t) & PortParams, sizeof(struct PortParams)) == COPYFAIL) { | ||
772 | p->RIOError.Error = COPYIN_FAILED; | ||
773 | return -EFAULT; | ||
774 | } | ||
775 | if (PortParams.Port >= RIO_PORTS) { | ||
776 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
777 | return -ENXIO; | ||
778 | } | ||
779 | PortP = (p->RIOPortp[PortParams.Port]); | ||
780 | PortParams.Config = PortP->Config; | ||
781 | PortParams.State = PortP->State; | ||
782 | rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port); | ||
783 | |||
784 | if (copyout((caddr_t) & PortParams, (int) arg, sizeof(struct PortParams)) == COPYFAIL) { | ||
785 | p->RIOError.Error = COPYOUT_FAILED; | ||
786 | return -EFAULT; | ||
787 | } | ||
788 | return retval; | ||
789 | |||
790 | case RIO_GET_PORT_TTY: | ||
791 | rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n"); | ||
792 | if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty)) | ||
793 | == COPYFAIL) { | ||
794 | p->RIOError.Error = COPYIN_FAILED; | ||
795 | return -EFAULT; | ||
796 | } | ||
797 | if (PortTty.port >= RIO_PORTS) { | ||
798 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
799 | return -ENXIO; | ||
800 | } | ||
801 | |||
802 | rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port); | ||
803 | PortP = (p->RIOPortp[PortTty.port]); | ||
838 | #if 0 | 804 | #if 0 |
839 | PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag; | 805 | PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag; |
840 | PortTty.Tty.tm.c_oflag = PortP->TtyP->tm.c_oflag; | 806 | PortTty.Tty.tm.c_oflag = PortP->TtyP->tm.c_oflag; |
841 | PortTty.Tty.tm.c_cflag = PortP->TtyP->tm.c_cflag; | 807 | PortTty.Tty.tm.c_cflag = PortP->TtyP->tm.c_cflag; |
842 | PortTty.Tty.tm.c_lflag = PortP->TtyP->tm.c_lflag; | 808 | PortTty.Tty.tm.c_lflag = PortP->TtyP->tm.c_lflag; |
843 | #endif | 809 | #endif |
844 | if (copyout((caddr_t)&PortTty, (int)arg, | 810 | if (copyout((caddr_t) & PortTty, (int) arg, sizeof(struct PortTty)) == COPYFAIL) { |
845 | sizeof(struct PortTty)) == COPYFAIL) { | 811 | p->RIOError.Error = COPYOUT_FAILED; |
846 | p->RIOError.Error = COPYOUT_FAILED; | 812 | return -EFAULT; |
847 | return -EFAULT; | 813 | } |
848 | } | 814 | return retval; |
849 | return retval; | 815 | |
850 | 816 | case RIO_SET_PORT_TTY: | |
851 | case RIO_SET_PORT_TTY : | 817 | if (copyin((int) arg, (caddr_t) & PortTty, sizeof(struct PortTty)) == COPYFAIL) { |
852 | if (copyin((int)arg, (caddr_t)&PortTty, | 818 | p->RIOError.Error = COPYIN_FAILED; |
853 | sizeof(struct PortTty)) == COPYFAIL) { | 819 | return -EFAULT; |
854 | p->RIOError.Error = COPYIN_FAILED; | 820 | } |
855 | return -EFAULT; | 821 | rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); |
856 | } | 822 | if (PortTty.port >= (ushort) RIO_PORTS) { |
857 | rio_dprintk (RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port); | 823 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
858 | if (PortTty.port >= (ushort) RIO_PORTS) { | 824 | return -ENXIO; |
859 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 825 | } |
860 | return -ENXIO; | 826 | PortP = (p->RIOPortp[PortTty.port]); |
861 | } | ||
862 | PortP = (p->RIOPortp[PortTty.port]); | ||
863 | #if 0 | 827 | #if 0 |
864 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 828 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
865 | PortP->TtyP->tm.c_iflag = PortTty.Tty.tm.c_iflag; | 829 | PortP->TtyP->tm.c_iflag = PortTty.Tty.tm.c_iflag; |
866 | PortP->TtyP->tm.c_oflag = PortTty.Tty.tm.c_oflag; | 830 | PortP->TtyP->tm.c_oflag = PortTty.Tty.tm.c_oflag; |
867 | PortP->TtyP->tm.c_cflag = PortTty.Tty.tm.c_cflag; | 831 | PortP->TtyP->tm.c_cflag = PortTty.Tty.tm.c_cflag; |
868 | PortP->TtyP->tm.c_lflag = PortTty.Tty.tm.c_lflag; | 832 | PortP->TtyP->tm.c_lflag = PortTty.Tty.tm.c_lflag; |
869 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 833 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
870 | #endif | 834 | #endif |
871 | 835 | ||
872 | RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP); | 836 | RIOParam(PortP, CONFIG, PortP->State & RIO_MODEM, OK_TO_SLEEP); |
873 | return retval; | 837 | return retval; |
874 | 838 | ||
875 | case RIO_SET_PORT_PARAMS : | 839 | case RIO_SET_PORT_PARAMS: |
876 | rio_dprintk (RIO_DEBUG_CTRL, "Set port params\n"); | 840 | rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n"); |
877 | if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams)) | 841 | if (copyin((int) arg, (caddr_t) & PortParams, sizeof(PortParams)) |
878 | == COPYFAIL ) { | 842 | == COPYFAIL) { |
879 | p->RIOError.Error = COPYIN_FAILED; | 843 | p->RIOError.Error = COPYIN_FAILED; |
880 | return -EFAULT; | 844 | return -EFAULT; |
881 | } | 845 | } |
882 | if (PortParams.Port >= (ushort) RIO_PORTS) { | 846 | if (PortParams.Port >= (ushort) RIO_PORTS) { |
883 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 847 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
884 | return -ENXIO; | 848 | return -ENXIO; |
885 | } | 849 | } |
886 | PortP = (p->RIOPortp[PortParams.Port]); | 850 | PortP = (p->RIOPortp[PortParams.Port]); |
887 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 851 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
888 | PortP->Config = PortParams.Config; | 852 | PortP->Config = PortParams.Config; |
889 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 853 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
890 | return retval; | 854 | return retval; |
891 | 855 | ||
892 | case RIO_GET_PORT_STATS : | 856 | case RIO_GET_PORT_STATS: |
893 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); | 857 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n"); |
894 | if ( copyin((int)arg, (caddr_t)&portStats, | 858 | if (copyin((int) arg, (caddr_t) & portStats, sizeof(struct portStats)) == COPYFAIL) { |
895 | sizeof(struct portStats)) == COPYFAIL ) { | 859 | p->RIOError.Error = COPYIN_FAILED; |
896 | p->RIOError.Error = COPYIN_FAILED; | 860 | return -EFAULT; |
897 | return -EFAULT; | 861 | } |
898 | } | 862 | if (portStats.port >= RIO_PORTS) { |
899 | if ( portStats.port >= RIO_PORTS ) { | 863 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
900 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 864 | return -ENXIO; |
901 | return -ENXIO; | 865 | } |
902 | } | 866 | PortP = (p->RIOPortp[portStats.port]); |
903 | PortP = (p->RIOPortp[portStats.port]); | 867 | portStats.gather = PortP->statsGather; |
904 | portStats.gather = PortP->statsGather; | 868 | portStats.txchars = PortP->txchars; |
905 | portStats.txchars = PortP->txchars; | 869 | portStats.rxchars = PortP->rxchars; |
906 | portStats.rxchars = PortP->rxchars; | 870 | portStats.opens = PortP->opens; |
907 | portStats.opens = PortP->opens; | 871 | portStats.closes = PortP->closes; |
908 | portStats.closes = PortP->closes; | 872 | portStats.ioctls = PortP->ioctls; |
909 | portStats.ioctls = PortP->ioctls; | 873 | if (copyout((caddr_t) & portStats, (int) arg, sizeof(struct portStats)) == COPYFAIL) { |
910 | if ( copyout((caddr_t)&portStats, (int)arg, | 874 | p->RIOError.Error = COPYOUT_FAILED; |
911 | sizeof(struct portStats)) == COPYFAIL ) { | 875 | return -EFAULT; |
912 | p->RIOError.Error = COPYOUT_FAILED; | 876 | } |
913 | return -EFAULT; | 877 | return retval; |
914 | } | 878 | |
915 | return retval; | 879 | case RIO_RESET_PORT_STATS: |
916 | 880 | port = (uint) arg; | |
917 | case RIO_RESET_PORT_STATS : | 881 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); |
918 | port = (uint) arg; | 882 | if (port >= RIO_PORTS) { |
919 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n"); | 883 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
920 | if ( port >= RIO_PORTS ) { | 884 | return -ENXIO; |
921 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 885 | } |
922 | return -ENXIO; | 886 | PortP = (p->RIOPortp[port]); |
923 | } | 887 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
924 | PortP = (p->RIOPortp[port]); | 888 | PortP->txchars = 0; |
925 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 889 | PortP->rxchars = 0; |
926 | PortP->txchars = 0; | 890 | PortP->opens = 0; |
927 | PortP->rxchars = 0; | 891 | PortP->closes = 0; |
928 | PortP->opens = 0; | 892 | PortP->ioctls = 0; |
929 | PortP->closes = 0; | 893 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
930 | PortP->ioctls = 0; | 894 | return retval; |
931 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | 895 | |
932 | return retval; | 896 | case RIO_GATHER_PORT_STATS: |
933 | 897 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); | |
934 | case RIO_GATHER_PORT_STATS : | 898 | if (copyin((int) arg, (caddr_t) & portStats, sizeof(struct portStats)) == COPYFAIL) { |
935 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n"); | 899 | p->RIOError.Error = COPYIN_FAILED; |
936 | if ( copyin( (int)arg, (caddr_t)&portStats, | 900 | return -EFAULT; |
937 | sizeof(struct portStats)) == COPYFAIL ) { | 901 | } |
938 | p->RIOError.Error = COPYIN_FAILED; | 902 | if (portStats.port >= RIO_PORTS) { |
939 | return -EFAULT; | 903 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
940 | } | 904 | return -ENXIO; |
941 | if ( portStats.port >= RIO_PORTS ) { | 905 | } |
942 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 906 | PortP = (p->RIOPortp[portStats.port]); |
943 | return -ENXIO; | 907 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
944 | } | 908 | PortP->statsGather = portStats.gather; |
945 | PortP = (p->RIOPortp[portStats.port]); | 909 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
946 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 910 | return retval; |
947 | PortP->statsGather = portStats.gather; | ||
948 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | ||
949 | return retval; | ||
950 | 911 | ||
951 | #ifdef DEBUG_SUPPORTED | 912 | #ifdef DEBUG_SUPPORTED |
952 | case RIO_READ_LEVELS: | 913 | case RIO_READ_LEVELS: |
953 | { | 914 | { |
954 | int num; | 915 | int num; |
955 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n"); | 916 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n"); |
956 | for ( num=0; RIODbInf[num].Flag; num++ ) ; | 917 | for (num = 0; RIODbInf[num].Flag; num++); |
957 | rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copy\n",num); | 918 | rio_dprintk(RIO_DEBUG_CTRL, "%d levels to copy\n", num); |
958 | if (copyout((caddr_t)RIODbInf,(int)arg, | 919 | if (copyout((caddr_t) RIODbInf, (int) arg, sizeof(struct DbInf) * (num + 1)) == COPYFAIL) { |
959 | sizeof(struct DbInf)*(num+1))==COPYFAIL) { | 920 | rio_dprintk(RIO_DEBUG_CTRL, "ReadLevels Copy failed\n"); |
960 | rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failed\n"); | 921 | p->RIOError.Error = COPYOUT_FAILED; |
961 | p->RIOError.Error = COPYOUT_FAILED; | 922 | return -EFAULT; |
962 | return -EFAULT; | 923 | } |
963 | } | 924 | rio_dprintk(RIO_DEBUG_CTRL, "%d levels to copied\n", num); |
964 | rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copied\n",num); | 925 | return retval; |
965 | return retval; | 926 | } |
966 | } | ||
967 | #endif | 927 | #endif |
968 | 928 | ||
969 | case RIO_READ_CONFIG: | 929 | case RIO_READ_CONFIG: |
970 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); | 930 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n"); |
971 | if (copyout((caddr_t)&p->RIOConf, (int)arg, | 931 | if (copyout((caddr_t) & p->RIOConf, (int) arg, sizeof(struct Conf)) == COPYFAIL) { |
972 | sizeof(struct Conf)) ==COPYFAIL ) { | 932 | p->RIOError.Error = COPYOUT_FAILED; |
973 | p->RIOError.Error = COPYOUT_FAILED; | 933 | return -EFAULT; |
974 | return -EFAULT; | 934 | } |
975 | } | 935 | return retval; |
976 | return retval; | 936 | |
977 | 937 | case RIO_SET_CONFIG: | |
978 | case RIO_SET_CONFIG: | 938 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); |
979 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n"); | 939 | if (!su) { |
980 | if ( !su ) { | 940 | p->RIOError.Error = NOT_SUPER_USER; |
981 | p->RIOError.Error = NOT_SUPER_USER; | 941 | return -EPERM; |
982 | return -EPERM; | 942 | } |
943 | if (copyin((int) arg, (caddr_t) & p->RIOConf, sizeof(struct Conf)) | ||
944 | == COPYFAIL) { | ||
945 | p->RIOError.Error = COPYIN_FAILED; | ||
946 | return -EFAULT; | ||
947 | } | ||
948 | /* | ||
949 | ** move a few value around | ||
950 | */ | ||
951 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
952 | if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING) | ||
953 | WWORD(p->RIOHosts[Host].ParmMapP->timer, p->RIOConf.Timer); | ||
954 | return retval; | ||
955 | |||
956 | case RIO_START_POLLER: | ||
957 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); | ||
958 | return -EINVAL; | ||
959 | |||
960 | case RIO_STOP_POLLER: | ||
961 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); | ||
962 | if (!su) { | ||
963 | p->RIOError.Error = NOT_SUPER_USER; | ||
964 | return -EPERM; | ||
965 | } | ||
966 | p->RIOPolling = NOT_POLLING; | ||
967 | return retval; | ||
968 | |||
969 | case RIO_SETDEBUG: | ||
970 | case RIO_GETDEBUG: | ||
971 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); | ||
972 | if (copyin((int) arg, (caddr_t) & DebugCtrl, sizeof(DebugCtrl)) | ||
973 | == COPYFAIL) { | ||
974 | p->RIOError.Error = COPYIN_FAILED; | ||
975 | return -EFAULT; | ||
976 | } | ||
977 | if (DebugCtrl.SysPort == NO_PORT) { | ||
978 | if (cmd == RIO_SETDEBUG) { | ||
979 | if (!su) { | ||
980 | p->RIOError.Error = NOT_SUPER_USER; | ||
981 | return -EPERM; | ||
983 | } | 982 | } |
984 | if ( copyin((int)arg, (caddr_t)&p->RIOConf, sizeof(struct Conf) ) | 983 | p->rio_debug = DebugCtrl.Debug; |
985 | ==COPYFAIL ) { | 984 | p->RIODebugWait = DebugCtrl.Wait; |
986 | p->RIOError.Error = COPYIN_FAILED; | 985 | rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait); |
987 | return -EFAULT; | 986 | } else { |
987 | rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait); | ||
988 | DebugCtrl.Debug = p->rio_debug; | ||
989 | DebugCtrl.Wait = p->RIODebugWait; | ||
990 | if (copyout((caddr_t) & DebugCtrl, (int) arg, sizeof(DebugCtrl)) == COPYFAIL) { | ||
991 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); | ||
992 | p->RIOError.Error = COPYOUT_FAILED; | ||
993 | return -EFAULT; | ||
988 | } | 994 | } |
989 | /* | 995 | } |
990 | ** move a few value around | 996 | } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) { |
991 | */ | 997 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort); |
992 | for (Host=0; Host < p->RIONumHosts; Host++) | 998 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
993 | if ( (p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING ) | 999 | return -ENXIO; |
994 | WWORD(p->RIOHosts[Host].ParmMapP->timer , | 1000 | } else if (cmd == RIO_SETDEBUG) { |
995 | p->RIOConf.Timer); | 1001 | if (!su) { |
996 | return retval; | 1002 | p->RIOError.Error = NOT_SUPER_USER; |
997 | 1003 | return -EPERM; | |
998 | case RIO_START_POLLER: | 1004 | } |
999 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLER\n"); | 1005 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
1000 | return -EINVAL; | 1006 | p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; |
1007 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1008 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
1009 | } else { | ||
1010 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
1011 | DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; | ||
1012 | if (copyout((caddr_t) & DebugCtrl, (int) arg, sizeof(DebugCtrl)) == COPYFAIL) { | ||
1013 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); | ||
1014 | p->RIOError.Error = COPYOUT_FAILED; | ||
1015 | return -EFAULT; | ||
1016 | } | ||
1017 | } | ||
1018 | return retval; | ||
1001 | 1019 | ||
1002 | case RIO_STOP_POLLER: | 1020 | case RIO_VERSID: |
1003 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n"); | 1021 | /* |
1004 | if ( !su ) { | 1022 | ** Enquire about the release and version. |
1005 | p->RIOError.Error = NOT_SUPER_USER; | 1023 | ** We return MAX_VERSION_LEN bytes, being a |
1006 | return -EPERM; | 1024 | ** textual null terminated string. |
1007 | } | 1025 | */ |
1008 | p->RIOPolling = NOT_POLLING; | 1026 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n"); |
1009 | return retval; | 1027 | if (copyout((caddr_t) RIOVersid(), (int) arg, sizeof(struct rioVersion)) == COPYFAIL) { |
1010 | 1028 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); | |
1011 | case RIO_SETDEBUG: | 1029 | p->RIOError.Error = COPYOUT_FAILED; |
1012 | case RIO_GETDEBUG: | 1030 | return -EFAULT; |
1013 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n"); | 1031 | } |
1014 | if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) ) | 1032 | return retval; |
1015 | ==COPYFAIL ) { | ||
1016 | p->RIOError.Error = COPYIN_FAILED; | ||
1017 | return -EFAULT; | ||
1018 | } | ||
1019 | if ( DebugCtrl.SysPort == NO_PORT ) { | ||
1020 | if ( cmd == RIO_SETDEBUG ) { | ||
1021 | if ( !su ) { | ||
1022 | p->RIOError.Error = NOT_SUPER_USER; | ||
1023 | return -EPERM; | ||
1024 | } | ||
1025 | p->rio_debug = DebugCtrl.Debug; | ||
1026 | p->RIODebugWait = DebugCtrl.Wait; | ||
1027 | rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", | ||
1028 | p->rio_debug,p->RIODebugWait); | ||
1029 | } | ||
1030 | else { | ||
1031 | rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", | ||
1032 | p->rio_debug,p->RIODebugWait); | ||
1033 | DebugCtrl.Debug = p->rio_debug; | ||
1034 | DebugCtrl.Wait = p->RIODebugWait; | ||
1035 | if ( copyout((caddr_t)&DebugCtrl,(int)arg, | ||
1036 | sizeof(DebugCtrl)) == COPYFAIL ) { | ||
1037 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", | ||
1038 | DebugCtrl.SysPort); | ||
1039 | p->RIOError.Error = COPYOUT_FAILED; | ||
1040 | return -EFAULT; | ||
1041 | } | ||
1042 | } | ||
1043 | } | ||
1044 | else if ( DebugCtrl.SysPort >= RIO_PORTS && | ||
1045 | DebugCtrl.SysPort != NO_PORT ) { | ||
1046 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", | ||
1047 | DebugCtrl.SysPort); | ||
1048 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1049 | return -ENXIO; | ||
1050 | } | ||
1051 | else if ( cmd == RIO_SETDEBUG ) { | ||
1052 | if ( !su ) { | ||
1053 | p->RIOError.Error = NOT_SUPER_USER; | ||
1054 | return -EPERM; | ||
1055 | } | ||
1056 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1057 | p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug; | ||
1058 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | ||
1059 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", | ||
1060 | p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
1061 | } | ||
1062 | else { | ||
1063 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", | ||
1064 | p->RIOPortp[DebugCtrl.SysPort]->Debug); | ||
1065 | DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug; | ||
1066 | if ( copyout((caddr_t)&DebugCtrl,(int)arg, | ||
1067 | sizeof(DebugCtrl))==COPYFAIL ) { | ||
1068 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n"); | ||
1069 | p->RIOError.Error = COPYOUT_FAILED; | ||
1070 | return -EFAULT; | ||
1071 | } | ||
1072 | } | ||
1073 | return retval; | ||
1074 | |||
1075 | case RIO_VERSID: | ||
1076 | /* | ||
1077 | ** Enquire about the release and version. | ||
1078 | ** We return MAX_VERSION_LEN bytes, being a | ||
1079 | ** textual null terminated string. | ||
1080 | */ | ||
1081 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID\n"); | ||
1082 | if ( copyout( (caddr_t)RIOVersid(), | ||
1083 | (int)arg, | ||
1084 | sizeof(struct rioVersion) ) == COPYFAIL ) | ||
1085 | { | ||
1086 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host); | ||
1087 | p->RIOError.Error = COPYOUT_FAILED; | ||
1088 | return -EFAULT; | ||
1089 | } | ||
1090 | return retval; | ||
1091 | 1033 | ||
1092 | /* | 1034 | /* |
1093 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 1035 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
1094 | ** !! commented out previous 'RIO_VERSID' functionality !! | 1036 | ** !! commented out previous 'RIO_VERSID' functionality !! |
1095 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 1037 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
1096 | ** | 1038 | ** |
1097 | case RIO_VERSID: | 1039 | case RIO_VERSID: |
1098 | ** | 1040 | ** |
1099 | ** Enquire about the release and version. | 1041 | ** Enquire about the release and version. |
1100 | ** We return MAX_VERSION_LEN bytes, being a textual null | 1042 | ** We return MAX_VERSION_LEN bytes, being a textual null |
1101 | ** terminated string. | 1043 | ** terminated string. |
1102 | ** | 1044 | ** |
1103 | rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID\n")); | 1045 | rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID\n")); |
1104 | if (copyout((caddr_t)RIOVersid(), | 1046 | if (copyout((caddr_t)RIOVersid(), |
1105 | (int)arg, MAX_VERSION_LEN ) == COPYFAIL ) { | 1047 | (int)arg, MAX_VERSION_LEN ) == COPYFAIL ) { |
1106 | rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user space\n",Host)); | 1048 | rio_dprint(RIO_DEBUG_CTRL, ("RIO_VERSID: Bad copy to user space\n",Host)); |
1107 | p->RIOError.Error = COPYOUT_FAILED; | 1049 | p->RIOError.Error = COPYOUT_FAILED; |
1108 | return -EFAULT; | 1050 | return -EFAULT; |
1109 | } | 1051 | } |
1110 | return retval; | 1052 | return retval; |
1111 | ** | 1053 | ** |
1112 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! | 1054 | ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
1113 | */ | 1055 | */ |
1114 | 1056 | ||
1115 | case RIO_NUM_HOSTS: | 1057 | case RIO_NUM_HOSTS: |
1116 | /* | 1058 | /* |
1117 | ** Enquire as to the number of hosts located | 1059 | ** Enquire as to the number of hosts located |
1118 | ** at init time. | 1060 | ** at init time. |
1119 | */ | 1061 | */ |
1120 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); | 1062 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n"); |
1121 | if (copyout((caddr_t)&p->RIONumHosts, (int)arg, | 1063 | if (copyout((caddr_t) & p->RIONumHosts, (int) arg, sizeof(p->RIONumHosts)) == COPYFAIL) { |
1122 | sizeof(p->RIONumHosts) )==COPYFAIL ) { | 1064 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); |
1123 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n"); | 1065 | p->RIOError.Error = COPYOUT_FAILED; |
1124 | p->RIOError.Error = COPYOUT_FAILED; | 1066 | return -EFAULT; |
1125 | return -EFAULT; | 1067 | } |
1126 | } | 1068 | return retval; |
1127 | return retval; | 1069 | |
1128 | 1070 | case RIO_HOST_FOAD: | |
1129 | case RIO_HOST_FOAD: | 1071 | /* |
1130 | /* | 1072 | ** Kill host. This may not be in the final version... |
1131 | ** Kill host. This may not be in the final version... | 1073 | */ |
1132 | */ | 1074 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int) arg); |
1133 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int)arg); | 1075 | if (!su) { |
1134 | if ( !su ) { | 1076 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); |
1135 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n"); | 1077 | p->RIOError.Error = NOT_SUPER_USER; |
1136 | p->RIOError.Error = NOT_SUPER_USER; | 1078 | return -EPERM; |
1137 | return -EPERM; | 1079 | } |
1138 | } | 1080 | p->RIOHalted = 1; |
1139 | p->RIOHalted = 1; | 1081 | p->RIOSystemUp = 0; |
1140 | p->RIOSystemUp = 0; | 1082 | |
1141 | 1083 | for (Host = 0; Host < p->RIONumHosts; Host++) { | |
1142 | for ( Host=0; Host<p->RIONumHosts; Host++ ) { | 1084 | (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot); |
1143 | (void)RIOBoardTest( p->RIOHosts[Host].PaddrP, | 1085 | bzero((caddr_t) & p->RIOHosts[Host].Flags, ((int) &p->RIOHosts[Host].____end_marker____) - ((int) &p->RIOHosts[Host].Flags)); |
1144 | p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, | 1086 | p->RIOHosts[Host].Flags = RC_WAITING; |
1145 | p->RIOHosts[Host].Slot ); | ||
1146 | bzero( (caddr_t)&p->RIOHosts[Host].Flags, | ||
1147 | ((int)&p->RIOHosts[Host].____end_marker____) - | ||
1148 | ((int)&p->RIOHosts[Host].Flags) ); | ||
1149 | p->RIOHosts[Host].Flags = RC_WAITING; | ||
1150 | #if 0 | 1087 | #if 0 |
1151 | RIOSetupDataStructs(p); | 1088 | RIOSetupDataStructs(p); |
1152 | #endif | 1089 | #endif |
1153 | } | 1090 | } |
1154 | RIOFoadWakeup(p); | 1091 | RIOFoadWakeup(p); |
1155 | p->RIONumBootPkts = 0; | 1092 | p->RIONumBootPkts = 0; |
1156 | p->RIOBooting = 0; | 1093 | p->RIOBooting = 0; |
1157 | 1094 | ||
1158 | #ifdef RINGBUFFER_SUPPORT | 1095 | #ifdef RINGBUFFER_SUPPORT |
1159 | for( loop=0; loop<RIO_PORTS; loop++ ) | 1096 | for (loop = 0; loop < RIO_PORTS; loop++) |
1160 | if ( p->RIOPortp[loop]->TxRingBuffer ) | 1097 | if (p->RIOPortp[loop]->TxRingBuffer) |
1161 | sysfree((void *)p->RIOPortp[loop]->TxRingBuffer, | 1098 | sysfree((void *) p->RIOPortp[loop]->TxRingBuffer, RIOBufferSize); |
1162 | RIOBufferSize ); | ||
1163 | #endif | 1099 | #endif |
1164 | #if 0 | 1100 | #if 0 |
1165 | bzero((caddr_t)&p->RIOPortp[0],RIO_PORTS*sizeof(struct Port)); | 1101 | bzero((caddr_t) & p->RIOPortp[0], RIO_PORTS * sizeof(struct Port)); |
1166 | #else | 1102 | #else |
1167 | printk ("HEEEEELP!\n"); | 1103 | printk("HEEEEELP!\n"); |
1168 | #endif | 1104 | #endif |
1169 | 1105 | ||
1170 | for( loop=0; loop<RIO_PORTS; loop++ ) { | 1106 | for (loop = 0; loop < RIO_PORTS; loop++) { |
1171 | #if 0 | 1107 | #if 0 |
1172 | p->RIOPortp[loop]->TtyP = &p->channel[loop]; | 1108 | p->RIOPortp[loop]->TtyP = &p->channel[loop]; |
1173 | #endif | 1109 | #endif |
1174 | |||
1175 | spin_lock_init(&p->RIOPortp[loop]->portSem); | ||
1176 | p->RIOPortp[loop]->InUse = NOT_INUSE; | ||
1177 | } | ||
1178 | |||
1179 | p->RIOSystemUp = 0; | ||
1180 | return retval; | ||
1181 | |||
1182 | case RIO_DOWNLOAD: | ||
1183 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); | ||
1184 | if ( !su ) { | ||
1185 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); | ||
1186 | p->RIOError.Error = NOT_SUPER_USER; | ||
1187 | return -EPERM; | ||
1188 | } | ||
1189 | if ( copyin((int)arg, (caddr_t)&DownLoad, | ||
1190 | sizeof(DownLoad) )==COPYFAIL ) { | ||
1191 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); | ||
1192 | p->RIOError.Error = COPYIN_FAILED; | ||
1193 | return -EFAULT; | ||
1194 | } | ||
1195 | rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", | ||
1196 | DownLoad.ProductCode); | ||
1197 | |||
1198 | /* | ||
1199 | ** It is important that the product code is an unsigned object! | ||
1200 | */ | ||
1201 | if ( DownLoad.ProductCode > MAX_PRODUCT ) { | ||
1202 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", | ||
1203 | DownLoad.ProductCode); | ||
1204 | p->RIOError.Error = NO_SUCH_PRODUCT; | ||
1205 | return -ENXIO; | ||
1206 | } | ||
1207 | /* | ||
1208 | ** do something! | ||
1209 | */ | ||
1210 | retval = (*(RIOBootTable[DownLoad.ProductCode]))(p, &DownLoad); | ||
1211 | /* <-- Panic */ | ||
1212 | p->RIOHalted = 0; | ||
1213 | /* | ||
1214 | ** and go back, content with a job well completed. | ||
1215 | */ | ||
1216 | return retval; | ||
1217 | |||
1218 | case RIO_PARMS: | ||
1219 | { | ||
1220 | uint host; | ||
1221 | |||
1222 | if (copyin((int)arg, (caddr_t)&host, | ||
1223 | sizeof(host) ) == COPYFAIL ) { | ||
1224 | rio_dprintk (RIO_DEBUG_CTRL, | ||
1225 | "RIO_HOST_REQ: Copy in from user space failed\n"); | ||
1226 | p->RIOError.Error = COPYIN_FAILED; | ||
1227 | return -EFAULT; | ||
1228 | } | ||
1229 | /* | ||
1230 | ** Fetch the parmmap | ||
1231 | */ | ||
1232 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS\n"); | ||
1233 | if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP, | ||
1234 | (int)arg, sizeof(PARM_MAP) )==COPYFAIL ) { | ||
1235 | p->RIOError.Error = COPYOUT_FAILED; | ||
1236 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); | ||
1237 | return -EFAULT; | ||
1238 | } | ||
1239 | } | ||
1240 | return retval; | ||
1241 | |||
1242 | case RIO_HOST_REQ: | ||
1243 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); | ||
1244 | if (copyin((int)arg, (caddr_t)&HostReq, | ||
1245 | sizeof(HostReq) )==COPYFAIL ) { | ||
1246 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); | ||
1247 | p->RIOError.Error = COPYIN_FAILED; | ||
1248 | return -EFAULT; | ||
1249 | } | ||
1250 | if ( HostReq.HostNum >= p->RIONumHosts ) { | ||
1251 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1252 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", | ||
1253 | HostReq.HostNum); | ||
1254 | return -ENXIO; | ||
1255 | } | ||
1256 | rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); | ||
1257 | 1110 | ||
1258 | if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum], | 1111 | spin_lock_init(&p->RIOPortp[loop]->portSem); |
1259 | (int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) { | 1112 | p->RIOPortp[loop]->InUse = NOT_INUSE; |
1260 | p->RIOError.Error = COPYOUT_FAILED; | 1113 | } |
1261 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); | 1114 | |
1262 | return -EFAULT; | 1115 | p->RIOSystemUp = 0; |
1263 | } | 1116 | return retval; |
1264 | return retval; | 1117 | |
1265 | 1118 | case RIO_DOWNLOAD: | |
1266 | case RIO_HOST_DPRAM: | 1119 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n"); |
1267 | rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAM\n"); | 1120 | if (!su) { |
1268 | if ( copyin( (int)arg, (caddr_t)&HostDpRam, | 1121 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n"); |
1269 | sizeof(HostDpRam) )==COPYFAIL ) { | 1122 | p->RIOError.Error = NOT_SUPER_USER; |
1270 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); | 1123 | return -EPERM; |
1271 | p->RIOError.Error = COPYIN_FAILED; | 1124 | } |
1272 | return -EFAULT; | 1125 | if (copyin((int) arg, (caddr_t) & DownLoad, sizeof(DownLoad)) == COPYFAIL) { |
1273 | } | 1126 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n"); |
1274 | if ( HostDpRam.HostNum >= p->RIONumHosts ) { | 1127 | p->RIOError.Error = COPYIN_FAILED; |
1275 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | 1128 | return -EFAULT; |
1276 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", | 1129 | } |
1277 | HostDpRam.HostNum); | 1130 | rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode); |
1278 | return -ENXIO; | ||
1279 | } | ||
1280 | rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); | ||
1281 | |||
1282 | if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { | ||
1283 | int off; | ||
1284 | /* It's hardware like this that really gets on my tits. */ | ||
1285 | static unsigned char copy[sizeof(struct DpRam)]; | ||
1286 | for ( off=0; off<sizeof(struct DpRam); off++ ) | ||
1287 | copy[off] = p->RIOHosts[HostDpRam.HostNum].Caddr[off]; | ||
1288 | if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP, | ||
1289 | sizeof(struct DpRam) ) == COPYFAIL ) { | ||
1290 | p->RIOError.Error = COPYOUT_FAILED; | ||
1291 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); | ||
1292 | return -EFAULT; | ||
1293 | } | ||
1294 | } | ||
1295 | else if (copyout((caddr_t)p->RIOHosts[HostDpRam.HostNum].Caddr, | ||
1296 | (int)HostDpRam.DpRamP, | ||
1297 | sizeof(struct DpRam) ) == COPYFAIL ) { | ||
1298 | p->RIOError.Error = COPYOUT_FAILED; | ||
1299 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); | ||
1300 | return -EFAULT; | ||
1301 | } | ||
1302 | return retval; | ||
1303 | |||
1304 | case RIO_SET_BUSY: | ||
1305 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); | ||
1306 | if ( (int)arg < 0 || (int)arg > 511 ) { | ||
1307 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n",(int)arg); | ||
1308 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1309 | return -EINVAL; | ||
1310 | } | ||
1311 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1312 | p->RIOPortp[(int)arg]->State |= RIO_BUSY; | ||
1313 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | ||
1314 | return retval; | ||
1315 | |||
1316 | case RIO_HOST_PORT: | ||
1317 | /* | ||
1318 | ** The daemon want port information | ||
1319 | ** (probably for debug reasons) | ||
1320 | */ | ||
1321 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); | ||
1322 | if ( copyin((int)arg, (caddr_t)&PortReq, | ||
1323 | sizeof(PortReq) )==COPYFAIL ) { | ||
1324 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); | ||
1325 | p->RIOError.Error = COPYIN_FAILED; | ||
1326 | return -EFAULT; | ||
1327 | } | ||
1328 | |||
1329 | if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ | ||
1330 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", | ||
1331 | PortReq.SysPort); | ||
1332 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1333 | return -ENXIO; | ||
1334 | } | ||
1335 | rio_dprintk (RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); | ||
1336 | if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort], | ||
1337 | (int)PortReq.PortP, | ||
1338 | sizeof(struct Port) ) == COPYFAIL) { | ||
1339 | p->RIOError.Error = COPYOUT_FAILED; | ||
1340 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); | ||
1341 | return -EFAULT; | ||
1342 | } | ||
1343 | return retval; | ||
1344 | |||
1345 | case RIO_HOST_RUP: | ||
1346 | /* | ||
1347 | ** The daemon want rup information | ||
1348 | ** (probably for debug reasons) | ||
1349 | */ | ||
1350 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); | ||
1351 | if (copyin((int)arg, (caddr_t)&RupReq, | ||
1352 | sizeof(RupReq) )==COPYFAIL ) { | ||
1353 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); | ||
1354 | p->RIOError.Error = COPYIN_FAILED; | ||
1355 | return -EFAULT; | ||
1356 | } | ||
1357 | if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ | ||
1358 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", | ||
1359 | RupReq.HostNum); | ||
1360 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1361 | return -ENXIO; | ||
1362 | } | ||
1363 | if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */ | ||
1364 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", | ||
1365 | RupReq.RupNum); | ||
1366 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1367 | return -EINVAL; | ||
1368 | } | ||
1369 | HostP = &p->RIOHosts[RupReq.HostNum]; | ||
1370 | |||
1371 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | ||
1372 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", | ||
1373 | RupReq.HostNum); | ||
1374 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
1375 | return -EIO; | ||
1376 | } | ||
1377 | rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", | ||
1378 | RupReq.RupNum,RupReq.HostNum); | ||
1379 | |||
1380 | if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP, | ||
1381 | (int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) { | ||
1382 | p->RIOError.Error = COPYOUT_FAILED; | ||
1383 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); | ||
1384 | return -EFAULT; | ||
1385 | } | ||
1386 | return retval; | ||
1387 | |||
1388 | case RIO_HOST_LPB: | ||
1389 | /* | ||
1390 | ** The daemon want lpb information | ||
1391 | ** (probably for debug reasons) | ||
1392 | */ | ||
1393 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); | ||
1394 | if (copyin((int)arg, (caddr_t)&LpbReq, | ||
1395 | sizeof(LpbReq) )==COPYFAIL ) { | ||
1396 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); | ||
1397 | p->RIOError.Error = COPYIN_FAILED; | ||
1398 | return -EFAULT; | ||
1399 | } | ||
1400 | if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ | ||
1401 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", | ||
1402 | LpbReq.Host); | ||
1403 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1404 | return -ENXIO; | ||
1405 | } | ||
1406 | if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */ | ||
1407 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", | ||
1408 | LpbReq.Link); | ||
1409 | p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; | ||
1410 | return -EINVAL; | ||
1411 | } | ||
1412 | HostP = &p->RIOHosts[LpbReq.Host]; | ||
1413 | |||
1414 | if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) { | ||
1415 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", | ||
1416 | LpbReq.Host ); | ||
1417 | p->RIOError.Error = HOST_NOT_RUNNING; | ||
1418 | return -EIO; | ||
1419 | } | ||
1420 | rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", | ||
1421 | LpbReq.Link, LpbReq.Host); | ||
1422 | |||
1423 | if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link], | ||
1424 | (int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) { | ||
1425 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); | ||
1426 | p->RIOError.Error = COPYOUT_FAILED; | ||
1427 | return -EFAULT; | ||
1428 | } | ||
1429 | return retval; | ||
1430 | |||
1431 | /* | ||
1432 | ** Here 3 IOCTL's that allow us to change the way in which | ||
1433 | ** rio logs errors. send them just to syslog or send them | ||
1434 | ** to both syslog and console or send them to just the console. | ||
1435 | ** | ||
1436 | ** See RioStrBuf() in util.c for the other half. | ||
1437 | */ | ||
1438 | case RIO_SYSLOG_ONLY: | ||
1439 | p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ | ||
1440 | return 0; | ||
1441 | |||
1442 | case RIO_SYSLOG_CONS: | ||
1443 | p->RIOPrintLogState = PRINT_TO_LOG_CONS;/* syslog and console */ | ||
1444 | return 0; | ||
1445 | |||
1446 | case RIO_CONS_ONLY: | ||
1447 | p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ | ||
1448 | return 0; | ||
1449 | |||
1450 | case RIO_SIGNALS_ON: | ||
1451 | if ( p->RIOSignalProcess ) { | ||
1452 | p->RIOError.Error = SIGNALS_ALREADY_SET; | ||
1453 | return -EBUSY; | ||
1454 | } | ||
1455 | p->RIOSignalProcess = getpid(); | ||
1456 | p->RIOPrintDisabled = DONT_PRINT; | ||
1457 | return retval; | ||
1458 | |||
1459 | case RIO_SIGNALS_OFF: | ||
1460 | if ( p->RIOSignalProcess != getpid() ) { | ||
1461 | p->RIOError.Error = NOT_RECEIVING_PROCESS; | ||
1462 | return -EPERM; | ||
1463 | } | ||
1464 | rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n"); | ||
1465 | p->RIOSignalProcess = 0; | ||
1466 | return retval; | ||
1467 | |||
1468 | case RIO_SET_BYTE_MODE: | ||
1469 | for ( Host=0; Host<p->RIONumHosts; Host++ ) | ||
1470 | if ( p->RIOHosts[Host].Type == RIO_AT ) | ||
1471 | p->RIOHosts[Host].Mode &= ~WORD_OPERATION; | ||
1472 | return retval; | ||
1473 | |||
1474 | case RIO_SET_WORD_MODE: | ||
1475 | for ( Host=0; Host<p->RIONumHosts; Host++ ) | ||
1476 | if ( p->RIOHosts[Host].Type == RIO_AT ) | ||
1477 | p->RIOHosts[Host].Mode |= WORD_OPERATION; | ||
1478 | return retval; | ||
1479 | |||
1480 | case RIO_SET_FAST_BUS: | ||
1481 | for ( Host=0; Host<p->RIONumHosts; Host++ ) | ||
1482 | if ( p->RIOHosts[Host].Type == RIO_AT ) | ||
1483 | p->RIOHosts[Host].Mode |= FAST_AT_BUS; | ||
1484 | return retval; | ||
1485 | |||
1486 | case RIO_SET_SLOW_BUS: | ||
1487 | for ( Host=0; Host<p->RIONumHosts; Host++ ) | ||
1488 | if ( p->RIOHosts[Host].Type == RIO_AT ) | ||
1489 | p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; | ||
1490 | return retval; | ||
1491 | |||
1492 | case RIO_MAP_B50_TO_50: | ||
1493 | case RIO_MAP_B50_TO_57600: | ||
1494 | case RIO_MAP_B110_TO_110: | ||
1495 | case RIO_MAP_B110_TO_115200: | ||
1496 | rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n"); | ||
1497 | port = (uint) arg; | ||
1498 | if ( port < 0 || port > 511 ) { | ||
1499 | rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); | ||
1500 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1501 | return -EINVAL; | ||
1502 | } | ||
1503 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1504 | switch( cmd ) | ||
1505 | { | ||
1506 | case RIO_MAP_B50_TO_50 : | ||
1507 | p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; | ||
1508 | break; | ||
1509 | case RIO_MAP_B50_TO_57600 : | ||
1510 | p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; | ||
1511 | break; | ||
1512 | case RIO_MAP_B110_TO_110 : | ||
1513 | p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; | ||
1514 | break; | ||
1515 | case RIO_MAP_B110_TO_115200 : | ||
1516 | p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; | ||
1517 | break; | ||
1518 | } | ||
1519 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | ||
1520 | return retval; | ||
1521 | |||
1522 | case RIO_STREAM_INFO: | ||
1523 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); | ||
1524 | return -EINVAL; | ||
1525 | 1131 | ||
1526 | case RIO_SEND_PACKET: | 1132 | /* |
1527 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); | 1133 | ** It is important that the product code is an unsigned object! |
1528 | if ( copyin( (int)arg, (caddr_t)&SendPack, | 1134 | */ |
1529 | sizeof(SendPack) )==COPYFAIL ) { | 1135 | if (DownLoad.ProductCode > MAX_PRODUCT) { |
1530 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); | 1136 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode); |
1531 | p->RIOError.Error = COPYIN_FAILED; | 1137 | p->RIOError.Error = NO_SUCH_PRODUCT; |
1532 | return -EFAULT; | 1138 | return -ENXIO; |
1533 | } | 1139 | } |
1534 | if ( SendPack.PortNum >= 128 ) { | 1140 | /* |
1535 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 1141 | ** do something! |
1536 | return -ENXIO; | 1142 | */ |
1537 | } | 1143 | retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad); |
1538 | 1144 | /* <-- Panic */ | |
1539 | PortP = p->RIOPortp[SendPack.PortNum]; | 1145 | p->RIOHalted = 0; |
1540 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 1146 | /* |
1541 | 1147 | ** and go back, content with a job well completed. | |
1542 | if ( !can_add_transmit(&PacketP,PortP) ) { | 1148 | */ |
1543 | p->RIOError.Error = UNIT_IS_IN_USE; | 1149 | return retval; |
1544 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1150 | |
1545 | return -ENOSPC; | 1151 | case RIO_PARMS: |
1546 | } | 1152 | { |
1547 | 1153 | uint host; | |
1548 | for ( loop=0; loop<(ushort)(SendPack.Len & 127); loop++ ) | 1154 | |
1549 | WBYTE(PacketP->data[loop], SendPack.Data[loop] ); | 1155 | if (copyin((int) arg, (caddr_t) & host, sizeof(host)) == COPYFAIL) { |
1550 | 1156 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); | |
1551 | WBYTE(PacketP->len, SendPack.Len); | 1157 | p->RIOError.Error = COPYIN_FAILED; |
1552 | 1158 | return -EFAULT; | |
1553 | add_transmit( PortP ); | 1159 | } |
1554 | /* | 1160 | /* |
1555 | ** Count characters transmitted for port statistics reporting | 1161 | ** Fetch the parmmap |
1556 | */ | 1162 | */ |
1557 | if (PortP->statsGather) | 1163 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n"); |
1558 | PortP->txchars += (SendPack.Len & 127); | 1164 | if (copyout((caddr_t) p->RIOHosts[host].ParmMapP, (int) arg, sizeof(PARM_MAP)) == COPYFAIL) { |
1559 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1165 | p->RIOError.Error = COPYOUT_FAILED; |
1560 | return retval; | 1166 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n"); |
1561 | 1167 | return -EFAULT; | |
1562 | case RIO_NO_MESG: | 1168 | } |
1563 | if ( su ) | 1169 | } |
1564 | p->RIONoMessage = 1; | 1170 | return retval; |
1565 | return su ? 0 : -EPERM; | 1171 | |
1566 | 1172 | case RIO_HOST_REQ: | |
1567 | case RIO_MESG: | 1173 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n"); |
1568 | if ( su ) | 1174 | if (copyin((int) arg, (caddr_t) & HostReq, sizeof(HostReq)) == COPYFAIL) { |
1569 | p->RIONoMessage = 0; | 1175 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n"); |
1570 | return su ? 0 : -EPERM; | 1176 | p->RIOError.Error = COPYIN_FAILED; |
1571 | 1177 | return -EFAULT; | |
1572 | case RIO_WHAT_MESG: | 1178 | } |
1573 | if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, | 1179 | if (HostReq.HostNum >= p->RIONumHosts) { |
1574 | sizeof(p->RIONoMessage) )==COPYFAIL ) { | 1180 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; |
1575 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); | 1181 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum); |
1576 | p->RIOError.Error = COPYOUT_FAILED; | 1182 | return -ENXIO; |
1577 | return -EFAULT; | 1183 | } |
1578 | } | 1184 | rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum); |
1579 | return 0; | 1185 | |
1580 | 1186 | if (copyout((caddr_t) & p->RIOHosts[HostReq.HostNum], (int) HostReq.HostP, sizeof(struct Host)) == COPYFAIL) { | |
1581 | case RIO_MEM_DUMP : | 1187 | p->RIOError.Error = COPYOUT_FAILED; |
1582 | if (copyin((int)arg, (caddr_t)&SubCmd, | 1188 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n"); |
1583 | sizeof(struct SubCmdStruct)) == COPYFAIL) { | 1189 | return -EFAULT; |
1584 | p->RIOError.Error = COPYIN_FAILED; | 1190 | } |
1585 | return -EFAULT; | 1191 | return retval; |
1586 | } | 1192 | |
1587 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", | 1193 | case RIO_HOST_DPRAM: |
1588 | SubCmd.Host, SubCmd.Rup, SubCmd.Addr); | 1194 | rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n"); |
1589 | 1195 | if (copyin((int) arg, (caddr_t) & HostDpRam, sizeof(HostDpRam)) == COPYFAIL) { | |
1590 | if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) { | 1196 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n"); |
1591 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | 1197 | p->RIOError.Error = COPYIN_FAILED; |
1592 | return -EINVAL; | 1198 | return -EFAULT; |
1593 | } | 1199 | } |
1594 | 1200 | if (HostDpRam.HostNum >= p->RIONumHosts) { | |
1595 | if (SubCmd.Host >= p->RIONumHosts ) { | 1201 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; |
1596 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | 1202 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum); |
1597 | return -EINVAL; | 1203 | return -ENXIO; |
1598 | } | 1204 | } |
1599 | 1205 | rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum); | |
1600 | port = p->RIOHosts[SubCmd.Host]. | 1206 | |
1601 | UnixRups[SubCmd.Rup].BaseSysPort; | 1207 | if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) { |
1602 | 1208 | int off; | |
1603 | PortP = p->RIOPortp[port]; | 1209 | /* It's hardware like this that really gets on my tits. */ |
1604 | 1210 | static unsigned char copy[sizeof(struct DpRam)]; | |
1605 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 1211 | for (off = 0; off < sizeof(struct DpRam); off++) |
1606 | 1212 | copy[off] = p->RIOHosts[HostDpRam.HostNum].Caddr[off]; | |
1607 | if ( RIOPreemptiveCmd(p, PortP, MEMDUMP ) == RIO_FAIL ) { | 1213 | if (copyout((caddr_t) copy, (int) HostDpRam.DpRamP, sizeof(struct DpRam)) == COPYFAIL) { |
1608 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); | 1214 | p->RIOError.Error = COPYOUT_FAILED; |
1609 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1215 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); |
1610 | return -EBUSY; | 1216 | return -EFAULT; |
1611 | } | 1217 | } |
1612 | else | 1218 | } else if (copyout((caddr_t) p->RIOHosts[HostDpRam.HostNum].Caddr, (int) HostDpRam.DpRamP, sizeof(struct DpRam)) == COPYFAIL) { |
1613 | PortP->State |= RIO_BUSY; | 1219 | p->RIOError.Error = COPYOUT_FAILED; |
1614 | 1220 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n"); | |
1615 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1221 | return -EFAULT; |
1616 | if ( copyout( (caddr_t)p->RIOMemDump, (int)arg, | 1222 | } |
1617 | MEMDUMP_SIZE) == COPYFAIL ) { | 1223 | return retval; |
1618 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); | 1224 | |
1619 | p->RIOError.Error = COPYOUT_FAILED; | 1225 | case RIO_SET_BUSY: |
1620 | return -EFAULT; | 1226 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n"); |
1621 | } | 1227 | if ((int) arg < 0 || (int) arg > 511) { |
1622 | return 0; | 1228 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n", (int) arg); |
1623 | 1229 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | |
1624 | case RIO_TICK: | 1230 | return -EINVAL; |
1625 | if ((int)arg < 0 || (int)arg >= p->RIONumHosts) | 1231 | } |
1626 | return -EINVAL; | 1232 | rio_spin_lock_irqsave(&PortP->portSem, flags); |
1627 | rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg); | 1233 | p->RIOPortp[(int) arg]->State |= RIO_BUSY; |
1628 | WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff); | 1234 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); |
1629 | return 0; | 1235 | return retval; |
1630 | 1236 | ||
1631 | case RIO_TOCK: | 1237 | case RIO_HOST_PORT: |
1632 | if ((int)arg < 0 || (int)arg >= p->RIONumHosts) | 1238 | /* |
1633 | return -EINVAL; | 1239 | ** The daemon want port information |
1634 | rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg); | 1240 | ** (probably for debug reasons) |
1635 | WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff); | 1241 | */ |
1636 | return 0; | 1242 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n"); |
1637 | 1243 | if (copyin((int) arg, (caddr_t) & PortReq, sizeof(PortReq)) == COPYFAIL) { | |
1638 | case RIO_READ_CHECK: | 1244 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n"); |
1639 | /* Check reads for pkts with data[0] the same */ | 1245 | p->RIOError.Error = COPYIN_FAILED; |
1640 | p->RIOReadCheck = !p->RIOReadCheck; | 1246 | return -EFAULT; |
1641 | if (copyout((caddr_t)&p->RIOReadCheck,(int)arg, | 1247 | } |
1642 | sizeof(uint))== COPYFAIL) { | 1248 | |
1643 | p->RIOError.Error = COPYOUT_FAILED; | 1249 | if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */ |
1644 | return -EFAULT; | 1250 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort); |
1645 | } | 1251 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; |
1646 | return 0; | 1252 | return -ENXIO; |
1647 | 1253 | } | |
1648 | case RIO_READ_REGISTER : | 1254 | rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort); |
1649 | if (copyin((int)arg, (caddr_t)&SubCmd, | 1255 | if (copyout((caddr_t) p->RIOPortp[PortReq.SysPort], (int) PortReq.PortP, sizeof(struct Port)) == COPYFAIL) { |
1650 | sizeof(struct SubCmdStruct)) == COPYFAIL) { | 1256 | p->RIOError.Error = COPYOUT_FAILED; |
1651 | p->RIOError.Error = COPYIN_FAILED; | 1257 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n"); |
1652 | return -EFAULT; | 1258 | return -EFAULT; |
1653 | } | 1259 | } |
1654 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", | 1260 | return retval; |
1655 | SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); | 1261 | |
1656 | 1262 | case RIO_HOST_RUP: | |
1657 | if (SubCmd.Port > 511) { | 1263 | /* |
1658 | rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", | 1264 | ** The daemon want rup information |
1659 | SubCmd.Port); | 1265 | ** (probably for debug reasons) |
1660 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | 1266 | */ |
1661 | return -EINVAL; | 1267 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n"); |
1662 | } | 1268 | if (copyin((int) arg, (caddr_t) & RupReq, sizeof(RupReq)) == COPYFAIL) { |
1663 | 1269 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n"); | |
1664 | if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) { | 1270 | p->RIOError.Error = COPYIN_FAILED; |
1665 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | 1271 | return -EFAULT; |
1666 | return -EINVAL; | 1272 | } |
1667 | } | 1273 | if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */ |
1668 | 1274 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum); | |
1669 | if (SubCmd.Host >= p->RIONumHosts ) { | 1275 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; |
1670 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | 1276 | return -ENXIO; |
1671 | return -EINVAL; | 1277 | } |
1672 | } | 1278 | if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */ |
1673 | 1279 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum); | |
1674 | port = p->RIOHosts[SubCmd.Host]. | 1280 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; |
1675 | UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; | 1281 | return -EINVAL; |
1676 | PortP = p->RIOPortp[port]; | 1282 | } |
1677 | 1283 | HostP = &p->RIOHosts[RupReq.HostNum]; | |
1678 | rio_spin_lock_irqsave(&PortP->portSem, flags); | 1284 | |
1679 | 1285 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { | |
1680 | if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) { | 1286 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum); |
1681 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); | 1287 | p->RIOError.Error = HOST_NOT_RUNNING; |
1682 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1288 | return -EIO; |
1683 | return -EBUSY; | 1289 | } |
1684 | } | 1290 | rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum); |
1685 | else | 1291 | |
1686 | PortP->State |= RIO_BUSY; | 1292 | if (copyout((caddr_t) HostP->UnixRups[RupReq.RupNum].RupP, (int) RupReq.RupP, sizeof(struct RUP)) == COPYFAIL) { |
1687 | 1293 | p->RIOError.Error = COPYOUT_FAILED; | |
1688 | rio_spin_unlock_irqrestore( &PortP->portSem , flags); | 1294 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n"); |
1689 | if (copyout((caddr_t)&p->CdRegister, (int)arg, | 1295 | return -EFAULT; |
1690 | sizeof(uint)) == COPYFAIL ) { | 1296 | } |
1691 | rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); | 1297 | return retval; |
1692 | p->RIOError.Error = COPYOUT_FAILED; | 1298 | |
1693 | return -EFAULT; | 1299 | case RIO_HOST_LPB: |
1694 | } | 1300 | /* |
1695 | return 0; | 1301 | ** The daemon want lpb information |
1696 | /* | 1302 | ** (probably for debug reasons) |
1697 | ** rio_make_dev: given port number (0-511) ORed with port type | 1303 | */ |
1698 | ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t | 1304 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n"); |
1699 | ** value to pass to mknod to create the correct device node. | 1305 | if (copyin((int) arg, (caddr_t) & LpbReq, sizeof(LpbReq)) == COPYFAIL) { |
1700 | */ | 1306 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n"); |
1701 | case RIO_MAKE_DEV: | 1307 | p->RIOError.Error = COPYIN_FAILED; |
1702 | { | 1308 | return -EFAULT; |
1703 | uint port = (uint)arg & RIO_MODEM_MASK; | 1309 | } |
1704 | 1310 | if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */ | |
1705 | switch ( (uint)arg & RIO_DEV_MASK ) { | 1311 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host); |
1706 | case RIO_DEV_DIRECT: | 1312 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; |
1707 | arg = (caddr_t)drv_makedev(MAJOR(dev), port); | 1313 | return -ENXIO; |
1708 | rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg); | 1314 | } |
1709 | return (int)arg; | 1315 | if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */ |
1710 | case RIO_DEV_MODEM: | 1316 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link); |
1711 | arg = (caddr_t)drv_makedev(MAJOR(dev), (port|RIO_MODEM_BIT) ); | 1317 | p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE; |
1712 | rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg); | 1318 | return -EINVAL; |
1713 | return (int)arg; | 1319 | } |
1714 | case RIO_DEV_XPRINT: | 1320 | HostP = &p->RIOHosts[LpbReq.Host]; |
1715 | arg = (caddr_t)drv_makedev(MAJOR(dev), port); | 1321 | |
1716 | rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg); | 1322 | if ((HostP->Flags & RUN_STATE) != RC_RUNNING) { |
1717 | return (int)arg; | 1323 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host); |
1718 | } | 1324 | p->RIOError.Error = HOST_NOT_RUNNING; |
1719 | rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n"); | 1325 | return -EIO; |
1720 | return -EINVAL; | 1326 | } |
1721 | } | 1327 | rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host); |
1722 | /* | 1328 | |
1723 | ** rio_minor: given a dev_t from a stat() call, return | 1329 | if (copyout((caddr_t) & HostP->LinkStrP[LpbReq.Link], (int) LpbReq.LpbP, sizeof(struct LPB)) == COPYFAIL) { |
1724 | ** the port number (0-511) ORed with the port type | 1330 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n"); |
1725 | ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) | 1331 | p->RIOError.Error = COPYOUT_FAILED; |
1726 | */ | 1332 | return -EFAULT; |
1727 | case RIO_MINOR: | 1333 | } |
1728 | { | 1334 | return retval; |
1729 | dev_t dv; | ||
1730 | int mino; | ||
1731 | |||
1732 | dv = (dev_t)((int)arg); | ||
1733 | mino = RIO_UNMODEM(dv); | ||
1734 | 1335 | ||
1735 | if ( RIO_ISMODEM(dv) ) { | 1336 | /* |
1736 | rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); | 1337 | ** Here 3 IOCTL's that allow us to change the way in which |
1737 | arg = (caddr_t)(mino | RIO_DEV_MODEM); | 1338 | ** rio logs errors. send them just to syslog or send them |
1738 | } | 1339 | ** to both syslog and console or send them to just the console. |
1739 | else { | 1340 | ** |
1740 | rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); | 1341 | ** See RioStrBuf() in util.c for the other half. |
1741 | arg = (caddr_t)(mino | RIO_DEV_DIRECT); | 1342 | */ |
1742 | } | 1343 | case RIO_SYSLOG_ONLY: |
1743 | return (int)arg; | 1344 | p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */ |
1744 | } | 1345 | return 0; |
1346 | |||
1347 | case RIO_SYSLOG_CONS: | ||
1348 | p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */ | ||
1349 | return 0; | ||
1350 | |||
1351 | case RIO_CONS_ONLY: | ||
1352 | p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */ | ||
1353 | return 0; | ||
1354 | |||
1355 | case RIO_SIGNALS_ON: | ||
1356 | if (p->RIOSignalProcess) { | ||
1357 | p->RIOError.Error = SIGNALS_ALREADY_SET; | ||
1358 | return -EBUSY; | ||
1359 | } | ||
1360 | p->RIOSignalProcess = getpid(); | ||
1361 | p->RIOPrintDisabled = DONT_PRINT; | ||
1362 | return retval; | ||
1363 | |||
1364 | case RIO_SIGNALS_OFF: | ||
1365 | if (p->RIOSignalProcess != getpid()) { | ||
1366 | p->RIOError.Error = NOT_RECEIVING_PROCESS; | ||
1367 | return -EPERM; | ||
1368 | } | ||
1369 | rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n"); | ||
1370 | p->RIOSignalProcess = 0; | ||
1371 | return retval; | ||
1372 | |||
1373 | case RIO_SET_BYTE_MODE: | ||
1374 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1375 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1376 | p->RIOHosts[Host].Mode &= ~WORD_OPERATION; | ||
1377 | return retval; | ||
1378 | |||
1379 | case RIO_SET_WORD_MODE: | ||
1380 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1381 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1382 | p->RIOHosts[Host].Mode |= WORD_OPERATION; | ||
1383 | return retval; | ||
1384 | |||
1385 | case RIO_SET_FAST_BUS: | ||
1386 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1387 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1388 | p->RIOHosts[Host].Mode |= FAST_AT_BUS; | ||
1389 | return retval; | ||
1390 | |||
1391 | case RIO_SET_SLOW_BUS: | ||
1392 | for (Host = 0; Host < p->RIONumHosts; Host++) | ||
1393 | if (p->RIOHosts[Host].Type == RIO_AT) | ||
1394 | p->RIOHosts[Host].Mode &= ~FAST_AT_BUS; | ||
1395 | return retval; | ||
1396 | |||
1397 | case RIO_MAP_B50_TO_50: | ||
1398 | case RIO_MAP_B50_TO_57600: | ||
1399 | case RIO_MAP_B110_TO_110: | ||
1400 | case RIO_MAP_B110_TO_115200: | ||
1401 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n"); | ||
1402 | port = (uint) arg; | ||
1403 | if (port < 0 || port > 511) { | ||
1404 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port); | ||
1405 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1406 | return -EINVAL; | ||
1407 | } | ||
1408 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1409 | switch (cmd) { | ||
1410 | case RIO_MAP_B50_TO_50: | ||
1411 | p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50; | ||
1412 | break; | ||
1413 | case RIO_MAP_B50_TO_57600: | ||
1414 | p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50; | ||
1415 | break; | ||
1416 | case RIO_MAP_B110_TO_110: | ||
1417 | p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110; | ||
1418 | break; | ||
1419 | case RIO_MAP_B110_TO_115200: | ||
1420 | p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110; | ||
1421 | break; | ||
1422 | } | ||
1423 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1424 | return retval; | ||
1425 | |||
1426 | case RIO_STREAM_INFO: | ||
1427 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n"); | ||
1428 | return -EINVAL; | ||
1429 | |||
1430 | case RIO_SEND_PACKET: | ||
1431 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n"); | ||
1432 | if (copyin((int) arg, (caddr_t) & SendPack, sizeof(SendPack)) == COPYFAIL) { | ||
1433 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n"); | ||
1434 | p->RIOError.Error = COPYIN_FAILED; | ||
1435 | return -EFAULT; | ||
1436 | } | ||
1437 | if (SendPack.PortNum >= 128) { | ||
1438 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1439 | return -ENXIO; | ||
1440 | } | ||
1441 | |||
1442 | PortP = p->RIOPortp[SendPack.PortNum]; | ||
1443 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1444 | |||
1445 | if (!can_add_transmit(&PacketP, PortP)) { | ||
1446 | p->RIOError.Error = UNIT_IS_IN_USE; | ||
1447 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1448 | return -ENOSPC; | ||
1449 | } | ||
1450 | |||
1451 | for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++) | ||
1452 | WBYTE(PacketP->data[loop], SendPack.Data[loop]); | ||
1453 | |||
1454 | WBYTE(PacketP->len, SendPack.Len); | ||
1455 | |||
1456 | add_transmit(PortP); | ||
1457 | /* | ||
1458 | ** Count characters transmitted for port statistics reporting | ||
1459 | */ | ||
1460 | if (PortP->statsGather) | ||
1461 | PortP->txchars += (SendPack.Len & 127); | ||
1462 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1463 | return retval; | ||
1464 | |||
1465 | case RIO_NO_MESG: | ||
1466 | if (su) | ||
1467 | p->RIONoMessage = 1; | ||
1468 | return su ? 0 : -EPERM; | ||
1469 | |||
1470 | case RIO_MESG: | ||
1471 | if (su) | ||
1472 | p->RIONoMessage = 0; | ||
1473 | return su ? 0 : -EPERM; | ||
1474 | |||
1475 | case RIO_WHAT_MESG: | ||
1476 | if (copyout((caddr_t) & p->RIONoMessage, (int) arg, sizeof(p->RIONoMessage)) == COPYFAIL) { | ||
1477 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n"); | ||
1478 | p->RIOError.Error = COPYOUT_FAILED; | ||
1479 | return -EFAULT; | ||
1480 | } | ||
1481 | return 0; | ||
1482 | |||
1483 | case RIO_MEM_DUMP: | ||
1484 | if (copyin((int) arg, (caddr_t) & SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) { | ||
1485 | p->RIOError.Error = COPYIN_FAILED; | ||
1486 | return -EFAULT; | ||
1487 | } | ||
1488 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr); | ||
1489 | |||
1490 | if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { | ||
1491 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1492 | return -EINVAL; | ||
1493 | } | ||
1494 | |||
1495 | if (SubCmd.Host >= p->RIONumHosts) { | ||
1496 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1497 | return -EINVAL; | ||
1498 | } | ||
1499 | |||
1500 | port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort; | ||
1501 | |||
1502 | PortP = p->RIOPortp[port]; | ||
1503 | |||
1504 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1505 | |||
1506 | if (RIOPreemptiveCmd(p, PortP, MEMDUMP) == RIO_FAIL) { | ||
1507 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n"); | ||
1508 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1509 | return -EBUSY; | ||
1510 | } else | ||
1511 | PortP->State |= RIO_BUSY; | ||
1512 | |||
1513 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1514 | if (copyout((caddr_t) p->RIOMemDump, (int) arg, MEMDUMP_SIZE) == COPYFAIL) { | ||
1515 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n"); | ||
1516 | p->RIOError.Error = COPYOUT_FAILED; | ||
1517 | return -EFAULT; | ||
1518 | } | ||
1519 | return 0; | ||
1520 | |||
1521 | case RIO_TICK: | ||
1522 | if ((int) arg < 0 || (int) arg >= p->RIONumHosts) | ||
1523 | return -EINVAL; | ||
1524 | rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int) arg); | ||
1525 | WBYTE(p->RIOHosts[(int) arg].SetInt, 0xff); | ||
1526 | return 0; | ||
1527 | |||
1528 | case RIO_TOCK: | ||
1529 | if ((int) arg < 0 || (int) arg >= p->RIONumHosts) | ||
1530 | return -EINVAL; | ||
1531 | rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int) arg); | ||
1532 | WBYTE((p->RIOHosts[(int) arg].ResetInt), 0xff); | ||
1533 | return 0; | ||
1534 | |||
1535 | case RIO_READ_CHECK: | ||
1536 | /* Check reads for pkts with data[0] the same */ | ||
1537 | p->RIOReadCheck = !p->RIOReadCheck; | ||
1538 | if (copyout((caddr_t) & p->RIOReadCheck, (int) arg, sizeof(uint)) == COPYFAIL) { | ||
1539 | p->RIOError.Error = COPYOUT_FAILED; | ||
1540 | return -EFAULT; | ||
1541 | } | ||
1542 | return 0; | ||
1543 | |||
1544 | case RIO_READ_REGISTER: | ||
1545 | if (copyin((int) arg, (caddr_t) & SubCmd, sizeof(struct SubCmdStruct)) == COPYFAIL) { | ||
1546 | p->RIOError.Error = COPYIN_FAILED; | ||
1547 | return -EFAULT; | ||
1548 | } | ||
1549 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr); | ||
1550 | |||
1551 | if (SubCmd.Port > 511) { | ||
1552 | rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port); | ||
1553 | p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE; | ||
1554 | return -EINVAL; | ||
1555 | } | ||
1556 | |||
1557 | if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) { | ||
1558 | p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE; | ||
1559 | return -EINVAL; | ||
1560 | } | ||
1561 | |||
1562 | if (SubCmd.Host >= p->RIONumHosts) { | ||
1563 | p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE; | ||
1564 | return -EINVAL; | ||
1565 | } | ||
1566 | |||
1567 | port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port; | ||
1568 | PortP = p->RIOPortp[port]; | ||
1569 | |||
1570 | rio_spin_lock_irqsave(&PortP->portSem, flags); | ||
1571 | |||
1572 | if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) { | ||
1573 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n"); | ||
1574 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1575 | return -EBUSY; | ||
1576 | } else | ||
1577 | PortP->State |= RIO_BUSY; | ||
1578 | |||
1579 | rio_spin_unlock_irqrestore(&PortP->portSem, flags); | ||
1580 | if (copyout((caddr_t) & p->CdRegister, (int) arg, sizeof(uint)) == COPYFAIL) { | ||
1581 | rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n"); | ||
1582 | p->RIOError.Error = COPYOUT_FAILED; | ||
1583 | return -EFAULT; | ||
1584 | } | ||
1585 | return 0; | ||
1586 | /* | ||
1587 | ** rio_make_dev: given port number (0-511) ORed with port type | ||
1588 | ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t | ||
1589 | ** value to pass to mknod to create the correct device node. | ||
1590 | */ | ||
1591 | case RIO_MAKE_DEV: | ||
1592 | { | ||
1593 | uint port = (uint) arg & RIO_MODEM_MASK; | ||
1594 | |||
1595 | switch ((uint) arg & RIO_DEV_MASK) { | ||
1596 | case RIO_DEV_DIRECT: | ||
1597 | arg = (caddr_t) drv_makedev(MAJOR(dev), port); | ||
1598 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, (int) arg); | ||
1599 | return (int) arg; | ||
1600 | case RIO_DEV_MODEM: | ||
1601 | arg = (caddr_t) drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT)); | ||
1602 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, (int) arg); | ||
1603 | return (int) arg; | ||
1604 | case RIO_DEV_XPRINT: | ||
1605 | arg = (caddr_t) drv_makedev(MAJOR(dev), port); | ||
1606 | rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, (int) arg); | ||
1607 | return (int) arg; | ||
1608 | } | ||
1609 | rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n"); | ||
1610 | return -EINVAL; | ||
1611 | } | ||
1612 | /* | ||
1613 | ** rio_minor: given a dev_t from a stat() call, return | ||
1614 | ** the port number (0-511) ORed with the port type | ||
1615 | ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT ) | ||
1616 | */ | ||
1617 | case RIO_MINOR: | ||
1618 | { | ||
1619 | dev_t dv; | ||
1620 | int mino; | ||
1621 | |||
1622 | dv = (dev_t) ((int) arg); | ||
1623 | mino = RIO_UNMODEM(dv); | ||
1624 | |||
1625 | if (RIO_ISMODEM(dv)) { | ||
1626 | rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino); | ||
1627 | arg = (caddr_t) (mino | RIO_DEV_MODEM); | ||
1628 | } else { | ||
1629 | rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino); | ||
1630 | arg = (caddr_t) (mino | RIO_DEV_DIRECT); | ||
1631 | } | ||
1632 | return (int) arg; | ||
1633 | } | ||
1745 | } | 1634 | } |
1746 | rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd); | 1635 | rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd); |
1747 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; | 1636 | p->RIOError.Error = IOCTL_COMMAND_UNKNOWN; |
1748 | 1637 | ||
1749 | func_exit (); | 1638 | func_exit(); |
1750 | return -EINVAL; | 1639 | return -EINVAL; |
1751 | } | 1640 | } |
1752 | 1641 | ||
1753 | /* | 1642 | /* |
1754 | ** Pre-emptive commands go on RUPs and are only one byte long. | 1643 | ** Pre-emptive commands go on RUPs and are only one byte long. |
1755 | */ | 1644 | */ |
1756 | int | 1645 | int RIOPreemptiveCmd(p, PortP, Cmd) |
1757 | RIOPreemptiveCmd(p, PortP, Cmd) | 1646 | struct rio_info *p; |
1758 | struct rio_info * p; | ||
1759 | struct Port *PortP; | 1647 | struct Port *PortP; |
1760 | uchar Cmd; | 1648 | uchar Cmd; |
1761 | { | 1649 | { |
@@ -1766,104 +1654,99 @@ uchar Cmd; | |||
1766 | int port; | 1654 | int port; |
1767 | 1655 | ||
1768 | #ifdef CHECK | 1656 | #ifdef CHECK |
1769 | CheckPortP( PortP ); | 1657 | CheckPortP(PortP); |
1770 | #endif | 1658 | #endif |
1771 | 1659 | ||
1772 | if ( PortP->State & RIO_DELETED ) { | 1660 | if (PortP->State & RIO_DELETED) { |
1773 | rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); | 1661 | rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n"); |
1774 | return RIO_FAIL; | 1662 | return RIO_FAIL; |
1775 | } | 1663 | } |
1776 | 1664 | ||
1777 | if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) { | 1665 | if (((int) ((char) PortP->InUse) == -1) || !(CmdBlkP = RIOGetCmdBlk())) { |
1778 | rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", | 1666 | rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n", Cmd, PortP->PortNum); |
1779 | Cmd, PortP->PortNum); | ||
1780 | return RIO_FAIL; | 1667 | return RIO_FAIL; |
1781 | } | 1668 | } |
1782 | 1669 | ||
1783 | rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", | 1670 | rio_dprintk(RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", (int) CmdBlkP, PortP->InUse); |
1784 | (int)CmdBlkP,PortP->InUse); | ||
1785 | 1671 | ||
1786 | PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0]; | 1672 | PktCmdP = (struct PktCmd_M *) &CmdBlkP->Packet.data[0]; |
1787 | 1673 | ||
1788 | CmdBlkP->Packet.src_unit = 0; | 1674 | CmdBlkP->Packet.src_unit = 0; |
1789 | if (PortP->SecondBlock) | 1675 | if (PortP->SecondBlock) |
1790 | rup = PortP->ID2; | 1676 | rup = PortP->ID2; |
1791 | else | 1677 | else |
1792 | rup = PortP->RupNum; | 1678 | rup = PortP->RupNum; |
1793 | CmdBlkP->Packet.dest_unit = rup; | 1679 | CmdBlkP->Packet.dest_unit = rup; |
1794 | CmdBlkP->Packet.src_port = COMMAND_RUP; | 1680 | CmdBlkP->Packet.src_port = COMMAND_RUP; |
1795 | CmdBlkP->Packet.dest_port = COMMAND_RUP; | 1681 | CmdBlkP->Packet.dest_port = COMMAND_RUP; |
1796 | CmdBlkP->Packet.len = PKT_CMD_BIT | 2; | 1682 | CmdBlkP->Packet.len = PKT_CMD_BIT | 2; |
1797 | CmdBlkP->PostFuncP = RIOUnUse; | 1683 | CmdBlkP->PostFuncP = RIOUnUse; |
1798 | CmdBlkP->PostArg = (int)PortP; | 1684 | CmdBlkP->PostArg = (int) PortP; |
1799 | PktCmdP->Command = Cmd; | 1685 | PktCmdP->Command = Cmd; |
1800 | port = PortP->HostPort % (ushort)PORTS_PER_RTA; | 1686 | port = PortP->HostPort % (ushort) PORTS_PER_RTA; |
1801 | /* | 1687 | /* |
1802 | ** Index ports 8-15 for 2nd block of 16 port RTA. | 1688 | ** Index ports 8-15 for 2nd block of 16 port RTA. |
1803 | */ | 1689 | */ |
1804 | if (PortP->SecondBlock) | 1690 | if (PortP->SecondBlock) |
1805 | port += (ushort) PORTS_PER_RTA; | 1691 | port += (ushort) PORTS_PER_RTA; |
1806 | PktCmdP->PhbNum = port; | 1692 | PktCmdP->PhbNum = port; |
1807 | 1693 | ||
1808 | switch ( Cmd ) { | 1694 | switch (Cmd) { |
1809 | case MEMDUMP: | 1695 | case MEMDUMP: |
1810 | rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n", | 1696 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n", (int) CmdBlkP, (int) SubCmd.Addr); |
1811 | (int)CmdBlkP, (int)SubCmd.Addr); | 1697 | PktCmdP->SubCommand = MEMDUMP; |
1812 | PktCmdP->SubCommand = MEMDUMP; | 1698 | PktCmdP->SubAddr = SubCmd.Addr; |
1813 | PktCmdP->SubAddr = SubCmd.Addr; | 1699 | break; |
1814 | break; | 1700 | case FCLOSE: |
1815 | case FCLOSE: | 1701 | rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n", (int) CmdBlkP); |
1816 | rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP); | 1702 | break; |
1817 | break; | 1703 | case READ_REGISTER: |
1818 | case READ_REGISTER: | 1704 | rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n", (int) SubCmd.Addr, (int) CmdBlkP); |
1819 | rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n", | 1705 | PktCmdP->SubCommand = READ_REGISTER; |
1820 | (int)SubCmd.Addr, (int)CmdBlkP); | 1706 | PktCmdP->SubAddr = SubCmd.Addr; |
1821 | PktCmdP->SubCommand = READ_REGISTER; | 1707 | break; |
1822 | PktCmdP->SubAddr = SubCmd.Addr; | 1708 | case RESUME: |
1823 | break; | 1709 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n", (int) CmdBlkP); |
1824 | case RESUME: | 1710 | break; |
1825 | rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP); | 1711 | case RFLUSH: |
1826 | break; | 1712 | rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n", (int) CmdBlkP); |
1827 | case RFLUSH: | 1713 | CmdBlkP->PostFuncP = RIORFlushEnable; |
1828 | rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP); | 1714 | break; |
1829 | CmdBlkP->PostFuncP = RIORFlushEnable; | 1715 | case SUSPEND: |
1830 | break; | 1716 | rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n", (int) CmdBlkP); |
1831 | case SUSPEND: | 1717 | break; |
1832 | rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP); | 1718 | |
1833 | break; | 1719 | case MGET: |
1834 | 1720 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int) CmdBlkP); | |
1835 | case MGET : | 1721 | break; |
1836 | rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP); | 1722 | |
1837 | break; | 1723 | case MSET: |
1838 | 1724 | case MBIC: | |
1839 | case MSET : | 1725 | case MBIS: |
1840 | case MBIC : | 1726 | CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; |
1841 | case MBIS : | 1727 | rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int) CmdBlkP); |
1842 | CmdBlkP->Packet.data[4] = (char) PortP->ModemLines; | 1728 | break; |
1843 | rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP); | 1729 | |
1844 | break; | 1730 | case WFLUSH: |
1845 | 1731 | /* | |
1846 | case WFLUSH: | 1732 | ** If we have queued up the maximum number of Write flushes |
1847 | /* | 1733 | ** allowed then we should not bother sending any more to the |
1848 | ** If we have queued up the maximum number of Write flushes | 1734 | ** RTA. |
1849 | ** allowed then we should not bother sending any more to the | 1735 | */ |
1850 | ** RTA. | 1736 | if ((int) ((char) PortP->WflushFlag) == (int) -1) { |
1851 | */ | 1737 | rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!"); |
1852 | if ((int)((char)PortP->WflushFlag) == (int)-1) { | 1738 | RIOFreeCmdBlk(CmdBlkP); |
1853 | rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!"); | 1739 | return (RIO_FAIL); |
1854 | RIOFreeCmdBlk(CmdBlkP); | 1740 | } else { |
1855 | return(RIO_FAIL); | 1741 | rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n", (int) CmdBlkP); |
1856 | } else { | 1742 | CmdBlkP->PostFuncP = RIOWFlushMark; |
1857 | rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n", | 1743 | } |
1858 | (int)CmdBlkP); | 1744 | break; |
1859 | CmdBlkP->PostFuncP = RIOWFlushMark; | ||
1860 | } | ||
1861 | break; | ||
1862 | } | 1745 | } |
1863 | 1746 | ||
1864 | PortP->InUse++; | 1747 | PortP->InUse++; |
1865 | 1748 | ||
1866 | Ret = RIOQueueCmdBlk( PortP->HostP, rup, CmdBlkP ); | 1749 | Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP); |
1867 | 1750 | ||
1868 | return Ret; | 1751 | return Ret; |
1869 | } | 1752 | } |