irq_user.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
  3. * Licensed under the GPL
  4. */
  5. #include <stdlib.h>
  6. #include <unistd.h>
  7. #include <errno.h>
  8. #include <signal.h>
  9. #include <string.h>
  10. #include <sys/poll.h>
  11. #include <sys/types.h>
  12. #include <sys/time.h>
  13. #include "user_util.h"
  14. #include "kern_util.h"
  15. #include "user.h"
  16. #include "process.h"
  17. #include "signal_user.h"
  18. #include "sigio.h"
  19. #include "irq_user.h"
  20. #include "os.h"
  21. struct irq_fd {
  22. struct irq_fd *next;
  23. void *id;
  24. int fd;
  25. int type;
  26. int irq;
  27. int pid;
  28. int events;
  29. int current_events;
  30. int freed;
  31. };
  32. static struct irq_fd *active_fds = NULL;
  33. static struct irq_fd **last_irq_ptr = &active_fds;
  34. static struct pollfd *pollfds = NULL;
  35. static int pollfds_num = 0;
  36. static int pollfds_size = 0;
  37. extern int io_count, intr_count;
  38. void sigio_handler(int sig, union uml_pt_regs *regs)
  39. {
  40. struct irq_fd *irq_fd, *next;
  41. int i, n;
  42. if(smp_sigio_handler()) return;
  43. while(1){
  44. n = poll(pollfds, pollfds_num, 0);
  45. if(n < 0){
  46. if(errno == EINTR) continue;
  47. printk("sigio_handler : poll returned %d, "
  48. "errno = %d\n", n, errno);
  49. break;
  50. }
  51. if(n == 0) break;
  52. irq_fd = active_fds;
  53. for(i = 0; i < pollfds_num; i++){
  54. if(pollfds[i].revents != 0){
  55. irq_fd->current_events = pollfds[i].revents;
  56. pollfds[i].fd = -1;
  57. }
  58. irq_fd = irq_fd->next;
  59. }
  60. for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){
  61. next = irq_fd->next;
  62. if(irq_fd->current_events != 0){
  63. irq_fd->current_events = 0;
  64. do_IRQ(irq_fd->irq, regs);
  65. /* This is here because the next irq may be
  66. * freed in the handler. If a console goes
  67. * away, both the read and write irqs will be
  68. * freed. After do_IRQ, ->next will point to
  69. * a good IRQ.
  70. * Irqs can't be freed inside their handlers,
  71. * so the next best thing is to have them
  72. * marked as needing freeing, so that they
  73. * can be freed here.
  74. */
  75. next = irq_fd->next;
  76. if(irq_fd->freed){
  77. free_irq(irq_fd->irq, irq_fd->id);
  78. free_irq_by_irq_and_dev(irq_fd->irq,
  79. irq_fd->id);
  80. }
  81. }
  82. }
  83. }
  84. }
  85. int activate_ipi(int fd, int pid)
  86. {
  87. return(os_set_fd_async(fd, pid));
  88. }
  89. static void maybe_sigio_broken(int fd, int type)
  90. {
  91. if(isatty(fd)){
  92. if((type == IRQ_WRITE) && !pty_output_sigio){
  93. write_sigio_workaround();
  94. add_sigio_fd(fd, 0);
  95. }
  96. else if((type == IRQ_READ) && !pty_close_sigio){
  97. write_sigio_workaround();
  98. add_sigio_fd(fd, 1);
  99. }
  100. }
  101. }
  102. int activate_fd(int irq, int fd, int type, void *dev_id)
  103. {
  104. struct pollfd *tmp_pfd;
  105. struct irq_fd *new_fd, *irq_fd;
  106. unsigned long flags;
  107. int pid, events, err, n, size;
  108. pid = os_getpid();
  109. err = os_set_fd_async(fd, pid);
  110. if(err < 0)
  111. goto out;
  112. new_fd = um_kmalloc(sizeof(*new_fd));
  113. err = -ENOMEM;
  114. if(new_fd == NULL)
  115. goto out;
  116. if(type == IRQ_READ) events = POLLIN | POLLPRI;
  117. else events = POLLOUT;
  118. *new_fd = ((struct irq_fd) { .next = NULL,
  119. .id = dev_id,
  120. .fd = fd,
  121. .type = type,
  122. .irq = irq,
  123. .pid = pid,
  124. .events = events,
  125. .current_events = 0,
  126. .freed = 0 } );
  127. /* Critical section - locked by a spinlock because this stuff can
  128. * be changed from interrupt handlers. The stuff above is done
  129. * outside the lock because it allocates memory.
  130. */
  131. /* Actually, it only looks like it can be called from interrupt
  132. * context. The culprit is reactivate_fd, which calls
  133. * maybe_sigio_broken, which calls write_sigio_workaround,
  134. * which calls activate_fd. However, write_sigio_workaround should
  135. * only be called once, at boot time. That would make it clear that
  136. * this is called only from process context, and can be locked with
  137. * a semaphore.
  138. */
  139. flags = irq_lock();
  140. for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
  141. if((irq_fd->fd == fd) && (irq_fd->type == type)){
  142. printk("Registering fd %d twice\n", fd);
  143. printk("Irqs : %d, %d\n", irq_fd->irq, irq);
  144. printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
  145. goto out_unlock;
  146. }
  147. }
  148. n = pollfds_num;
  149. if(n == pollfds_size){
  150. while(1){
  151. /* Here we have to drop the lock in order to call
  152. * kmalloc, which might sleep. If something else
  153. * came in and changed the pollfds array, we free
  154. * the buffer and try again.
  155. */
  156. irq_unlock(flags);
  157. size = (pollfds_num + 1) * sizeof(pollfds[0]);
  158. tmp_pfd = um_kmalloc(size);
  159. flags = irq_lock();
  160. if(tmp_pfd == NULL)
  161. goto out_unlock;
  162. if(n == pollfds_size)
  163. break;
  164. kfree(tmp_pfd);
  165. }
  166. if(pollfds != NULL){
  167. memcpy(tmp_pfd, pollfds,
  168. sizeof(pollfds[0]) * pollfds_size);
  169. kfree(pollfds);
  170. }
  171. pollfds = tmp_pfd;
  172. pollfds_size++;
  173. }
  174. if(type == IRQ_WRITE)
  175. fd = -1;
  176. pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
  177. .events = events,
  178. .revents = 0 });
  179. pollfds_num++;
  180. *last_irq_ptr = new_fd;
  181. last_irq_ptr = &new_fd->next;
  182. irq_unlock(flags);
  183. /* This calls activate_fd, so it has to be outside the critical
  184. * section.
  185. */
  186. maybe_sigio_broken(fd, type);
  187. return(0);
  188. out_unlock:
  189. irq_unlock(flags);
  190. kfree(new_fd);
  191. out:
  192. return(err);
  193. }
  194. static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
  195. {
  196. struct irq_fd **prev;
  197. unsigned long flags;
  198. int i = 0;
  199. flags = irq_lock();
  200. prev = &active_fds;
  201. while(*prev != NULL){
  202. if((*test)(*prev, arg)){
  203. struct irq_fd *old_fd = *prev;
  204. if((pollfds[i].fd != -1) &&
  205. (pollfds[i].fd != (*prev)->fd)){
  206. printk("free_irq_by_cb - mismatch between "
  207. "active_fds and pollfds, fd %d vs %d\n",
  208. (*prev)->fd, pollfds[i].fd);
  209. goto out;
  210. }
  211. pollfds_num--;
  212. /* This moves the *whole* array after pollfds[i] (though
  213. * it doesn't spot as such)! */
  214. memmove(&pollfds[i], &pollfds[i + 1],
  215. (pollfds_num - i) * sizeof(pollfds[0]));
  216. if(last_irq_ptr == &old_fd->next)
  217. last_irq_ptr = prev;
  218. *prev = (*prev)->next;
  219. if(old_fd->type == IRQ_WRITE)
  220. ignore_sigio_fd(old_fd->fd);
  221. kfree(old_fd);
  222. continue;
  223. }
  224. prev = &(*prev)->next;
  225. i++;
  226. }
  227. out:
  228. irq_unlock(flags);
  229. }
  230. struct irq_and_dev {
  231. int irq;
  232. void *dev;
  233. };
  234. static int same_irq_and_dev(struct irq_fd *irq, void *d)
  235. {
  236. struct irq_and_dev *data = d;
  237. return((irq->irq == data->irq) && (irq->id == data->dev));
  238. }
  239. void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
  240. {
  241. struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
  242. .dev = dev });
  243. free_irq_by_cb(same_irq_and_dev, &data);
  244. }
  245. static int same_fd(struct irq_fd *irq, void *fd)
  246. {
  247. return(irq->fd == *((int *) fd));
  248. }
  249. void free_irq_by_fd(int fd)
  250. {
  251. free_irq_by_cb(same_fd, &fd);
  252. }
  253. static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
  254. {
  255. struct irq_fd *irq;
  256. int i = 0;
  257. for(irq=active_fds; irq != NULL; irq = irq->next){
  258. if((irq->fd == fd) && (irq->irq == irqnum)) break;
  259. i++;
  260. }
  261. if(irq == NULL){
  262. printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
  263. goto out;
  264. }
  265. if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
  266. printk("find_irq_by_fd - mismatch between active_fds and "
  267. "pollfds, fd %d vs %d, need %d\n", irq->fd,
  268. pollfds[i].fd, fd);
  269. irq = NULL;
  270. goto out;
  271. }
  272. *index_out = i;
  273. out:
  274. return(irq);
  275. }
  276. void free_irq_later(int irq, void *dev_id)
  277. {
  278. struct irq_fd *irq_fd;
  279. unsigned long flags;
  280. flags = irq_lock();
  281. for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
  282. if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
  283. break;
  284. }
  285. if(irq_fd == NULL){
  286. printk("free_irq_later found no irq, irq = %d, "
  287. "dev_id = 0x%p\n", irq, dev_id);
  288. goto out;
  289. }
  290. irq_fd->freed = 1;
  291. out:
  292. irq_unlock(flags);
  293. }
  294. void reactivate_fd(int fd, int irqnum)
  295. {
  296. struct irq_fd *irq;
  297. unsigned long flags;
  298. int i;
  299. flags = irq_lock();
  300. irq = find_irq_by_fd(fd, irqnum, &i);
  301. if(irq == NULL){
  302. irq_unlock(flags);
  303. return;
  304. }
  305. pollfds[i].fd = irq->fd;
  306. irq_unlock(flags);
  307. /* This calls activate_fd, so it has to be outside the critical
  308. * section.
  309. */
  310. maybe_sigio_broken(fd, irq->type);
  311. }
  312. void deactivate_fd(int fd, int irqnum)
  313. {
  314. struct irq_fd *irq;
  315. unsigned long flags;
  316. int i;
  317. flags = irq_lock();
  318. irq = find_irq_by_fd(fd, irqnum, &i);
  319. if(irq == NULL)
  320. goto out;
  321. pollfds[i].fd = -1;
  322. out:
  323. irq_unlock(flags);
  324. }
  325. int deactivate_all_fds(void)
  326. {
  327. struct irq_fd *irq;
  328. int err;
  329. for(irq=active_fds;irq != NULL;irq = irq->next){
  330. err = os_clear_fd_async(irq->fd);
  331. if(err)
  332. return(err);
  333. }
  334. /* If there is a signal already queued, after unblocking ignore it */
  335. set_handler(SIGIO, SIG_IGN, 0, -1);
  336. return(0);
  337. }
  338. void forward_ipi(int fd, int pid)
  339. {
  340. int err;
  341. err = os_set_owner(fd, pid);
  342. if(err < 0)
  343. printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
  344. "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
  345. }
  346. void forward_interrupts(int pid)
  347. {
  348. struct irq_fd *irq;
  349. unsigned long flags;
  350. int err;
  351. flags = irq_lock();
  352. for(irq=active_fds;irq != NULL;irq = irq->next){
  353. err = os_set_owner(irq->fd, pid);
  354. if(err < 0){
  355. /* XXX Just remove the irq rather than
  356. * print out an infinite stream of these
  357. */
  358. printk("Failed to forward %d to pid %d, err = %d\n",
  359. irq->fd, pid, -err);
  360. }
  361. irq->pid = pid;
  362. }
  363. irq_unlock(flags);
  364. }
  365. void init_irq_signals(int on_sigstack)
  366. {
  367. __sighandler_t h;
  368. int flags;
  369. flags = on_sigstack ? SA_ONSTACK : 0;
  370. if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
  371. else h = boot_timer_handler;
  372. set_handler(SIGVTALRM, h, flags | SA_RESTART,
  373. SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
  374. set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
  375. SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
  376. signal(SIGWINCH, SIG_IGN);
  377. }
  378. /*
  379. * Overrides for Emacs so that we follow Linus's tabbing style.
  380. * Emacs will notice this stuff at the end of the file and automatically
  381. * adjust the settings for this buffer only. This must remain at the end
  382. * of the file.
  383. * ---------------------------------------------------------------------------
  384. * Local variables:
  385. * c-file-style: "linux"
  386. * End:
  387. */