Changeset 518 for GPL/trunk/lib32/pci.c
- Timestamp:
- Jul 20, 2010, 5:46:55 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GPL/trunk/lib32/pci.c
r458 r518 47 47 struct pci_bus pci_busses[MAX_PCI_BUSSES] = {0}; 48 48 49 BOOL 49 BOOL fSuspended = FALSE; 50 50 extern int nrCardsDetected; 51 51 52 52 53 #define PCI_CONFIG_ENABLE 54 #define PCI_CONFIG_ADDRESS 55 #define PCI_CONFIG_DATA 56 57 #ifdef ACPI 58 APIRET APIENTRY ACPIFindPCIDevice(ULONG Bus, ULONG Dev, ULONG Fun, ULONG *PicIRQ, ULONG *ApicIRQ, ULONG *Hdl, char *Component); 59 #endif 53 #define PCI_CONFIG_ENABLE 0x80000000 54 #define PCI_CONFIG_ADDRESS 0xCF8 55 #define PCI_CONFIG_DATA 0xCFC 56 57 #ifdef ACPI 58 APIRET APIENTRY ACPIFindPCIDevice(ULONG Bus, ULONG Dev, ULONG Fun, ULONG *PicIRQ, ULONG *ApicIRQ, ULONG *Hdl, char *Component); 59 #endif 60 60 61 61 //****************************************************************************** 62 62 #define CONFIG_CMD(dev, where) \ 63 63 (PCI_CONFIG_ENABLE | (dev->bus->number<<16) | (dev->devfn<<8) | (where & ~3)) 64 64 //****************************************************************************** 65 65 int pci_read_config_byte(struct pci_dev *dev, int where, u8 *value) 66 66 { 67 68 69 67 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 68 *value = inb(PCI_CONFIG_DATA + (where&3)); 69 return PCIBIOS_SUCCESSFUL; 70 70 } 71 71 //****************************************************************************** … … 73 73 int pci_read_config_word(struct pci_dev *dev, int where, u16 *value) 74 74 { 75 76 77 75 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 76 *value = inw(PCI_CONFIG_DATA + (where&2)); 77 return PCIBIOS_SUCCESSFUL; 78 78 } 79 79 //****************************************************************************** … … 81 81 int pci_read_config_dword(struct pci_dev *dev, int where, u32 *value) 82 82 { 83 84 85 83 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 84 *value = inl(PCI_CONFIG_DATA); 85 return PCIBIOS_SUCCESSFUL; 86 86 } 87 87 //****************************************************************************** … … 89 89 int pci_write_config_byte(struct pci_dev *dev, int where, u8 value) 90 90 { 91 92 93 91 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 92 outb(value, PCI_CONFIG_DATA + (where&3)); 93 return PCIBIOS_SUCCESSFUL; 94 94 } 95 95 //****************************************************************************** … … 97 97 int pci_write_config_word(struct pci_dev *dev, int where, u16 value) 98 98 { 99 100 101 99 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 100 outw(value, PCI_CONFIG_DATA + (where&2)); 101 return PCIBIOS_SUCCESSFUL; 102 102 } 103 103 //****************************************************************************** … … 105 105 int pci_write_config_dword(struct pci_dev *dev, int where, u32 value) 106 106 { 107 108 109 107 outl(CONFIG_CMD(dev,where), PCI_CONFIG_ADDRESS); 108 outl(value, PCI_CONFIG_DATA); 109 return PCIBIOS_SUCCESSFUL; 110 110 } 111 111 //****************************************************************************** … … 113 113 int pcidev_prepare(struct pci_dev *dev) 114 114 { 115 116 115 dprintf(("pcidev_prepare %x not implemented", dev)); 116 return 1; //todo: correct return value?? 117 117 } 118 118 //****************************************************************************** … … 120 120 int pcidev_activate(struct pci_dev *dev) 121 121 { 122 123 122 dprintf(("pcidev_activate %x not implemented", dev)); 123 return 1; //todo: correct return value?? 124 124 } 125 125 //****************************************************************************** … … 127 127 int pcidev_deactivate(struct pci_dev *dev) 128 128 { 129 130 131 } 132 133 134 135 //****************************************************************************** 136 //****************************************************************************** 137 #ifdef ACPI 129 dprintf(("pcidev_deactivate %x not implemented", dev)); 130 return 1; //todo: correct return value?? 131 } 132 133 134 135 //****************************************************************************** 136 //****************************************************************************** 137 #ifdef ACPI 138 138 struct SaveIRQForSlot 139 139 { 140 141 142 143 BYTE Pin; 140 ULONG ulSlotNo; 141 BYTE LowIRQ; 142 BYTE HighIRQ; 143 BYTE Pin; 144 144 }; 145 145 extern struct SaveIRQForSlot sISRHigh[]; 146 extern int 146 extern int SaveIRQCounter; 147 147 #endif 148 148 149 static int pci_query_device(unsigned int vendor, unsigned int device, 150 struct pci_dev near *pcidev, int idx)151 { 152 #ifdef ACPI 153 APIRET rc; 154 # endif155 int resNo, addr, found = 0;156 u32 devNr, busNr, funcNr, detectedId, pciId, cfgaddrreg, temp, temp2; 157 # ifdef ACPI158 ULONG temp1,temp3; //PS++ 159 #endif 160 u8 headerType;161 162 pciId = (device << 16) | vendor;163 164 cfgaddrreg = inl(PCI_CONFIG_ADDRESS); 165 for(busNr=0;busNr<MAX_PCI_BUSSES;busNr++) //BusNumber<255 166 { 167 for(devNr=0;devNr<32;devNr++) 168 169 for(funcNr=0;funcNr<8;funcNr++) 170 { 171 headerType = 0;172 temp = PCI_CONFIG_ENABLE | (busNr<<16) | (devNr<<11) | (funcNr<<8);173 outl(temp, PCI_CONFIG_ADDRESS); 174 detectedId = inl(PCI_CONFIG_DATA); 175 if( detectedId != 0xffffffff ) 176 { 177 outl(temp | (PCI_HEADER_TYPE & ~3), PCI_CONFIG_ADDRESS); 178 headerType = inb(PCI_CONFIG_DATA + (PCI_HEADER_TYPE & 3)); 179 } 180 // printk("det: %x (%x), need: %x\n", detectedId, headerType, pciId); 181 182 if( detectedId == pciId && 183 (headerType & 0x7f) == PCI_HEADER_TYPE_NORMAL ) 184 185 if( found++ == idx ) 186 187 memset((void near *)pcidev, 0, sizeof(struct pci_dev));188 189 pcidev->vendor = vendor; 190 pcidev->device = device;191 pcidev->bus = &pci_busses[busNr];192 pcidev->bus->number = busNr; 193 pcidev->devfn = (devNr << 3) | funcNr;194 pcidev->hdr_type = headerType & 0x7f;195 196 pcidev->prepare = pcidev_prepare;197 pcidev->activate = pcidev_activate; 198 pcidev->deactivate = pcidev_deactivate;199 pcidev->active = 1; 200 pcidev->ro = 0;201 pcidev->sibling = NULL;202 pcidev->next = NULL;203 pcidev->dma_mask = 0xFFFFFFFF;204 205 // Subsystem ID 206 pci_read_config_word(pcidev, PCI_SUBSYSTEM_VENDOR_ID, 207 &pcidev->subsystem_vendor);208 pci_read_config_word(pcidev, PCI_SUBSYSTEM_ID, 209 &pcidev->subsystem_device);210 211 // I/O and MEM 212 resNo = 0;213 for( addr = PCI_BASE_ADDRESS_0; addr <= PCI_BASE_ADDRESS_5; addr += 4 ) 214 { 215 pci_read_config_dword(pcidev, addr, &temp); 216 if( temp != 0 && temp != 0xffffffff ) 217 { 218 pci_write_config_dword(pcidev, addr, 0xffffffff);219 pci_read_config_dword(pcidev, addr, &temp2); 220 pci_write_config_dword(pcidev, addr, temp); 221 222 if( temp & PCI_BASE_ADDRESS_SPACE_IO ) 223 { 224 pcidev->resource[resNo].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 225 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_IO_MASK;226 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 227 ~(temp2 & PCI_BASE_ADDRESS_IO_MASK) + 1;228 } 229 else 230 { 231 pcidev->resource[resNo].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE;232 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_MEM_MASK; 233 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 234 ~(temp2 & PCI_BASE_ADDRESS_MEM_MASK) + 1; 235 } 236 237 resNo++;238 239 } 240 } 241 242 // IRQ and PIN 243 pci_read_config_dword(pcidev, PCI_INTERRUPT_LINE, &temp);244 #ifdef ACPI 245 sISRHigh[SaveIRQCounter].Pin = (temp >> 8) & 0xf; 246 temp2 = temp3 = 0; 247 rc = ACPIFindPCIDevice( (ULONG)busNr, // Bus 248 (ULONG)devNr, // Dev 249 (ULONG)(pcidev->devfn >> 8) & 7, // Function 250 &temp1, // PIC IRQ 251 &temp3, // APIC IRQ 252 NULL, // ACPI handle to finding device 253 "Uniaud32"); // Name for acpi log 254 if (!rc) 255 { 256 // Check APIC IRQ, if we have /SMP /APIC, must be set 257 if (temp1) 258 temp = (temp & (~0xff)) | (temp1 & 0xff); 259 // Check PIC IRQ 260 else if (temp3) 261 temp = (temp & (~0xff)) | (temp3 & 0xff); 262 dprintf(("pci_query_device: IRQs ACPI PIC%d APIC%d", temp1, temp3)); 263 sISRHigh[SaveIRQCounter].LowIRQ = temp1; 264 sISRHigh[SaveIRQCounter].HighIRQ = temp3;265 } 266 #endif /* ACPI */ 267 if( (u8)temp && (u8)temp != 0xff ) 268 { 269 pcidev->irq_resource[0].flags = IORESOURCE_IRQ; 270 pcidev->irq_resource[0].start = 271 pcidev->irq_resource[0].end = temp & 0xffff;272 pcidev->irq = (u8)temp;273 } 274 275 return 1; 276 } 277 } 278 279 // don't need to check more, if function 0 not present or single 280 if( funcNr == 0 && !(headerType & 0x80) ) break;281 282 } 283 } 284 outl(cfgaddrreg, PCI_CONFIG_ADDRESS); 285 return 0; 286 287 } 288 289 // ******************************************************************************290 // ******************************************************************************149 //Find the next matching PCI device starting with the device specified by pcidev 150 static ULONG pci_query_device(const struct pci_device_id *id_table, struct pci_dev near *pcidev, ULONG ulLast) 151 { 152 int resNo, addr; 153 u32 devNr, busNr, funcNr, detectedId, cfgaddrreg, temp, temp2; 154 #ifdef ACPI 155 APIRET rc; 156 ULONG temp1,temp3; //PS++ 157 #endif 158 u8 headerType; 159 160 busNr = (ulLast >> 8) & 0x1f; 161 devNr = PCI_SLOT(ulLast); 162 funcNr = PCI_FUNC(ulLast); 163 if (ulLast) funcNr++; 164 165 cfgaddrreg = inl(PCI_CONFIG_ADDRESS); 166 for(;busNr<MAX_PCI_BUSSES;busNr++) { //BusNumber<255 167 for(;devNr<32;devNr++) { 168 for(;funcNr<8;funcNr++) { 169 headerType = 0; 170 temp = PCI_CONFIG_ENABLE | (busNr<<16) | (devNr<<11) | (funcNr<<8); 171 outl(temp, PCI_CONFIG_ADDRESS); 172 detectedId = inl(PCI_CONFIG_DATA); 173 174 if ( detectedId == 0xffffffff ) { 175 if ( funcNr == 0 ) break; /* if func 0 isn't there, the others aren't either */ 176 continue; 177 } 178 179 outl(temp + PCI_CLASS_REVISION, PCI_CONFIG_ADDRESS); 180 temp2 = inl(PCI_CONFIG_DATA) >> 8; /* get class */ 181 182 //dprintf(("det=%x(%x) %x need=%x%x %x", detectedId, headerType, temp2, id_table->device&0xffff, id_table->vendor, id_table->class)); 183 184 if ( id_table->class ) { 185 if ( (temp2 & id_table->class_mask) != id_table->class ) continue; 186 } else { 187 if ( (id_table->device == PCI_ANY_ID) && ((temp2 >> 8) != PCI_CLASS_MULTIMEDIA_AUDIO) ) continue; 188 } 189 190 if (id_table->vendor != (detectedId & 0xffff)) continue; 191 if ( (id_table->device != PCI_ANY_ID) && (id_table->device != (detectedId >> 16)) ) continue; 192 193 outl(temp | (PCI_HEADER_TYPE & ~3), PCI_CONFIG_ADDRESS); 194 headerType = inb(PCI_CONFIG_DATA + (PCI_HEADER_TYPE & 3)); 195 196 if ( (headerType & 0x7f) != PCI_HEADER_TYPE_NORMAL ) continue; 197 198 memset((void near *)pcidev, 0, sizeof(struct pci_dev)); 199 200 pcidev->vendor = detectedId & 0xffff; 201 pcidev->device = detectedId >> 16; 202 pcidev->bus = &pci_busses[busNr]; 203 pcidev->bus->number = busNr; 204 pcidev->devfn = PCI_DEVFN(devNr, funcNr); 205 pcidev->hdr_type = headerType & 0x7f; 206 207 pcidev->prepare = pcidev_prepare; 208 pcidev->activate = pcidev_activate; 209 pcidev->deactivate = pcidev_deactivate; 210 pcidev->active = 1; 211 pcidev->ro = 0; 212 pcidev->sibling = NULL; 213 pcidev->next = NULL; 214 pcidev->dma_mask = 0xFFFFFFFF; 215 216 // Subsystem ID 217 pci_read_config_word(pcidev, PCI_SUBSYSTEM_VENDOR_ID, &pcidev->subsystem_vendor); 218 pci_read_config_word(pcidev, PCI_SUBSYSTEM_ID, &pcidev->subsystem_device); 219 220 // I/O and MEM 221 resNo = 0; 222 for( addr = PCI_BASE_ADDRESS_0; addr <= PCI_BASE_ADDRESS_5; addr += 4 ) { 223 pci_read_config_dword(pcidev, addr, &temp); 224 if( temp != 0 && temp != 0xffffffff ) { 225 pci_write_config_dword(pcidev, addr, 0xffffffff); 226 pci_read_config_dword(pcidev, addr, &temp2); 227 pci_write_config_dword(pcidev, addr, temp); 228 229 if( temp & PCI_BASE_ADDRESS_SPACE_IO ) { 230 pcidev->resource[resNo].flags = IORESOURCE_IO | PCI_BASE_ADDRESS_SPACE_IO; 231 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_IO_MASK; 232 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 233 ~(temp2 & PCI_BASE_ADDRESS_IO_MASK) + 1; 234 } 235 else 236 { 237 pcidev->resource[resNo].flags = IORESOURCE_MEM | IORESOURCE_MEM_WRITEABLE; 238 pcidev->resource[resNo].start = temp & PCI_BASE_ADDRESS_MEM_MASK; 239 pcidev->resource[resNo].end = pcidev->resource[resNo].start + 240 ~(temp2 & PCI_BASE_ADDRESS_MEM_MASK) + 1; 241 } 242 243 resNo++; 244 245 } 246 } 247 248 // IRQ and PIN 249 pci_read_config_dword(pcidev, PCI_INTERRUPT_LINE, &temp); 250 #ifdef ACPI 251 sISRHigh[SaveIRQCounter].Pin = (temp >> 8) & 0xf; 252 temp2 = temp3 = 0; 253 rc = ACPIFindPCIDevice( (ULONG)busNr, // Bus 254 (ULONG)devNr, // Dev 255 (ULONG)(pcidev->devfn >> 8) & 7, // Function 256 &temp1, // PIC IRQ 257 &temp3, // APIC IRQ 258 NULL, // ACPI handle to finding device 259 "Uniaud32"); // Name for acpi log 260 if (!rc) { 261 // Check APIC IRQ, if we have /SMP /APIC, must be set 262 if (temp1) temp = (temp & (~0xff)) | (temp1 & 0xff); 263 // Check PIC IRQ 264 else if (temp3) temp = (temp & (~0xff)) | (temp3 & 0xff); 265 dprintf(("pci_query_device: IRQs ACPI PIC%d APIC%d", temp1, temp3)); 266 sISRHigh[SaveIRQCounter].LowIRQ = temp1; 267 sISRHigh[SaveIRQCounter].HighIRQ = temp3; 268 } 269 #endif /* ACPI */ 270 if( (u8)temp && (u8)temp != 0xff ) { 271 pcidev->irq_resource[0].flags = IORESOURCE_IRQ; 272 pcidev->irq_resource[0].start = pcidev->irq_resource[0].end = temp & 0xffff; 273 pcidev->irq = (u8)temp; 274 } 275 276 return (0x8000 | (busNr << 8) | PCI_DEVFN(devNr, funcNr)); 277 } /* for funcNr */ 278 funcNr = 0; 279 } /* for devNr */ 280 devNr = 0; 281 } 282 outl(cfgaddrreg, PCI_CONFIG_ADDRESS); 283 return 0; 284 } 285 286 //****************************************************************************** 287 //****************************************************************************** 288 // Called from: 289 //if from==NULL search pci bus 290 //if from!=NULL only search already found devices starting with from 291 291 struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, struct pci_dev *from) 292 292 { 293 int i, idx; 294 295 if((int)from < 8) { 296 idx = (int)from; // dirty hack 297 // return 0; 298 } else 299 idx = 0; 300 301 for(i=0;i<MAX_PCI_DEVICES;i++) 302 { 303 if(pci_devices[i].devfn == 0) 304 { 305 if( pci_query_device(vendor, device, (struct pci_dev near *)&pci_devices[i], idx) ) 306 return &pci_devices[i]; 307 else 308 break; 309 } 310 } 311 312 return NULL; 293 int i; 294 struct pci_device_id id_table; 295 296 for(i=0;i<MAX_PCI_DEVICES;i++) { 297 if ( pci_devices[i].devfn && (pci_devices[i].vendor == vendor) && (pci_devices[i].device == device) ) return &pci_devices[i]; 298 } 299 300 for(i=0;i<MAX_PCI_DEVICES;i++) { 301 if(pci_devices[i].devfn == 0) { 302 memset(&id_table, 0, sizeof(id_table)); 303 id_table.vendor = vendor; 304 id_table.device = device; 305 if( pci_query_device(&id_table, (struct pci_dev near *)&pci_devices[i], 0) ) return &pci_devices[i]; 306 else break; 307 } 308 } 309 310 return NULL; 313 311 } 314 312 //****************************************************************************** 315 313 //****************************************************************************** 316 314 struct resource * __request_region(struct resource *a, unsigned long start, 317 318 { 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 resource->name= name;338 339 resource->end= start + n; // - 1;340 341 342 343 344 345 346 347 348 315 unsigned long n, const char *name) 316 { 317 struct resource *resource; 318 319 if(a->flags & IORESOURCE_MEM) { 320 if(RMRequestMem(/*hResMgr,*/ start, n) == FALSE) { 321 printk("RMRequestIO failed for io %x, length %x\n", start, n); 322 return NULL; 323 } 324 } 325 else if(a->flags & IORESOURCE_IO) { 326 if(RMRequestIO(/*hResMgr,*/ start, n) == FALSE) { 327 printk("RMRequestIO failed for io %x, length %x\n", start, n); 328 return NULL; 329 } 330 } 331 332 resource = kmalloc(sizeof(struct resource), GFP_KERNEL); 333 if (resource == NULL) 334 return NULL; 335 resource->name = name; 336 resource->start = start; 337 resource->end = start + n; // - 1; 338 resource->flags = a->flags; 339 resource->parent = 340 resource->child = NULL; 341 342 // insert in list 343 resource->sibling = a->sibling; 344 a->sibling = resource; 345 346 return resource; 349 347 } 350 348 //****************************************************************************** 351 349 //****************************************************************************** 352 350 void __release_region(struct resource *a, 353 354 { 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 351 unsigned long start, unsigned long n) 352 { 353 struct resource *resource; 354 struct resource **ppres = &a->sibling; 355 unsigned long end = start + n; // - 1; 356 357 while( *ppres ) 358 { 359 resource = *ppres; 360 361 if( resource->start == start && resource->end == end ) 362 { 363 // remove from list 364 *ppres = resource->sibling; 365 kfree(resource); 366 return; 367 } 368 369 ppres = &resource->sibling; 370 } 373 371 } 374 372 //****************************************************************************** … … 376 374 int pci_get_flags (struct pci_dev *dev, int n_base) 377 375 { 378 379 380 381 382 376 if(n_base >= DEVICE_COUNT_RESOURCE || !dev->resource[n_base].flags) { 377 DebugInt3(); 378 return 0; 379 } 380 return dev->resource[n_base].flags; 383 381 } 384 382 //****************************************************************************** … … 386 384 int pcibios_present(void) 387 385 { 388 389 386 printk("pcibios_present -> pretend BIOS present\n"); 387 return 1; 390 388 } 391 389 //****************************************************************************** … … 393 391 struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn) 394 392 { 395 396 397 393 printk("pci_find_slot %d %x not implemented!!\n", bus, devfn); 394 DebugInt3(); 395 return NULL; 398 396 } 399 397 //****************************************************************************** … … 401 399 int pci_dma_supported(struct pci_dev *dev, unsigned long mask) 402 400 { 403 404 401 printk("pci_dma_supported: return TRUE\n"); 402 return 1; 405 403 } 406 404 //****************************************************************************** … … 408 406 int pci_find_capability(struct pci_dev *dev, int cap) 409 407 { 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 408 u16 status; 409 u8 pos, id; 410 int ttl = 48; 411 412 pci_read_config_word(dev, PCI_STATUS, &status); 413 if (!(status & PCI_STATUS_CAP_LIST)) 414 return 0; 415 pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &pos); 416 while (ttl-- && pos >= 0x40) { 417 pos &= ~3; 418 pci_read_config_byte(dev, pos + PCI_CAP_LIST_ID, &id); 419 if (id == 0xff) 420 break; 421 if (id == cap) 422 return pos; 423 pci_read_config_byte(dev, pos + PCI_CAP_LIST_NEXT, &pos); 424 } 425 return 0; 428 426 } 429 427 //****************************************************************************** 430 428 /* 431 * 432 * 433 * 429 * Set power management state of a device. For transitions from state D3 430 * it isn't as straightforward as one could assume since many devices forget 431 * their configuration space during wakeup. Returns old power state. 434 432 */ 435 433 //****************************************************************************** 436 434 int pci_set_power_state(struct pci_dev *dev, int new_state) 437 435 { 438 439 440 u8pci_latency, pci_cacheline;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 436 u32 base[5], romaddr; 437 u16 pci_command, pwr_command; 438 u8 pci_latency, pci_cacheline; 439 int i, old_state; 440 int pm = pci_find_capability(dev, PCI_CAP_ID_PM); 441 442 if (!pm) 443 return 0; 444 pci_read_config_word(dev, pm + PCI_PM_CTRL, &pwr_command); 445 old_state = pwr_command & PCI_PM_CTRL_STATE_MASK; 446 if (old_state == new_state) 447 return old_state; 448 if (old_state == 3) { 449 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 450 pci_write_config_word(dev, PCI_COMMAND, pci_command & ~(PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); 451 for (i = 0; i < 5; i++) 452 pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, &base[i]); 453 pci_read_config_dword(dev, PCI_ROM_ADDRESS, &romaddr); 454 pci_read_config_byte(dev, PCI_LATENCY_TIMER, &pci_latency); 455 pci_read_config_byte(dev, PCI_CACHE_LINE_SIZE, &pci_cacheline); 456 pci_write_config_word(dev, pm + PCI_PM_CTRL, new_state); 457 for (i = 0; i < 5; i++) 458 pci_write_config_dword(dev, PCI_BASE_ADDRESS_0 + i*4, base[i]); 459 pci_write_config_dword(dev, PCI_ROM_ADDRESS, romaddr); 460 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 461 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, pci_cacheline); 462 pci_write_config_byte(dev, PCI_LATENCY_TIMER, pci_latency); 463 pci_write_config_word(dev, PCI_COMMAND, pci_command); 464 } else 465 pci_write_config_word(dev, pm + PCI_PM_CTRL, (pwr_command & ~PCI_PM_CTRL_STATE_MASK) | new_state); 466 return old_state; 469 467 } 470 468 //****************************************************************************** 471 469 /* 472 * 473 * 474 * 470 * Initialize device before it's used by a driver. Ask low-level code 471 * to enable I/O and memory. Wake up the device if it was suspended. 472 * Beware, this function can fail. 475 473 */ 476 474 //****************************************************************************** 477 475 int pci_enable_device(struct pci_dev *dev) 478 476 { 479 480 481 printk("pci_enable_device %x\n", dev);482 483 484 485 486 477 u16 pci_command; 478 479 dprintf(("pci_enable_device %x\n", dev)); 480 481 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 482 pci_write_config_word(dev, PCI_COMMAND, pci_command | (PCI_COMMAND_IO | PCI_COMMAND_MEMORY)); 483 pci_set_power_state(dev, 0); 484 return 0; 487 485 } 488 486 //****************************************************************************** … … 490 488 int pci_register_driver(struct pci_driver *driver) 491 489 { 492 int i, j, dev_num; 493 struct pci_dev *pcidev; 494 495 for( i = 0; driver->id_table[i].vendor; i++) 496 { 497 dev_num = 0; 498 while( (pcidev = pci_find_device(driver->id_table[i].vendor, 499 driver->id_table[i].device, 500 (struct pci_dev *)dev_num)) != NULL ) 501 { 502 RMInit(); 503 if( driver->probe) { 504 printk("found: %x, id: %x idx %i\n",driver->id_table[i].vendor, driver->id_table[i].device, dev_num); 505 506 if(driver->probe(pcidev, &driver->id_table[i]) == 0) { 507 pcidev->pcidriver = (void *)driver; 508 pcidev->current_state = 4; 509 510 // create adapter 511 RMDone((driver->id_table[i].device << 16) | driver->id_table[i].vendor); 512 nrCardsDetected++; 513 } 514 else pcidev->devfn = 0; 515 } 516 517 RMDone(0); 518 519 dev_num++; 520 521 } 522 } 523 if (nrCardsDetected >=1) 524 return 1; 525 526 return 0; 490 int iTableIx, iNumCards, iTmp; 491 ULONG ulLast; 492 struct pci_dev *pcidev; 493 494 if (!driver->probe) return 0; 495 496 iNumCards = 0; 497 498 /* find an empty slot */ 499 for (iTmp=0; iTmp<MAX_PCI_DEVICES; iTmp++) { 500 if (pci_devices[iTmp].devfn == 0) break; 501 } 502 if (iTmp >= MAX_PCI_DEVICES) return 0; 503 pcidev = &pci_devices[iTmp]; 504 505 for( iTableIx = 0; driver->id_table[iTableIx].vendor; iTableIx++) { 506 ulLast = 0; 507 while( (ulLast = pci_query_device(&driver->id_table[iTableIx], pcidev, ulLast)) ) { 508 509 510 RMInit(); 511 dprintf(("pci_register_driver: found=%x:%x searching for %x:%x\n", 512 pcidev->vendor, pcidev->device, driver->id_table[iTableIx].vendor, driver->id_table[iTableIx].device)); 513 514 if(driver->probe(pcidev, &driver->id_table[iTableIx]) == 0) { 515 pcidev->pcidriver = (void *)driver; 516 pcidev->current_state = 4; 517 518 // create adapter 519 RMDone((pcidev->device << 16) | pcidev->vendor); 520 iNumCards++; 521 522 /* find another empty slot */ 523 for (iTmp=0; iTmp<MAX_PCI_DEVICES; iTmp++) { 524 if (pci_devices[iTmp].devfn == 0) break; 525 } 526 if (iTmp >= MAX_PCI_DEVICES) break; 527 pcidev = &pci_devices[iTmp]; 528 } else pcidev->devfn = 0; 529 530 RMDone(0); 531 } 532 } 533 534 return iNumCards; 527 535 } 528 536 //****************************************************************************** … … 530 538 int pci_module_init(struct pci_driver *drv) 531 539 { 532 int res = pci_register_driver(drv); 533 if (res < 0) 534 return res; 535 if (res == 0) 536 return -ENODEV; 537 return 0; 540 int res = pci_register_driver(drv); 541 if (res == 0) return -ENODEV; 542 return res; 538 543 } 539 544 //****************************************************************************** … … 541 546 int pci_unregister_driver(struct pci_driver *driver) 542 547 { 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 548 struct pci_dev *pcidev; 549 int i = 0, j; 550 551 while(driver->id_table[i].vendor) 552 { 553 for(j=0;j<MAX_PCI_DEVICES;j++) 554 { 555 if(pci_devices[j].vendor == driver->id_table[i].vendor && 556 pci_devices[j].device == driver->id_table[i].device) 557 { 558 if(driver->remove) { 559 driver->remove(&pci_devices[j]); 560 } 561 } 562 } 563 i++; 564 } 565 return 0; 561 566 } 562 567 //****************************************************************************** … … 564 569 void pci_set_master(struct pci_dev *dev) 565 570 { 566 567 568 569 570 571 572 573 574 571 u16 cmd; 572 573 pci_read_config_word(dev, PCI_COMMAND, &cmd); 574 if (! (cmd & PCI_COMMAND_MASTER)) { 575 dprintf(("pci_set_master %x", dev)); 576 cmd |= PCI_COMMAND_MASTER; 577 pci_write_config_word(dev, PCI_COMMAND, cmd); 578 } 579 return; 575 580 } 576 581 //****************************************************************************** … … 579 584 struct pm_dev *pm_register(pm_dev_t type, unsigned long id, pm_callback callback) 580 585 { 581 582 583 586 dprintf(("pm_register STUB")); 587 DebugInt3(); 588 return NULL; 584 589 } 585 590 //****************************************************************************** … … 588 593 void pm_unregister(struct pm_dev *dev) 589 594 { 590 595 dprintf(("pm_unregister STUB")); 591 596 } 592 597 //****************************************************************************** … … 594 599 int __compat_get_order(unsigned long size) 595 600 { 596 597 598 599 600 601 602 603 604 601 int order; 602 603 size = (size-1) >> (PAGE_SHIFT-1); 604 order = -1; 605 do { 606 size >>= 1; 607 order++; 608 } while (size); 609 return order; 605 610 } 606 611 //****************************************************************************** 607 612 //****************************************************************************** 608 613 void *pci_alloc_consistent(struct pci_dev *hwdev, 609 long size, dma_addr_t *dma_handle) 610 { 611 void *ret = NULL; 612 int gfp = GFP_ATOMIC; 613 int order; 614 #ifdef DEBUG 615 dprintf(("pci_alloc_consistent %d mask %x", size, (hwdev) ? hwdev->dma_mask : 0)); 616 #endif 617 if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) { 618 //try not to exhaust low memory (< 16mb) so allocate from the high region first 619 //if that doesn't satisfy the dma mask requirement, then get it from the low 620 //regino anyway 621 if(hwdev->dma_mask > 0x00ffffff) { 622 order = __compat_get_order(size); 623 ret = (void *)__get_free_pages(gfp|GFP_DMAHIGHMEM, order); 624 *dma_handle = virt_to_bus(ret); 625 if(*dma_handle > hwdev->dma_mask) { 626 free_pages((unsigned long)ret, __compat_get_order(size)); 627 //be sure and allocate below 16 mb 628 gfp |= GFP_DMA; 629 ret = NULL; 630 } 631 } 632 else { //must always allocate below 16 mb 633 gfp |= GFP_DMA; 634 } 635 } 636 if(ret == NULL) { 637 ret = (void *)__get_free_pages(gfp, __compat_get_order(size)); 638 } 639 640 if (ret != NULL) { 641 memset(ret, 0, size); 642 *dma_handle = virt_to_bus(ret); 643 } 644 return ret; 614 long size, dma_addr_t *dma_handle) 615 { 616 void *ret = NULL; 617 int gfp = GFP_ATOMIC; 618 int order; 619 dprintf(("pci_alloc_consistent %d mask %x", size, (hwdev) ? hwdev->dma_mask : 0)); 620 if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) { 621 //try not to exhaust low memory (< 16mb) so allocate from the high region first 622 //if that doesn't satisfy the dma mask requirement, then get it from the low 623 //regino anyway 624 if(hwdev->dma_mask > 0x00ffffff) { 625 order = __compat_get_order(size); 626 ret = (void *)__get_free_pages(gfp|GFP_DMAHIGHMEM, order); 627 *dma_handle = virt_to_bus(ret); 628 if(*dma_handle > hwdev->dma_mask) { 629 free_pages((unsigned long)ret, __compat_get_order(size)); 630 //be sure and allocate below 16 mb 631 gfp |= GFP_DMA; 632 ret = NULL; 633 } 634 } 635 else { //must always allocate below 16 mb 636 gfp |= GFP_DMA; 637 } 638 } 639 if(ret == NULL) { 640 ret = (void *)__get_free_pages(gfp, __compat_get_order(size)); 641 } 642 643 if (ret != NULL) { 644 memset(ret, 0, size); 645 *dma_handle = virt_to_bus(ret); 646 } 647 return ret; 645 648 } 646 649 //****************************************************************************** 647 650 //****************************************************************************** 648 651 void pci_free_consistent(struct pci_dev *hwdev, long size, 649 650 { 651 652 void *vaddr, dma_addr_t dma_handle) 653 { 654 free_pages((unsigned long)vaddr, __compat_get_order(size)); 652 655 } 653 656 //****************************************************************************** … … 655 658 void pci_set_driver_data (struct pci_dev *dev, void *driver_data) 656 659 { 657 658 660 if (dev) 661 dev->driver_data = driver_data; 659 662 } 660 663 //****************************************************************************** … … 662 665 void *pci_get_driver_data (struct pci_dev *dev) 663 666 { 664 665 666 667 if (dev) 668 return dev->driver_data; 669 return 0; 667 670 } 668 671 //****************************************************************************** … … 670 673 unsigned long pci_get_dma_mask (struct pci_dev *dev) 671 674 { 672 673 674 675 if (dev) 676 return dev->dma_mask; 677 return 0; 675 678 } 676 679 //****************************************************************************** … … 678 681 int release_resource(struct resource *newres) 679 682 { 680 683 return 0; 681 684 } 682 685 … … 685 688 int pci_set_latency_time(struct pci_dev *dev, int latency) 686 689 { 687 688 690 pci_write_config_byte(dev, PCI_LATENCY_TIMER, latency); 691 return 0; 689 692 } 690 693 … … 701 704 int pci_orig_save_state(struct pci_dev *dev, u32 *buffer) 702 705 { 703 704 705 706 707 708 709 706 int i; 707 if (buffer) { 708 /* XXX: 100% dword access ok here? */ 709 for (i = 0; i < 16; i++) 710 pci_read_config_dword(dev, i * 4,&buffer[i]); 711 } 712 return 0; 710 713 } 711 714 … … 719 722 pci_orig_restore_state(struct pci_dev *dev, u32 *buffer) 720 723 { 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 724 int i; 725 726 if (buffer) { 727 for (i = 0; i < 16; i++) 728 pci_write_config_dword(dev,i * 4, buffer[i]); 729 } 730 /* 731 * otherwise, write the context information we know from bootup. 732 * This works around a problem where warm-booting from Windows 733 * combined with a D3(hot)->D0 transition causes PCI config 734 * header data to be forgotten. 735 */ 736 else { 737 for (i = 0; i < 6; i ++) 738 pci_write_config_dword(dev, 739 PCI_BASE_ADDRESS_0 + (i * 4), 740 dev->resource[i].start); 741 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 742 } 743 return 0; 741 744 } 742 745 743 746 struct saved_config_tbl { 744 745 747 struct pci_dev *pci; 748 u32 config[16]; 746 749 }; 747 750 static struct saved_config_tbl saved_tbl[16]; … … 749 752 int pci_save_state(struct pci_dev *pci) 750 753 { 751 752 753 754 755 756 757 758 759 760 761 754 int i; 755 /* FIXME: mutex needed for race? */ 756 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) { 757 if (! saved_tbl[i].pci) { 758 saved_tbl[i].pci = pci; 759 pci_orig_save_state(pci, saved_tbl[i].config); 760 return 1; 761 } 762 } 763 printk(KERN_DEBUG "snd: no pci config space found!\n"); 764 return 0; 762 765 } 763 766 764 767 int pci_restore_state(struct pci_dev *pci) 765 768 { 766 767 768 769 770 771 772 773 774 775 776 769 int i; 770 /* FIXME: mutex needed for race? */ 771 for (i = 0; i < ARRAY_SIZE(saved_tbl); i++) { 772 if (saved_tbl[i].pci == pci) { 773 saved_tbl[i].pci = NULL; 774 pci_orig_restore_state(pci, saved_tbl[i].config); 775 return 0; 776 } 777 } 778 printk(KERN_DEBUG "snd: no saved pci config!\n"); 779 return 1; 777 780 } 778 781 779 782 void pci_disable_device(struct pci_dev *dev) 780 783 { 781 782 783 784 785 786 787 784 u16 pci_command; 785 786 pci_read_config_word(dev, PCI_COMMAND, &pci_command); 787 if (pci_command & PCI_COMMAND_MASTER) { 788 pci_command &= ~PCI_COMMAND_MASTER; 789 pci_write_config_word(dev, PCI_COMMAND, pci_command); 790 } 788 791 } 789 792 790 793 int pci_request_region(struct pci_dev *pdev, int bar, char *res_name) 791 794 { 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 795 int flags; 796 797 if (pci_resource_len(pdev, bar) == 0) 798 return 0; 799 flags = pci_get_flags(pdev, bar); 800 if (flags & IORESOURCE_IO) { 801 if (check_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar))) 802 goto err_out; 803 request_region(pci_resource_start(pdev, bar), 804 pci_resource_len(pdev, bar), res_name); 805 } 806 else if (flags & IORESOURCE_MEM) { 807 if (check_mem_region(pci_resource_start(pdev, bar), pci_resource_len(pdev, bar))) 808 goto err_out; 809 request_mem_region(pci_resource_start(pdev, bar), 810 pci_resource_len(pdev, bar), res_name); 811 } 812 813 return 0; 811 814 812 815 err_out: 813 814 815 816 817 818 816 printk(KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", 817 flags & IORESOURCE_IO ? "I/O" : "mem", 818 bar + 1, /* PCI BAR # */ 819 pci_resource_len(pdev, bar), pci_resource_start(pdev, bar), 820 res_name); 821 return -EBUSY; 819 822 } 820 823 821 824 void pci_release_region(struct pci_dev *pdev, int bar) 822 825 { 823 824 825 826 827 828 829 830 831 832 833 834 835 826 int flags; 827 828 if (pci_resource_len(pdev, bar) == 0) 829 return; 830 flags = pci_get_flags(pdev, bar); 831 if (flags & IORESOURCE_IO) { 832 release_region(pci_resource_start(pdev, bar), 833 pci_resource_len(pdev, bar)); 834 } 835 else if (flags & IORESOURCE_MEM) { 836 release_mem_region(pci_resource_start(pdev, bar), 837 pci_resource_len(pdev, bar)); 838 } 836 839 } 837 840 838 841 int pci_request_regions(struct pci_dev *pdev, char *res_name) 839 842 { 840 841 842 843 844 845 846 847 848 849 843 int i; 844 845 for (i = 0; i < 6; i++) 846 if (pci_request_region(pdev, i, res_name)) 847 goto err; 848 return 0; 849 err: 850 while (--i >= 0) 851 pci_release_region(pdev, i); 852 return -EBUSY; 850 853 } 851 854 852 855 void pci_release_regions(struct pci_dev *pdev) 853 856 { 854 855 856 857 int i; 858 for (i = 0; i < 6; i++) 859 pci_release_region(pdev, i); 857 860 } 858 861 859 862 const struct pci_device_id * pci_match_device(const struct pci_device_id *ids, struct pci_dev *dev) 860 863 { 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 864 u16 subsystem_vendor, subsystem_device; 865 866 pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor); 867 pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &subsystem_device); 868 869 while (ids->vendor || ids->subvendor || ids->class_mask) { 870 if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) && 871 (ids->device == PCI_ANY_ID || ids->device == dev->device) && 872 (ids->subvendor == PCI_ANY_ID || ids->subvendor == subsystem_vendor) && 873 (ids->subdevice == PCI_ANY_ID || ids->subdevice == subsystem_device) && 874 !((ids->class ^ dev->_class) & ids->class_mask)) 875 return ids; 876 ids++; 877 } 878 return NULL; 876 879 } 877 880 878 881 int snd_pci_dev_present(const struct pci_device_id *ids) 879 882 { 880 881 882 883 884 885 883 while (ids->vendor || ids->subvendor) { 884 if (pci_find_device(ids->vendor, ids->subvendor, NULL)) 885 return 1; 886 ids++; 887 } 888 return 0; 886 889 } 887 890 888 891 struct pci_driver_mapping { 889 890 891 892 893 892 struct pci_dev *dev; 893 struct pci_driver *drv; 894 unsigned long dma_mask; 895 void *driver_data; 896 u32 saved_config[16]; 894 897 }; 895 898 … … 900 903 static struct pci_driver_mapping *get_pci_driver_mapping(struct pci_dev *dev) 901 904 { 902 903 904 905 906 907 905 int i; 906 907 for (i = 0; i < PCI_MAX_MAPPINGS; i++) 908 if (drvmap[i].dev == dev) 909 return &drvmap[i]; 910 return NULL; 908 911 } 909 912 910 913 struct pci_driver *snd_pci_compat_get_pci_driver(struct pci_dev *dev) 911 914 { 912 913 914 915 915 struct pci_driver_mapping *map = get_pci_driver_mapping(dev); 916 if (map) 917 return map->drv; 918 return NULL; 916 919 } 917 920 #if 0 918 921 void * pci_get_drvdata (struct pci_dev *dev) 919 922 { 920 921 922 923 923 struct pci_driver_mapping *map = get_pci_driver_mapping(dev); 924 if (map) 925 return map->driver_data; 926 return NULL; 924 927 } 925 928 … … 927 930 void pci_set_drvdata (struct pci_dev *dev, void *driver_data) 928 931 { 929 930 931 932 struct pci_driver_mapping *map = get_pci_driver_mapping(dev); 933 if (map) 934 map->driver_data = driver_data; 932 935 } 933 936 #endif … … 938 941 OSSRET OSS32_APMResume() 939 942 { 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 943 int i; 944 struct pci_driver *driver; 945 946 dprintf(("OSS32_APMResume")); 947 948 fSuspended = FALSE; 949 950 for(i=0;i<MAX_PCI_DEVICES;i++) 951 { 952 if(pci_devices[i].devfn) 953 { 954 driver = pci_devices[i].pcidriver; 955 if(driver && driver->resume) { 956 driver->resume(&pci_devices[i]); 957 } 958 } 959 } 960 961 return OSSERR_SUCCESS; 959 962 } 960 963 //****************************************************************************** … … 962 965 OSSRET OSS32_APMSuspend() 963 966 { 964 int i; 965 struct pci_driver *driver; 966 967 dprintf(("OSS32_APMSuspend")); 968 969 fSuspended = TRUE; 970 971 for(i=0;i<MAX_PCI_DEVICES;i++) 972 { 973 if(pci_devices[i].devfn) 974 { 975 driver = pci_devices[i].pcidriver; 976 if(driver && driver->suspend) { 977 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold); 978 } 979 } 980 } 981 982 return OSSERR_SUCCESS; 983 } 984 967 int i; 968 struct pci_driver *driver; 969 970 dprintf(("OSS32_APMSuspend 1")); 971 972 fSuspended = TRUE; 973 974 for(i=0;i<MAX_PCI_DEVICES;i++) 975 { 976 if(pci_devices[i].devfn) 977 { 978 driver = pci_devices[i].pcidriver; 979 if(driver && driver->suspend) { 980 driver->suspend(&pci_devices[i], SNDRV_CTL_POWER_D3cold); 981 } 982 } 983 } 984 985 dprintf(("OSS32_APMSuspend 2")); 986 return OSSERR_SUCCESS; 987 } 988
Note:
See TracChangeset
for help on using the changeset viewer.