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 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 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 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 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 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 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 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 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