viocons.c 31 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195
  1. /* -*- linux-c -*-
  2. *
  3. * drivers/char/viocons.c
  4. *
  5. * iSeries Virtual Terminal
  6. *
  7. * Authors: Dave Boutcher <boutcher@us.ibm.com>
  8. * Ryan Arnold <ryanarn@us.ibm.com>
  9. * Colin Devilbiss <devilbis@us.ibm.com>
  10. * Stephen Rothwell <sfr@au1.ibm.com>
  11. *
  12. * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation
  13. *
  14. * This program is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU General Public License as
  16. * published by the Free Software Foundation; either version 2 of the
  17. * License, or (at your option) anyu later version.
  18. *
  19. * This program is distributed in the hope that it will be useful, but
  20. * WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. * General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU General Public License
  25. * along with this program; if not, write to the Free Software Foundation,
  26. * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  27. */
  28. #include <linux/config.h>
  29. #include <linux/version.h>
  30. #include <linux/kernel.h>
  31. #include <linux/proc_fs.h>
  32. #include <linux/errno.h>
  33. #include <linux/vmalloc.h>
  34. #include <linux/mm.h>
  35. #include <linux/console.h>
  36. #include <linux/module.h>
  37. #include <asm/uaccess.h>
  38. #include <linux/init.h>
  39. #include <linux/wait.h>
  40. #include <linux/spinlock.h>
  41. #include <asm/ioctls.h>
  42. #include <linux/kd.h>
  43. #include <linux/tty.h>
  44. #include <linux/tty_flip.h>
  45. #include <linux/sysrq.h>
  46. #include <asm/iSeries/vio.h>
  47. #include <asm/iSeries/HvLpEvent.h>
  48. #include <asm/iSeries/HvCallEvent.h>
  49. #include <asm/iSeries/HvLpConfig.h>
  50. #include <asm/iSeries/HvCall.h>
  51. #ifdef CONFIG_VT
  52. #error You must turn off CONFIG_VT to use CONFIG_VIOCONS
  53. #endif
  54. #define VIOTTY_MAGIC (0x0DCB)
  55. #define VTTY_PORTS 10
  56. #define VIOCONS_KERN_WARN KERN_WARNING "viocons: "
  57. #define VIOCONS_KERN_INFO KERN_INFO "viocons: "
  58. static DEFINE_SPINLOCK(consolelock);
  59. static DEFINE_SPINLOCK(consoleloglock);
  60. #ifdef CONFIG_MAGIC_SYSRQ
  61. static int vio_sysrq_pressed;
  62. extern int sysrq_enabled;
  63. #endif
  64. /*
  65. * The structure of the events that flow between us and OS/400. You can't
  66. * mess with this unless the OS/400 side changes too
  67. */
  68. struct viocharlpevent {
  69. struct HvLpEvent event;
  70. u32 reserved;
  71. u16 version;
  72. u16 subtype_result_code;
  73. u8 virtual_device;
  74. u8 len;
  75. u8 data[VIOCHAR_MAX_DATA];
  76. };
  77. #define VIOCHAR_WINDOW 10
  78. #define VIOCHAR_HIGHWATERMARK 3
  79. enum viocharsubtype {
  80. viocharopen = 0x0001,
  81. viocharclose = 0x0002,
  82. viochardata = 0x0003,
  83. viocharack = 0x0004,
  84. viocharconfig = 0x0005
  85. };
  86. enum viochar_rc {
  87. viochar_rc_ebusy = 1
  88. };
  89. #define VIOCHAR_NUM_BUF 16
  90. /*
  91. * Our port information. We store a pointer to one entry in the
  92. * tty_driver_data
  93. */
  94. static struct port_info {
  95. int magic;
  96. struct tty_struct *tty;
  97. HvLpIndex lp;
  98. u8 vcons;
  99. u64 seq; /* sequence number of last HV send */
  100. u64 ack; /* last ack from HV */
  101. /*
  102. * When we get writes faster than we can send it to the partition,
  103. * buffer the data here. Note that used is a bit map of used buffers.
  104. * It had better have enough bits to hold VIOCHAR_NUM_BUF the bitops assume
  105. * it is a multiple of unsigned long
  106. */
  107. unsigned long used;
  108. u8 *buffer[VIOCHAR_NUM_BUF];
  109. int bufferBytes[VIOCHAR_NUM_BUF];
  110. int curbuf;
  111. int bufferOverflow;
  112. int overflowMessage;
  113. } port_info[VTTY_PORTS];
  114. #define viochar_is_console(pi) ((pi) == &port_info[0])
  115. #define viochar_port(pi) ((pi) - &port_info[0])
  116. static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp);
  117. static struct tty_driver *viotty_driver;
  118. void hvlog(char *fmt, ...)
  119. {
  120. int i;
  121. unsigned long flags;
  122. va_list args;
  123. static char buf[256];
  124. spin_lock_irqsave(&consoleloglock, flags);
  125. va_start(args, fmt);
  126. i = vscnprintf(buf, sizeof(buf) - 1, fmt, args);
  127. va_end(args);
  128. buf[i++] = '\r';
  129. HvCall_writeLogBuffer(buf, i);
  130. spin_unlock_irqrestore(&consoleloglock, flags);
  131. }
  132. void hvlogOutput(const char *buf, int count)
  133. {
  134. unsigned long flags;
  135. int begin;
  136. int index;
  137. static const char cr = '\r';
  138. begin = 0;
  139. spin_lock_irqsave(&consoleloglock, flags);
  140. for (index = 0; index < count; index++) {
  141. if (buf[index] == '\n') {
  142. /*
  143. * Start right after the last '\n' or at the zeroth
  144. * array position and output the number of characters
  145. * including the newline.
  146. */
  147. HvCall_writeLogBuffer(&buf[begin], index - begin + 1);
  148. begin = index + 1;
  149. HvCall_writeLogBuffer(&cr, 1);
  150. }
  151. }
  152. if ((index - begin) > 0)
  153. HvCall_writeLogBuffer(&buf[begin], index - begin);
  154. spin_unlock_irqrestore(&consoleloglock, flags);
  155. }
  156. /*
  157. * Make sure we're pointing to a valid port_info structure. Shamelessly
  158. * plagerized from serial.c
  159. */
  160. static inline int viotty_paranoia_check(struct port_info *pi,
  161. char *name, const char *routine)
  162. {
  163. static const char *bad_pi_addr = VIOCONS_KERN_WARN
  164. "warning: bad address for port_info struct (%s) in %s\n";
  165. static const char *badmagic = VIOCONS_KERN_WARN
  166. "warning: bad magic number for port_info struct (%s) in %s\n";
  167. if ((pi < &port_info[0]) || (viochar_port(pi) > VTTY_PORTS)) {
  168. printk(bad_pi_addr, name, routine);
  169. return 1;
  170. }
  171. if (pi->magic != VIOTTY_MAGIC) {
  172. printk(badmagic, name, routine);
  173. return 1;
  174. }
  175. return 0;
  176. }
  177. /*
  178. * Add data to our pending-send buffers.
  179. *
  180. * NOTE: Don't use printk in here because it gets nastily recursive.
  181. * hvlog can be used to log to the hypervisor buffer
  182. */
  183. static int buffer_add(struct port_info *pi, const char *buf, size_t len)
  184. {
  185. size_t bleft;
  186. size_t curlen;
  187. const char *curbuf;
  188. int nextbuf;
  189. curbuf = buf;
  190. bleft = len;
  191. while (bleft > 0) {
  192. /*
  193. * If there is no space left in the current buffer, we have
  194. * filled everything up, so return. If we filled the previous
  195. * buffer we would already have moved to the next one.
  196. */
  197. if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
  198. hvlog ("\n\rviocons: No overflow buffer available for memcpy().\n");
  199. pi->bufferOverflow++;
  200. pi->overflowMessage = 1;
  201. break;
  202. }
  203. /*
  204. * Turn on the "used" bit for this buffer. If it's already on,
  205. * that's fine.
  206. */
  207. set_bit(pi->curbuf, &pi->used);
  208. /*
  209. * See if this buffer has been allocated. If not, allocate it.
  210. */
  211. if (pi->buffer[pi->curbuf] == NULL) {
  212. pi->buffer[pi->curbuf] =
  213. kmalloc(VIOCHAR_MAX_DATA, GFP_ATOMIC);
  214. if (pi->buffer[pi->curbuf] == NULL) {
  215. hvlog("\n\rviocons: kmalloc failed allocating spaces for buffer %d.",
  216. pi->curbuf);
  217. break;
  218. }
  219. }
  220. /* Figure out how much we can copy into this buffer. */
  221. if (bleft < (VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf]))
  222. curlen = bleft;
  223. else
  224. curlen = VIOCHAR_MAX_DATA - pi->bufferBytes[pi->curbuf];
  225. /* Copy the data into the buffer. */
  226. memcpy(pi->buffer[pi->curbuf] + pi->bufferBytes[pi->curbuf],
  227. curbuf, curlen);
  228. pi->bufferBytes[pi->curbuf] += curlen;
  229. curbuf += curlen;
  230. bleft -= curlen;
  231. /*
  232. * Now see if we've filled this buffer. If not then
  233. * we'll try to use it again later. If we've filled it
  234. * up then we'll advance the curbuf to the next in the
  235. * circular queue.
  236. */
  237. if (pi->bufferBytes[pi->curbuf] == VIOCHAR_MAX_DATA) {
  238. nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;
  239. /*
  240. * Move to the next buffer if it hasn't been used yet
  241. */
  242. if (test_bit(nextbuf, &pi->used) == 0)
  243. pi->curbuf = nextbuf;
  244. }
  245. }
  246. return len - bleft;
  247. }
  248. /*
  249. * Send pending data
  250. *
  251. * NOTE: Don't use printk in here because it gets nastily recursive.
  252. * hvlog can be used to log to the hypervisor buffer
  253. */
  254. static void send_buffers(struct port_info *pi)
  255. {
  256. HvLpEvent_Rc hvrc;
  257. int nextbuf;
  258. struct viocharlpevent *viochar;
  259. unsigned long flags;
  260. spin_lock_irqsave(&consolelock, flags);
  261. viochar = (struct viocharlpevent *)
  262. vio_get_event_buffer(viomajorsubtype_chario);
  263. /* Make sure we got a buffer */
  264. if (viochar == NULL) {
  265. hvlog("\n\rviocons: Can't get viochar buffer in sendBuffers().");
  266. spin_unlock_irqrestore(&consolelock, flags);
  267. return;
  268. }
  269. if (pi->used == 0) {
  270. hvlog("\n\rviocons: in sendbuffers(), but no buffers used.\n");
  271. vio_free_event_buffer(viomajorsubtype_chario, viochar);
  272. spin_unlock_irqrestore(&consolelock, flags);
  273. return;
  274. }
  275. /*
  276. * curbuf points to the buffer we're filling. We want to
  277. * start sending AFTER this one.
  278. */
  279. nextbuf = (pi->curbuf + 1) % VIOCHAR_NUM_BUF;
  280. /*
  281. * Loop until we find a buffer with the used bit on
  282. */
  283. while (test_bit(nextbuf, &pi->used) == 0)
  284. nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;
  285. initDataEvent(viochar, pi->lp);
  286. /*
  287. * While we have buffers with data, and our send window
  288. * is open, send them
  289. */
  290. while ((test_bit(nextbuf, &pi->used)) &&
  291. ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
  292. viochar->len = pi->bufferBytes[nextbuf];
  293. viochar->event.xCorrelationToken = pi->seq++;
  294. viochar->event.xSizeMinus1 =
  295. offsetof(struct viocharlpevent, data) + viochar->len;
  296. memcpy(viochar->data, pi->buffer[nextbuf], viochar->len);
  297. hvrc = HvCallEvent_signalLpEvent(&viochar->event);
  298. if (hvrc) {
  299. /*
  300. * MUST unlock the spinlock before doing a printk
  301. */
  302. vio_free_event_buffer(viomajorsubtype_chario, viochar);
  303. spin_unlock_irqrestore(&consolelock, flags);
  304. printk(VIOCONS_KERN_WARN
  305. "error sending event! return code %d\n",
  306. (int)hvrc);
  307. return;
  308. }
  309. /*
  310. * clear the used bit, zero the number of bytes in
  311. * this buffer, and move to the next buffer
  312. */
  313. clear_bit(nextbuf, &pi->used);
  314. pi->bufferBytes[nextbuf] = 0;
  315. nextbuf = (nextbuf + 1) % VIOCHAR_NUM_BUF;
  316. }
  317. /*
  318. * If we have emptied all the buffers, start at 0 again.
  319. * this will re-use any allocated buffers
  320. */
  321. if (pi->used == 0) {
  322. pi->curbuf = 0;
  323. if (pi->overflowMessage)
  324. pi->overflowMessage = 0;
  325. if (pi->tty) {
  326. tty_wakeup(pi->tty);
  327. }
  328. }
  329. vio_free_event_buffer(viomajorsubtype_chario, viochar);
  330. spin_unlock_irqrestore(&consolelock, flags);
  331. }
  332. /*
  333. * Our internal writer. Gets called both from the console device and
  334. * the tty device. the tty pointer will be NULL if called from the console.
  335. * Return total number of bytes "written".
  336. *
  337. * NOTE: Don't use printk in here because it gets nastily recursive. hvlog
  338. * can be used to log to the hypervisor buffer
  339. */
  340. static int internal_write(struct port_info *pi, const char *buf, size_t len)
  341. {
  342. HvLpEvent_Rc hvrc;
  343. size_t bleft;
  344. size_t curlen;
  345. const char *curbuf;
  346. unsigned long flags;
  347. struct viocharlpevent *viochar;
  348. /*
  349. * Write to the hvlog of inbound data are now done prior to
  350. * calling internal_write() since internal_write() is only called in
  351. * the event that an lp event path is active, which isn't the case for
  352. * logging attempts prior to console initialization.
  353. *
  354. * If there is already data queued for this port, send it prior to
  355. * attempting to send any new data.
  356. */
  357. if (pi->used)
  358. send_buffers(pi);
  359. spin_lock_irqsave(&consolelock, flags);
  360. viochar = vio_get_event_buffer(viomajorsubtype_chario);
  361. if (viochar == NULL) {
  362. spin_unlock_irqrestore(&consolelock, flags);
  363. hvlog("\n\rviocons: Can't get vio buffer in internal_write().");
  364. return -EAGAIN;
  365. }
  366. initDataEvent(viochar, pi->lp);
  367. curbuf = buf;
  368. bleft = len;
  369. while ((bleft > 0) && (pi->used == 0) &&
  370. ((pi->seq - pi->ack) < VIOCHAR_WINDOW)) {
  371. if (bleft > VIOCHAR_MAX_DATA)
  372. curlen = VIOCHAR_MAX_DATA;
  373. else
  374. curlen = bleft;
  375. viochar->event.xCorrelationToken = pi->seq++;
  376. memcpy(viochar->data, curbuf, curlen);
  377. viochar->len = curlen;
  378. viochar->event.xSizeMinus1 =
  379. offsetof(struct viocharlpevent, data) + curlen;
  380. hvrc = HvCallEvent_signalLpEvent(&viochar->event);
  381. if (hvrc) {
  382. hvlog("viocons: error sending event! %d\n", (int)hvrc);
  383. goto out;
  384. }
  385. curbuf += curlen;
  386. bleft -= curlen;
  387. }
  388. /* If we didn't send it all, buffer as much of it as we can. */
  389. if (bleft > 0)
  390. bleft -= buffer_add(pi, curbuf, bleft);
  391. out:
  392. vio_free_event_buffer(viomajorsubtype_chario, viochar);
  393. spin_unlock_irqrestore(&consolelock, flags);
  394. return len - bleft;
  395. }
  396. static struct port_info *get_port_data(struct tty_struct *tty)
  397. {
  398. unsigned long flags;
  399. struct port_info *pi;
  400. spin_lock_irqsave(&consolelock, flags);
  401. if (tty) {
  402. pi = (struct port_info *)tty->driver_data;
  403. if (!pi || viotty_paranoia_check(pi, tty->name,
  404. "get_port_data")) {
  405. pi = NULL;
  406. }
  407. } else
  408. /*
  409. * If this is the console device, use the lp from
  410. * the first port entry
  411. */
  412. pi = &port_info[0];
  413. spin_unlock_irqrestore(&consolelock, flags);
  414. return pi;
  415. }
  416. /*
  417. * Initialize the common fields in a charLpEvent
  418. */
  419. static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
  420. {
  421. memset(viochar, 0, sizeof(struct viocharlpevent));
  422. viochar->event.xFlags.xValid = 1;
  423. viochar->event.xFlags.xFunction = HvLpEvent_Function_Int;
  424. viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck;
  425. viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck;
  426. viochar->event.xType = HvLpEvent_Type_VirtualIo;
  427. viochar->event.xSubtype = viomajorsubtype_chario | viochardata;
  428. viochar->event.xSourceLp = HvLpConfig_getLpIndex();
  429. viochar->event.xTargetLp = lp;
  430. viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent);
  431. viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
  432. viochar->event.xTargetInstanceId = viopath_targetinst(lp);
  433. }
  434. /*
  435. * early console device write
  436. */
  437. static void viocons_write_early(struct console *co, const char *s, unsigned count)
  438. {
  439. hvlogOutput(s, count);
  440. }
  441. /*
  442. * console device write
  443. */
  444. static void viocons_write(struct console *co, const char *s, unsigned count)
  445. {
  446. int index;
  447. int begin;
  448. struct port_info *pi;
  449. static const char cr = '\r';
  450. /*
  451. * Check port data first because the target LP might be valid but
  452. * simply not active, in which case we want to hvlog the output.
  453. */
  454. pi = get_port_data(NULL);
  455. if (pi == NULL) {
  456. hvlog("\n\rviocons_write: unable to get port data.");
  457. return;
  458. }
  459. hvlogOutput(s, count);
  460. if (!viopath_isactive(pi->lp))
  461. return;
  462. /*
  463. * Any newline character found will cause a
  464. * carriage return character to be emitted as well.
  465. */
  466. begin = 0;
  467. for (index = 0; index < count; index++) {
  468. if (s[index] == '\n') {
  469. /*
  470. * Newline found. Print everything up to and
  471. * including the newline
  472. */
  473. internal_write(pi, &s[begin], index - begin + 1);
  474. begin = index + 1;
  475. /* Emit a carriage return as well */
  476. internal_write(pi, &cr, 1);
  477. }
  478. }
  479. /* If any characters left to write, write them now */
  480. if ((index - begin) > 0)
  481. internal_write(pi, &s[begin], index - begin);
  482. }
  483. /*
  484. * Work out the device associate with this console
  485. */
  486. static struct tty_driver *viocons_device(struct console *c, int *index)
  487. {
  488. *index = c->index;
  489. return viotty_driver;
  490. }
  491. /*
  492. * console device I/O methods
  493. */
  494. static struct console viocons_early = {
  495. .name = "viocons",
  496. .write = viocons_write_early,
  497. .flags = CON_PRINTBUFFER,
  498. .index = -1,
  499. };
  500. static struct console viocons = {
  501. .name = "viocons",
  502. .write = viocons_write,
  503. .device = viocons_device,
  504. .flags = CON_PRINTBUFFER,
  505. .index = -1,
  506. };
  507. /*
  508. * TTY Open method
  509. */
  510. static int viotty_open(struct tty_struct *tty, struct file *filp)
  511. {
  512. int port;
  513. unsigned long flags;
  514. struct port_info *pi;
  515. port = tty->index;
  516. if ((port < 0) || (port >= VTTY_PORTS))
  517. return -ENODEV;
  518. spin_lock_irqsave(&consolelock, flags);
  519. pi = &port_info[port];
  520. /* If some other TTY is already connected here, reject the open */
  521. if ((pi->tty) && (pi->tty != tty)) {
  522. spin_unlock_irqrestore(&consolelock, flags);
  523. printk(VIOCONS_KERN_WARN
  524. "attempt to open device twice from different ttys\n");
  525. return -EBUSY;
  526. }
  527. tty->driver_data = pi;
  528. pi->tty = tty;
  529. spin_unlock_irqrestore(&consolelock, flags);
  530. return 0;
  531. }
  532. /*
  533. * TTY Close method
  534. */
  535. static void viotty_close(struct tty_struct *tty, struct file *filp)
  536. {
  537. unsigned long flags;
  538. struct port_info *pi;
  539. spin_lock_irqsave(&consolelock, flags);
  540. pi = (struct port_info *)tty->driver_data;
  541. if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_close")) {
  542. spin_unlock_irqrestore(&consolelock, flags);
  543. return;
  544. }
  545. if (tty->count == 1)
  546. pi->tty = NULL;
  547. spin_unlock_irqrestore(&consolelock, flags);
  548. }
  549. /*
  550. * TTY Write method
  551. */
  552. static int viotty_write(struct tty_struct *tty, const unsigned char *buf,
  553. int count)
  554. {
  555. struct port_info *pi;
  556. pi = get_port_data(tty);
  557. if (pi == NULL) {
  558. hvlog("\n\rviotty_write: no port data.");
  559. return -ENODEV;
  560. }
  561. if (viochar_is_console(pi))
  562. hvlogOutput(buf, count);
  563. /*
  564. * If the path to this LP is closed, don't bother doing anything more.
  565. * just dump the data on the floor and return count. For some reason
  566. * some user level programs will attempt to probe available tty's and
  567. * they'll attempt a viotty_write on an invalid port which maps to an
  568. * invalid target lp. If this is the case then ignore the
  569. * viotty_write call and, since the viopath isn't active to this
  570. * partition, return count.
  571. */
  572. if (!viopath_isactive(pi->lp))
  573. return count;
  574. return internal_write(pi, buf, count);
  575. }
  576. /*
  577. * TTY put_char method
  578. */
  579. static void viotty_put_char(struct tty_struct *tty, unsigned char ch)
  580. {
  581. struct port_info *pi;
  582. pi = get_port_data(tty);
  583. if (pi == NULL)
  584. return;
  585. /* This will append '\r' as well if the char is '\n' */
  586. if (viochar_is_console(pi))
  587. hvlogOutput(&ch, 1);
  588. if (viopath_isactive(pi->lp))
  589. internal_write(pi, &ch, 1);
  590. }
  591. /*
  592. * TTY write_room method
  593. */
  594. static int viotty_write_room(struct tty_struct *tty)
  595. {
  596. int i;
  597. int room = 0;
  598. struct port_info *pi;
  599. unsigned long flags;
  600. spin_lock_irqsave(&consolelock, flags);
  601. pi = (struct port_info *)tty->driver_data;
  602. if (!pi || viotty_paranoia_check(pi, tty->name, "viotty_write_room")) {
  603. spin_unlock_irqrestore(&consolelock, flags);
  604. return 0;
  605. }
  606. /* If no buffers are used, return the max size. */
  607. if (pi->used == 0) {
  608. spin_unlock_irqrestore(&consolelock, flags);
  609. return VIOCHAR_MAX_DATA * VIOCHAR_NUM_BUF;
  610. }
  611. /*
  612. * We retain the spinlock because we want to get an accurate
  613. * count and it can change on us between each operation if we
  614. * don't hold the spinlock.
  615. */
  616. for (i = 0; ((i < VIOCHAR_NUM_BUF) && (room < VIOCHAR_MAX_DATA)); i++)
  617. room += (VIOCHAR_MAX_DATA - pi->bufferBytes[i]);
  618. spin_unlock_irqrestore(&consolelock, flags);
  619. if (room > VIOCHAR_MAX_DATA)
  620. room = VIOCHAR_MAX_DATA;
  621. return room;
  622. }
  623. /*
  624. * TTY chars_in_buffer method
  625. */
  626. static int viotty_chars_in_buffer(struct tty_struct *tty)
  627. {
  628. return 0;
  629. }
  630. static int viotty_ioctl(struct tty_struct *tty, struct file *file,
  631. unsigned int cmd, unsigned long arg)
  632. {
  633. switch (cmd) {
  634. /*
  635. * the ioctls below read/set the flags usually shown in the leds
  636. * don't use them - they will go away without warning
  637. */
  638. case KDGETLED:
  639. case KDGKBLED:
  640. return put_user(0, (char *)arg);
  641. case KDSKBLED:
  642. return 0;
  643. }
  644. return n_tty_ioctl(tty, file, cmd, arg);
  645. }
  646. /*
  647. * Handle an open charLpEvent. Could be either interrupt or ack
  648. */
  649. static void vioHandleOpenEvent(struct HvLpEvent *event)
  650. {
  651. unsigned long flags;
  652. struct viocharlpevent *cevent = (struct viocharlpevent *)event;
  653. u8 port = cevent->virtual_device;
  654. struct port_info *pi;
  655. int reject = 0;
  656. if (event->xFlags.xFunction == HvLpEvent_Function_Ack) {
  657. if (port >= VTTY_PORTS)
  658. return;
  659. spin_lock_irqsave(&consolelock, flags);
  660. /* Got the lock, don't cause console output */
  661. pi = &port_info[port];
  662. if (event->xRc == HvLpEvent_Rc_Good) {
  663. pi->seq = pi->ack = 0;
  664. /*
  665. * This line allows connections from the primary
  666. * partition but once one is connected from the
  667. * primary partition nothing short of a reboot
  668. * of linux will allow access from the hosting
  669. * partition again without a required iSeries fix.
  670. */
  671. pi->lp = event->xTargetLp;
  672. }
  673. spin_unlock_irqrestore(&consolelock, flags);
  674. if (event->xRc != HvLpEvent_Rc_Good)
  675. printk(VIOCONS_KERN_WARN
  676. "handle_open_event: event->xRc == (%d).\n",
  677. event->xRc);
  678. if (event->xCorrelationToken != 0) {
  679. atomic_t *aptr= (atomic_t *)event->xCorrelationToken;
  680. atomic_set(aptr, 1);
  681. } else
  682. printk(VIOCONS_KERN_WARN
  683. "weird...got open ack without atomic\n");
  684. return;
  685. }
  686. /* This had better require an ack, otherwise complain */
  687. if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) {
  688. printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
  689. return;
  690. }
  691. spin_lock_irqsave(&consolelock, flags);
  692. /* Got the lock, don't cause console output */
  693. /* Make sure this is a good virtual tty */
  694. if (port >= VTTY_PORTS) {
  695. event->xRc = HvLpEvent_Rc_SubtypeError;
  696. cevent->subtype_result_code = viorc_openRejected;
  697. /*
  698. * Flag state here since we can't printk while holding
  699. * a spinlock.
  700. */
  701. reject = 1;
  702. } else {
  703. pi = &port_info[port];
  704. if ((pi->lp != HvLpIndexInvalid) &&
  705. (pi->lp != event->xSourceLp)) {
  706. /*
  707. * If this is tty is already connected to a different
  708. * partition, fail.
  709. */
  710. event->xRc = HvLpEvent_Rc_SubtypeError;
  711. cevent->subtype_result_code = viorc_openRejected;
  712. reject = 2;
  713. } else {
  714. pi->lp = event->xSourceLp;
  715. event->xRc = HvLpEvent_Rc_Good;
  716. cevent->subtype_result_code = viorc_good;
  717. pi->seq = pi->ack = 0;
  718. reject = 0;
  719. }
  720. }
  721. spin_unlock_irqrestore(&consolelock, flags);
  722. if (reject == 1)
  723. printk(VIOCONS_KERN_WARN "open rejected: bad virtual tty.\n");
  724. else if (reject == 2)
  725. printk(VIOCONS_KERN_WARN
  726. "open rejected: console in exclusive use by another partition.\n");
  727. /* Return the acknowledgement */
  728. HvCallEvent_ackLpEvent(event);
  729. }
  730. /*
  731. * Handle a close charLpEvent. This should ONLY be an Interrupt because the
  732. * virtual console should never actually issue a close event to the hypervisor
  733. * because the virtual console never goes away. A close event coming from the
  734. * hypervisor simply means that there are no client consoles connected to the
  735. * virtual console.
  736. *
  737. * Regardless of the number of connections masqueraded on the other side of
  738. * the hypervisor ONLY ONE close event should be called to accompany the ONE
  739. * open event that is called. The close event should ONLY be called when NO
  740. * MORE connections (masqueraded or not) exist on the other side of the
  741. * hypervisor.
  742. */
  743. static void vioHandleCloseEvent(struct HvLpEvent *event)
  744. {
  745. unsigned long flags;
  746. struct viocharlpevent *cevent = (struct viocharlpevent *)event;
  747. u8 port = cevent->virtual_device;
  748. if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
  749. if (port >= VTTY_PORTS) {
  750. printk(VIOCONS_KERN_WARN
  751. "close message from invalid virtual device.\n");
  752. return;
  753. }
  754. /* For closes, just mark the console partition invalid */
  755. spin_lock_irqsave(&consolelock, flags);
  756. /* Got the lock, don't cause console output */
  757. if (port_info[port].lp == event->xSourceLp)
  758. port_info[port].lp = HvLpIndexInvalid;
  759. spin_unlock_irqrestore(&consolelock, flags);
  760. printk(VIOCONS_KERN_INFO "close from %d\n", event->xSourceLp);
  761. } else
  762. printk(VIOCONS_KERN_WARN
  763. "got unexpected close acknowlegement\n");
  764. }
  765. /*
  766. * Handle a config charLpEvent. Could be either interrupt or ack
  767. */
  768. static void vioHandleConfig(struct HvLpEvent *event)
  769. {
  770. struct viocharlpevent *cevent = (struct viocharlpevent *)event;
  771. HvCall_writeLogBuffer(cevent->data, cevent->len);
  772. if (cevent->data[0] == 0x01)
  773. printk(VIOCONS_KERN_INFO "window resized to %d: %d: %d: %d\n",
  774. cevent->data[1], cevent->data[2],
  775. cevent->data[3], cevent->data[4]);
  776. else
  777. printk(VIOCONS_KERN_WARN "unknown config event\n");
  778. }
  779. /*
  780. * Handle a data charLpEvent.
  781. */
  782. static void vioHandleData(struct HvLpEvent *event)
  783. {
  784. struct tty_struct *tty;
  785. unsigned long flags;
  786. struct viocharlpevent *cevent = (struct viocharlpevent *)event;
  787. struct port_info *pi;
  788. int index;
  789. u8 port = cevent->virtual_device;
  790. if (port >= VTTY_PORTS) {
  791. printk(VIOCONS_KERN_WARN "data on invalid virtual device %d\n",
  792. port);
  793. return;
  794. }
  795. /*
  796. * Hold the spinlock so that we don't take an interrupt that
  797. * changes tty between the time we fetch the port_info
  798. * pointer and the time we paranoia check.
  799. */
  800. spin_lock_irqsave(&consolelock, flags);
  801. pi = &port_info[port];
  802. /*
  803. * Change 05/01/2003 - Ryan Arnold: If a partition other than
  804. * the current exclusive partition tries to send us data
  805. * events then just drop them on the floor because we don't
  806. * want his stinking data. He isn't authorized to receive
  807. * data because he wasn't the first one to get the console,
  808. * therefore he shouldn't be allowed to send data either.
  809. * This will work without an iSeries fix.
  810. */
  811. if (pi->lp != event->xSourceLp) {
  812. spin_unlock_irqrestore(&consolelock, flags);
  813. return;
  814. }
  815. tty = pi->tty;
  816. if (tty == NULL) {
  817. spin_unlock_irqrestore(&consolelock, flags);
  818. printk(VIOCONS_KERN_WARN "no tty for virtual device %d\n",
  819. port);
  820. return;
  821. }
  822. if (tty->magic != TTY_MAGIC) {
  823. spin_unlock_irqrestore(&consolelock, flags);
  824. printk(VIOCONS_KERN_WARN "tty bad magic\n");
  825. return;
  826. }
  827. /*
  828. * Just to be paranoid, make sure the tty points back to this port
  829. */
  830. pi = (struct port_info *)tty->driver_data;
  831. if (!pi || viotty_paranoia_check(pi, tty->name, "vioHandleData")) {
  832. spin_unlock_irqrestore(&consolelock, flags);
  833. return;
  834. }
  835. spin_unlock_irqrestore(&consolelock, flags);
  836. /*
  837. * Change 07/21/2003 - Ryan Arnold: functionality added to
  838. * support sysrq utilizing ^O as the sysrq key. The sysrq
  839. * functionality will only work if built into the kernel and
  840. * then only if sysrq is enabled through the proc filesystem.
  841. */
  842. for (index = 0; index < cevent->len; index++) {
  843. #ifdef CONFIG_MAGIC_SYSRQ
  844. if (sysrq_enabled) {
  845. /* 0x0f is the ascii character for ^O */
  846. if (cevent->data[index] == '\x0f') {
  847. vio_sysrq_pressed = 1;
  848. /*
  849. * continue because we don't want to add
  850. * the sysrq key into the data string.
  851. */
  852. continue;
  853. } else if (vio_sysrq_pressed) {
  854. handle_sysrq(cevent->data[index], NULL, tty);
  855. vio_sysrq_pressed = 0;
  856. /*
  857. * continue because we don't want to add
  858. * the sysrq sequence into the data string.
  859. */
  860. continue;
  861. }
  862. }
  863. #endif
  864. /*
  865. * The sysrq sequence isn't included in this check if
  866. * sysrq is enabled and compiled into the kernel because
  867. * the sequence will never get inserted into the buffer.
  868. * Don't attempt to copy more data into the buffer than we
  869. * have room for because it would fail without indication.
  870. */
  871. if ((tty->flip.count + 1) > TTY_FLIPBUF_SIZE) {
  872. printk(VIOCONS_KERN_WARN "input buffer overflow!\n");
  873. break;
  874. }
  875. tty_insert_flip_char(tty, cevent->data[index], TTY_NORMAL);
  876. }
  877. /* if cevent->len == 0 then no data was added to the buffer and flip.count == 0 */
  878. if (tty->flip.count)
  879. /* The next call resets flip.count when the data is flushed. */
  880. tty_flip_buffer_push(tty);
  881. }
  882. /*
  883. * Handle an ack charLpEvent.
  884. */
  885. static void vioHandleAck(struct HvLpEvent *event)
  886. {
  887. struct viocharlpevent *cevent = (struct viocharlpevent *)event;
  888. unsigned long flags;
  889. u8 port = cevent->virtual_device;
  890. if (port >= VTTY_PORTS) {
  891. printk(VIOCONS_KERN_WARN "data on invalid virtual device\n");
  892. return;
  893. }
  894. spin_lock_irqsave(&consolelock, flags);
  895. port_info[port].ack = event->xCorrelationToken;
  896. spin_unlock_irqrestore(&consolelock, flags);
  897. if (port_info[port].used)
  898. send_buffers(&port_info[port]);
  899. }
  900. /*
  901. * Handle charLpEvents and route to the appropriate routine
  902. */
  903. static void vioHandleCharEvent(struct HvLpEvent *event)
  904. {
  905. int charminor;
  906. if (event == NULL)
  907. return;
  908. charminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
  909. switch (charminor) {
  910. case viocharopen:
  911. vioHandleOpenEvent(event);
  912. break;
  913. case viocharclose:
  914. vioHandleCloseEvent(event);
  915. break;
  916. case viochardata:
  917. vioHandleData(event);
  918. break;
  919. case viocharack:
  920. vioHandleAck(event);
  921. break;
  922. case viocharconfig:
  923. vioHandleConfig(event);
  924. break;
  925. default:
  926. if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
  927. (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
  928. event->xRc = HvLpEvent_Rc_InvalidSubtype;
  929. HvCallEvent_ackLpEvent(event);
  930. }
  931. }
  932. }
  933. /*
  934. * Send an open event
  935. */
  936. static int send_open(HvLpIndex remoteLp, void *sem)
  937. {
  938. return HvCallEvent_signalLpEventFast(remoteLp,
  939. HvLpEvent_Type_VirtualIo,
  940. viomajorsubtype_chario | viocharopen,
  941. HvLpEvent_AckInd_DoAck, HvLpEvent_AckType_ImmediateAck,
  942. viopath_sourceinst(remoteLp),
  943. viopath_targetinst(remoteLp),
  944. (u64)(unsigned long)sem, VIOVERSION << 16,
  945. 0, 0, 0, 0);
  946. }
  947. static struct tty_operations serial_ops = {
  948. .open = viotty_open,
  949. .close = viotty_close,
  950. .write = viotty_write,
  951. .put_char = viotty_put_char,
  952. .write_room = viotty_write_room,
  953. .chars_in_buffer = viotty_chars_in_buffer,
  954. .ioctl = viotty_ioctl,
  955. };
  956. static int __init viocons_init2(void)
  957. {
  958. atomic_t wait_flag;
  959. int rc;
  960. /* +2 for fudge */
  961. rc = viopath_open(HvLpConfig_getPrimaryLpIndex(),
  962. viomajorsubtype_chario, VIOCHAR_WINDOW + 2);
  963. if (rc)
  964. printk(VIOCONS_KERN_WARN "error opening to primary %d\n", rc);
  965. if (viopath_hostLp == HvLpIndexInvalid)
  966. vio_set_hostlp();
  967. /*
  968. * And if the primary is not the same as the hosting LP, open to the
  969. * hosting lp
  970. */
  971. if ((viopath_hostLp != HvLpIndexInvalid) &&
  972. (viopath_hostLp != HvLpConfig_getPrimaryLpIndex())) {
  973. printk(VIOCONS_KERN_INFO "open path to hosting (%d)\n",
  974. viopath_hostLp);
  975. rc = viopath_open(viopath_hostLp, viomajorsubtype_chario,
  976. VIOCHAR_WINDOW + 2); /* +2 for fudge */
  977. if (rc)
  978. printk(VIOCONS_KERN_WARN
  979. "error opening to partition %d: %d\n",
  980. viopath_hostLp, rc);
  981. }
  982. if (vio_setHandler(viomajorsubtype_chario, vioHandleCharEvent) < 0)
  983. printk(VIOCONS_KERN_WARN
  984. "error seting handler for console events!\n");
  985. /*
  986. * First, try to open the console to the hosting lp.
  987. * Wait on a semaphore for the response.
  988. */
  989. atomic_set(&wait_flag, 0);
  990. if ((viopath_isactive(viopath_hostLp)) &&
  991. (send_open(viopath_hostLp, (void *)&wait_flag) == 0)) {
  992. printk(VIOCONS_KERN_INFO "hosting partition %d\n",
  993. viopath_hostLp);
  994. while (atomic_read(&wait_flag) == 0)
  995. mb();
  996. atomic_set(&wait_flag, 0);
  997. }
  998. /*
  999. * If we don't have an active console, try the primary
  1000. */
  1001. if ((!viopath_isactive(port_info[0].lp)) &&
  1002. (viopath_isactive(HvLpConfig_getPrimaryLpIndex())) &&
  1003. (send_open(HvLpConfig_getPrimaryLpIndex(), (void *)&wait_flag)
  1004. == 0)) {
  1005. printk(VIOCONS_KERN_INFO "opening console to primary partition\n");
  1006. while (atomic_read(&wait_flag) == 0)
  1007. mb();
  1008. }
  1009. /* Initialize the tty_driver structure */
  1010. viotty_driver = alloc_tty_driver(VTTY_PORTS);
  1011. viotty_driver->owner = THIS_MODULE;
  1012. viotty_driver->driver_name = "vioconsole";
  1013. viotty_driver->devfs_name = "vcs/";
  1014. viotty_driver->name = "tty";
  1015. viotty_driver->name_base = 1;
  1016. viotty_driver->major = TTY_MAJOR;
  1017. viotty_driver->minor_start = 1;
  1018. viotty_driver->type = TTY_DRIVER_TYPE_CONSOLE;
  1019. viotty_driver->subtype = 1;
  1020. viotty_driver->init_termios = tty_std_termios;
  1021. viotty_driver->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_RESET_TERMIOS;
  1022. tty_set_operations(viotty_driver, &serial_ops);
  1023. if (tty_register_driver(viotty_driver)) {
  1024. printk(VIOCONS_KERN_WARN "couldn't register console driver\n");
  1025. put_tty_driver(viotty_driver);
  1026. viotty_driver = NULL;
  1027. }
  1028. unregister_console(&viocons_early);
  1029. register_console(&viocons);
  1030. return 0;
  1031. }
  1032. static int __init viocons_init(void)
  1033. {
  1034. int i;
  1035. printk(VIOCONS_KERN_INFO "registering console\n");
  1036. for (i = 0; i < VTTY_PORTS; i++) {
  1037. port_info[i].lp = HvLpIndexInvalid;
  1038. port_info[i].magic = VIOTTY_MAGIC;
  1039. }
  1040. HvCall_setLogBufferFormatAndCodepage(HvCall_LogBuffer_ASCII, 437);
  1041. register_console(&viocons_early);
  1042. return 0;
  1043. }
  1044. console_initcall(viocons_init);
  1045. module_init(viocons_init2);