PNP BIOS fixes and additions
PATCH 1/1 PNP BIOS fixes and additions
Hi all,
changes in this patch (applies to 2.4.7-ac3):
- added '#ifdef CONFIG_HOTPLUG' aroud pnp_bios_dock_station_info() function to shut up gcc warning;
- better fix for pnpid32_to_pnpid() function (suggested by David Hinds);
- pnpbios_rawdata_2_pci_dev(), pnpid32_to_pnpid() and pnpbios_insert_device() functions declared __init;
- added memory region, fixed location IO and and (most important !) device name parsing to pnpbios_rawdata_2_pci_dev() function.
Tested with 2.4.7-ac1 on my new SMP motherboard :)
Best regards.
Signature · 2 lines
Andrey Panin | Embedded systems software engineer [email protected] | PGP key: http://www.orbita1.ru/~pazke/AndreyPanin.asc
drivers/pnp/pnp_bios.c +72 -32
@@ -290,6 +290,7 @@ }#endif +#ifdef CONFIG_HOTPLUG /* * Call pnp bios with function 0x05, "get docking station information" */
@@ -303,6 +304,7 @@ status =call_pnp_bios (PNP_GET_DOCKING_STATION_INFORMATION ,0 ,PNP_TS1 ,PNP_DS ,0 ,0 ,0 ,0 ); return status; } +#endif /* * Call pnp bios with function 0x09, "set statically allocated resource
@@ -630,16 +632,66 @@EXPORT_SYMBOL (pnp_bios_present);EXPORT_SYMBOL (pnp_bios_dev_node_info); +static void inline pnpbios_add_irqresource (struct pci_dev *dev,int irq) +{ +int i =0 ; +while (dev->irq_resource[i].start && i <DEVICE_COUNT_IRQ ) i++; +if (i <DEVICE_COUNT_IRQ ) + dev->irq_resource[i].start = irq; +} + +static void inline pnpbios_add_dmaresource (struct pci_dev *dev,int dma) +{ +int i =0 ; +while (dev->dma_resource[i].start && i <DEVICE_COUNT_DMA ) i++; +if (i <DEVICE_COUNT_DMA ) + dev->dma_resource[i].start = dma; +} + +static void __init pnpbios_add_ioresource (struct pci_dev *dev,int io, +int len,int flags) +{ +int i =0 ; +while (dev->resource[i].start && i <DEVICE_COUNT_RESOURCE ) i++; +if (i <DEVICE_COUNT_RESOURCE ) { + dev->resource[i].start = io; + dev->resource[i].end = io + len; + dev->resource[i].flags =IORESOURCE_MEM ; + } +} +/* parse PNPBIOS "Allocated Resources Block" and fill IO,IRQ,DMA into pci_dev */ -static void pnpbios_rawdata_2_pci_dev (struct pnp_bios_node *node,struct pci_dev *pci_dev) +static void __init pnpbios_rawdata_2_pci_dev (struct pnp_bios_node *node,struct pci_dev *pci_dev) {unsigned char *p = node->data, *lastp=NULL ;int mask,i,io,irq=0 ,len,dma=-1 ; +memset (pci_dev,0 ,sizeof (struct pci_dev ));while ( (char *)p < ((char *)node->data + node->size )) {if (p==lastp)break ;if ( p[0 ] &0x80 ) {// large item +switch (p[0 ] &0x7f ) { +case 0x01 :// memory + io = *(short *) &p[4 ]; + len = *(short *) &p[10 ]; +pnpbios_add_ioresource (pci_dev, io, len,IORESOURCE_MEM ); +break ; +case 0x02 :// device name + len = *(short *) &p[1 ]; +memcpy (pci_dev->name, p +3 , len >=80 ?79 : len); +break ; +case 0x05 :// 32-bit memory + io = *(int *) &p[4 ]; + len = *(int *) &p[16 ]; +pnpbios_add_ioresource (pci_dev, io, len,IORESOURCE_MEM ); +break ; +case 0x06 :// fixed location 32-bit memory + io = *(int *) &p[4 ]; + len = *(int *) &p[8 ]; +pnpbios_add_ioresource (pci_dev, io, len,IORESOURCE_MEM ); +break ; + } lastp = p+3 ; p = p + p[1 ] + p[2 ]*256 +3 ;continue ;
@@ -651,36 +703,24 @@ mask= p[1 ] + p[2 ]*256 ;for (i=0 ;i<16 ;i++, mask=mask>>1 )if (mask &0x01 ) irq=i; - i=0 ; -while (pci_dev->irq_resource[i].start && i<DEVICE_COUNT_IRQ ) - i++; -if (i<DEVICE_COUNT_IRQ ) - pci_dev->irq_resource[i].start=irq; +pnpbios_add_irqresource (pci_dev, irq);break ;case 0x05 :// dma mask = p[1 ];for (i=0 ;i<8 ;i++, mask = mask>>1 )if (mask&0x01 ) dma=i; - i=0 ; -while (pci_dev->dma_resource[i].start && i<DEVICE_COUNT_DMA ) - i++; -if (i<DEVICE_COUNT_DMA ) - pci_dev->dma_resource[i].start=dma; - +pnpbios_add_dmaresource (pci_dev, dma);break ;case 0x08 :// io io= p[2 ] + p[3 ] *256 ; len = p[7 ]; - i=0 ; -while (pci_dev->resource[i].start && i<DEVICE_COUNT_RESOURCE ) - i++; -if (i<DEVICE_COUNT_RESOURCE ) { - pci_dev->resource[i].start=io; - pci_dev->resource[i].end=io+len; - pci_dev->resource[i].flags=IORESOURCE_IO ; - } - +pnpbios_add_ioresource (pci_dev, io, len,IORESOURCE_IO );break ; +case 0x09 :// fixed location io + io = p[1 ] + p[2 ] *256 ; + len = p[3 ]; +pnpbios_add_ioresource (pci_dev, io, len,IORESOURCE_IO ); +break ; } lastp=p+1 ; p = p + (p[0 ] &0x07 ) +1 ;
@@ -691,21 +731,21 @@#define HEX (id,a) hex[((id)>>a) & 15]#define CHAR (id,a) (0x40 + (((id)>>a) & 31)) -static char *pnpid32_to_pnpid (u32 id) +static char *__init pnpid32_to_pnpid (u32 id) {const char *hex ="0123456789abcdef" ;static char str[8 ]; - id =cpu_to_le32 (id); - str[0 ] =CHAR (id,2 ); - str[1 ] =CHAR ((((id &3 ) <<3 ) | ((id >>13 ) &7 )),0 ); - str[2 ] =CHAR (id,8 ); - str[3 ] =HEX (id,20 ); - str[4 ] =HEX (id,16 ); - str[5 ] =HEX (id,28 ); - str[6 ] =HEX (id,24 ); + id =be32_to_cpu (id); + str[0 ] =CHAR (id,26 ); + str[1 ] =CHAR (id,21 ); + str[2 ] =CHAR (id,16 ); + str[3 ] =HEX (id,12 ); + str[4 ] =HEX (id,8 ); + str[5 ] =HEX (id,4 ); + str[6 ] =HEX (id,0 ); str[7 ] ='\0' ;return str; -} +}#undef CHAR#undef HEX
@@ -716,7 +756,7 @@static LIST_HEAD (pnpbios_devices); -static int pnpbios_insert_device (struct pci_dev *dev) +static int __init pnpbios_insert_device (struct pci_dev *dev) {/* FIXME: Need to check for re-add of existing node */ list_add_tail (&dev->global_list, &pnpbios_devices);