1 /*
2 Copyright 1999, Be Incorporated. All Rights Reserved.
3 This file may be used under the terms of the Be Sample Code License.
4 */
5
6 #include <string.h>
7 #include <stdlib.h>
8 #include <signal.h>
9
10 #include "cm_private.h"
11
12
13 extern void dump_card(cmedia_pci_dev * card);
14
15 #if !defined(_KERNEL_EXPORT_H)
16 #include <KernelExport.h>
17 #endif /* _KERNEL_EXPORT_H */
18
19 #define MIDI_ACTIVE_SENSE 0xfe
20 #define SNOOZE_GRANULARITY 500
21
22 extern generic_mpu401_module * mpu401;
23
24 void
midi_interrupt_op(int32 op,void * data)25 midi_interrupt_op(
26 int32 op,
27 void * data)
28 {
29 midi_dev * port = (midi_dev *)data;
30 ddprintf(("port = %p\n", port));
31 if (op == B_MPU_401_ENABLE_CARD_INT) {
32 cpu_status cp;
33 ddprintf(("cmedia_pci: B_MPU_401_ENABLE_CARD_INT\n"));
34 cp = disable_interrupts();
35 acquire_spinlock(&port->card->hardware);
36 increment_interrupt_handler(port->card);
37 set_direct(port->card, 0x01, 0x00, 0x80);
38 set_indirect(port->card, 0x2A, 0x04, 0xff);
39 release_spinlock(&port->card->hardware);
40 restore_interrupts(cp);
41 }
42 else if (op == B_MPU_401_DISABLE_CARD_INT) {
43 /* turn off MPU interrupts */
44 cpu_status cp;
45 ddprintf(("cmedia_pci: B_MPU_401_DISABLE_CARD_INT\n"));
46 cp = disable_interrupts();
47 acquire_spinlock(&port->card->hardware);
48 set_direct(port->card, 0x01, 0x80, 0x80);
49 /* remove interrupt handler if necessary */
50 decrement_interrupt_handler(port->card);
51 release_spinlock(&port->card->hardware);
52 restore_interrupts(cp);
53 }
54 ddprintf(("cmedia_pci: midi_interrupt_op() done\n"));
55 }
56
57 static status_t midi_open(const char *name, uint32 flags, void **cookie);
58 static status_t midi_close(void *cookie);
59 static status_t midi_free(void *cookie);
60 static status_t midi_control(void *cookie, uint32 op, void *data, size_t len);
61 static status_t midi_read(void *cookie, off_t pos, void *data, size_t *len);
62 static status_t midi_write(void *cookie, off_t pos, const void *data, size_t *len);
63
64
65 device_hooks midi_hooks = {
66 &midi_open,
67 &midi_close,
68 &midi_free,
69 &midi_control,
70 &midi_read,
71 &midi_write,
72 NULL, /* select */
73 NULL, /* deselect */
74 NULL, /* readv */
75 NULL /* writev */
76 };
77
78 static status_t
midi_open(const char * name,uint32 flags,void ** cookie)79 midi_open(
80 const char * name,
81 uint32 flags,
82 void ** cookie)
83 {
84 int ix;
85 int ret;
86
87 ddprintf(("cmedia_pci: midi_open()\n"));
88
89 *cookie = NULL;
90 for (ix=0; ix<num_cards; ix++) {
91 if (!strcmp(name, cards[ix].midi.name)) {
92 break;
93 }
94 }
95 if (ix >= num_cards) {
96 ddprintf(("bad device\n"));
97 return ENODEV;
98 }
99
100 ddprintf(("cmedia_pci: mpu401: %p open(): %p driver: %p\n", mpu401, mpu401->open_hook, cards[ix].midi.driver));
101 ret = (*mpu401->open_hook)(cards[ix].midi.driver, flags, cookie);
102 if (ret >= B_OK) {
103 cards[ix].midi.cookie = *cookie;
104 atomic_add(&cards[ix].midi.count, 1);
105 }
106 ddprintf(("cmedia_pci: mpu401: open returns %x / %p\n", ret, *cookie));
107 return ret;
108 }
109
110
111 static status_t
midi_close(void * cookie)112 midi_close(
113 void * cookie)
114 {
115 ddprintf(("cmedia_pci: midi_close()\n"));
116 return (*mpu401->close_hook)(cookie);
117 }
118
119
120 static status_t
midi_free(void * cookie)121 midi_free(
122 void * cookie)
123 {
124 int ix;
125 status_t f;
126 ddprintf(("cmedia_pci: midi_free()\n"));
127 f = (*mpu401->free_hook)(cookie);
128 for (ix=0; ix<num_cards; ix++) {
129 if (cards[ix].midi.cookie == cookie) {
130 if (atomic_add(&cards[ix].midi.count, -1) == 1) {
131 cards[ix].midi.cookie = NULL;
132 ddprintf(("cleared %p card %d\n", cookie, ix));
133 }
134 break;
135 }
136 }
137 ddprintf(("cmedia_pci: midi_free() done\n"));
138 return f;
139 }
140
141
142 static status_t
midi_control(void * cookie,uint32 iop,void * data,size_t len)143 midi_control(
144 void * cookie,
145 uint32 iop,
146 void * data,
147 size_t len)
148 {
149 return (*mpu401->control_hook)(cookie, iop, data, len);
150 }
151
152
153 static status_t
midi_read(void * cookie,off_t pos,void * ptr,size_t * nread)154 midi_read(
155 void * cookie,
156 off_t pos,
157 void * ptr,
158 size_t * nread)
159 {
160 return (*mpu401->read_hook)(cookie, pos, ptr, nread);
161 }
162
163
164 static status_t
midi_write(void * cookie,off_t pos,const void * ptr,size_t * nwritten)165 midi_write(
166 void * cookie,
167 off_t pos,
168 const void * ptr,
169 size_t * nwritten)
170 {
171 return (*mpu401->write_hook)(cookie, pos, ptr, nwritten);
172 }
173
174
175 bool
midi_interrupt(cmedia_pci_dev * dev)176 midi_interrupt(
177 cmedia_pci_dev * dev)
178 {
179 if (!dev->midi.driver) {
180 // kprintf("aiigh\n");
181 return false;
182 }
183
184 return (*mpu401->interrupt_hook)(dev->midi.driver);
185 }
186
187