rioctrl.c 47 KB

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