midi.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:14k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  **********************************************************************
  3.  *     midi.c - /dev/midi interface for emu10k1 driver
  4.  *     Copyright 1999, 2000 Creative Labs, Inc.
  5.  *
  6.  **********************************************************************
  7.  *
  8.  *     Date                 Author          Summary of changes
  9.  *     ----                 ------          ------------------
  10.  *     October 20, 1999     Bertrand Lee    base code release
  11.  *
  12.  **********************************************************************
  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
  17.  *     the License, or (at your option) any later version.
  18.  *
  19.  *     This program is distributed in the hope that it will be useful,
  20.  *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  *     GNU General Public License for more details.
  23.  *
  24.  *     You should have received a copy of the GNU General Public
  25.  *     License along with this program; if not, write to the Free
  26.  *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  27.  *     USA.
  28.  *
  29.  **********************************************************************
  30.  */
  31. #define __NO_VERSION__
  32. #include <linux/module.h>
  33. #include <linux/poll.h>
  34. #include <linux/slab.h>
  35. #include <linux/version.h>
  36. #include <linux/sched.h>
  37. #include <linux/smp_lock.h>
  38. #include <asm/uaccess.h>
  39. #include "hwaccess.h"
  40. #include "cardmo.h"
  41. #include "cardmi.h"
  42. #include "midi.h"
  43. #ifdef EMU10K1_SEQUENCER
  44. #include "../sound_config.h"
  45. #endif
  46. static spinlock_t midi_spinlock __attribute((unused)) = SPIN_LOCK_UNLOCKED;
  47. static void init_midi_hdr(struct midi_hdr *midihdr)
  48. {
  49. midihdr->bufferlength = MIDIIN_BUFLEN;
  50. midihdr->bytesrecorded = 0;
  51. midihdr->flags = 0;
  52. }
  53. static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
  54. {
  55. struct midi_hdr *midihdr;
  56. if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL) {
  57. ERROR();
  58. return -EINVAL;
  59. }
  60. init_midi_hdr(midihdr);
  61. if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) {
  62. ERROR();
  63. kfree(midihdr);
  64. return -1;
  65. }
  66. if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) < 0) {
  67. ERROR();
  68. kfree(midihdr->data);
  69. kfree(midihdr);
  70. return -1;
  71. }
  72. *midihdrptr = midihdr;
  73. list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
  74. return 0;
  75. }
  76. static int emu10k1_midi_open(struct inode *inode, struct file *file)
  77. {
  78. int minor = MINOR(inode->i_rdev);
  79. struct emu10k1_card *card = NULL;
  80. struct emu10k1_mididevice *midi_dev;
  81. struct list_head *entry;
  82. DPF(2, "emu10k1_midi_open()n");
  83. /* Check for correct device to open */
  84. list_for_each(entry, &emu10k1_devs) {
  85. card = list_entry(entry, struct emu10k1_card, list);
  86. if (card->midi_dev == minor)
  87. goto match;
  88. }
  89. return -ENODEV;
  90. match:
  91. #ifdef EMU10K1_SEQUENCER
  92. if (card->seq_mididev) /* card is opened by sequencer */
  93. return -EBUSY;
  94. #endif
  95. /* Wait for device to become free */
  96. down(&card->open_sem);
  97. while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
  98. if (file->f_flags & O_NONBLOCK) {
  99. up(&card->open_sem);
  100. return -EBUSY;
  101. }
  102. up(&card->open_sem);
  103. interruptible_sleep_on(&card->open_wait);
  104. if (signal_pending(current)) {
  105. return -ERESTARTSYS;
  106. }
  107. down(&card->open_sem);
  108. }
  109. if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
  110. return -EINVAL;
  111. midi_dev->card = card;
  112. midi_dev->mistate = MIDIIN_STATE_STOPPED;
  113. init_waitqueue_head(&midi_dev->oWait);
  114. init_waitqueue_head(&midi_dev->iWait);
  115. midi_dev->ird = 0;
  116. midi_dev->iwr = 0;
  117. midi_dev->icnt = 0;
  118. INIT_LIST_HEAD(&midi_dev->mid_hdrs);
  119. if (file->f_mode & FMODE_READ) {
  120. struct midi_openinfo dsCardMidiOpenInfo;
  121. struct midi_hdr *midihdr1;
  122. struct midi_hdr *midihdr2;
  123. dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
  124. if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo) < 0) {
  125. ERROR();
  126. kfree(midi_dev);
  127. return -ENODEV;
  128. }
  129. /* Add two buffers to receive sysex buffer */
  130. if (midiin_add_buffer(midi_dev, &midihdr1) < 0) {
  131. kfree(midi_dev);
  132. return -ENODEV;
  133. }
  134. if (midiin_add_buffer(midi_dev, &midihdr2) < 0) {
  135. list_del(&midihdr1->list);
  136. kfree(midihdr1->data);
  137. kfree(midihdr1);
  138. kfree(midi_dev);
  139. return -ENODEV;
  140. }
  141. }
  142. if (file->f_mode & FMODE_WRITE) {
  143. struct midi_openinfo dsCardMidiOpenInfo;
  144. dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
  145. if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
  146. ERROR();
  147. kfree(midi_dev);
  148. return -ENODEV;
  149. }
  150. }
  151. file->private_data = (void *) midi_dev;
  152. card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
  153. up(&card->open_sem);
  154. return 0;
  155. }
  156. static int emu10k1_midi_release(struct inode *inode, struct file *file)
  157. {
  158. struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
  159. struct emu10k1_card *card;
  160. lock_kernel();
  161. card = midi_dev->card;
  162. DPF(2, "emu10k1_midi_release()n");
  163. if (file->f_mode & FMODE_WRITE) {
  164. if (!(file->f_flags & O_NONBLOCK)) {
  165. while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
  166. DPF(4, "Cannot close - buffers not emptyn");
  167. interruptible_sleep_on(&midi_dev->oWait);
  168. }
  169. }
  170. emu10k1_mpuout_close(card);
  171. }
  172. if (file->f_mode & FMODE_READ) {
  173. struct midi_hdr *midihdr;
  174. if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
  175. emu10k1_mpuin_stop(card);
  176. midi_dev->mistate = MIDIIN_STATE_STOPPED;
  177. }
  178. emu10k1_mpuin_reset(card);
  179. emu10k1_mpuin_close(card);
  180. while (!list_empty(&midi_dev->mid_hdrs)) {
  181. midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
  182. list_del(midi_dev->mid_hdrs.next);
  183. kfree(midihdr->data);
  184. kfree(midihdr);
  185. }
  186. }
  187. kfree(midi_dev);
  188. down(&card->open_sem);
  189. card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
  190. up(&card->open_sem);
  191. wake_up_interruptible(&card->open_wait);
  192. unlock_kernel();
  193. return 0;
  194. }
  195. static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count, loff_t * pos)
  196. {
  197. struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
  198. ssize_t ret = 0;
  199. u16 cnt;
  200. unsigned long flags;
  201. DPD(4, "emu10k1_midi_read(), count %#xn", (u32) count);
  202. if (pos != &file->f_pos)
  203. return -ESPIPE;
  204. if (!access_ok(VERIFY_WRITE, buffer, count))
  205. return -EFAULT;
  206. if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
  207. if (emu10k1_mpuin_start(midi_dev->card) < 0) {
  208. ERROR();
  209. return -EINVAL;
  210. }
  211. midi_dev->mistate = MIDIIN_STATE_STARTED;
  212. }
  213. while (count > 0) {
  214. cnt = MIDIIN_BUFLEN - midi_dev->ird;
  215. spin_lock_irqsave(&midi_spinlock, flags);
  216. if (midi_dev->icnt < cnt)
  217. cnt = midi_dev->icnt;
  218. spin_unlock_irqrestore(&midi_spinlock, flags);
  219. if (cnt > count)
  220. cnt = count;
  221. if (cnt <= 0) {
  222. if (file->f_flags & O_NONBLOCK)
  223. return ret ? ret : -EAGAIN;
  224. DPF(2, " Go to sleep...n");
  225. interruptible_sleep_on(&midi_dev->iWait);
  226. if (signal_pending(current))
  227. return ret ? ret : -ERESTARTSYS;
  228. continue;
  229. }
  230. if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
  231. ERROR();
  232. return ret ? ret : -EFAULT;
  233. }
  234. midi_dev->ird += cnt;
  235. midi_dev->ird %= MIDIIN_BUFLEN;
  236. spin_lock_irqsave(&midi_spinlock, flags);
  237. midi_dev->icnt -= cnt;
  238. spin_unlock_irqrestore(&midi_spinlock, flags);
  239. count -= cnt;
  240. buffer += cnt;
  241. ret += cnt;
  242. if (midi_dev->icnt == 0)
  243. break;
  244. }
  245. return ret;
  246. }
  247. static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t count, loff_t * pos)
  248. {
  249. struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
  250. struct midi_hdr *midihdr;
  251. ssize_t ret = 0;
  252. unsigned long flags;
  253. DPD(4, "emu10k1_midi_write(), count=%#xn", (u32) count);
  254. if (pos != &file->f_pos)
  255. return -ESPIPE;
  256. if (!access_ok(VERIFY_READ, buffer, count))
  257. return -EFAULT;
  258. if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
  259. return -EINVAL;
  260. midihdr->bufferlength = count;
  261. midihdr->bytesrecorded = 0;
  262. midihdr->flags = 0;
  263. if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
  264. ERROR();
  265. kfree(midihdr);
  266. return -EINVAL;
  267. }
  268. if (copy_from_user(midihdr->data, buffer, count)) {
  269. kfree(midihdr->data);
  270. kfree(midihdr);
  271. return ret ? ret : -EFAULT;
  272. }
  273. spin_lock_irqsave(&midi_spinlock, flags);
  274. if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) < 0) {
  275. ERROR();
  276. kfree(midihdr->data);
  277. kfree(midihdr);
  278. spin_unlock_irqrestore(&midi_spinlock, flags);
  279. return -EINVAL;
  280. }
  281. spin_unlock_irqrestore(&midi_spinlock, flags);
  282. return count;
  283. }
  284. static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
  285. {
  286. struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
  287. unsigned long flags;
  288. unsigned int mask = 0;
  289. DPF(4, "emu10k1_midi_poll() calledn");
  290. if (file->f_mode & FMODE_WRITE)
  291. poll_wait(file, &midi_dev->oWait, wait);
  292. if (file->f_mode & FMODE_READ)
  293. poll_wait(file, &midi_dev->iWait, wait);
  294. spin_lock_irqsave(&midi_spinlock, flags);
  295. if (file->f_mode & FMODE_WRITE)
  296. mask |= POLLOUT | POLLWRNORM;
  297. if (file->f_mode & FMODE_READ) {
  298. if (midi_dev->mistate == MIDIIN_STATE_STARTED)
  299. if (midi_dev->icnt > 0)
  300. mask |= POLLIN | POLLRDNORM;
  301. }
  302. spin_unlock_irqrestore(&midi_spinlock, flags);
  303. return mask;
  304. }
  305. int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
  306. {
  307. struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
  308. struct midi_hdr *midihdr = NULL;
  309. unsigned long flags;
  310. int i;
  311. DPF(4, "emu10k1_midi_callback()n");
  312. spin_lock_irqsave(&midi_spinlock, flags);
  313. switch (msg) {
  314. case ICARDMIDI_OUTLONGDATA:
  315. midihdr = (struct midi_hdr *) pmsg[2];
  316. kfree(midihdr->data);
  317. kfree(midihdr);
  318. wake_up_interruptible(&midi_dev->oWait);
  319. break;
  320. case ICARDMIDI_INLONGDATA:
  321. midihdr = (struct midi_hdr *) pmsg[2];
  322. for (i = 0; i < midihdr->bytesrecorded; i++) {
  323. midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
  324. midi_dev->iwr %= MIDIIN_BUFLEN;
  325. }
  326. midi_dev->icnt += midihdr->bytesrecorded;
  327. if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
  328. init_midi_hdr(midihdr);
  329. emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
  330. wake_up_interruptible(&midi_dev->iWait);
  331. }
  332. break;
  333. case ICARDMIDI_INDATA:
  334. {
  335. u8 *pBuf = (u8 *) & pmsg[1];
  336. u16 bytesvalid = pmsg[2];
  337. for (i = 0; i < bytesvalid; i++) {
  338. midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
  339. midi_dev->iwr %= MIDIIN_BUFLEN;
  340. }
  341. midi_dev->icnt += bytesvalid;
  342. }
  343. wake_up_interruptible(&midi_dev->iWait);
  344. break;
  345. default: /* Unknown message */
  346. spin_unlock_irqrestore(&midi_spinlock, flags);
  347. return -1;
  348. }
  349. spin_unlock_irqrestore(&midi_spinlock, flags);
  350. return 0;
  351. }
  352. /* MIDI file operations */
  353. struct file_operations emu10k1_midi_fops = {
  354. owner: THIS_MODULE,
  355. read: emu10k1_midi_read,
  356. write: emu10k1_midi_write,
  357. poll: emu10k1_midi_poll,
  358. open: emu10k1_midi_open,
  359. release: emu10k1_midi_release,
  360. };
  361. #ifdef EMU10K1_SEQUENCER
  362. /* functions used for sequencer access */
  363. int emu10k1_seq_midi_open(int dev, int mode,
  364. void (*input) (int dev, unsigned char data),
  365. void (*output) (int dev))
  366. {
  367. struct emu10k1_card *card;
  368. struct midi_openinfo dsCardMidiOpenInfo;
  369. struct emu10k1_mididevice *midi_dev;
  370. if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
  371. return -EINVAL;
  372. card = midi_devs[dev]->devc;
  373. if (card->open_mode) /* card is opened native */
  374. return -EBUSY;
  375. DPF(2, "emu10k1_seq_midi_open()n");
  376. if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL)
  377. return -EINVAL;
  378. midi_dev->card = card;
  379. midi_dev->mistate = MIDIIN_STATE_STOPPED;
  380. init_waitqueue_head(&midi_dev->oWait);
  381. init_waitqueue_head(&midi_dev->iWait);
  382. midi_dev->ird = 0;
  383. midi_dev->iwr = 0;
  384. midi_dev->icnt = 0;
  385. INIT_LIST_HEAD(&midi_dev->mid_hdrs);
  386. dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
  387. if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo) < 0) {
  388. ERROR();
  389. return -ENODEV;
  390. }
  391. card->seq_mididev = midi_dev;
  392. return 0;
  393. }
  394. void emu10k1_seq_midi_close(int dev)
  395. {
  396. struct emu10k1_card *card;
  397. DPF(2, "emu10k1_seq_midi_close()n");
  398. if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
  399. return;
  400. card = midi_devs[dev]->devc;
  401. emu10k1_mpuout_close(card);
  402. if (card->seq_mididev) {
  403. kfree(card->seq_mididev);
  404. card->seq_mididev = 0;
  405. }
  406. }
  407. int emu10k1_seq_midi_out(int dev, unsigned char midi_byte)
  408. {
  409. struct emu10k1_card *card;
  410. struct midi_hdr *midihdr;
  411. unsigned long flags;
  412. if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
  413. return -EINVAL;
  414. card = midi_devs[dev]->devc;
  415. if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr), GFP_KERNEL)) == NULL)
  416. return -EINVAL;
  417. midihdr->bufferlength = 1;
  418. midihdr->bytesrecorded = 0;
  419. midihdr->flags = 0;
  420. if ((midihdr->data = (u8 *) kmalloc(1, GFP_KERNEL)) == NULL) {
  421. ERROR();
  422. kfree(midihdr);
  423. return -EINVAL;
  424. }
  425. *(midihdr->data) = midi_byte;
  426. spin_lock_irqsave(&midi_spinlock, flags);
  427. if (emu10k1_mpuout_add_buffer(card, midihdr) < 0) {
  428. ERROR();
  429. kfree(midihdr->data);
  430. kfree(midihdr);
  431. spin_unlock_irqrestore(&midi_spinlock, flags);
  432. return -EINVAL;
  433. }
  434. spin_unlock_irqrestore(&midi_spinlock, flags);
  435. return 1;
  436. }
  437. int emu10k1_seq_midi_start_read(int dev)
  438. {
  439. return 0;
  440. }
  441. int emu10k1_seq_midi_end_read(int dev)
  442. {
  443. return 0;
  444. }
  445. void emu10k1_seq_midi_kick(int dev)
  446. {
  447. }
  448. int emu10k1_seq_midi_buffer_status(int dev)
  449. {
  450. int count;
  451. struct midi_queue *queue;
  452. struct emu10k1_card *card;
  453. if (midi_devs[dev] == NULL || midi_devs[dev]->devc == NULL)
  454. return -EINVAL;
  455. count = 0;
  456. card = midi_devs[dev]->devc;
  457. queue = card->mpuout->firstmidiq;
  458. while (queue != NULL) {
  459. count++;
  460. if (queue == card->mpuout->lastmidiq)
  461. break;
  462. queue = queue->next;
  463. }
  464. return count;
  465. }
  466. #endif