rioctrl.c 47 KB

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