Changeset 63 for GPL/trunk/lib32/pci.c
- Timestamp:
- Jan 3, 2006, 11:33:10 PM (20 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/lib32/pci.c
r35 r63 41 41 #include <osspci.h> 42 42 43 #define MAX_PCI_BUSSES 16 44 #define MAX_PCI_DEVICES 16 45 43 46 struct pci_dev pci_devices[MAX_PCI_DEVICES] = {0}; 44 47 struct pci_bus pci_busses[MAX_PCI_BUSSES] = {0}; 45 48 46 HRESMGR hResMgr = 0;47 48 49 BOOL fSuspended = FALSE; 49 50 extern int nrCardsDetected; 50 //****************************************************************************** 51 //****************************************************************************** 52 OSSRET OSS32_APMResume() 53 { 54 int i; 55 struct pci_driver *driver; 56 57 dprintf(("OSS32_APMResume")); 58 for(i=0;i<MAX_PCI_DEVICES;i++) 59 { 60 if(pci_devices[i].devfn) 61 { 62 driver = pci_devices[i].pcidriver; 63 if(driver && driver->resume) { 64 driver->resume(&pci_devices[i]); 65 fSuspended = FALSE; 66 } 67 } 68 } 69 fSuspended = FALSE; 70 return OSSERR_SUCCESS; 71 } 72 //****************************************************************************** 73 //****************************************************************************** 74 OSSRET OSS32_APMSuspend() 75 { 76 int i; 77 struct pci_driver *driver; 78 79 dprintf(("OSS32_APMSuspend")); 80 fSuspended = TRUE; 81 for(i=0;i<MAX_PCI_DEVICES;i++) 82 { 83 if(pci_devices[i].devfn) 84 { 85 driver = pci_devices[i].pcidriver; 86 if(driver && driver->suspend) { 87 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold); 88 } 89 } 90 } 91 return OSSERR_SUCCESS; 92 } 93 //****************************************************************************** 94 //****************************************************************************** 95 int pcidev_prepare(struct pci_dev *dev) 96 { 97 dprintf(("pcidev_prepare %x not implemented", dev)); 98 return 1; //todo: correct return value?? 99 } 100 //****************************************************************************** 101 //****************************************************************************** 102 int pcidev_activate(struct pci_dev *dev) 103 { 104 dprintf(("pcidev_activate %x not implemented", dev)); 105 return 1; //todo: correct return value?? 106 } 107 //****************************************************************************** 108 //****************************************************************************** 109 int pcidev_deactivate(struct pci_dev *dev) 110 { 111 dprintf(("pcidev_deactivate %x not implemented", dev)); 112 return 1; //todo: correct return value?? 113 } 51 114 52 115 53 #define PCI_CONFIG_ENABLE 0x80000000 116 54 #define PCI_CONFIG_ADDRESS 0xCF8 117 55 #define PCI_CONFIG_DATA 0xCFC 118 /* 119 * get number of devices of given PCIID 120 */ 121 int pci_get_dev_num(ULONG pciId) 122 { 123 ULONG devNr, busNr, funcNr, temp, cfgaddrreg, detectedId; 124 int found = 0; 56 57 58 //****************************************************************************** 59 #define CONFIG_CMD(dev, where) \ 60 (PCI_CONFIG_ENABLE | (dev->bus->number<<16) | (dev->devfn<<8) | (where & ~3)) 61 //****************************************************************************** 62 int pci_read_config_byte(struct pci_dev *dev, int where, u8 *value) 63 { 64 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 65 *value = inb(PCI_CONFIG_DATA + (where&3)); 66 return PCIBIOS_SUCCESSFUL; 67 } 68 //****************************************************************************** 69 //****************************************************************************** 70 int pci_read_config_word(struct pci_dev *dev, int where, u16 *value) 71 { 72 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 73 *value = inw(PCI_CONFIG_DATA + (where&2)); 74 return PCIBIOS_SUCCESSFUL; 75 } 76 //****************************************************************************** 77 //****************************************************************************** 78 int pci_read_config_dword(struct pci_dev *dev, int where, u32 *value) 79 { 80 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 81 *value = inl(PCI_CONFIG_DATA); 82 return PCIBIOS_SUCCESSFUL; 83 } 84 //****************************************************************************** 85 //****************************************************************************** 86 int pci_write_config_byte(struct pci_dev *dev, int where, u8 value) 87 { 88 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 89 outb(value, PCI_CONFIG_DATA + (where&3)); 90 return PCIBIOS_SUCCESSFUL; 91 } 92 //****************************************************************************** 93 //****************************************************************************** 94 int pci_write_config_word(struct pci_dev *dev, int where, u16 value) 95 { 96 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 97 outw(value, PCI_CONFIG_DATA + (where&2)); 98 return PCIBIOS_SUCCESSFUL; 99 } 100 //****************************************************************************** 101 //****************************************************************************** 102 int pci_write_config_dword(struct pci_dev *dev, int where, u32 value) 103 { 104 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 105 outl(value, PCI_CONFIG_DATA); 106 return PCIBIOS_SUCCESSFUL; 107 } 108 //****************************************************************************** 109 //****************************************************************************** 110 int pcidev_prepare(struct pci_dev *dev) 111 { 112 dprintf(("pcidev_prepare %x not implemented", dev)); 113 return 1; //todo: correct return value?? 114 } 115 //****************************************************************************** 116 //****************************************************************************** 117 int pcidev_activate(struct pci_dev *dev) 118 { 119 dprintf(("pcidev_activate %x not implemented", dev)); 120 return 1; //todo: correct return value?? 121 } 122 //****************************************************************************** 123 //****************************************************************************** 124 int pcidev_deactivate(struct pci_dev *dev) 125 { 126 dprintf(("pcidev_deactivate %x not implemented", dev)); 127 return 1; //todo: correct return value?? 128 } 129 130 131 132 //****************************************************************************** 133 //****************************************************************************** 134 static int pci_query_device(unsigned int vendor, unsigned int device, 135 struct pci_dev near *pcidev, int idx) 136 { 137 int resNo, addr, found = 0; 138 u32 devNr, busNr, funcNr, detectedId, pciId, cfgaddrreg, temp, temp2; 139 u8 headerType; 140 141 pciId = (device << 16) | vendor; 125 142 126 143 cfgaddrreg = inl(PCI_CONFIG_ADDRESS); … … 131 148 for(funcNr=0;funcNr<8;funcNr++) 132 149 { 133 temp = ((ULONG)((ULONG)devNr<<11UL) + ((ULONG)busNr<<16UL) + ((ULONG)funcNr << 8UL));134 135 outl( PCI_CONFIG_ENABLE|temp, PCI_CONFIG_ADDRESS);150 headerType = 0; 151 temp = PCI_CONFIG_ENABLE | (busNr<<16) | (devNr<<11) | (funcNr<<8); 152 outl(temp, PCI_CONFIG_ADDRESS); 136 153 detectedId = inl(PCI_CONFIG_DATA); 137 // printk("det: %x, need: %x\n", detectedId, pciId); 138 if(detectedId == pciId) 139 found++; 154 if( detectedId != 0xffffffff ) 155 { 156 outl(temp | (PCI_HEADER_TYPE & ~3), PCI_CONFIG_ADDRESS); 157 headerType = inb(PCI_CONFIG_DATA + (PCI_HEADER_TYPE & 3)); 158 } 159 // printk("det: %x (%x), need: %x\n", detectedId, headerType, pciId); 160 161 if( detectedId == pciId && 162 (headerType & 0x7f) == PCI_HEADER_TYPE_NORMAL ) 163 { 164 if( found++ == idx ) 165 { 166 memset((void near *)pcidev, 0, sizeof(struct pci_dev)); 167 168 pcidev->vendor = vendor; 169 pcidev->device = device; 170 pcidev->bus = &pci_busses[busNr]; 171 pcidev->bus->number = busNr; 172 pcidev->devfn = (devNr << 3) | funcNr; 173 pcidev->hdr_type = headerType & 0x7f; 174 175 pcidev->prepare = pcidev_prepare; 176 pcidev->activate = pcidev_activate; 177 pcidev->deactivate = pcidev_deactivate; 178 pcidev->active = 1; 179 pcidev->ro = 0; 180 pcidev->sibling = NULL; 181 pcidev->next = NULL; 182 pcidev->dma_mask = 0xFFFFFFFF; 183 184 // Subsystem ID 185 pci_read_config_word(pcidev, PCI_SUBSYSTEM_VENDOR_ID, 186 &pcidev->subsystem_vendor); 187 pci_read_config_word(pcidev, PCI_SUBSYSTEM_ID, 188 &pcidev->subsystem_device); 189 190 // I/O and MEM 191 resNo = 0; 192 for( addr = PCI_BASE_ADDRESS_0; addr <= PCI_BASE_ADDRESS_5; addr += 4 ) 193 { 194 pci_read_config_dword(pcidev, addr, &temp); 195 if( temp != 0 && temp != 0xffffffff ) 196 { 197 pci_write_config_dword(pcidev, addr, 0xffffffff); 198 pci_read_config_dword(pcidev, addr, &temp2); 199 pci_write_config_dword(pcidev, addr, temp); 200 201 if( temp & PCI_BASE_ADDRESS_SPACE_IO ) 202 { 203 pcidev->resource[resNo].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 204 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_IO_MASK; 205 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 206 ~(temp2 & PCI_BASE_ADDRESS_IO_MASK) + 1; 207 } 208 else 209 { 210 pcidev->resource[resNo].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE; 211 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_MEM_MASK; 212 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 213 ~(temp2 & PCI_BASE_ADDRESS_MEM_MASK) + 1; 214 } 215 216 resNo++; 217 218 } 219 } 220 221 // IRQ and PIN 222 pci_read_config_dword(pcidev, PCI_INTERRUPT_LINE, &temp); 223 if( (u8)temp && (u8)temp != 0xff ) 224 { 225 pcidev->irq_resource[0].flags = IORESOURCE_IRQ; 226 pcidev->irq_resource[0].start = 227 pcidev->irq_resource[0].end = temp & 0xffff; 228 pcidev->irq = (u8)temp; 229 } 230 231 return 1; 232 } 233 } 234 235 // don't need to check more, if function 0 not present or single 236 if( funcNr == 0 && !(headerType & 0x80) ) break; 140 237 } 141 238 } 142 } 143 144 if(!found) { 145 outl(cfgaddrreg, PCI_CONFIG_ADDRESS); 146 return 0; 147 } 148 return found; 149 } 150 //****************************************************************************** 151 //TODO: Doesn't completely fill in the pci_dev structure 152 //****************************************************************************** 153 int FindPCIDevice(unsigned int vendor, unsigned int device, struct pci_dev near *pcidev, int idx) 154 { 155 IDC_RESOURCE idcres; 156 int i, residx = 0; 157 158 pcidev->prepare = pcidev_prepare; 159 pcidev->activate = pcidev_activate; 160 pcidev->deactivate = pcidev_deactivate; 161 pcidev->active = 1; 162 pcidev->ro = 0; 163 pcidev->sibling = NULL; 164 pcidev->next = NULL; 165 pcidev->vendor = vendor; 166 pcidev->device = device; 167 pcidev->dma_mask = 0xFFFFFFFF; 168 169 170 // printk("FindPCIDevice vend: %x, id: %x\n",vendor, device); 171 hResMgr = 0; 172 hResMgr = RMFindPCIDevice(vendor, device, &idcres, idx); 173 if(hResMgr == 0) { 174 return FALSE; 175 } 176 pcidev->devfn = idcres.devfn; 177 //pcidev->devfn = idcres.devfn + 1; 178 179 for(i=0;i<MAX_RES_IO;i++) { 180 if(idcres.io[i] != 0xffff) { 181 pcidev->resource[residx].name = 0; 182 pcidev->resource[residx].child = 0; 183 pcidev->resource[residx].sibling = 0; 184 pcidev->resource[residx].parent = 0; 185 pcidev->resource[residx].start = idcres.io[i]; 186 pcidev->resource[residx].end = idcres.io[i] + idcres.iolength[i]; //inclusive?? 187 pcidev->resource[residx].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 188 189 residx++; 190 } 191 } 192 for(i=0;i<MAX_RES_MEM;i++) { 193 if(idcres.mem[i] != 0xffffffff) { 194 pcidev->resource[residx].name = 0; 195 pcidev->resource[residx].child = 0; 196 pcidev->resource[residx].sibling = 0; 197 pcidev->resource[residx].parent = 0; 198 pcidev->resource[residx].start = idcres.mem[i]; 199 pcidev->resource[residx].end = idcres.mem[i] + idcres.memlength[i]; //inclusive?? 200 pcidev->resource[residx].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE; 201 printk("residx: %i start: %x\n", residx, pcidev->resource[residx].start); 202 residx++; 203 } 204 } 205 for(i=0;i<MAX_RES_DMA;i++) { 206 if(idcres.dma[i] != 0xffff) { 207 pcidev->dma_resource[i].name = 0; 208 pcidev->dma_resource[i].child = 0; 209 pcidev->dma_resource[i].sibling = 0; 210 pcidev->dma_resource[i].parent = 0; 211 pcidev->dma_resource[i].start = idcres.dma[i]; 212 pcidev->dma_resource[i].end = idcres.dma[i]; 213 //todo: 8/16 bits 214 pcidev->dma_resource[i].flags = IORESOURCE_DMA; 215 } 216 } 217 for(i=0;i<MAX_RES_IRQ;i++) { 218 if(idcres.irq[i] != 0xffff) { 219 pcidev->irq_resource[i].name = 0; 220 pcidev->irq_resource[i].child = 0; 221 pcidev->irq_resource[i].sibling = 0; 222 pcidev->irq_resource[i].parent = 0; 223 pcidev->irq_resource[i].start = idcres.irq[i]; 224 pcidev->irq_resource[i].end = idcres.irq[i]; 225 //todo: irq flags 226 pcidev->irq_resource[9].flags = IORESOURCE_IRQ; 227 } 228 } 229 if(pcidev->irq_resource[0].start != 0xffff) { 230 pcidev->irq = pcidev->irq_resource[0].start; 231 } 232 else pcidev->irq = 0; 233 234 if(idcres.busnr > MAX_PCI_BUSSES) { 235 DebugInt3(); 236 return FALSE; 237 } 238 pcidev->bus = &pci_busses[idcres.busnr]; 239 pcidev->bus->number = idcres.busnr; 240 241 pci_read_config_word(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &pcidev->subsystem_vendor); 242 pci_read_config_word(pcidev, PCI_SUBSYSTEM_ID, &pcidev->subsystem_device); 243 244 return TRUE; 245 } 239 } 240 outl(cfgaddrreg, PCI_CONFIG_ADDRESS); 241 return 0; 242 243 } 244 246 245 //****************************************************************************** 247 246 //****************************************************************************** … … 249 248 { 250 249 int i, idx; 251 HRESMGR hResMgrTmp = 0;252 250 253 251 if((int)from < 8) { 254 252 idx = (int)from; // dirty hack 255 // return 0;253 // return 0; 256 254 } else 257 255 idx = 0; 258 // printk("searching device. vendor %x, pci id %x, idx %i\n",vendor,device, idx); 259 //not very pretty 260 if(hResMgr) { 261 hResMgrTmp = hResMgr; 262 hResMgr = 0; 263 } 256 264 257 for(i=0;i<MAX_PCI_DEVICES;i++) 265 258 { 266 259 if(pci_devices[i].devfn == 0) 267 260 { 268 if(FindPCIDevice(vendor, device, (struct pci_dev near *)&pci_devices[i], idx) == TRUE) { 269 if(hResMgrTmp) { 270 RMDestroy(hResMgr); 271 hResMgr = hResMgrTmp; 272 } 273 // pci_read_config_dword(&pci_devices[i], PCI_CLASS_REVISION, &pci_devices[i]._class); 274 // if (((pci_devices[i]._class >> 8) & 0xffff) == PCI_CLASS_MULTIMEDIA_AUDIO) 275 return &pci_devices[i]; 276 } 277 #ifdef DEBUG 278 printk("wrong device. vendor %x, pci id %x\n",vendor,device); 279 #endif 280 break; 281 } 282 } 283 if(hResMgrTmp) { 284 RMDestroy(hResMgr); 285 hResMgr = hResMgrTmp; 286 } 287 return 0; 288 } 289 //****************************************************************************** 290 //****************************************************************************** 291 struct resource * __request_region(struct resource *a, unsigned long start, unsigned long n, const char *name) 292 { 293 struct resource *resource; 261 if( pci_query_device(vendor, device, (struct pci_dev near *)&pci_devices[i], idx) ) 262 return &pci_devices[i]; 263 else 264 break; 265 } 266 } 267 268 return NULL; 269 } 270 //****************************************************************************** 271 //****************************************************************************** 272 struct resource * __request_region(struct resource *a, unsigned long start, 273 unsigned long n, const char *name) 274 { 275 struct resource *resource; 294 276 295 277 if(a->flags & IORESOURCE_MEM) { 296 if(RMRequestMem( hResMgr,start, n) == FALSE) {278 if(RMRequestMem(/*hResMgr,*/ start, n) == FALSE) { 297 279 printk("RMRequestIO failed for io %x, length %x\n", start, n); 298 280 return NULL; 299 281 } 300 282 } 301 else 302 if(a->flags & IORESOURCE_IO) { 303 if(RMRequestIO(hResMgr, start, n) == FALSE) { 283 else if(a->flags & IORESOURCE_IO) { 284 if(RMRequestIO(/*hResMgr,*/ start, n) == FALSE) { 304 285 printk("RMRequestIO failed for io %x, length %x\n", start, n); 305 286 return NULL; … … 307 288 } 308 289 309 resource = kmalloc(sizeof(struct resource), GFP_KERNEL); 310 if (resource == NULL) 311 return NULL; 312 resource->name = name; 313 resource->start = start; 314 resource->end = start + n - 1; 315 resource->flags = a->flags; 316 return resource; 317 } 318 //****************************************************************************** 319 //****************************************************************************** 320 void __release_region(struct resource *resource, unsigned long b, unsigned long c) 321 { 322 if(resource) { 323 kfree(resource); 290 resource = kmalloc(sizeof(struct resource), GFP_KERNEL); 291 if (resource == NULL) 292 return NULL; 293 resource->name = name; 294 resource->start = start; 295 resource->end = start + n; // - 1; 296 resource->flags = a->flags; 297 resource->parent = 298 resource->child = NULL; 299 300 // insert in list 301 resource->sibling = a->sibling; 302 a->sibling = resource; 303 304 return resource; 305 } 306 //****************************************************************************** 307 //****************************************************************************** 308 void __release_region(struct resource *a, 309 unsigned long start, unsigned long n) 310 { 311 struct resource *resource; 312 struct resource **ppres = &a->sibling; 313 unsigned long end = start + n; // - 1; 314 315 while( *ppres ) 316 { 317 resource = *ppres; 318 319 if( resource->start == start && resource->end == end ) 320 { 321 // remove from list 322 *ppres = resource->sibling; 323 kfree(resource); 324 return; 325 } 326 327 ppres = &resource->sibling; 324 328 } 325 329 } … … 335 339 } 336 340 //****************************************************************************** 337 #define CONFIG_CMD(dev, where) (0x80000000 | (dev->bus->number << 16) | (dev->devfn << 8) | (where & ~3))338 //******************************************************************************339 int pci_read_config_byte(struct pci_dev *dev, int where, u8 *value)340 {341 outl(CONFIG_CMD(dev,where), 0xCF8);342 *value = inb(0xCFC + (where&3));343 return PCIBIOS_SUCCESSFUL;344 }345 //******************************************************************************346 //******************************************************************************347 int pci_read_config_word(struct pci_dev *dev, int where, u16 *value)348 {349 outl(CONFIG_CMD(dev,where), 0xCF8);350 *value = inw(0xCFC + (where&2));351 return PCIBIOS_SUCCESSFUL;352 }353 //******************************************************************************354 //******************************************************************************355 int pci_read_config_dword(struct pci_dev *dev, int where, u32 *value)356 {357 outl(CONFIG_CMD(dev,where), 0xCF8);358 *value = inl(0xCFC);359 return PCIBIOS_SUCCESSFUL;360 }361 //******************************************************************************362 //******************************************************************************363 int pci_write_config_byte(struct pci_dev *dev, int where, u8 value)364 {365 outl(CONFIG_CMD(dev,where), 0xCF8);366 outb(value, 0xCFC + (where&3));367 return PCIBIOS_SUCCESSFUL;368 }369 //******************************************************************************370 //******************************************************************************371 int pci_write_config_word(struct pci_dev *dev, int where, u16 value)372 {373 outl(CONFIG_CMD(dev,where), 0xCF8);374 outw(value, 0xCFC + (where&2));375 return PCIBIOS_SUCCESSFUL;376 }377 //******************************************************************************378 //******************************************************************************379 int pci_write_config_dword(struct pci_dev *dev, int where, u32 value)380 {381 outl(CONFIG_CMD(dev,where), 0xCF8);382 outl(value, 0xCFC);383 return PCIBIOS_SUCCESSFUL;384 }385 //******************************************************************************386 341 //****************************************************************************** 387 342 int pcibios_present(void) … … 409 364 int pci_find_capability(struct pci_dev *dev, int cap) 410 365 { 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 366 u16 status; 367 u8 pos, id; 368 int ttl = 48; 369 370 pci_read_config_word(dev, PCI_STATUS, &status); 371 if (!(status & PCI_STATUS_CAP_LIST)) 372 return 0; 373 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos); 374 while (ttl-- && pos >= 0x40) { 375 pos &= ~3; 376 pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id); 377 if (id == 0xff) 378 break; 379 if (id == cap) 380 return pos; 381 pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos); 382 } 383 return 0; 429 384 } 430 385 //****************************************************************************** … … 437 392 int pci_set_power_state(struct pci_dev *dev, int new_state) 438 393 { 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 394 u32 base[5], romaddr; 395 u16 pci_command, pwr_command; 396 u8 pci_latency, pci_cacheline; 397 int i, old_state; 398 int pm = pci_find_capability(dev, PCI_CAP_ID_PM); 399 400 if (!pm) 401 return 0; 402 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pwr_command); 403 old_state = pwr_command & PCI_PM_CTRL_STATE_MASK; 404 if (old_state == new_state) 405 return old_state; 406 if (old_state == 3) { 407 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 408 pci_write_config_word(dev, PCI_COMMAND, pci_command & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); 409 for (i = 0; i < 5; i++) 410 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, &base[i]); 411 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &romaddr); 412 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); 413 pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_cacheline); 414 pci_write_config_word(dev, pm + PCI_PM_CTRL, new_state); 415 for (i = 0; i < 5; i++) 416 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, base[i]); 417 pci_write_config_dword(dev, PCI_ROM_ADDRESS, romaddr); 418 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 419 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cacheline); 420 pci_write_config_byte(dev, PCI_LATENCY_TIMER, pci_latency); 421 pci_write_config_word(dev, PCI_COMMAND, pci_command); 422 } else 423 pci_write_config_word(dev, pm + PCI_PM_CTRL, (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | new_state); 424 return old_state; 470 425 } 471 426 //****************************************************************************** … … 478 433 int pci_enable_device(struct pci_dev *dev) 479 434 { 480 481 482 483 484 485 486 487 435 u16 pci_command; 436 437 printk("pci_enable_device %x\n", dev); 438 439 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 440 pci_write_config_word(dev, PCI_COMMAND, pci_command | (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); 441 pci_set_power_state(dev, 0); 442 return 0; 488 443 } 489 444 //****************************************************************************** … … 491 446 int pci_register_driver(struct pci_driver *driver) 492 447 { 493 struct pci_dev *pcidev = NULL; 494 int i = 0, j; 495 int dev_num; 496 ULONG pcidevid; 497 498 while(driver->id_table[i].vendor) 448 int i, j, dev_num; 449 struct pci_dev *pcidev; 450 451 for( i = 0; driver->id_table[i].vendor; i++) 499 452 { 500 pcidevid = ((ULONG)driver->id_table[i].device << 16) | 501 (ULONG)driver->id_table[i].vendor; 502 dev_num = pci_get_dev_num(pcidevid); 503 504 if (dev_num) { 505 printk("found: %i number of %x, id: %x\n",dev_num,driver->id_table[i].vendor, driver->id_table[i].device); 506 507 for (j=0; j < dev_num; j++) // dirty hack for multiply cards with same PCIID 508 { 509 pcidev = pci_find_device(driver->id_table[i].vendor, driver->id_table[i].device, (struct pci_dev *)j); 510 // printk("checking pci vend: %x, id: %x %i\n",driver->id_table[i].vendor, driver->id_table[i].device, i); 511 #ifdef DEBUG 512 // dprintf(("checked device: vendor %x, pci id %x, pcidev %x, probe %x", 513 // driver->id_table[i].vendor,driver->id_table[i].device, pcidev, driver->probe)); 514 #endif 515 if(pcidev && driver->probe) { 516 printk("found: %x, id: %x idx %i\n",driver->id_table[i].vendor, driver->id_table[i].device, j); 517 518 if(driver->probe(pcidev, &driver->id_table[i]) == 0) { 519 //remove resource manager object for this device and 520 //register resources with RM 521 RMFinialize(hResMgr); 522 hResMgr = 0; 523 524 //save driver pointer for suspend/resume calls 525 pcidev->pcidriver = (void *)driver; 526 pcidev->current_state = 4; 527 //return 1; 528 } 529 else pcidev->devfn = 0; 530 531 RMDestroy(hResMgr); 532 hResMgr = 0; 453 dev_num = 0; 454 while( (pcidev = pci_find_device(driver->id_table[i].vendor, 455 driver->id_table[i].device, 456 (struct pci_dev *)dev_num)) != NULL ) 457 { 458 RMInit(); 459 if( driver->probe) { 460 printk("found: %x, id: %x idx %i\n",driver->id_table[i].vendor, driver->id_table[i].device, dev_num); 461 462 if(driver->probe(pcidev, &driver->id_table[i]) == 0) { 463 pcidev->pcidriver = (void *)driver; 464 pcidev->current_state = 4; 465 466 // create adapter 467 RMDone((driver->id_table[i].vendor << 16) | driver->id_table[i].device); 468 469 return 1; 533 470 } 534 } // for j 535 return dev_num; 536 } 537 i++; 471 else pcidev->devfn = 0; 472 } 473 474 RMDone(0); 475 476 dev_num++; 477 478 } 538 479 } 539 480 return 0; … … 578 519 void pci_set_master(struct pci_dev *dev) 579 520 { 580 581 582 583 521 u16 cmd; 522 523 pci_read_config_word(dev, PCI_COMMAND, &cmd); 524 if (! (cmd & PCI_COMMAND_MASTER)) { 584 525 dprintf(("pci_set_master %x", dev)); 585 586 587 526 cmd |= PCI_COMMAND_MASTER; 527 pci_write_config_word(dev, PCI_COMMAND, cmd); 528 } 588 529 return; 589 530 } … … 722 663 int pci_orig_save_state(struct pci_dev *dev, u32 *buffer) 723 664 { 724 725 726 727 728 729 730 665 int i; 666 if (buffer) { 667 /* XXX: 100% dword access ok here? */ 668 for (i = 0; i < 16; i++) 669 pci_read_config_dword(dev, i * 4,&buffer[i]); 670 } 671 return 0; 731 672 } 732 673 … … 740 681 pci_orig_restore_state(struct pci_dev *dev, u32 *buffer) 741 682 { 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 683 int i; 684 685 if (buffer) { 686 for (i = 0; i < 16; i++) 687 pci_write_config_dword(dev,i * 4, buffer[i]); 688 } 689 /* 690 * otherwise, write the context information we know from bootup. 691 * This works around a problem where warm-booting from Windows 692 * combined with a D3(hot)->D0 transition causes PCI config 693 * header data to be forgotten. 694 */ 695 else { 696 for (i = 0; i < 6; i ++) 697 pci_write_config_dword(dev, 698 PCI_BASE_ADDRESS_0 + (i * 4), 699 dev->resource[i].start); 700 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 701 } 702 return 0; 762 703 } 763 704 764 705 struct saved_config_tbl { 765 766 706 struct pci_dev *pci; 707 u32 config[16]; 767 708 }; 768 709 static struct saved_config_tbl saved_tbl[16]; … … 770 711 void pci_save_state(struct pci_dev *pci) 771 712 { 772 773 774 775 776 777 778 779 780 781 713 int i; 714 /* FIXME: mutex needed for race? */ 715 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) { 716 if (! saved_tbl[i].pci) { 717 saved_tbl[i].pci = pci; 718 pci_orig_save_state(pci, saved_tbl[i].config); 719 return; 720 } 721 } 722 printk(KERN_DEBUG "snd: no pci config space found!\n"); 782 723 } 783 724 784 725 void pci_restore_state(struct pci_dev *pci) 785 726 { 786 787 788 789 790 791 792 793 794 795 727 int i; 728 /* FIXME: mutex needed for race? */ 729 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) { 730 if (saved_tbl[i].pci == pci) { 731 saved_tbl[i].pci = NULL; 732 pci_orig_restore_state(pci, saved_tbl[i].config); 733 return; 734 } 735 } 736 printk(KERN_DEBUG "snd: no saved pci config!\n"); 796 737 } 797 738 … … 809 750 int pci_request_region(struct pci_dev *pdev, int bar, char *res_name) 810 751 { 811 int flags; 812 813 if (pci_resource_len(pdev, bar) == 0) 814 return 0; 815 flags = pci_get_flags(pdev, bar); 816 if (flags & IORESOURCE_IO) { 817 if (check_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar))) 818 goto err_out; 819 request_region(pci_resource_start(pdev, bar), 820 pci_resource_len(pdev, bar), res_name); 821 } 822 return 0; 752 int flags; 753 754 if (pci_resource_len(pdev, bar) == 0) 755 return 0; 756 flags = pci_get_flags(pdev, bar); 757 if (flags & IORESOURCE_IO) { 758 if (check_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar))) 759 goto err_out; 760 request_region(pci_resource_start(pdev, bar), 761 pci_resource_len(pdev, bar), res_name); 762 } 763 else if (flags & IORESOURCE_MEM) { 764 if (check_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar))) 765 goto err_out; 766 request_mem_region(pci_resource_start(pdev, bar), 767 pci_resource_len(pdev, bar), res_name); 768 } 769 770 return 0; 823 771 824 772 err_out: 825 826 827 828 829 830 773 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", 774 flags & IORESOURCE_IO ? "I/O" : "mem", 775 bar + 1, /* PCI BAR # */ 776 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar), 777 res_name); 778 return -EBUSY; 831 779 } 832 780 833 781 void pci_release_region(struct pci_dev *pdev, int bar) 834 782 { 835 int flags; 836 837 if (pci_resource_len(pdev, bar) == 0) 838 return; 839 flags = pci_get_flags(pdev, bar); 840 if (flags & IORESOURCE_IO) { 841 release_region(pci_resource_start(pdev, bar), 842 pci_resource_len(pdev, bar)); 843 } 783 int flags; 784 785 if (pci_resource_len(pdev, bar) == 0) 786 return; 787 flags = pci_get_flags(pdev, bar); 788 if (flags & IORESOURCE_IO) { 789 release_region(pci_resource_start(pdev, bar), 790 pci_resource_len(pdev, bar)); 791 } 792 else if (flags & IORESOURCE_MEM) { 793 release_mem_region(pci_resource_start(pdev, bar), 794 pci_resource_len(pdev, bar)); 795 } 844 796 } 845 797 846 798 int pci_request_regions(struct pci_dev *pdev, char *res_name) 847 799 { 848 849 850 851 852 853 854 err:855 856 857 800 int i; 801 802 for (i = 0; i < 6; i++) 803 if (pci_request_region(pdev, i, res_name)) 804 goto err; 805 return 0; 806 err: 807 while (--i >= 0) 808 pci_release_region(pdev, i); 809 return -EBUSY; 858 810 } 859 811 860 812 void pci_release_regions(struct pci_dev *pdev) 861 813 { 862 863 864 814 int i; 815 for (i = 0; i < 6; i++) 816 pci_release_region(pdev, i); 865 817 } 866 818 … … 886 838 int snd_pci_dev_present(const struct pci_device_id *ids) 887 839 { 888 889 890 891 892 893 840 while (ids->vendor || ids->subvendor) { 841 if (pci_find_device(ids->vendor, ids->subvendor, NULL)) 842 return 1; 843 ids++; 844 } 845 return 0; 894 846 } 895 847 … … 940 892 } 941 893 #endif 894 895 896 //****************************************************************************** 897 //****************************************************************************** 898 OSSRET OSS32_APMResume() 899 { 900 int i; 901 struct pci_driver *driver; 902 903 dprintf(("OSS32_APMResume")); 904 905 for(i=0;i<MAX_PCI_DEVICES;i++) 906 { 907 if(pci_devices[i].devfn) 908 { 909 driver = pci_devices[i].pcidriver; 910 if(driver && driver->resume) { 911 driver->resume(&pci_devices[i]); 912 // fSuspended = FALSE; 913 } 914 } 915 } 916 917 fSuspended = FALSE; 918 919 return OSSERR_SUCCESS; 920 } 921 //****************************************************************************** 922 //****************************************************************************** 923 OSSRET OSS32_APMSuspend() 924 { 925 int i; 926 struct pci_driver *driver; 927 928 dprintf(("OSS32_APMSuspend")); 929 930 fSuspended = TRUE; 931 932 for(i=0;i<MAX_PCI_DEVICES;i++) 933 { 934 if(pci_devices[i].devfn) 935 { 936 driver = pci_devices[i].pcidriver; 937 if(driver && driver->suspend) { 938 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold); 939 } 940 } 941 } 942 943 return OSSERR_SUCCESS; 944 } 945
Note:
See TracChangeset
for help on using the changeset viewer.