1 /** 2 * pci.c 3 * @author: Dirk Vogt 4 * @date: 2010-02-18 5 */ 6 7 #include "common.h" 8 9 #include <ddekit/pci.h> 10 #include <ddekit/panic.h> 11 #include <minix/syslib.h> 12 13 #ifdef DDEBUG_LEVEL_PCI 14 #undef DDEBUG 15 #define DDEBUG DDEBUG_LEVEL_PCI 16 #endif 17 18 #include "util.h" 19 #include "debug.h" 20 21 #define PCI_MAX_DEVS 32 22 23 #define PCI_TAKE_ALL (-1) 24 25 struct ddekit_pci_dev { 26 int devind; /* thats how we identify the defice at the pci server */ 27 ddekit_uint16_t vid; /* as we get them for */ 28 /* free during iteration store them */ 29 ddekit_uint16_t did; 30 int bus; 31 int slot; /* slot should equal index in dev array */ 32 int func; /* don't support multiple functionalities yet -> 0 */ 33 }; 34 35 struct ddekit_pci_dev pci_devs[PCI_MAX_DEVS]; 36 37 static struct ddekit_pci_dev * ddekit_get_dev_helper(int bus, int slot, 38 int func); 39 40 /****************************************************************************/ 41 /* ddekit_pci_init_only_one */ 42 /****************************************************************************/ 43 void ddekit_pci_init_only_one(int skip) 44 { 45 /* 46 * If skip is not PCI_TAKE_ALL this function will skip skip PCI DEVICES 47 * and than only take on PCI device. 48 */ 49 50 int res, count, more, take_all = 0; 51 52 if (skip == -1) { 53 take_all = 1; 54 } 55 56 DDEBUG_MSG_INFO("Initializing PCI subsystem..."); 57 58 pci_init(); 59 60 /* 61 * Iterate the PCI-bus 62 */ 63 64 more = 1; 65 66 for (count = 0 ; count < PCI_MAX_DEVS ; count++) { 67 68 struct ddekit_pci_dev *d = &pci_devs[count]; 69 70 if (more) { 71 if ( count==0 ) { 72 res = pci_first_dev(&d->devind, &d->vid, &d->did); 73 } else { 74 d->devind = pci_devs[count-1].devind; 75 res = pci_next_dev(&d->devind, &d->vid, &d->did); 76 } 77 78 if (res && d->devind!=0 && (take_all || skip == 0)) { 79 80 DDEBUG_MSG_VERBOSE("Found pci device: " 81 "(ind: %x, vid: %x, did: %x) " 82 "mapped to slot %x", 83 d->devind, d->vid, d->did, count); 84 d->slot = count; 85 d->bus = 0; 86 d->func = 0; 87 res = pci_reserve_ok(d->devind); 88 if (res != 0) { 89 ddekit_panic("ddekit_pci_init_only_one: " 90 "pci_reserve_ok failed (%d)\n",res); 91 } 92 93 } else { 94 /* no more PCI devices */ 95 DDEBUG_MSG_VERBOSE("Found %d PCI devices.", count); 96 d->devind = -1; 97 more = 0; 98 } /*if (res) */ 99 } else { 100 d->devind = -1; 101 } 102 if (!take_all) { 103 skip--; 104 } 105 } 106 } 107 108 /****************************************************************************/ 109 /* ddekit_pci_get_device_id */ 110 /****************************************************************************/ 111 void ddekit_pci_init(void) 112 { 113 ddekit_pci_init_only_one(DDEKIT_PCI_ANY_ID); 114 } 115 116 /****************************************************************************/ 117 /* ddekit_pci_get_device_id */ 118 /****************************************************************************/ 119 int ddekit_pci_get_device(int nr, int *bus, int *slot, int *func) 120 { 121 if(nr >= 0 && nr < PCI_MAX_DEVS) { 122 123 *bus = 0; 124 *slot = nr; 125 *func =0; 126 127 return 0; 128 } 129 130 return -1; 131 } 132 133 /****************************************************************************/ 134 /* ddekit_pci_get_device_id */ 135 /****************************************************************************/ 136 static struct ddekit_pci_dev * 137 ddekit_get_dev_helper(int bus, int slot, int func) 138 { 139 /* 140 * Used internally to look up devices. 141 * Should make it easier to support multiple buses somewhen 142 */ 143 struct ddekit_pci_dev * ret = 0; 144 if (slot >= 0 && slot < PCI_MAX_DEVS) { 145 ret = &pci_devs[slot]; 146 } 147 if (ret->devind == -1) { 148 ret = 0; 149 } 150 return ret; 151 } 152 153 /****************************************************************************/ 154 /* ddekit_pci_read */ 155 /****************************************************************************/ 156 int ddekit_pci_read 157 (int bus, int slot, int func, int pos, int len, ddekit_uint32_t *val) 158 { 159 switch(len) { 160 case 1: 161 return ddekit_pci_readb(bus, slot, func, pos, 162 (ddekit_uint8_t*) val); 163 case 2: 164 return ddekit_pci_readw(bus, slot, func, pos, 165 (ddekit_uint16_t*) val); 166 case 4: 167 return ddekit_pci_readl(bus, slot, func, pos, val); 168 default: return -1; 169 } 170 } 171 172 /****************************************************************************/ 173 /* ddekit_pci_write */ 174 /****************************************************************************/ 175 int ddekit_pci_write 176 (int bus, int slot, int func, int pos, int len, ddekit_uint32_t val) 177 { 178 switch(len) { 179 case 1: 180 return ddekit_pci_writeb(bus, slot, func, pos, 181 (ddekit_uint8_t) val); 182 case 2: 183 return ddekit_pci_writew(bus, slot, func, pos, 184 (ddekit_uint16_t) val); 185 case 4: 186 return ddekit_pci_writel(bus, slot, func, pos, val); 187 default: return -1; 188 } 189 } 190 191 /****************************************************************************/ 192 /* ddekit_pci_readb */ 193 /****************************************************************************/ 194 int ddekit_pci_readb (int bus, int slot, int func, int pos, ddekit_uint8_t *val) { 195 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 196 if (func!=0) { 197 *val=0; 198 return 0; 199 } 200 if (dev) { 201 *val = pci_attr_r8 (dev->devind, pos); 202 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", 203 bus, slot, func, pos, *val); 204 return 0; 205 } 206 return -1; 207 } 208 209 /****************************************************************************/ 210 /* ddekit_pci_readw */ 211 /****************************************************************************/ 212 int ddekit_pci_readw 213 (int bus, int slot, int func, int pos, ddekit_uint16_t *val) { 214 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 215 if (func!=0) { 216 *val=0; 217 return 0; 218 } 219 if (dev) { 220 *val = pci_attr_r16 (dev->devind, pos); 221 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", 222 bus, slot, func, pos, *val); 223 return 0; 224 } 225 return -1; 226 } 227 228 /****************************************************************************/ 229 /* ddekit_pci_readl */ 230 /****************************************************************************/ 231 int ddekit_pci_readl 232 (int bus, int slot, int func, int pos, ddekit_uint32_t *val) { 233 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 234 if (func!=0) { 235 *val=0; 236 return 0; 237 } 238 if (dev) { 239 *val = pci_attr_r32 (dev->devind, pos); 240 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", 241 bus, slot, func, pos, *val); 242 return 0; 243 } 244 return -1; 245 } 246 247 /****************************************************************************/ 248 /* ddekit_pci_writeb */ 249 /****************************************************************************/ 250 int ddekit_pci_writeb 251 (int bus, int slot, int func, int pos, ddekit_uint8_t val) { 252 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 253 if (dev) { 254 pci_attr_w8 (dev->devind, pos, val); 255 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", 256 bus, slot, func, pos, val); 257 return 0; 258 } 259 return -1; 260 } 261 262 /****************************************************************************/ 263 /* ddekit_pci_writel */ 264 /****************************************************************************/ 265 int ddekit_pci_writew 266 (int bus, int slot, int func, int pos, ddekit_uint16_t val) { 267 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 268 if (dev) { 269 pci_attr_w16 (dev->devind, pos, val); 270 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x", 271 bus,slot,func,pos, val); 272 return 0; 273 } 274 return -1; 275 } 276 277 /****************************************************************************/ 278 /* ddekit_pci_writel */ 279 /****************************************************************************/ 280 int ddekit_pci_writel 281 (int bus, int slot, int func, int pos, ddekit_uint32_t val) { 282 struct ddekit_pci_dev * dev = ddekit_get_dev_helper(bus, slot, func); 283 if (dev) { 284 pci_attr_w32 (dev->devind, pos, val); 285 DDEBUG_MSG_VERBOSE("bus: %d, slot: %d, func: %d, pos: %x %x",bus,slot,func,pos, val); 286 return 0; 287 } 288 return -1; 289 } 290 291 /****************************************************************************/ 292 /* ddekit_pci_find_device */ 293 /****************************************************************************/ 294 struct ddekit_pci_dev *ddekit_pci_find_device 295 (int *bus, int *slot, int *func, struct ddekit_pci_dev *start) 296 { 297 int i,search=0; 298 299 if(start) 300 search = 1; 301 302 for(i=0; i < PCI_MAX_DEVS ; i++) 303 { 304 /* start searching? */ 305 if (search) 306 search = (&pci_devs[i]==start); 307 else 308 { 309 struct ddekit_pci_dev * dev = &pci_devs[i]; 310 if ((*slot==dev->slot || *slot == DDEKIT_PCI_ANY_ID) 311 && (*func==dev->func || *func == DDEKIT_PCI_ANY_ID)) 312 { 313 *bus = 0; 314 *slot = dev->slot; 315 *func = dev->func; 316 return dev; 317 } 318 } 319 } 320 return 0; 321 } 322 323 /****************************************************************************/ 324 /* ddekit_pci_get_vendor */ 325 /****************************************************************************/ 326 unsigned short ddekit_pci_get_vendor(struct ddekit_pci_dev *dev) 327 { 328 return dev->vid; 329 } 330 331 /****************************************************************************/ 332 /* ddekit_pci_get_device_id */ 333 /****************************************************************************/ 334 unsigned short ddekit_pci_get_device_id(struct ddekit_pci_dev *dev) 335 { 336 return dev->did; 337 } 338 339 /* 340 * XXX: Those are neither used be DDEFBSD or DDELinux implement them 341 * when you need them 342 */ 343 344 /****************************************************************************/ 345 /* ddekit_pci_enable_device */ 346 /****************************************************************************/ 347 int ddekit_pci_enable_device(struct ddekit_pci_dev *dev) 348 { 349 WARN_UNIMPL; 350 return 0; 351 } 352 353 /****************************************************************************/ 354 /* ddekit_pci_disable_device */ 355 /****************************************************************************/ 356 int ddekit_pci_disable_device(struct ddekit_pci_dev *dev) 357 { 358 WARN_UNIMPL; 359 return 0; 360 } 361 362 /****************************************************************************/ 363 /* ddekit_pci_set_master */ 364 /****************************************************************************/ 365 void ddekit_pci_set_master(struct ddekit_pci_dev *dev) 366 { 367 WARN_UNIMPL; 368 } 369 370 371 /****************************************************************************/ 372 /* ddekit_pci_get_sub_vendor */ 373 /****************************************************************************/ 374 unsigned short ddekit_pci_get_sub_vendor(struct ddekit_pci_dev *dev) 375 { 376 WARN_UNIMPL; 377 return 0; 378 } 379 380 /****************************************************************************/ 381 /* ddekit_pci_get_sub_device */ 382 /****************************************************************************/ 383 unsigned short ddekit_pci_get_sub_device(struct ddekit_pci_dev *dev) 384 { 385 WARN_UNIMPL; 386 return 0; 387 } 388 389 /****************************************************************************/ 390 /* ddekit_pci_get_dev_class */ 391 /****************************************************************************/ 392 unsigned ddekit_pci_get_dev_class(struct ddekit_pci_dev *dev) 393 { 394 WARN_UNIMPL; 395 return 0; 396 } 397 398 /****************************************************************************/ 399 /* ddekit_pci_get_irq */ 400 /****************************************************************************/ 401 unsigned long 402 ddekit_pci_get_irq(struct ddekit_pci_dev *dev) 403 { 404 WARN_UNIMPL; 405 return 0; 406 } 407 408 /****************************************************************************/ 409 /* ddekit_pci_get_name */ 410 /****************************************************************************/ 411 char *ddekit_pci_get_name(struct ddekit_pci_dev *dev) 412 { 413 WARN_UNIMPL; 414 return 0; 415 } 416 417 /****************************************************************************/ 418 /* ddekit_pci_get_slot_name */ 419 /****************************************************************************/ 420 char *ddekit_pci_get_slot_name(struct ddekit_pci_dev *dev) 421 { 422 WARN_UNIMPL; 423 return 0; 424 } 425 426 /****************************************************************************/ 427 /* ddekit_pci_get_resource */ 428 /****************************************************************************/ 429 ddekit_pci_res_t * 430 ddekit_pci_get_resource(struct ddekit_pci_dev *dev, unsigned int idx) 431 { 432 WARN_UNIMPL; 433 return 0; 434 } 435 436 /****************************************************************************/ 437 /* ddekit_pci_irq_enable */ 438 /****************************************************************************/ 439 int ddekit_pci_irq_enable 440 (int bus, int slot, int func, int pin, int *irq) 441 { 442 /* call not needed */ 443 #if 0 444 WARN_UNIMPL; 445 #endif 446 return 0; 447 } 448 449