rioctrl.c 47 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  1. /*
  2. ** -----------------------------------------------------------------------------
  3. **
  4. ** Perle Specialix driver for Linux
  5. ** Ported from existing RIO Driver for SCO sources.
  6. *
  7. * (C) 1990 - 2000 Specialix International Ltd., Byfleet, Surrey, UK.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program; if not, write to the Free Software
  21. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22. **
  23. ** Module : rioctrl.c
  24. ** SID : 1.3
  25. ** Last Modified : 11/6/98 10:33:42
  26. ** Retrieved : 11/6/98 10:33:49
  27. **
  28. ** ident @(#)rioctrl.c 1.3
  29. **
  30. ** -----------------------------------------------------------------------------
  31. */
  32. #include <linux/module.h>
  33. #include <linux/sched.h>
  34. #include <linux/slab.h>
  35. #include <linux/errno.h>
  36. #include <asm/io.h>
  37. #include <asm/system.h>
  38. #include <asm/string.h>
  39. #include <asm/uaccess.h>
  40. #include <linux/termios.h>
  41. #include <linux/serial.h>
  42. #include <linux/generic_serial.h>
  43. #include "linux_compat.h"
  44. #include "rio_linux.h"
  45. #include "pkt.h"
  46. #include "daemon.h"
  47. #include "rio.h"
  48. #include "riospace.h"
  49. #include "cmdpkt.h"
  50. #include "map.h"
  51. #include "rup.h"
  52. #include "port.h"
  53. #include "riodrvr.h"
  54. #include "rioinfo.h"
  55. #include "func.h"
  56. #include "errors.h"
  57. #include "pci.h"
  58. #include "parmmap.h"
  59. #include "unixrup.h"
  60. #include "board.h"
  61. #include "host.h"
  62. #include "phb.h"
  63. #include "link.h"
  64. #include "cmdblk.h"
  65. #include "route.h"
  66. #include "cirrus.h"
  67. #include "rioioctl.h"
  68. static struct LpbReq LpbReq;
  69. static struct RupReq RupReq;
  70. static struct PortReq PortReq;
  71. static struct HostReq HostReq; /* oh really? global? and no locking? */
  72. static struct HostDpRam HostDpRam;
  73. static struct DebugCtrl DebugCtrl;
  74. static struct Map MapEnt;
  75. static struct PortSetup PortSetup;
  76. static struct DownLoad DownLoad;
  77. static struct SendPack SendPack;
  78. /* static struct StreamInfo StreamInfo; */
  79. /* static char modemtable[RIO_PORTS]; */
  80. static struct SpecialRupCmd SpecialRupCmd;
  81. static struct PortParams PortParams;
  82. static struct portStats portStats;
  83. static struct SubCmdStruct {
  84. ushort Host;
  85. ushort Rup;
  86. ushort Port;
  87. ushort Addr;
  88. } SubCmd;
  89. struct PortTty {
  90. uint port;
  91. struct ttystatics Tty;
  92. };
  93. static struct PortTty PortTty;
  94. typedef struct ttystatics TERMIO;
  95. /*
  96. ** This table is used when the config.rio downloads bin code to the
  97. ** driver. We index the table using the product code, 0-F, and call
  98. ** the function pointed to by the entry, passing the information
  99. ** about the boot.
  100. ** The RIOBootCodeUNKNOWN entry is there to politely tell the calling
  101. ** process to bog off.
  102. */
  103. static int
  104. (*RIOBootTable[MAX_PRODUCT]) (struct rio_info *, struct DownLoad *) = {
  105. /* 0 */ RIOBootCodeHOST,
  106. /* Host Card */
  107. /* 1 */ RIOBootCodeRTA,
  108. /* RTA */
  109. };
  110. #define drv_makedev(maj, min) ((((uint) maj & 0xff) << 8) | ((uint) min & 0xff))
  111. static int copy_from_io(void __user *to, void __iomem *from, size_t size)
  112. {
  113. void *buf = kmalloc(size, GFP_KERNEL);
  114. int res = -ENOMEM;
  115. if (buf) {
  116. rio_memcpy_fromio(buf, from, size);
  117. res = copy_to_user(to, buf, size);
  118. kfree(buf);
  119. }
  120. return res;
  121. }
  122. int riocontrol(struct rio_info *p, dev_t dev, int cmd, unsigned long arg, int su)
  123. {
  124. uint Host; /* leave me unsigned! */
  125. uint port; /* and me! */
  126. struct Host *HostP;
  127. ushort loop;
  128. int Entry;
  129. struct Port *PortP;
  130. struct PKT __iomem *PacketP;
  131. int retval = 0;
  132. unsigned long flags;
  133. void __user *argp = (void __user *)arg;
  134. func_enter();
  135. /* Confuse the compiler to think that we've initialized these */
  136. Host = 0;
  137. PortP = NULL;
  138. rio_dprintk(RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: %p\n", cmd, argp);
  139. switch (cmd) {
  140. /*
  141. ** RIO_SET_TIMER
  142. **
  143. ** Change the value of the host card interrupt timer.
  144. ** If the host card number is -1 then all host cards are changed
  145. ** otherwise just the specified host card will be changed.
  146. */
  147. case RIO_SET_TIMER:
  148. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_TIMER to %ldms\n", arg);
  149. {
  150. int host, value;
  151. host = (arg >> 16) & 0x0000FFFF;
  152. value = arg & 0x0000ffff;
  153. if (host == -1) {
  154. for (host = 0; host < p->RIONumHosts; host++) {
  155. if (p->RIOHosts[host].Flags == RC_RUNNING) {
  156. writew(value, &p->RIOHosts[host].ParmMapP->timer);
  157. }
  158. }
  159. } else if (host >= p->RIONumHosts) {
  160. return -EINVAL;
  161. } else {
  162. if (p->RIOHosts[host].Flags == RC_RUNNING) {
  163. writew(value, &p->RIOHosts[host].ParmMapP->timer);
  164. }
  165. }
  166. }
  167. return 0;
  168. case RIO_FOAD_RTA:
  169. rio_dprintk(RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
  170. return RIOCommandRta(p, arg, RIOFoadRta);
  171. case RIO_ZOMBIE_RTA:
  172. rio_dprintk(RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
  173. return RIOCommandRta(p, arg, RIOZombieRta);
  174. case RIO_IDENTIFY_RTA:
  175. rio_dprintk(RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
  176. return RIOIdentifyRta(p, argp);
  177. case RIO_KILL_NEIGHBOUR:
  178. rio_dprintk(RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
  179. return RIOKillNeighbour(p, argp);
  180. case SPECIAL_RUP_CMD:
  181. {
  182. struct CmdBlk *CmdBlkP;
  183. rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
  184. if (copy_from_user(&SpecialRupCmd, argp, sizeof(SpecialRupCmd))) {
  185. rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
  186. p->RIOError.Error = COPYIN_FAILED;
  187. return -EFAULT;
  188. }
  189. CmdBlkP = RIOGetCmdBlk();
  190. if (!CmdBlkP) {
  191. rio_dprintk(RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n");
  192. return -ENXIO;
  193. }
  194. CmdBlkP->Packet = SpecialRupCmd.Packet;
  195. if (SpecialRupCmd.Host >= p->RIONumHosts)
  196. SpecialRupCmd.Host = 0;
  197. rio_dprintk(RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n", SpecialRupCmd.Host, SpecialRupCmd.RupNum);
  198. if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
  199. printk(KERN_WARNING "rio: FAILED TO QUEUE SPECIAL RUP COMMAND\n");
  200. }
  201. return 0;
  202. }
  203. case RIO_DEBUG_MEM:
  204. return -EPERM;
  205. case RIO_ALL_MODEM:
  206. rio_dprintk(RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
  207. p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
  208. return -EINVAL;
  209. case RIO_GET_TABLE:
  210. /*
  211. ** Read the routing table from the device driver to user space
  212. */
  213. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
  214. if ((retval = RIOApel(p)) != 0)
  215. return retval;
  216. if (copy_to_user(argp, p->RIOConnectTable, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
  217. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
  218. p->RIOError.Error = COPYOUT_FAILED;
  219. return -EFAULT;
  220. }
  221. {
  222. int entry;
  223. rio_dprintk(RIO_DEBUG_CTRL, "*****\nMAP ENTRIES\n");
  224. for (entry = 0; entry < TOTAL_MAP_ENTRIES; entry++) {
  225. if ((p->RIOConnectTable[entry].ID == 0) && (p->RIOConnectTable[entry].HostUniqueNum == 0) && (p->RIOConnectTable[entry].RtaUniqueNum == 0))
  226. continue;
  227. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum);
  228. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum);
  229. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID);
  230. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2);
  231. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int) p->RIOConnectTable[entry].Flags);
  232. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int) p->RIOConnectTable[entry].SysPort);
  233. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit);
  234. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link);
  235. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit);
  236. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link);
  237. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit);
  238. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link);
  239. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit);
  240. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link);
  241. rio_dprintk(RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name);
  242. }
  243. rio_dprintk(RIO_DEBUG_CTRL, "*****\nEND MAP ENTRIES\n");
  244. }
  245. p->RIOQuickCheck = NOT_CHANGED; /* a table has been gotten */
  246. return 0;
  247. case RIO_PUT_TABLE:
  248. /*
  249. ** Write the routing table to the device driver from user space
  250. */
  251. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
  252. if (!su) {
  253. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
  254. p->RIOError.Error = NOT_SUPER_USER;
  255. return -EPERM;
  256. }
  257. if (copy_from_user(&p->RIOConnectTable[0], argp, TOTAL_MAP_ENTRIES * sizeof(struct Map))) {
  258. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
  259. p->RIOError.Error = COPYIN_FAILED;
  260. return -EFAULT;
  261. }
  262. /*
  263. ***********************************
  264. {
  265. int entry;
  266. rio_dprint(RIO_DEBUG_CTRL, ("*****\nMAP ENTRIES\n") );
  267. for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
  268. {
  269. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
  270. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
  271. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
  272. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
  273. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Flags = 0x%x\n", entry, p->RIOConnectTable[entry].Flags ) );
  274. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.SysPort = 0x%x\n", entry, p->RIOConnectTable[entry].SysPort ) );
  275. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
  276. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[0].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
  277. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
  278. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[1].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
  279. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
  280. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[2].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
  281. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[3].Unit = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
  282. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Top[4].Link = %b\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
  283. rio_dprint(RIO_DEBUG_CTRL, ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
  284. }
  285. rio_dprint(RIO_DEBUG_CTRL, ("*****\nEND MAP ENTRIES\n") );
  286. }
  287. ***********************************
  288. */
  289. return RIONewTable(p);
  290. case RIO_GET_BINDINGS:
  291. /*
  292. ** Send bindings table, containing unique numbers of RTAs owned
  293. ** by this system to user space
  294. */
  295. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
  296. if (!su) {
  297. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
  298. p->RIOError.Error = NOT_SUPER_USER;
  299. return -EPERM;
  300. }
  301. if (copy_to_user(argp, p->RIOBindTab, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
  302. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
  303. p->RIOError.Error = COPYOUT_FAILED;
  304. return -EFAULT;
  305. }
  306. return 0;
  307. case RIO_PUT_BINDINGS:
  308. /*
  309. ** Receive a bindings table, containing unique numbers of RTAs owned
  310. ** by this system
  311. */
  312. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
  313. if (!su) {
  314. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
  315. p->RIOError.Error = NOT_SUPER_USER;
  316. return -EPERM;
  317. }
  318. if (copy_from_user(&p->RIOBindTab[0], argp, (sizeof(ulong) * MAX_RTA_BINDINGS))) {
  319. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
  320. p->RIOError.Error = COPYIN_FAILED;
  321. return -EFAULT;
  322. }
  323. return 0;
  324. case RIO_BIND_RTA:
  325. {
  326. int EmptySlot = -1;
  327. /*
  328. ** Bind this RTA to host, so that it will be booted by
  329. ** host in 'boot owned RTAs' mode.
  330. */
  331. rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
  332. if (!su) {
  333. rio_dprintk(RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
  334. p->RIOError.Error = NOT_SUPER_USER;
  335. return -EPERM;
  336. }
  337. for (Entry = 0; Entry < MAX_RTA_BINDINGS; Entry++) {
  338. if ((EmptySlot == -1) && (p->RIOBindTab[Entry] == 0L))
  339. EmptySlot = Entry;
  340. else if (p->RIOBindTab[Entry] == arg) {
  341. /*
  342. ** Already exists - delete
  343. */
  344. p->RIOBindTab[Entry] = 0L;
  345. rio_dprintk(RIO_DEBUG_CTRL, "Removing Rta %ld from p->RIOBindTab\n", arg);
  346. return 0;
  347. }
  348. }
  349. /*
  350. ** Dosen't exist - add
  351. */
  352. if (EmptySlot != -1) {
  353. p->RIOBindTab[EmptySlot] = arg;
  354. rio_dprintk(RIO_DEBUG_CTRL, "Adding Rta %lx to p->RIOBindTab\n", arg);
  355. } else {
  356. rio_dprintk(RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %lx not added\n", arg);
  357. return -ENOMEM;
  358. }
  359. return 0;
  360. }
  361. case RIO_RESUME:
  362. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME\n");
  363. port = arg;
  364. if ((port < 0) || (port > 511)) {
  365. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
  366. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  367. return -EINVAL;
  368. }
  369. PortP = p->RIOPortp[port];
  370. if (!PortP->Mapped) {
  371. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
  372. p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
  373. return -EINVAL;
  374. }
  375. if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
  376. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
  377. return -EINVAL;
  378. }
  379. rio_spin_lock_irqsave(&PortP->portSem, flags);
  380. if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RIOC_RESUME) ==
  381. RIO_FAIL) {
  382. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
  383. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  384. return -EBUSY;
  385. } else {
  386. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
  387. PortP->State |= RIO_BUSY;
  388. }
  389. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  390. return retval;
  391. case RIO_ASSIGN_RTA:
  392. rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
  393. if (!su) {
  394. rio_dprintk(RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
  395. p->RIOError.Error = NOT_SUPER_USER;
  396. return -EPERM;
  397. }
  398. if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
  399. rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
  400. p->RIOError.Error = COPYIN_FAILED;
  401. return -EFAULT;
  402. }
  403. return RIOAssignRta(p, &MapEnt);
  404. case RIO_CHANGE_NAME:
  405. rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
  406. if (!su) {
  407. rio_dprintk(RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
  408. p->RIOError.Error = NOT_SUPER_USER;
  409. return -EPERM;
  410. }
  411. if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
  412. rio_dprintk(RIO_DEBUG_CTRL, "Copy from user space failed\n");
  413. p->RIOError.Error = COPYIN_FAILED;
  414. return -EFAULT;
  415. }
  416. return RIOChangeName(p, &MapEnt);
  417. case RIO_DELETE_RTA:
  418. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
  419. if (!su) {
  420. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
  421. p->RIOError.Error = NOT_SUPER_USER;
  422. return -EPERM;
  423. }
  424. if (copy_from_user(&MapEnt, argp, sizeof(MapEnt))) {
  425. rio_dprintk(RIO_DEBUG_CTRL, "Copy from data space failed\n");
  426. p->RIOError.Error = COPYIN_FAILED;
  427. return -EFAULT;
  428. }
  429. return RIODeleteRta(p, &MapEnt);
  430. case RIO_QUICK_CHECK:
  431. if (copy_to_user(argp, &p->RIORtaDisCons, sizeof(unsigned int))) {
  432. p->RIOError.Error = COPYOUT_FAILED;
  433. return -EFAULT;
  434. }
  435. return 0;
  436. case RIO_LAST_ERROR:
  437. if (copy_to_user(argp, &p->RIOError, sizeof(struct Error)))
  438. return -EFAULT;
  439. return 0;
  440. case RIO_GET_LOG:
  441. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
  442. return -EINVAL;
  443. case RIO_GET_MODTYPE:
  444. if (copy_from_user(&port, argp, sizeof(unsigned int))) {
  445. p->RIOError.Error = COPYIN_FAILED;
  446. return -EFAULT;
  447. }
  448. rio_dprintk(RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
  449. if (port < 0 || port > 511) {
  450. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
  451. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  452. return -EINVAL;
  453. }
  454. PortP = (p->RIOPortp[port]);
  455. if (!PortP->Mapped) {
  456. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
  457. p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
  458. return -EINVAL;
  459. }
  460. /*
  461. ** Return module type of port
  462. */
  463. port = PortP->HostP->UnixRups[PortP->RupNum].ModTypes;
  464. if (copy_to_user(argp, &port, sizeof(unsigned int))) {
  465. p->RIOError.Error = COPYOUT_FAILED;
  466. return -EFAULT;
  467. }
  468. return (0);
  469. case RIO_BLOCK_OPENS:
  470. rio_dprintk(RIO_DEBUG_CTRL, "Opens block until booted\n");
  471. for (Entry = 0; Entry < RIO_PORTS; Entry++) {
  472. rio_spin_lock_irqsave(&PortP->portSem, flags);
  473. p->RIOPortp[Entry]->WaitUntilBooted = 1;
  474. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  475. }
  476. return 0;
  477. case RIO_SETUP_PORTS:
  478. rio_dprintk(RIO_DEBUG_CTRL, "Setup ports\n");
  479. if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
  480. p->RIOError.Error = COPYIN_FAILED;
  481. rio_dprintk(RIO_DEBUG_CTRL, "EFAULT");
  482. return -EFAULT;
  483. }
  484. if (PortSetup.From > PortSetup.To || PortSetup.To >= RIO_PORTS) {
  485. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  486. rio_dprintk(RIO_DEBUG_CTRL, "ENXIO");
  487. return -ENXIO;
  488. }
  489. if (PortSetup.XpCps > p->RIOConf.MaxXpCps || PortSetup.XpCps < p->RIOConf.MinXpCps) {
  490. p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
  491. rio_dprintk(RIO_DEBUG_CTRL, "EINVAL");
  492. return -EINVAL;
  493. }
  494. if (!p->RIOPortp) {
  495. printk(KERN_ERR "rio: No p->RIOPortp array!\n");
  496. rio_dprintk(RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
  497. return -EIO;
  498. }
  499. rio_dprintk(RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
  500. for (loop = PortSetup.From; loop <= PortSetup.To; loop++) {
  501. rio_dprintk(RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
  502. }
  503. rio_dprintk(RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
  504. rio_dprintk(RIO_DEBUG_CTRL, "Retval:%x\n", retval);
  505. return retval;
  506. case RIO_GET_PORT_SETUP:
  507. rio_dprintk(RIO_DEBUG_CTRL, "Get port setup\n");
  508. if (copy_from_user(&PortSetup, argp, sizeof(PortSetup))) {
  509. p->RIOError.Error = COPYIN_FAILED;
  510. return -EFAULT;
  511. }
  512. if (PortSetup.From >= RIO_PORTS) {
  513. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  514. return -ENXIO;
  515. }
  516. port = PortSetup.To = PortSetup.From;
  517. PortSetup.IxAny = (p->RIOPortp[port]->Config & RIO_IXANY) ? 1 : 0;
  518. PortSetup.IxOn = (p->RIOPortp[port]->Config & RIO_IXON) ? 1 : 0;
  519. PortSetup.Drain = (p->RIOPortp[port]->Config & RIO_WAITDRAIN) ? 1 : 0;
  520. PortSetup.Store = p->RIOPortp[port]->Store;
  521. PortSetup.Lock = p->RIOPortp[port]->Lock;
  522. PortSetup.XpCps = p->RIOPortp[port]->Xprint.XpCps;
  523. memcpy(PortSetup.XpOn, p->RIOPortp[port]->Xprint.XpOn, MAX_XP_CTRL_LEN);
  524. memcpy(PortSetup.XpOff, p->RIOPortp[port]->Xprint.XpOff, MAX_XP_CTRL_LEN);
  525. PortSetup.XpOn[MAX_XP_CTRL_LEN - 1] = '\0';
  526. PortSetup.XpOff[MAX_XP_CTRL_LEN - 1] = '\0';
  527. if (copy_to_user(argp, &PortSetup, sizeof(PortSetup))) {
  528. p->RIOError.Error = COPYOUT_FAILED;
  529. return -EFAULT;
  530. }
  531. return retval;
  532. case RIO_GET_PORT_PARAMS:
  533. rio_dprintk(RIO_DEBUG_CTRL, "Get port params\n");
  534. if (copy_from_user(&PortParams, argp, sizeof(struct PortParams))) {
  535. p->RIOError.Error = COPYIN_FAILED;
  536. return -EFAULT;
  537. }
  538. if (PortParams.Port >= RIO_PORTS) {
  539. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  540. return -ENXIO;
  541. }
  542. PortP = (p->RIOPortp[PortParams.Port]);
  543. PortParams.Config = PortP->Config;
  544. PortParams.State = PortP->State;
  545. rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
  546. if (copy_to_user(argp, &PortParams, sizeof(struct PortParams))) {
  547. p->RIOError.Error = COPYOUT_FAILED;
  548. return -EFAULT;
  549. }
  550. return retval;
  551. case RIO_GET_PORT_TTY:
  552. rio_dprintk(RIO_DEBUG_CTRL, "Get port tty\n");
  553. if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
  554. p->RIOError.Error = COPYIN_FAILED;
  555. return -EFAULT;
  556. }
  557. if (PortTty.port >= RIO_PORTS) {
  558. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  559. return -ENXIO;
  560. }
  561. rio_dprintk(RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
  562. PortP = (p->RIOPortp[PortTty.port]);
  563. if (copy_to_user(argp, &PortTty, sizeof(struct PortTty))) {
  564. p->RIOError.Error = COPYOUT_FAILED;
  565. return -EFAULT;
  566. }
  567. return retval;
  568. case RIO_SET_PORT_TTY:
  569. if (copy_from_user(&PortTty, argp, sizeof(struct PortTty))) {
  570. p->RIOError.Error = COPYIN_FAILED;
  571. return -EFAULT;
  572. }
  573. rio_dprintk(RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
  574. if (PortTty.port >= (ushort) RIO_PORTS) {
  575. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  576. return -ENXIO;
  577. }
  578. PortP = (p->RIOPortp[PortTty.port]);
  579. RIOParam(PortP, RIOC_CONFIG, PortP->State & RIO_MODEM,
  580. OK_TO_SLEEP);
  581. return retval;
  582. case RIO_SET_PORT_PARAMS:
  583. rio_dprintk(RIO_DEBUG_CTRL, "Set port params\n");
  584. if (copy_from_user(&PortParams, argp, sizeof(PortParams))) {
  585. p->RIOError.Error = COPYIN_FAILED;
  586. return -EFAULT;
  587. }
  588. if (PortParams.Port >= (ushort) RIO_PORTS) {
  589. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  590. return -ENXIO;
  591. }
  592. PortP = (p->RIOPortp[PortParams.Port]);
  593. rio_spin_lock_irqsave(&PortP->portSem, flags);
  594. PortP->Config = PortParams.Config;
  595. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  596. return retval;
  597. case RIO_GET_PORT_STATS:
  598. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
  599. if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
  600. p->RIOError.Error = COPYIN_FAILED;
  601. return -EFAULT;
  602. }
  603. if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
  604. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  605. return -ENXIO;
  606. }
  607. PortP = (p->RIOPortp[portStats.port]);
  608. portStats.gather = PortP->statsGather;
  609. portStats.txchars = PortP->txchars;
  610. portStats.rxchars = PortP->rxchars;
  611. portStats.opens = PortP->opens;
  612. portStats.closes = PortP->closes;
  613. portStats.ioctls = PortP->ioctls;
  614. if (copy_to_user(argp, &portStats, sizeof(struct portStats))) {
  615. p->RIOError.Error = COPYOUT_FAILED;
  616. return -EFAULT;
  617. }
  618. return retval;
  619. case RIO_RESET_PORT_STATS:
  620. port = arg;
  621. rio_dprintk(RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
  622. if (port >= RIO_PORTS) {
  623. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  624. return -ENXIO;
  625. }
  626. PortP = (p->RIOPortp[port]);
  627. rio_spin_lock_irqsave(&PortP->portSem, flags);
  628. PortP->txchars = 0;
  629. PortP->rxchars = 0;
  630. PortP->opens = 0;
  631. PortP->closes = 0;
  632. PortP->ioctls = 0;
  633. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  634. return retval;
  635. case RIO_GATHER_PORT_STATS:
  636. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
  637. if (copy_from_user(&portStats, argp, sizeof(struct portStats))) {
  638. p->RIOError.Error = COPYIN_FAILED;
  639. return -EFAULT;
  640. }
  641. if (portStats.port < 0 || portStats.port >= RIO_PORTS) {
  642. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  643. return -ENXIO;
  644. }
  645. PortP = (p->RIOPortp[portStats.port]);
  646. rio_spin_lock_irqsave(&PortP->portSem, flags);
  647. PortP->statsGather = portStats.gather;
  648. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  649. return retval;
  650. case RIO_READ_CONFIG:
  651. rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
  652. if (copy_to_user(argp, &p->RIOConf, sizeof(struct Conf))) {
  653. p->RIOError.Error = COPYOUT_FAILED;
  654. return -EFAULT;
  655. }
  656. return retval;
  657. case RIO_SET_CONFIG:
  658. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
  659. if (!su) {
  660. p->RIOError.Error = NOT_SUPER_USER;
  661. return -EPERM;
  662. }
  663. if (copy_from_user(&p->RIOConf, argp, sizeof(struct Conf))) {
  664. p->RIOError.Error = COPYIN_FAILED;
  665. return -EFAULT;
  666. }
  667. /*
  668. ** move a few value around
  669. */
  670. for (Host = 0; Host < p->RIONumHosts; Host++)
  671. if ((p->RIOHosts[Host].Flags & RUN_STATE) == RC_RUNNING)
  672. writew(p->RIOConf.Timer, &p->RIOHosts[Host].ParmMapP->timer);
  673. return retval;
  674. case RIO_START_POLLER:
  675. rio_dprintk(RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
  676. return -EINVAL;
  677. case RIO_STOP_POLLER:
  678. rio_dprintk(RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
  679. if (!su) {
  680. p->RIOError.Error = NOT_SUPER_USER;
  681. return -EPERM;
  682. }
  683. p->RIOPolling = NOT_POLLING;
  684. return retval;
  685. case RIO_SETDEBUG:
  686. case RIO_GETDEBUG:
  687. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
  688. if (copy_from_user(&DebugCtrl, argp, sizeof(DebugCtrl))) {
  689. p->RIOError.Error = COPYIN_FAILED;
  690. return -EFAULT;
  691. }
  692. if (DebugCtrl.SysPort == NO_PORT) {
  693. if (cmd == RIO_SETDEBUG) {
  694. if (!su) {
  695. p->RIOError.Error = NOT_SUPER_USER;
  696. return -EPERM;
  697. }
  698. p->rio_debug = DebugCtrl.Debug;
  699. p->RIODebugWait = DebugCtrl.Wait;
  700. rio_dprintk(RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n", p->rio_debug, p->RIODebugWait);
  701. } else {
  702. rio_dprintk(RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n", p->rio_debug, p->RIODebugWait);
  703. DebugCtrl.Debug = p->rio_debug;
  704. DebugCtrl.Wait = p->RIODebugWait;
  705. if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
  706. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
  707. p->RIOError.Error = COPYOUT_FAILED;
  708. return -EFAULT;
  709. }
  710. }
  711. } else if (DebugCtrl.SysPort >= RIO_PORTS && DebugCtrl.SysPort != NO_PORT) {
  712. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n", DebugCtrl.SysPort);
  713. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  714. return -ENXIO;
  715. } else if (cmd == RIO_SETDEBUG) {
  716. if (!su) {
  717. p->RIOError.Error = NOT_SUPER_USER;
  718. return -EPERM;
  719. }
  720. rio_spin_lock_irqsave(&PortP->portSem, flags);
  721. p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
  722. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  723. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
  724. } else {
  725. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n", p->RIOPortp[DebugCtrl.SysPort]->Debug);
  726. DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
  727. if (copy_to_user(argp, &DebugCtrl, sizeof(DebugCtrl))) {
  728. rio_dprintk(RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
  729. p->RIOError.Error = COPYOUT_FAILED;
  730. return -EFAULT;
  731. }
  732. }
  733. return retval;
  734. case RIO_VERSID:
  735. /*
  736. ** Enquire about the release and version.
  737. ** We return MAX_VERSION_LEN bytes, being a
  738. ** textual null terminated string.
  739. */
  740. rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID\n");
  741. if (copy_to_user(argp, RIOVersid(), sizeof(struct rioVersion))) {
  742. rio_dprintk(RIO_DEBUG_CTRL, "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
  743. p->RIOError.Error = COPYOUT_FAILED;
  744. return -EFAULT;
  745. }
  746. return retval;
  747. case RIO_NUM_HOSTS:
  748. /*
  749. ** Enquire as to the number of hosts located
  750. ** at init time.
  751. */
  752. rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
  753. if (copy_to_user(argp, &p->RIONumHosts, sizeof(p->RIONumHosts))) {
  754. rio_dprintk(RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
  755. p->RIOError.Error = COPYOUT_FAILED;
  756. return -EFAULT;
  757. }
  758. return retval;
  759. case RIO_HOST_FOAD:
  760. /*
  761. ** Kill host. This may not be in the final version...
  762. */
  763. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD %ld\n", arg);
  764. if (!su) {
  765. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
  766. p->RIOError.Error = NOT_SUPER_USER;
  767. return -EPERM;
  768. }
  769. p->RIOHalted = 1;
  770. p->RIOSystemUp = 0;
  771. for (Host = 0; Host < p->RIONumHosts; Host++) {
  772. (void) RIOBoardTest(p->RIOHosts[Host].PaddrP, p->RIOHosts[Host].Caddr, p->RIOHosts[Host].Type, p->RIOHosts[Host].Slot);
  773. memset(&p->RIOHosts[Host].Flags, 0, ((char *) &p->RIOHosts[Host].____end_marker____) - ((char *) &p->RIOHosts[Host].Flags));
  774. p->RIOHosts[Host].Flags = RC_WAITING;
  775. }
  776. RIOFoadWakeup(p);
  777. p->RIONumBootPkts = 0;
  778. p->RIOBooting = 0;
  779. printk("HEEEEELP!\n");
  780. for (loop = 0; loop < RIO_PORTS; loop++) {
  781. spin_lock_init(&p->RIOPortp[loop]->portSem);
  782. p->RIOPortp[loop]->InUse = NOT_INUSE;
  783. }
  784. p->RIOSystemUp = 0;
  785. return retval;
  786. case RIO_DOWNLOAD:
  787. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
  788. if (!su) {
  789. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
  790. p->RIOError.Error = NOT_SUPER_USER;
  791. return -EPERM;
  792. }
  793. if (copy_from_user(&DownLoad, argp, sizeof(DownLoad))) {
  794. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
  795. p->RIOError.Error = COPYIN_FAILED;
  796. return -EFAULT;
  797. }
  798. rio_dprintk(RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n", DownLoad.ProductCode);
  799. /*
  800. ** It is important that the product code is an unsigned object!
  801. */
  802. if (DownLoad.ProductCode >= MAX_PRODUCT) {
  803. rio_dprintk(RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n", DownLoad.ProductCode);
  804. p->RIOError.Error = NO_SUCH_PRODUCT;
  805. return -ENXIO;
  806. }
  807. /*
  808. ** do something!
  809. */
  810. retval = (*(RIOBootTable[DownLoad.ProductCode])) (p, &DownLoad);
  811. /* <-- Panic */
  812. p->RIOHalted = 0;
  813. /*
  814. ** and go back, content with a job well completed.
  815. */
  816. return retval;
  817. case RIO_PARMS:
  818. {
  819. unsigned int host;
  820. if (copy_from_user(&host, argp, sizeof(host))) {
  821. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
  822. p->RIOError.Error = COPYIN_FAILED;
  823. return -EFAULT;
  824. }
  825. /*
  826. ** Fetch the parmmap
  827. */
  828. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS\n");
  829. if (copy_from_io(argp, p->RIOHosts[host].ParmMapP, sizeof(PARM_MAP))) {
  830. p->RIOError.Error = COPYOUT_FAILED;
  831. rio_dprintk(RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
  832. return -EFAULT;
  833. }
  834. }
  835. return retval;
  836. case RIO_HOST_REQ:
  837. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
  838. if (copy_from_user(&HostReq, argp, sizeof(HostReq))) {
  839. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
  840. p->RIOError.Error = COPYIN_FAILED;
  841. return -EFAULT;
  842. }
  843. if (HostReq.HostNum >= p->RIONumHosts) {
  844. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  845. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n", HostReq.HostNum);
  846. return -ENXIO;
  847. }
  848. rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
  849. if (copy_to_user(HostReq.HostP, &p->RIOHosts[HostReq.HostNum], sizeof(struct Host))) {
  850. p->RIOError.Error = COPYOUT_FAILED;
  851. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
  852. return -EFAULT;
  853. }
  854. return retval;
  855. case RIO_HOST_DPRAM:
  856. rio_dprintk(RIO_DEBUG_CTRL, "Request for DPRAM\n");
  857. if (copy_from_user(&HostDpRam, argp, sizeof(HostDpRam))) {
  858. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
  859. p->RIOError.Error = COPYIN_FAILED;
  860. return -EFAULT;
  861. }
  862. if (HostDpRam.HostNum >= p->RIONumHosts) {
  863. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  864. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n", HostDpRam.HostNum);
  865. return -ENXIO;
  866. }
  867. rio_dprintk(RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
  868. if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
  869. int off;
  870. /* It's hardware like this that really gets on my tits. */
  871. static unsigned char copy[sizeof(struct DpRam)];
  872. for (off = 0; off < sizeof(struct DpRam); off++)
  873. copy[off] = readb(p->RIOHosts[HostDpRam.HostNum].Caddr + off);
  874. if (copy_to_user(HostDpRam.DpRamP, copy, sizeof(struct DpRam))) {
  875. p->RIOError.Error = COPYOUT_FAILED;
  876. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
  877. return -EFAULT;
  878. }
  879. } else if (copy_from_io(HostDpRam.DpRamP, p->RIOHosts[HostDpRam.HostNum].Caddr, sizeof(struct DpRam))) {
  880. p->RIOError.Error = COPYOUT_FAILED;
  881. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
  882. return -EFAULT;
  883. }
  884. return retval;
  885. case RIO_SET_BUSY:
  886. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
  887. if (arg > 511) {
  888. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %ld\n", arg);
  889. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  890. return -EINVAL;
  891. }
  892. rio_spin_lock_irqsave(&PortP->portSem, flags);
  893. p->RIOPortp[arg]->State |= RIO_BUSY;
  894. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  895. return retval;
  896. case RIO_HOST_PORT:
  897. /*
  898. ** The daemon want port information
  899. ** (probably for debug reasons)
  900. */
  901. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
  902. if (copy_from_user(&PortReq, argp, sizeof(PortReq))) {
  903. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
  904. p->RIOError.Error = COPYIN_FAILED;
  905. return -EFAULT;
  906. }
  907. if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
  908. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n", PortReq.SysPort);
  909. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  910. return -ENXIO;
  911. }
  912. rio_dprintk(RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
  913. if (copy_to_user(PortReq.PortP, p->RIOPortp[PortReq.SysPort], sizeof(struct Port))) {
  914. p->RIOError.Error = COPYOUT_FAILED;
  915. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
  916. return -EFAULT;
  917. }
  918. return retval;
  919. case RIO_HOST_RUP:
  920. /*
  921. ** The daemon want rup information
  922. ** (probably for debug reasons)
  923. */
  924. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
  925. if (copy_from_user(&RupReq, argp, sizeof(RupReq))) {
  926. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
  927. p->RIOError.Error = COPYIN_FAILED;
  928. return -EFAULT;
  929. }
  930. if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
  931. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n", RupReq.HostNum);
  932. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  933. return -ENXIO;
  934. }
  935. if (RupReq.RupNum >= MAX_RUP + LINKS_PER_UNIT) { /* eek! */
  936. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n", RupReq.RupNum);
  937. p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  938. return -EINVAL;
  939. }
  940. HostP = &p->RIOHosts[RupReq.HostNum];
  941. if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
  942. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n", RupReq.HostNum);
  943. p->RIOError.Error = HOST_NOT_RUNNING;
  944. return -EIO;
  945. }
  946. rio_dprintk(RIO_DEBUG_CTRL, "Request for rup %d from host %d\n", RupReq.RupNum, RupReq.HostNum);
  947. if (copy_from_io(RupReq.RupP, HostP->UnixRups[RupReq.RupNum].RupP, sizeof(struct RUP))) {
  948. p->RIOError.Error = COPYOUT_FAILED;
  949. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
  950. return -EFAULT;
  951. }
  952. return retval;
  953. case RIO_HOST_LPB:
  954. /*
  955. ** The daemon want lpb information
  956. ** (probably for debug reasons)
  957. */
  958. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
  959. if (copy_from_user(&LpbReq, argp, sizeof(LpbReq))) {
  960. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
  961. p->RIOError.Error = COPYIN_FAILED;
  962. return -EFAULT;
  963. }
  964. if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
  965. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n", LpbReq.Host);
  966. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  967. return -ENXIO;
  968. }
  969. if (LpbReq.Link >= LINKS_PER_UNIT) { /* eek! */
  970. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n", LpbReq.Link);
  971. p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
  972. return -EINVAL;
  973. }
  974. HostP = &p->RIOHosts[LpbReq.Host];
  975. if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
  976. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n", LpbReq.Host);
  977. p->RIOError.Error = HOST_NOT_RUNNING;
  978. return -EIO;
  979. }
  980. rio_dprintk(RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n", LpbReq.Link, LpbReq.Host);
  981. if (copy_from_io(LpbReq.LpbP, &HostP->LinkStrP[LpbReq.Link], sizeof(struct LPB))) {
  982. rio_dprintk(RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
  983. p->RIOError.Error = COPYOUT_FAILED;
  984. return -EFAULT;
  985. }
  986. return retval;
  987. /*
  988. ** Here 3 IOCTL's that allow us to change the way in which
  989. ** rio logs errors. send them just to syslog or send them
  990. ** to both syslog and console or send them to just the console.
  991. **
  992. ** See RioStrBuf() in util.c for the other half.
  993. */
  994. case RIO_SYSLOG_ONLY:
  995. p->RIOPrintLogState = PRINT_TO_LOG; /* Just syslog */
  996. return 0;
  997. case RIO_SYSLOG_CONS:
  998. p->RIOPrintLogState = PRINT_TO_LOG_CONS; /* syslog and console */
  999. return 0;
  1000. case RIO_CONS_ONLY:
  1001. p->RIOPrintLogState = PRINT_TO_CONS; /* Just console */
  1002. return 0;
  1003. case RIO_SIGNALS_ON:
  1004. if (p->RIOSignalProcess) {
  1005. p->RIOError.Error = SIGNALS_ALREADY_SET;
  1006. return -EBUSY;
  1007. }
  1008. /* FIXME: PID tracking */
  1009. p->RIOSignalProcess = current->pid;
  1010. p->RIOPrintDisabled = DONT_PRINT;
  1011. return retval;
  1012. case RIO_SIGNALS_OFF:
  1013. if (p->RIOSignalProcess != current->pid) {
  1014. p->RIOError.Error = NOT_RECEIVING_PROCESS;
  1015. return -EPERM;
  1016. }
  1017. rio_dprintk(RIO_DEBUG_CTRL, "Clear signal process to zero\n");
  1018. p->RIOSignalProcess = 0;
  1019. return retval;
  1020. case RIO_SET_BYTE_MODE:
  1021. for (Host = 0; Host < p->RIONumHosts; Host++)
  1022. if (p->RIOHosts[Host].Type == RIO_AT)
  1023. p->RIOHosts[Host].Mode &= ~WORD_OPERATION;
  1024. return retval;
  1025. case RIO_SET_WORD_MODE:
  1026. for (Host = 0; Host < p->RIONumHosts; Host++)
  1027. if (p->RIOHosts[Host].Type == RIO_AT)
  1028. p->RIOHosts[Host].Mode |= WORD_OPERATION;
  1029. return retval;
  1030. case RIO_SET_FAST_BUS:
  1031. for (Host = 0; Host < p->RIONumHosts; Host++)
  1032. if (p->RIOHosts[Host].Type == RIO_AT)
  1033. p->RIOHosts[Host].Mode |= FAST_AT_BUS;
  1034. return retval;
  1035. case RIO_SET_SLOW_BUS:
  1036. for (Host = 0; Host < p->RIONumHosts; Host++)
  1037. if (p->RIOHosts[Host].Type == RIO_AT)
  1038. p->RIOHosts[Host].Mode &= ~FAST_AT_BUS;
  1039. return retval;
  1040. case RIO_MAP_B50_TO_50:
  1041. case RIO_MAP_B50_TO_57600:
  1042. case RIO_MAP_B110_TO_110:
  1043. case RIO_MAP_B110_TO_115200:
  1044. rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping\n");
  1045. port = arg;
  1046. if (port < 0 || port > 511) {
  1047. rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
  1048. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1049. return -EINVAL;
  1050. }
  1051. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1052. switch (cmd) {
  1053. case RIO_MAP_B50_TO_50:
  1054. p->RIOPortp[port]->Config |= RIO_MAP_50_TO_50;
  1055. break;
  1056. case RIO_MAP_B50_TO_57600:
  1057. p->RIOPortp[port]->Config &= ~RIO_MAP_50_TO_50;
  1058. break;
  1059. case RIO_MAP_B110_TO_110:
  1060. p->RIOPortp[port]->Config |= RIO_MAP_110_TO_110;
  1061. break;
  1062. case RIO_MAP_B110_TO_115200:
  1063. p->RIOPortp[port]->Config &= ~RIO_MAP_110_TO_110;
  1064. break;
  1065. }
  1066. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1067. return retval;
  1068. case RIO_STREAM_INFO:
  1069. rio_dprintk(RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
  1070. return -EINVAL;
  1071. case RIO_SEND_PACKET:
  1072. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
  1073. if (copy_from_user(&SendPack, argp, sizeof(SendPack))) {
  1074. rio_dprintk(RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
  1075. p->RIOError.Error = COPYIN_FAILED;
  1076. return -EFAULT;
  1077. }
  1078. if (SendPack.PortNum >= 128) {
  1079. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1080. return -ENXIO;
  1081. }
  1082. PortP = p->RIOPortp[SendPack.PortNum];
  1083. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1084. if (!can_add_transmit(&PacketP, PortP)) {
  1085. p->RIOError.Error = UNIT_IS_IN_USE;
  1086. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1087. return -ENOSPC;
  1088. }
  1089. for (loop = 0; loop < (ushort) (SendPack.Len & 127); loop++)
  1090. writeb(SendPack.Data[loop], &PacketP->data[loop]);
  1091. writeb(SendPack.Len, &PacketP->len);
  1092. add_transmit(PortP);
  1093. /*
  1094. ** Count characters transmitted for port statistics reporting
  1095. */
  1096. if (PortP->statsGather)
  1097. PortP->txchars += (SendPack.Len & 127);
  1098. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1099. return retval;
  1100. case RIO_NO_MESG:
  1101. if (su)
  1102. p->RIONoMessage = 1;
  1103. return su ? 0 : -EPERM;
  1104. case RIO_MESG:
  1105. if (su)
  1106. p->RIONoMessage = 0;
  1107. return su ? 0 : -EPERM;
  1108. case RIO_WHAT_MESG:
  1109. if (copy_to_user(argp, &p->RIONoMessage, sizeof(p->RIONoMessage))) {
  1110. rio_dprintk(RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
  1111. p->RIOError.Error = COPYOUT_FAILED;
  1112. return -EFAULT;
  1113. }
  1114. return 0;
  1115. case RIO_MEM_DUMP:
  1116. if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
  1117. p->RIOError.Error = COPYIN_FAILED;
  1118. return -EFAULT;
  1119. }
  1120. rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
  1121. if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) {
  1122. p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  1123. return -EINVAL;
  1124. }
  1125. if (SubCmd.Host >= p->RIONumHosts) {
  1126. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1127. return -EINVAL;
  1128. }
  1129. port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort;
  1130. PortP = p->RIOPortp[port];
  1131. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1132. if (RIOPreemptiveCmd(p, PortP, RIOC_MEMDUMP) == RIO_FAIL) {
  1133. rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
  1134. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1135. return -EBUSY;
  1136. } else
  1137. PortP->State |= RIO_BUSY;
  1138. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1139. if (copy_to_user(argp, p->RIOMemDump, MEMDUMP_SIZE)) {
  1140. rio_dprintk(RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
  1141. p->RIOError.Error = COPYOUT_FAILED;
  1142. return -EFAULT;
  1143. }
  1144. return 0;
  1145. case RIO_TICK:
  1146. if (arg >= p->RIONumHosts)
  1147. return -EINVAL;
  1148. rio_dprintk(RIO_DEBUG_CTRL, "Set interrupt for host %ld\n", arg);
  1149. writeb(0xFF, &p->RIOHosts[arg].SetInt);
  1150. return 0;
  1151. case RIO_TOCK:
  1152. if (arg >= p->RIONumHosts)
  1153. return -EINVAL;
  1154. rio_dprintk(RIO_DEBUG_CTRL, "Clear interrupt for host %ld\n", arg);
  1155. writeb(0xFF, &p->RIOHosts[arg].ResetInt);
  1156. return 0;
  1157. case RIO_READ_CHECK:
  1158. /* Check reads for pkts with data[0] the same */
  1159. p->RIOReadCheck = !p->RIOReadCheck;
  1160. if (copy_to_user(argp, &p->RIOReadCheck, sizeof(unsigned int))) {
  1161. p->RIOError.Error = COPYOUT_FAILED;
  1162. return -EFAULT;
  1163. }
  1164. return 0;
  1165. case RIO_READ_REGISTER:
  1166. if (copy_from_user(&SubCmd, argp, sizeof(struct SubCmdStruct))) {
  1167. p->RIOError.Error = COPYIN_FAILED;
  1168. return -EFAULT;
  1169. }
  1170. 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);
  1171. if (SubCmd.Port > 511) {
  1172. rio_dprintk(RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", SubCmd.Port);
  1173. p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
  1174. return -EINVAL;
  1175. }
  1176. if (SubCmd.Rup >= MAX_RUP + LINKS_PER_UNIT) {
  1177. p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
  1178. return -EINVAL;
  1179. }
  1180. if (SubCmd.Host >= p->RIONumHosts) {
  1181. p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
  1182. return -EINVAL;
  1183. }
  1184. port = p->RIOHosts[SubCmd.Host].UnixRups[SubCmd.Rup].BaseSysPort + SubCmd.Port;
  1185. PortP = p->RIOPortp[port];
  1186. rio_spin_lock_irqsave(&PortP->portSem, flags);
  1187. if (RIOPreemptiveCmd(p, PortP, RIOC_READ_REGISTER) ==
  1188. RIO_FAIL) {
  1189. rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
  1190. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1191. return -EBUSY;
  1192. } else
  1193. PortP->State |= RIO_BUSY;
  1194. rio_spin_unlock_irqrestore(&PortP->portSem, flags);
  1195. if (copy_to_user(argp, &p->CdRegister, sizeof(unsigned int))) {
  1196. rio_dprintk(RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
  1197. p->RIOError.Error = COPYOUT_FAILED;
  1198. return -EFAULT;
  1199. }
  1200. return 0;
  1201. /*
  1202. ** rio_make_dev: given port number (0-511) ORed with port type
  1203. ** (RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT) return dev_t
  1204. ** value to pass to mknod to create the correct device node.
  1205. */
  1206. case RIO_MAKE_DEV:
  1207. {
  1208. unsigned int port = arg & RIO_MODEM_MASK;
  1209. unsigned int ret;
  1210. switch (arg & RIO_DEV_MASK) {
  1211. case RIO_DEV_DIRECT:
  1212. ret = drv_makedev(MAJOR(dev), port);
  1213. rio_dprintk(RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n", port, ret);
  1214. return ret;
  1215. case RIO_DEV_MODEM:
  1216. ret = drv_makedev(MAJOR(dev), (port | RIO_MODEM_BIT));
  1217. rio_dprintk(RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n", port, ret);
  1218. return ret;
  1219. case RIO_DEV_XPRINT:
  1220. ret = drv_makedev(MAJOR(dev), port);
  1221. rio_dprintk(RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n", port, ret);
  1222. return ret;
  1223. }
  1224. rio_dprintk(RIO_DEBUG_CTRL, "MAKE Device is called\n");
  1225. return -EINVAL;
  1226. }
  1227. /*
  1228. ** rio_minor: given a dev_t from a stat() call, return
  1229. ** the port number (0-511) ORed with the port type
  1230. ** ( RIO_DEV_DIRECT, RIO_DEV_MODEM, RIO_DEV_XPRINT )
  1231. */
  1232. case RIO_MINOR:
  1233. {
  1234. dev_t dv;
  1235. int mino;
  1236. unsigned long ret;
  1237. dv = (dev_t) (arg);
  1238. mino = RIO_UNMODEM(dv);
  1239. if (RIO_ISMODEM(dv)) {
  1240. rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
  1241. ret = mino | RIO_DEV_MODEM;
  1242. } else {
  1243. rio_dprintk(RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
  1244. ret = mino | RIO_DEV_DIRECT;
  1245. }
  1246. return ret;
  1247. }
  1248. }
  1249. rio_dprintk(RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n", cmd);
  1250. p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
  1251. func_exit();
  1252. return -EINVAL;
  1253. }
  1254. /*
  1255. ** Pre-emptive commands go on RUPs and are only one byte long.
  1256. */
  1257. int RIOPreemptiveCmd(struct rio_info *p, struct Port *PortP, u8 Cmd)
  1258. {
  1259. struct CmdBlk *CmdBlkP;
  1260. struct PktCmd_M *PktCmdP;
  1261. int Ret;
  1262. ushort rup;
  1263. int port;
  1264. if (PortP->State & RIO_DELETED) {
  1265. rio_dprintk(RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
  1266. return RIO_FAIL;
  1267. }
  1268. if ((PortP->InUse == (typeof(PortP->InUse))-1) ||
  1269. !(CmdBlkP = RIOGetCmdBlk())) {
  1270. rio_dprintk(RIO_DEBUG_CTRL, "Cannot allocate command block "
  1271. "for command %d on port %d\n", Cmd, PortP->PortNum);
  1272. return RIO_FAIL;
  1273. }
  1274. rio_dprintk(RIO_DEBUG_CTRL, "Command blk %p - InUse now %d\n",
  1275. CmdBlkP, PortP->InUse);
  1276. PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
  1277. CmdBlkP->Packet.src_unit = 0;
  1278. if (PortP->SecondBlock)
  1279. rup = PortP->ID2;
  1280. else
  1281. rup = PortP->RupNum;
  1282. CmdBlkP->Packet.dest_unit = rup;
  1283. CmdBlkP->Packet.src_port = COMMAND_RUP;
  1284. CmdBlkP->Packet.dest_port = COMMAND_RUP;
  1285. CmdBlkP->Packet.len = PKT_CMD_BIT | 2;
  1286. CmdBlkP->PostFuncP = RIOUnUse;
  1287. CmdBlkP->PostArg = (unsigned long) PortP;
  1288. PktCmdP->Command = Cmd;
  1289. port = PortP->HostPort % (ushort) PORTS_PER_RTA;
  1290. /*
  1291. ** Index ports 8-15 for 2nd block of 16 port RTA.
  1292. */
  1293. if (PortP->SecondBlock)
  1294. port += (ushort) PORTS_PER_RTA;
  1295. PktCmdP->PhbNum = port;
  1296. switch (Cmd) {
  1297. case RIOC_MEMDUMP:
  1298. rio_dprintk(RIO_DEBUG_CTRL, "Queue MEMDUMP command blk %p "
  1299. "(addr 0x%x)\n", CmdBlkP, (int) SubCmd.Addr);
  1300. PktCmdP->SubCommand = RIOC_MEMDUMP;
  1301. PktCmdP->SubAddr = SubCmd.Addr;
  1302. break;
  1303. case RIOC_FCLOSE:
  1304. rio_dprintk(RIO_DEBUG_CTRL, "Queue FCLOSE command blk %p\n",
  1305. CmdBlkP);
  1306. break;
  1307. case RIOC_READ_REGISTER:
  1308. rio_dprintk(RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) "
  1309. "command blk %p\n", (int) SubCmd.Addr, CmdBlkP);
  1310. PktCmdP->SubCommand = RIOC_READ_REGISTER;
  1311. PktCmdP->SubAddr = SubCmd.Addr;
  1312. break;
  1313. case RIOC_RESUME:
  1314. rio_dprintk(RIO_DEBUG_CTRL, "Queue RESUME command blk %p\n",
  1315. CmdBlkP);
  1316. break;
  1317. case RIOC_RFLUSH:
  1318. rio_dprintk(RIO_DEBUG_CTRL, "Queue RFLUSH command blk %p\n",
  1319. CmdBlkP);
  1320. CmdBlkP->PostFuncP = RIORFlushEnable;
  1321. break;
  1322. case RIOC_SUSPEND:
  1323. rio_dprintk(RIO_DEBUG_CTRL, "Queue SUSPEND command blk %p\n",
  1324. CmdBlkP);
  1325. break;
  1326. case RIOC_MGET:
  1327. rio_dprintk(RIO_DEBUG_CTRL, "Queue MGET command blk %p\n",
  1328. CmdBlkP);
  1329. break;
  1330. case RIOC_MSET:
  1331. case RIOC_MBIC:
  1332. case RIOC_MBIS:
  1333. CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
  1334. rio_dprintk(RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command "
  1335. "blk %p\n", CmdBlkP);
  1336. break;
  1337. case RIOC_WFLUSH:
  1338. /*
  1339. ** If we have queued up the maximum number of Write flushes
  1340. ** allowed then we should not bother sending any more to the
  1341. ** RTA.
  1342. */
  1343. if (PortP->WflushFlag == (typeof(PortP->WflushFlag))-1) {
  1344. rio_dprintk(RIO_DEBUG_CTRL, "Trashed WFLUSH, "
  1345. "WflushFlag about to wrap!");
  1346. RIOFreeCmdBlk(CmdBlkP);
  1347. return (RIO_FAIL);
  1348. } else {
  1349. rio_dprintk(RIO_DEBUG_CTRL, "Queue WFLUSH command "
  1350. "blk %p\n", CmdBlkP);
  1351. CmdBlkP->PostFuncP = RIOWFlushMark;
  1352. }
  1353. break;
  1354. }
  1355. PortP->InUse++;
  1356. Ret = RIOQueueCmdBlk(PortP->HostP, rup, CmdBlkP);
  1357. return Ret;
  1358. }