1 /* 2 * Copyright (c) 2002, Thomas Kurschel 3 * Copyright 2004-2011 Haiku, Inc. All rights reserved. 4 * Distributed under the terms of the MIT License. 5 * 6 * Authors: 7 * Thomas Kurschel 8 * Clemens Zeidler, <haiku@clemens-zeidler.de> 9 * Alexander von Gluck IV, kallisti5@unixzen.com 10 */ 11 12 13 #include "driver.h" 14 #include "device.h" 15 #include "lock.h" 16 17 #include <stdlib.h> 18 #include <stdio.h> 19 #include <string.h> 20 21 #include <AGP.h> 22 #include <KernelExport.h> 23 #include <OS.h> 24 #include <PCI.h> 25 #include <SupportDefs.h> 26 27 28 #define TRACE_DRIVER 29 #ifdef TRACE_DRIVER 30 # define TRACE(x...) dprintf("radeon_hd: " x) 31 #else 32 # define TRACE(x...) ; 33 #endif 34 35 #define ERROR(x...) dprintf("radeon_hd: " x) 36 37 #define MAX_CARDS 1 38 39 40 // ATI / AMD cards starting at the Radeon X700 have an AtomBIOS 41 42 // list of supported devices 43 const struct supported_device { 44 uint32 pciID; 45 uint8 dceMajor; // Display block family 46 uint8 dceMinor; // Display block family 47 uint16 chipsetID; 48 uint32 chipsetFlags; 49 const char* deviceName; 50 } kSupportedDevices[] = { 51 // Marketing Names: Radeon X?00 52 // Intorduced: 2004 53 // Codename: Loki 54 // R420 Series (Radeon) DCE 0.0 (*very* early AtomBIOS) 55 56 // Marketing Names: Radeon X1?00 57 // Introduced: 2005 58 // Codename: Fudo 59 #if 0 60 {0x791e, 1, 0, RADEON_RS690, CHIP_IGP, "Radeon X1200"}, 61 {0x791f, 1, 0, RADEON_RS690, CHIP_IGP, "Radeon X1200"}, 62 {0x793f, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1200"}, 63 {0x7941, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1200"}, 64 {0x7942, 1, 0, RADEON_RS600, CHIP_IGP, "Radeon X1250"}, 65 {0x796c, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"}, 66 {0x796d, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"}, 67 {0x796e, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon 2100"}, 68 {0x796f, 1, 0, RADEON_RS740, CHIP_IGP, "Radeon RS740"}, 69 {0x7140, 1, 0, RADEON_RV515, CHIP_STD, "Radeon X1600"}, 70 {0x7100, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 71 {0x7104, 1, 0, RADEON_R520, CHIP_STD, "FireGL v7200"}, 72 {0x7109, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 73 {0x710a, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 74 {0x710b, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 75 {0x710c, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 76 {0x7120, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 77 {0x7129, 1, 0, RADEON_R520, CHIP_STD, "Radeon X1800"}, 78 #endif 79 80 // Marketing Names: Radeon HD 24xx - HD 42xx 81 // Introduced: 2006 82 // Codename: Pele 83 {0x94c7, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2350"}, 84 {0x94c1, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 2400"}, 85 {0x94c3, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2400"}, 86 {0x94cc, 2, 0, RADEON_RV610, CHIP_STD, "Radeon HD 2400"}, 87 {0x9586, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600"}, 88 {0x9588, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600"}, 89 {0x958a, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 2600 X2"}, 90 // Radeon 2700 - RV630 91 {0x9400, 2, 0, RADEON_R600, CHIP_STD, "Radeon HD 2900"}, 92 {0x9401, 2, 0, RADEON_R600, CHIP_STD, "Radeon HD 2900"}, 93 {0x9402, 2, 0, RADEON_R600, CHIP_STD, "Radeon HD 2900"}, 94 {0x9403, 2, 0, RADEON_R600, CHIP_STD, "Radeon HD 2900 Pro"}, 95 {0x9405, 2, 0, RADEON_R600, CHIP_STD, "Radeon HD 2900"}, 96 {0x940a, 2, 0, RADEON_R600, CHIP_STD, "Radeon FireGL V8650"}, 97 {0x940b, 2, 0, RADEON_R600, CHIP_STD, "Radeon FireGL V8600"}, 98 {0x940f, 2, 0, RADEON_R600, CHIP_STD, "Radeon FireGL V7600"}, 99 {0x9616, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3000"}, 100 {0x9611, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 3100"}, 101 {0x9613, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 3100"}, 102 {0x9610, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"}, 103 {0x9612, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"}, 104 {0x9615, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3200"}, 105 {0x9614, 2, 0, RADEON_RV610, CHIP_IGP, "Radeon HD 3300"}, 106 // Radeon 3430 - RV620 107 {0x95c5, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"}, 108 {0x95c6, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"}, 109 {0x95c7, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"}, 110 {0x95c9, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3450"}, 111 {0x95c4, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3470"}, 112 {0x95c0, 3, 0, RADEON_RV620, CHIP_STD, "Radeon HD 3550"}, 113 {0x9581, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"}, 114 {0x9583, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"}, 115 {0x9598, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3600"}, 116 {0x9591, 3, 0, RADEON_RV635, CHIP_STD, "Radeon HD 3600"}, 117 {0x9589, 2, 0, RADEON_RV630, CHIP_STD, "Radeon HD 3610"}, 118 // Radeon 3650 - RV635 119 // Radeon 3670 - RV635 120 {0x9507, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3830"}, 121 {0x9505, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850"}, 122 {0x9513, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850 X2"}, 123 {0x9515, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3850"}, 124 {0x9501, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3870"}, 125 {0x950F, 2, 0, RADEON_RV670, CHIP_STD, "Radeon HD 3870 X2"}, 126 {0x9710, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4200"}, 127 {0x9715, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4250"}, 128 {0x9712, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4270"}, 129 {0x9714, 3, 0, RADEON_RV620, CHIP_IGP, "Radeon HD 4290"}, 130 131 // Marketing Names: Radeon HD 4330 - HD 4890, HD 51xx, HD 5xxV 132 // Introduced: 2008 133 // Codename: Wekiva 134 // Radeon 4330 - RV710 135 {0x954f, 3, 2, RADEON_RV710, CHIP_IGP, "Radeon HD 4300"}, 136 {0x9552, 3, 2, RADEON_RV710, CHIP_IGP, "Radeon HD 4300"}, 137 {0x9555, 3, 2, RADEON_RV710, CHIP_STD, "Radeon HD 4350"}, 138 {0x9540, 3, 2, RADEON_RV710, CHIP_STD, "Radeon HD 4550"}, 139 {0x9480, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4650"}, 140 {0x9498, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4650"}, 141 {0x94b4, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4700"}, 142 {0x9490, 3, 2, RADEON_RV730, CHIP_STD, "Radeon HD 4710"}, 143 {0x94b3, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4770"}, 144 {0x94b5, 3, 2, RADEON_RV740, CHIP_STD, "Radeon HD 4770"}, 145 {0x944a, 3, 1, RADEON_RV770, CHIP_MOBILE, "Radeon HD 4850"}, 146 {0x944e, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4810"}, 147 {0x944c, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4830"}, 148 {0x9442, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4850"}, 149 {0x9443, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4850 X2"}, 150 {0x94a1, 3, 1, RADEON_RV770, CHIP_IGP, "Radeon HD 4860"}, 151 {0x9440, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4870"}, 152 {0x9441, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4870 X2"}, 153 {0x9460, 3, 1, RADEON_RV770, CHIP_STD, "Radeon HD 4890"}, 154 155 // From here on AMD no longer used numeric identifiers 156 157 // Marketing Names: Radeon HD 54xx ~ HD 63xx 158 // Introduced: 2009 159 // Codename: Evergreen 160 // Cedar 161 {0x68e1, 4, 0, RADEON_CEDAR, CHIP_STD, "Radeon HD 5430"}, 162 {0x68f9, 4, 0, RADEON_CEDAR, CHIP_STD, "Radeon HD 5450"}, 163 {0x68e0, 4, 0, RADEON_CEDAR, CHIP_IGP, "Radeon HD 5470"}, 164 // Redwood 165 {0x68da, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5500"}, 166 {0x68d9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5570"}, 167 {0x68b9, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5600"}, 168 {0x68c1, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5650"}, 169 {0x68d8, 4, 0, RADEON_REDWOOD, CHIP_STD, "Radeon HD 5670"}, 170 // Juniper 171 {0x68be, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 5700"}, 172 {0x68b8, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 5770"}, 173 // Juniper LE / XT (67X0 is rebranded 57X0 + tweaks) 174 {0x68bf, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 6750"}, 175 {0x68ba, 4, 0, RADEON_JUNIPER, CHIP_STD, "Radeon HD 6770"}, 176 // Cypress 177 {0x689e, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5800"}, 178 {0x6899, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5850"}, 179 {0x6898, 4, 0, RADEON_CYPRESS, CHIP_STD, "Radeon HD 5870"}, 180 // Hemlock 181 {0x689c, 4, 0, RADEON_HEMLOCK, CHIP_STD, "Radeon HD 5900"}, 182 // Fusion APUS 183 // Palm 184 {0x9804, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6250"}, 185 {0x9805, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6290"}, 186 {0x9807, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6290"}, 187 {0x9802, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6310"}, 188 {0x9803, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6310"}, 189 {0x9806, 4, 1, RADEON_PALM, CHIP_APU, "Radeon HD 6320"}, 190 // Sumo (no VGA / LVDS!, only DP) 191 {0x9640, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6550D"}, 192 {0x9641, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD SUMO M"}, 193 {0x9647, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6520G (M)"}, 194 {0x9648, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6480G (M)"}, 195 {0x964a, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD 6530D"}, 196 {0x964e, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD SUMO M"}, 197 {0x964f, 4, 1, RADEON_SUMO, CHIP_APU, "Radeon HD SUMO M"}, 198 // Sumo2 (no VGA / LVDS!, only DP) 199 {0x9642, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD 6370D"}, 200 {0x9643, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD SUMO2 M"}, 201 {0x9644, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD 6410D"}, 202 {0x9645, 4, 1, RADEON_SUMO2, CHIP_APU, "Radeon HD SUMO2 M"}, 203 204 // Radeon HD 64xx - HD 69xx 205 // Introduced: 2010 206 // Codename: Nothern Islands 207 // Caicos 208 {0x6760, 5, 0, RADEON_CAICOS, CHIP_MOBILE, "Radeon HD 6470M"}, 209 {0x6761, 5, 0, RADEON_CAICOS, CHIP_MOBILE, "Radeon HD 6430M"}, 210 {0x6762, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 211 {0x6763, 5, 0, RADEON_CAICOS, CHIP_DISCREET, "Radeon HD E6460"}, 212 {0x6764, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 213 {0x6765, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 214 {0x6766, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 215 {0x6767, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 216 {0x6768, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 217 {0x6770, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 6400"}, 218 {0x6778, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD CAICOS"}, 219 {0x6779, 5, 0, RADEON_CAICOS, CHIP_STD, "Radeon HD 6450"}, 220 // Turks 221 {0x6740, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6770M"}, 222 {0x6741, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6650M"}, 223 {0x6742, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD 6625M"}, 224 {0x6743, 5, 0, RADEON_TURKS, CHIP_DISCREET, "Radeon HD E6760"}, 225 {0x6744, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD TURKS M"}, 226 {0x6745, 5, 0, RADEON_TURKS, CHIP_MOBILE, "Radeon HD TURKS M"}, 227 {0x6746, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD TURKS"}, 228 {0x6747, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD TURKS"}, 229 {0x6748, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD TURKS"}, 230 {0x6749, 5, 0, RADEON_TURKS, CHIP_STD, "FirePro v4900"}, 231 {0x6750, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6500"}, 232 {0x6758, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6670"}, 233 {0x6759, 5, 0, RADEON_TURKS, CHIP_STD, "Radeon HD 6570"}, 234 // Barts 235 {0x673e, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6790"}, 236 {0x6739, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6850"}, 237 {0x6738, 5, 0, RADEON_BARTS, CHIP_STD, "Radeon HD 6870"}, 238 // Cayman 239 {0x6700, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 240 {0x6701, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 241 {0x6702, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 242 {0x6703, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 243 {0x6704, 5, 0, RADEON_CAYMAN, CHIP_STD, "FirePro v????"}, 244 {0x6705, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 245 {0x6706, 5, 0, RADEON_CAYMAN, CHIP_STD, "FirePro v????"}, 246 {0x6707, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 247 {0x6708, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 248 {0x6709, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 249 {0x6718, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6970"}, 250 {0x6719, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6950"}, 251 {0x671C, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD CAYMAN"}, 252 {0x671F, 5, 0, RADEON_CAYMAN, CHIP_STD, "Radeon HD 6900"}, 253 // Antilles 254 {0x671d, 5, 0, RADEON_ANTILLES, CHIP_STD, "Radeon HD 6990"}, 255 256 // Marketing Names: Radeon HD 74xx - HD 79xx 257 // Introduced: Late 2011 258 // Codename: Southern Islands 259 // Lombok 260 // Thames 261 // Tahiti 262 {0x679A, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7950"}, 263 {0x6798, 6, 0, RADEON_TAHITI, CHIP_STD, "Radeon HD 7970"} 264 // New Zealand 265 }; 266 267 268 int32 api_version = B_CUR_DRIVER_API_VERSION; 269 270 271 char* gDeviceNames[MAX_CARDS + 1]; 272 radeon_info* gDeviceInfo[MAX_CARDS]; 273 pci_module_info* gPCI; 274 mutex gLock; 275 276 277 static status_t 278 get_next_radeon_hd(int32* _cookie, pci_info &info, uint32 &type) 279 { 280 int32 index = *_cookie; 281 282 // find devices 283 284 for (; gPCI->get_nth_pci_info(index, &info) == B_OK; index++) { 285 // check vendor 286 if (info.vendor_id != VENDOR_ID_ATI 287 || info.class_base != PCI_display 288 || info.class_sub != PCI_vga) 289 continue; 290 291 // check device 292 for (uint32 i = 0; i < sizeof(kSupportedDevices) 293 / sizeof(kSupportedDevices[0]); i++) { 294 if (info.device_id == kSupportedDevices[i].pciID) { 295 type = i; 296 *_cookie = index + 1; 297 return B_OK; 298 } 299 } 300 } 301 302 return B_ENTRY_NOT_FOUND; 303 } 304 305 306 extern "C" const char** 307 publish_devices(void) 308 { 309 TRACE("%s\n", __func__); 310 return (const char**)gDeviceNames; 311 } 312 313 314 extern "C" status_t 315 init_hardware(void) 316 { 317 TRACE("%s\n", __func__); 318 319 status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI); 320 if (status != B_OK) { 321 ERROR("%s: ERROR: pci module unavailable\n", __func__); 322 return status; 323 } 324 325 int32 cookie = 0; 326 uint32 type; 327 pci_info info; 328 status = get_next_radeon_hd(&cookie, info, type); 329 330 put_module(B_PCI_MODULE_NAME); 331 return status; 332 } 333 334 335 extern "C" status_t 336 init_driver(void) 337 { 338 TRACE("%s\n", __func__); 339 340 status_t status = get_module(B_PCI_MODULE_NAME, (module_info**)&gPCI); 341 if (status != B_OK) { 342 ERROR("%s: ERROR: pci module unavailable\n", __func__); 343 return status; 344 } 345 346 mutex_init(&gLock, "radeon hd ksync"); 347 348 // find devices 349 350 int32 found = 0; 351 352 for (int32 cookie = 0; found < MAX_CARDS;) { 353 pci_info* info = (pci_info*)malloc(sizeof(pci_info)); 354 if (info == NULL) 355 break; 356 357 uint32 type; 358 status = get_next_radeon_hd(&cookie, *info, type); 359 if (status < B_OK) { 360 free(info); 361 break; 362 } 363 364 // create device names & allocate device info structure 365 366 char name[64]; 367 sprintf(name, "graphics/radeon_hd_%02x%02x%02x", 368 info->bus, info->device, 369 info->function); 370 371 gDeviceNames[found] = strdup(name); 372 if (gDeviceNames[found] == NULL) 373 break; 374 375 gDeviceInfo[found] = (radeon_info*)malloc(sizeof(radeon_info)); 376 if (gDeviceInfo[found] == NULL) { 377 free(gDeviceNames[found]); 378 break; 379 } 380 381 // initialize the structure for later use 382 383 memset(gDeviceInfo[found], 0, sizeof(radeon_info)); 384 gDeviceInfo[found]->init_status = B_NO_INIT; 385 gDeviceInfo[found]->id = found; 386 gDeviceInfo[found]->pci = info; 387 gDeviceInfo[found]->registers = (uint8*)info->u.h0.base_registers[0]; 388 gDeviceInfo[found]->pciID = kSupportedDevices[type].pciID; 389 gDeviceInfo[found]->deviceName = kSupportedDevices[type].deviceName; 390 gDeviceInfo[found]->chipsetID = kSupportedDevices[type].chipsetID; 391 gDeviceInfo[found]->dceMajor = kSupportedDevices[type].dceMajor; 392 gDeviceInfo[found]->dceMinor = kSupportedDevices[type].dceMinor; 393 gDeviceInfo[found]->chipsetFlags = kSupportedDevices[type].chipsetFlags; 394 395 ERROR("%s: GPU(%ld) %s, revision = 0x%x\n", __func__, found, 396 kSupportedDevices[type].deviceName, info->revision); 397 398 found++; 399 } 400 401 gDeviceNames[found] = NULL; 402 403 if (found == 0) { 404 mutex_destroy(&gLock); 405 put_module(B_AGP_GART_MODULE_NAME); 406 put_module(B_PCI_MODULE_NAME); 407 ERROR("%s: no supported devices found\n", __func__); 408 return ENODEV; 409 } 410 411 return B_OK; 412 } 413 414 415 extern "C" void 416 uninit_driver(void) 417 { 418 TRACE("%s\n", __func__); 419 420 mutex_destroy(&gLock); 421 422 // free device related structures 423 char* name; 424 for (int32 index = 0; (name = gDeviceNames[index]) != NULL; index++) { 425 free(gDeviceInfo[index]); 426 free(name); 427 } 428 429 put_module(B_PCI_MODULE_NAME); 430 } 431 432 433 extern "C" device_hooks* 434 find_device(const char* name) 435 { 436 int index; 437 438 TRACE("%s\n", __func__); 439 440 for (index = 0; gDeviceNames[index] != NULL; index++) { 441 if (!strcmp(name, gDeviceNames[index])) 442 return &gDeviceHooks; 443 } 444 445 ERROR("%s: %s wasn't found!\n", __func__, name); 446 return NULL; 447 } 448 449