1#include <KernelExport.h> 2#include <Drivers.h> 3#include <Errors.h> 4#include <OS.h> 5#include <PCI.h> 6#include <malloc.h> 7#include <string.h> 8#include <stdio.h> 9 10#include "lala.h" 11 12#define MAX_DEVICES 8 13 14int32 api_version = B_CUR_DRIVER_API_VERSION; 15 16sem_id drv_sem; 17char * drv_path[MAX_DEVICES + 1]; 18audio_drv_t * drv_data[MAX_DEVICES]; 19int drv_open_count[MAX_DEVICES]; 20void * drv_cookie[MAX_DEVICES]; 21int drv_count; 22 23pci_module_info *pcimodule; 24 25extern driver_info_t driver_info; 26 27status_t 28init_hardware(void) 29{ 30 dprintf("init_hardware\n"); 31 return B_OK; 32} 33 34 35status_t 36init_driver(void) 37{ 38 struct pci_info info; 39 struct pci_info *pciinfo = &info; 40 int pciindex; 41 int devindex; 42 43 dprintf("init_driver\n"); 44 dprintf("driver base name '%s'\n", driver_info.basename); 45 46 if (get_module(B_PCI_MODULE_NAME, (module_info **) &pcimodule) < 0) { 47 return B_ERROR; 48 } 49 50 drv_sem = create_sem(1, "drv_sem"); 51 52 drv_count = 0; 53 54 for (pciindex = 0; B_OK == pcimodule->get_nth_pci_info(pciindex, pciinfo); pciindex++) { 55// dprintf("Checking PCI device, vendor 0x%04x, id 0x%04x, bus 0x%02x, dev 0x%02x, func 0x%02x, rev 0x%02x, api 0x%02x, sub 0x%02x, base 0x%02x\n", 56// pciinfo->vendor_id, pciinfo->device_id, pciinfo->bus, pciinfo->device, pciinfo->function, 57// pciinfo->revision, pciinfo->class_api, pciinfo->class_sub, pciinfo->class_base); 58 59 for (devindex = 0; driver_info.pci_id_table[devindex].vendor != 0; devindex++) { 60 if (driver_info.pci_id_table[devindex].vendor != -1 && driver_info.pci_id_table[devindex].vendor != pciinfo->vendor_id) 61 continue; 62 if (driver_info.pci_id_table[devindex].device != -1 && driver_info.pci_id_table[devindex].device != pciinfo->device_id) 63 continue; 64 if (driver_info.pci_id_table[devindex].revision != -1 && driver_info.pci_id_table[devindex].revision != pciinfo->revision) 65 continue; 66 if (driver_info.pci_id_table[devindex].class != -1 && driver_info.pci_id_table[devindex].class != pciinfo->class_base) 67 continue; 68 if (driver_info.pci_id_table[devindex].subclass != -1 && driver_info.pci_id_table[devindex].subclass != pciinfo->class_sub) 69 continue; 70 if (pciinfo->header_type == 0) { 71 if (driver_info.pci_id_table[devindex].subsystem_vendor != -1 && driver_info.pci_id_table[devindex].subsystem_vendor != pciinfo->u.h0.subsystem_vendor_id) 72 continue; 73 if (driver_info.pci_id_table[devindex].subsystem_device != -1 && driver_info.pci_id_table[devindex].subsystem_device != pciinfo->u.h0.subsystem_id) 74 continue; 75 } 76 77 dprintf("found device '%s'\n", driver_info.pci_id_table[devindex].name); 78 79 drv_path[drv_count] = (char *) malloc(strlen(driver_info.basename) + 5); 80 sprintf(drv_path[drv_count], "%s/%d", driver_info.basename, drv_count + 1); 81 82 drv_data[drv_count] = (audio_drv_t *) malloc(sizeof(audio_drv_t)); 83 drv_data[drv_count]->pci = pcimodule; 84 drv_data[drv_count]->bus = pciinfo->bus; 85 drv_data[drv_count]->device = pciinfo->device; 86 drv_data[drv_count]->function = pciinfo->function; 87 drv_data[drv_count]->name = driver_info.pci_id_table[devindex].name; 88 drv_data[drv_count]->param = driver_info.pci_id_table[devindex].param; 89 drv_open_count[drv_count] = 0; 90 91 drv_count++; 92 break; 93 } 94 if (drv_count == MAX_DEVICES) 95 break; 96 } 97 98 drv_path[drv_count + 1] = NULL; 99 100 return B_OK; 101} 102 103void 104uninit_driver(void) 105{ 106 int i; 107 dprintf("uninit_driver\n"); 108 109 for (i = 0; i < drv_count; i++) { 110 free(drv_path[i]); 111 free(drv_data[i]); 112 } 113 delete_sem(drv_sem); 114} 115 116static status_t 117driver_open(const char *name, uint32 flags, void** cookie) 118{ 119 int index; 120 status_t res; 121 122 acquire_sem(drv_sem); 123 124 for (index = 0; index < drv_count; index++) { 125 if (0 == strcmp(drv_path[index], name)) 126 break; 127 } 128 if (index == drv_count) { // name not found 129 release_sem(drv_sem); 130 return B_ERROR; 131 } 132 *cookie = (void *) index; 133 134 if (drv_open_count[index] == 0) { 135 res = driver_info.attach(drv_data[index], &drv_cookie[index]); 136 drv_open_count[index] = (res == B_OK) ? 1 : 0; 137 } else { 138 res = B_OK; 139 drv_open_count[index]++; 140 } 141 142 release_sem(drv_sem); 143 144 return res; 145} 146 147static status_t 148driver_close(void* cookie) 149{ 150 dprintf("close\n"); 151 return B_OK; 152} 153 154static status_t 155driver_free(void* cookie) 156{ 157 int index; 158 status_t res; 159 160 dprintf("free\n"); 161 162 index = (int) cookie; 163 164 acquire_sem(drv_sem); 165 166 drv_open_count[index]--; 167 168 if (drv_open_count[index] == 0) 169 res = driver_info.detach(drv_data[index], drv_cookie[index]); 170 else 171 res = B_OK; 172 173 release_sem(drv_sem); 174 175 return res; 176} 177 178static status_t 179driver_control(void* cookie, uint32 op, void* arg, size_t len) 180{ 181 return B_OK; 182} 183 184static status_t 185driver_read(void* cookie, off_t position, void *buf, size_t* num_bytes) 186{ 187 *num_bytes = 0; 188 return B_IO_ERROR; 189} 190 191static status_t 192driver_write(void* cookie, off_t position, const void* buffer, size_t* num_bytes) 193{ 194 *num_bytes = 0; 195 return B_IO_ERROR; 196} 197 198device_hooks driver_hooks = { 199 driver_open, 200 driver_close, 201 driver_free, 202 driver_control, 203 driver_read, 204 driver_write 205}; 206 207const char ** 208publish_devices(void) 209{ 210 dprintf("publish_devices\n"); 211 return (const char **) drv_path; 212} 213 214device_hooks* 215find_device(const char* name) 216{ 217 dprintf("find_device\n"); 218 return &driver_hooks; 219} 220 221