irq_user.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  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. }
  79. }
  80. }
  81. }
  82. }
  83. int activate_ipi(int fd, int pid)
  84. {
  85. return(os_set_fd_async(fd, pid));
  86. }
  87. static void maybe_sigio_broken(int fd, int type)
  88. {
  89. if(isatty(fd)){
  90. if((type == IRQ_WRITE) && !pty_output_sigio){
  91. write_sigio_workaround();
  92. add_sigio_fd(fd, 0);
  93. }
  94. else if((type == IRQ_READ) && !pty_close_sigio){
  95. write_sigio_workaround();
  96. add_sigio_fd(fd, 1);
  97. }
  98. }
  99. }
  100. int activate_fd(int irq, int fd, int type, void *dev_id)
  101. {
  102. struct pollfd *tmp_pfd;
  103. struct irq_fd *new_fd, *irq_fd;
  104. unsigned long flags;
  105. int pid, events, err, n, size;
  106. pid = os_getpid();
  107. err = os_set_fd_async(fd, pid);
  108. if(err < 0)
  109. goto out;
  110. new_fd = um_kmalloc(sizeof(*new_fd));
  111. err = -ENOMEM;
  112. if(new_fd == NULL)
  113. goto out;
  114. if(type == IRQ_READ) events = POLLIN | POLLPRI;
  115. else events = POLLOUT;
  116. *new_fd = ((struct irq_fd) { .next = NULL,
  117. .id = dev_id,
  118. .fd = fd,
  119. .type = type,
  120. .irq = irq,
  121. .pid = pid,
  122. .events = events,
  123. .current_events = 0,
  124. .freed = 0 } );
  125. /* Critical section - locked by a spinlock because this stuff can
  126. * be changed from interrupt handlers. The stuff above is done
  127. * outside the lock because it allocates memory.
  128. */
  129. /* Actually, it only looks like it can be called from interrupt
  130. * context. The culprit is reactivate_fd, which calls
  131. * maybe_sigio_broken, which calls write_sigio_workaround,
  132. * which calls activate_fd. However, write_sigio_workaround should
  133. * only be called once, at boot time. That would make it clear that
  134. * this is called only from process context, and can be locked with
  135. * a semaphore.
  136. */
  137. flags = irq_lock();
  138. for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
  139. if((irq_fd->fd == fd) && (irq_fd->type == type)){
  140. printk("Registering fd %d twice\n", fd);
  141. printk("Irqs : %d, %d\n", irq_fd->irq, irq);
  142. printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id);
  143. goto out_unlock;
  144. }
  145. }
  146. n = pollfds_num;
  147. if(n == pollfds_size){
  148. while(1){
  149. /* Here we have to drop the lock in order to call
  150. * kmalloc, which might sleep. If something else
  151. * came in and changed the pollfds array, we free
  152. * the buffer and try again.
  153. */
  154. irq_unlock(flags);
  155. size = (pollfds_num + 1) * sizeof(pollfds[0]);
  156. tmp_pfd = um_kmalloc(size);
  157. flags = irq_lock();
  158. if(tmp_pfd == NULL)
  159. goto out_unlock;
  160. if(n == pollfds_size)
  161. break;
  162. kfree(tmp_pfd);
  163. }
  164. if(pollfds != NULL){
  165. memcpy(tmp_pfd, pollfds,
  166. sizeof(pollfds[0]) * pollfds_size);
  167. kfree(pollfds);
  168. }
  169. pollfds = tmp_pfd;
  170. pollfds_size++;
  171. }
  172. if(type == IRQ_WRITE)
  173. fd = -1;
  174. pollfds[pollfds_num] = ((struct pollfd) { .fd = fd,
  175. .events = events,
  176. .revents = 0 });
  177. pollfds_num++;
  178. *last_irq_ptr = new_fd;
  179. last_irq_ptr = &new_fd->next;
  180. irq_unlock(flags);
  181. /* This calls activate_fd, so it has to be outside the critical
  182. * section.
  183. */
  184. maybe_sigio_broken(fd, type);
  185. return(0);
  186. out_unlock:
  187. irq_unlock(flags);
  188. kfree(new_fd);
  189. out:
  190. return(err);
  191. }
  192. static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
  193. {
  194. struct irq_fd **prev;
  195. unsigned long flags;
  196. int i = 0;
  197. flags = irq_lock();
  198. prev = &active_fds;
  199. while(*prev != NULL){
  200. if((*test)(*prev, arg)){
  201. struct irq_fd *old_fd = *prev;
  202. if((pollfds[i].fd != -1) &&
  203. (pollfds[i].fd != (*prev)->fd)){
  204. printk("free_irq_by_cb - mismatch between "
  205. "active_fds and pollfds, fd %d vs %d\n",
  206. (*prev)->fd, pollfds[i].fd);
  207. goto out;
  208. }
  209. pollfds_num--;
  210. /* This moves the *whole* array after pollfds[i] (though
  211. * it doesn't spot as such)! */
  212. memmove(&pollfds[i], &pollfds[i + 1],
  213. (pollfds_num - i) * sizeof(pollfds[0]));
  214. if(last_irq_ptr == &old_fd->next)
  215. last_irq_ptr = prev;
  216. *prev = (*prev)->next;
  217. if(old_fd->type == IRQ_WRITE)
  218. ignore_sigio_fd(old_fd->fd);
  219. kfree(old_fd);
  220. continue;
  221. }
  222. prev = &(*prev)->next;
  223. i++;
  224. }
  225. out:
  226. irq_unlock(flags);
  227. }
  228. struct irq_and_dev {
  229. int irq;
  230. void *dev;
  231. };
  232. static int same_irq_and_dev(struct irq_fd *irq, void *d)
  233. {
  234. struct irq_and_dev *data = d;
  235. return((irq->irq == data->irq) && (irq->id == data->dev));
  236. }
  237. void free_irq_by_irq_and_dev(unsigned int irq, void *dev)
  238. {
  239. struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq,
  240. .dev = dev });
  241. free_irq_by_cb(same_irq_and_dev, &data);
  242. }
  243. static int same_fd(struct irq_fd *irq, void *fd)
  244. {
  245. return(irq->fd == *((int *) fd));
  246. }
  247. void free_irq_by_fd(int fd)
  248. {
  249. free_irq_by_cb(same_fd, &fd);
  250. }
  251. static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
  252. {
  253. struct irq_fd *irq;
  254. int i = 0;
  255. for(irq=active_fds; irq != NULL; irq = irq->next){
  256. if((irq->fd == fd) && (irq->irq == irqnum)) break;
  257. i++;
  258. }
  259. if(irq == NULL){
  260. printk("find_irq_by_fd doesn't have descriptor %d\n", fd);
  261. goto out;
  262. }
  263. if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){
  264. printk("find_irq_by_fd - mismatch between active_fds and "
  265. "pollfds, fd %d vs %d, need %d\n", irq->fd,
  266. pollfds[i].fd, fd);
  267. irq = NULL;
  268. goto out;
  269. }
  270. *index_out = i;
  271. out:
  272. return(irq);
  273. }
  274. void free_irq_later(int irq, void *dev_id)
  275. {
  276. struct irq_fd *irq_fd;
  277. unsigned long flags;
  278. flags = irq_lock();
  279. for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){
  280. if((irq_fd->irq == irq) && (irq_fd->id == dev_id))
  281. break;
  282. }
  283. if(irq_fd == NULL){
  284. printk("free_irq_later found no irq, irq = %d, "
  285. "dev_id = 0x%p\n", irq, dev_id);
  286. goto out;
  287. }
  288. irq_fd->freed = 1;
  289. out:
  290. irq_unlock(flags);
  291. }
  292. void reactivate_fd(int fd, int irqnum)
  293. {
  294. struct irq_fd *irq;
  295. unsigned long flags;
  296. int i;
  297. flags = irq_lock();
  298. irq = find_irq_by_fd(fd, irqnum, &i);
  299. if(irq == NULL){
  300. irq_unlock(flags);
  301. return;
  302. }
  303. pollfds[i].fd = irq->fd;
  304. irq_unlock(flags);
  305. /* This calls activate_fd, so it has to be outside the critical
  306. * section.
  307. */
  308. maybe_sigio_broken(fd, irq->type);
  309. }
  310. void deactivate_fd(int fd, int irqnum)
  311. {
  312. struct irq_fd *irq;
  313. unsigned long flags;
  314. int i;
  315. flags = irq_lock();
  316. irq = find_irq_by_fd(fd, irqnum, &i);
  317. if(irq == NULL)
  318. goto out;
  319. pollfds[i].fd = -1;
  320. out:
  321. irq_unlock(flags);
  322. }
  323. int deactivate_all_fds(void)
  324. {
  325. struct irq_fd *irq;
  326. int err;
  327. for(irq=active_fds;irq != NULL;irq = irq->next){
  328. err = os_clear_fd_async(irq->fd);
  329. if(err)
  330. return(err);
  331. }
  332. /* If there is a signal already queued, after unblocking ignore it */
  333. set_handler(SIGIO, SIG_IGN, 0, -1);
  334. return(0);
  335. }
  336. void forward_ipi(int fd, int pid)
  337. {
  338. int err;
  339. err = os_set_owner(fd, pid);
  340. if(err < 0)
  341. printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
  342. "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
  343. }
  344. void forward_interrupts(int pid)
  345. {
  346. struct irq_fd *irq;
  347. unsigned long flags;
  348. int err;
  349. flags = irq_lock();
  350. for(irq=active_fds;irq != NULL;irq = irq->next){
  351. err = os_set_owner(irq->fd, pid);
  352. if(err < 0){
  353. /* XXX Just remove the irq rather than
  354. * print out an infinite stream of these
  355. */
  356. printk("Failed to forward %d to pid %d, err = %d\n",
  357. irq->fd, pid, -err);
  358. }
  359. irq->pid = pid;
  360. }
  361. irq_unlock(flags);
  362. }
  363. void init_irq_signals(int on_sigstack)
  364. {
  365. __sighandler_t h;
  366. int flags;
  367. flags = on_sigstack ? SA_ONSTACK : 0;
  368. if(timer_irq_inited) h = (__sighandler_t) alarm_handler;
  369. else h = boot_timer_handler;
  370. set_handler(SIGVTALRM, h, flags | SA_RESTART,
  371. SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
  372. set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
  373. SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
  374. signal(SIGWINCH, SIG_IGN);
  375. }
  376. /*
  377. * Overrides for Emacs so that we follow Linus's tabbing style.
  378. * Emacs will notice this stuff at the end of the file and automatically
  379. * adjust the settings for this buffer only. This must remain at the end
  380. * of the file.
  381. * ---------------------------------------------------------------------------
  382. * Local variables:
  383. * c-file-style: "linux"
  384. * End:
  385. */