Resource Management Improvements (1/4)
Subsystems (2)
RFC PATCH 1/1 Resource Management Improvements (1/4)
This patch is the first of 4 experimental pnp patches. It is against a clean 2.5.59 kernel. I would appreciate for those who are interested, if you would test this patch series and post your results on lkml. These changes appear to be very stable on my test systems and I feel they will be a dramatic improvement to the pnp layer.
Patch 1 contains resource management improvements that will allow the pnp layer to resolve virtually any resource conflict. A new kernel parameter "pnp_max_moves=" was added to allow the user to describe the maximum number of device levels to move during conflict resolution. This powerful new engine also includes many cleanups and more verbose reporting. All devices are configured when added instead of when activated. This will increase the odds that the conflict will be possible to resolve because resources cannot be moved in an active device.
drivers/pnp/base.h +11 -0
@@ -4,6 +4,17 @@extern int pnp_interface_attach_device (struct pnp_dev *dev);extern void pnp_name_device (struct pnp_dev *dev);extern void pnp_fixup_device (struct pnp_dev *dev); +extern int pnp_configure_device (struct pnp_dev *dev);extern void pnp_free_resources (struct pnp_resources *resources);extern int __pnp_add_device (struct pnp_dev *dev);extern void __pnp_remove_device (struct pnp_dev *dev); + +/* resource conflict types */ +#define CONFLICT_TYPE_NONE 0x0000/* there are no conflicts, other than those in the link */ +#define CONFLICT_TYPE_RESERVED 0x0001/* the resource requested was reserved */ +#define CONFLICT_TYPE_IN_USE 0x0002/* there is a conflict because the resource is in use */ +#define CONFLICT_TYPE_PCI 0x0004/* there is a conflict with a pci device */ +#define CONFLICT_TYPE_INVALID 0x0008/* the resource requested is invalid */ +#define CONFLICT_TYPE_INTERNAL 0x0010/* resources within the device conflict with each ohter */ +#define CONFLICT_TYPE_PNP_WARM 0x0020/* there is a conflict with a pnp device that is active */ +#define CONFLICT_TYPE_PNP_COLD 0x0040/* there is a conflict with a pnp device that is disabled */
drivers/pnp/card.c +4 -5
@@ -22,9 +22,9 @@LIST_HEAD (pnp_cards); -static const struct pnp_card_device_id *match_card (struct pnpc_driver *drv,struct pnp_card *card) +static const struct pnp_card_id *match_card (struct pnpc_driver *drv,struct pnp_card *card) { -const struct pnp_card_device_id *drv_id = drv->id_table; +const struct pnp_card_id *drv_id = drv->id_table;while (*drv_id->id){if (compare_pnp_id (card->id,drv_id->id))return drv_id;
@@ -106,7 +106,6 @@return -EINVAL ;sprintf (card->dev.bus_id,"%02x:%02x" , card->protocol->number, card->number);INIT_LIST_HEAD (&card->rdevs); -strcpy (card->dev.name,card->name); card->dev.parent = &card->protocol->dev; card->dev.bus = &pnpc_bus_type; card->dev.release = &pnp_release_card;
@@ -221,7 +220,7 @@ cdrv =to_pnpc_driver (card->dev.driver);if (dev->active ==0 ) {if (!(cdrv->flags &PNPC_DRIVER_DO_NOT_ACTIVATE )) { -if (pnp_activate_dev (dev,NULL )<0 ) { +if (pnp_activate_dev (dev)<0 ) {pnp_device_detach (dev);return NULL ; }
@@ -286,7 +285,7 @@int error =0 ;struct pnpc_driver *drv =to_pnpc_driver (dev->driver);struct pnp_card *card =to_pnp_card (dev); -const struct pnp_card_device_id *card_id =NULL ; +const struct pnp_card_id *card_id =NULL ;pnp_dbg ("pnp: match found with the PnP card '%s' and the driver '%s'" , dev->bus_id,drv->name);
drivers/pnp/core.c +12 -14
@@ -104,31 +104,29 @@static void pnp_release_device (struct device *dmdev) {struct pnp_dev * dev =to_pnp_dev (dmdev); -if (dev->res) -pnp_free_resources (dev->res); +if (dev->possible) +pnp_free_resources (dev->possible);pnp_free_ids (dev);kfree (dev); }int __pnp_add_device (struct pnp_dev *dev) { -int error =0 ; +int ret;pnp_name_device (dev);pnp_fixup_device (dev); -strncpy (dev->dev.name,dev->name,DEVICE_NAME_SIZE -1 ); - dev->dev.name[DEVICE_NAME_SIZE -1 ] ='\0' ; dev->dev.bus = &pnp_bus_type; dev->dev.release = &pnp_release_device; dev->status =PNP_READY ; - error =device_register (&dev->dev); -if (error ==0 ){ -spin_lock (&pnp_lock); -list_add_tail (&dev->global_list, &pnp_global); -list_add_tail (&dev->protocol_list, &dev->protocol->devices); -spin_unlock (&pnp_lock); +spin_lock (&pnp_lock); +list_add_tail (&dev->global_list, &pnp_global); +list_add_tail (&dev->protocol_list, &dev->protocol->devices); +spin_unlock (&pnp_lock); +pnp_configure_device (dev); + ret =device_register (&dev->dev); +if (ret ==0 )pnp_interface_attach_device (dev); - } -return error; +return ret; }/*
@@ -172,7 +170,7 @@static int __init pnp_init (void ) { -printk (KERN_INFO "Linux Plug and Play Support v0.94 (c) Adam Belay\n" ); +printk (KERN_INFO "Linux Plug and Play Support v0.95 (c) Adam Belay\n" );return bus_register (&pnp_bus_type); }
drivers/pnp/driver.c +1 -1
@@ -103,7 +103,7 @@if (pnp_dev->active ==0 ) {if (!(pnp_drv->flags &PNP_DRIVER_DO_NOT_ACTIVATE )) { - error =pnp_activate_dev (pnp_dev,NULL ); + error =pnp_activate_dev (pnp_dev);if (error <0 )return error; }
drivers/pnp/interface.c +6 -12
@@ -218,7 +218,7 @@static ssize_t pnp_show_possible_resources (struct device *dmdev,char *buf) {struct pnp_dev *dev =to_pnp_dev (dmdev); -struct pnp_resources * res = dev->res; +struct pnp_resources * res = dev->possible;int dep =0 ;pnp_info_buffer_t *buffer;
@@ -251,7 +251,7 @@ str +=sprintf (str,"DISABLED\n" ); goto done; } -for (i =0 ; i <DEVICE_COUNT_IO ; i++) { +for (i =0 ; i <PNP_MAX_PORT ; i++) {if (pnp_port_valid (dev, i)) { str +=sprintf (str,"io" ); str += sprintf(str," 0x%lx-0x%lx \n",
@@ -259,7 +259,7 @@ pnp_port_end(dev, i)); } } -for (i =0 ; i <DEVICE_COUNT_MEM ; i++) { +for (i =0 ; i <PNP_MAX_MEM ; i++) {if (pnp_mem_valid (dev, i)) { str +=sprintf (str,"mem" ); str += sprintf(str," 0x%lx-0x%lx \n",
@@ -267,13 +267,13 @@ pnp_mem_end(dev, i)); } } -for (i =0 ; i <DEVICE_COUNT_IRQ ; i++) { +for (i =0 ; i <PNP_MAX_IRQ ; i++) {if (pnp_irq_valid (dev, i)) { str +=sprintf (str,"irq" ); str +=sprintf (str," %ld \n" ,pnp_irq (dev, i)); } } -for (i =0 ; i <DEVICE_COUNT_DMA ; i++) { +for (i =0 ; i <PNP_MAX_DMA ; i++) {if (pnp_dma_valid (dev, i)) { str +=sprintf (str,"dma" ); str +=sprintf (str," %ld \n" ,pnp_dma (dev, i));
@@ -316,13 +316,7 @@ goto done; }if (!strnicmp (command,"auto" ,4 )) { - error =pnp_activate_dev (dev,NULL ); - goto done; - } -if (!strnicmp (command,"manual" ,6 )) { -if (num_args !=2 ) - goto done; - error =pnp_raw_set_dev (dev,depnum,NULL ); + error =pnp_activate_dev (dev); goto done; } done:
drivers/pnp/isapnp/core.c +8 -52
119 lines not on this page · raw message
drivers/pnp/names.c +1 -1
@@ -30,7 +30,7 @@ pnp_name_device(struct pnp_dev *dev) {int i; -char *name = dev->name; +char *name = dev->dev.name;for (i=0 ; i<sizeof (pnp_id_eisaid)/sizeof (pnp_id_eisaid[0 ]); i++){if (compare_pnp_id (dev->id,pnp_id_eisaid[i])){sprintf (name,"%s" , pnp_id_names[i]);
drivers/pnp/pnpbios/core.c +45 -46
172 lines not on this page · raw message
drivers/pnp/quirks.c +4 -4
@@ -29,7 +29,7 @@static void quirk_awe32_resources (struct pnp_dev *dev) {struct pnp_port *port, *port2, *port3; -struct pnp_resources *res = dev->res->dep; +struct pnp_resources *res = dev->possible->dep;/* * Unfortunately the isapnp_add_port_resource is too tightly bound
@@ -57,7 +57,7 @@static void quirk_cmi8330_resources (struct pnp_dev *dev) { -struct pnp_resources *res = dev->res->dep; +struct pnp_resources *res = dev->possible->dep;for ( ; res ; res = res->dep ) {
@@ -77,7 +77,7 @@static void quirk_sb16audio_resources (struct pnp_dev *dev) {struct pnp_port *port; -struct pnp_resources *res = dev->res->dep; +struct pnp_resources *res = dev->possible->dep;int changed =0 ;/*
@@ -115,7 +115,7 @@*/ struct pnp_resources *res;int max; - res = dev->res; + res = dev->possible; max =0 ;for (res = res->dep; res; res = res->dep) {if (res->dma->map > max)
drivers/pnp/resource.c +695 -370
1,342 lines not on this page · raw message
drivers/pnp/system.c +1 -1
@@ -53,7 +53,7 @@ {int i; -for (i=0 ;i<DEVICE_COUNT_IO ;i++) { +for (i=0 ;i<PNP_MAX_PORT ;i++) {if (pnp_port_valid (dev, i))/* end of resources */ continue ;
drivers/serial/8250_pnp.c +3 -3
@@ -317,7 +317,7 @@ {unsigned int map =0x1FF8 ;struct pnp_irq *irq; -struct pnp_resources *res = dev->res; +struct pnp_resources *res = dev->possible;serial8250_get_irq_map (&map);
@@ -357,10 +357,10 @@*/ static int serial_pnp_guess_board (struct pnp_dev *dev,int *flags) { -struct pnp_resources *res = dev->res; +struct pnp_resources *res = dev->possible;struct pnp_resources *resa; -if (!(check_name (dev->name) || (dev->card &&check_name (dev->card->name)))) +if (!(check_name (dev->dev.name) || (dev->card &&check_name (dev->card->dev.name))))return -ENODEV ;if (!res)
include/linux/pnp.h +207 -217
576 lines not on this page · raw message
Jaroslav Kysela
maintainerQuoted 5 lines · Adam Belay
drivers/pnp/pnpbios/core.c +0
-1@@ -825,10 +825,10 @@ }/* while */ end: - if (pnp_port_valid(dev, 0) == 0 &&
drivers/pnp/pnpbios/core.c line 834
Quoted 10 lines
drivers/pnp/pnpbios/core.c +4
-3-pnp_mem_valid (dev,0 ) ==0 && -pnp_irq_valid (dev,0 ) ==0 && - pnp_dma_valid(dev, 0) == 0) +if (pnp_port_start (dev,0 ) ==0 && +pnp_mem_start (dev,0 ) ==0 && +pnp_irq (dev,0 ) ==-1 && +pnp_dma (dev,0 ) ==-1 ) dev->active =0 ;else dev->active =1 ;
Again, why this?
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
Jaroslav Kysela
maintainerQuoted 6 lines · Adam Belay
This patch is the first of 4 experimental pnp patches. It is against a clean 2.5.59 kernel. I would appreciate for those who are interested, if you would test this patch series and post your results on lkml. These changes appear to be very stable on my test systems and I feel they will be a dramatic improvement to the pnp layer.
Quoted 8 lines
Patch 1 contains resource management improvements that will allow the pnp layer to resolve virtually any resource conflict. A new kernel parameter "pnp_max_moves=" was added to allow the user to describe the maximum number of device levels to move during conflict resolution. This powerful new engine also includes many cleanups and more verbose reporting. All devices are configured when added instead of when activated. This will increase the odds that the conflict will be possible to resolve because resources cannot be moved in an active device.
I don't agree with this. Simply, why to activate devices which will not be ever used? You'll occupy resources which can be assigned to another device. Also, you simply removed my configuration templates, so the driver cannot tell explicitly which resources PnP layer should assign. Also activation (and resource allocation) should be on request allowing driver to do things manually. Bad bad bad. We're again in state a month ago when nothing worked and ALSA ISA PnP drivers are still broken, because your model doesn't have all features like good old ISA PnP code. Also, with all respects, I think that you're trying to write very clever code. It's also bad. It will end with numerous problems and with undeterministic behaviour like unnamed commercial OS. Let users to pass their own configurations.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
Jaroslav Kysela
maintainerPnP model
In reply to Adam BelayHi all,
I think that we need to discuss deeply the right PnP model. The
actual changes proposed by Adam are going to be more and more complex without allowing the user interactions inside the "auto" steps. The auto-configuration might be good and bad as we all know, but having an method to skip it is necessary.
I strongly vote to follow the same behaviour as PCI code does:
It means call the activation / enabling / setting functions from the probe() callbacks. Only the driver knows what's the best. Including the manual assignment of resources.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
Re: PnP model
Quoted 4 lines · Jaroslav Kysela
I strongly vote to follow the same behaviour as PCI code does:
It means call the activation / enabling / setting functions from theprobe()callbacks. Only the driver knows what's the best. Including the manual assignment of resources.
I agree. A lot of drivers should be able to use one model for everything including "enable_device" stuff. Right now its all a bit too detailed.
Also the locking model seems very unclear and there are hot swappable ISA bays
Re: PnP model
In reply to Jaroslav KyselaQuoted 3 lines · Jaroslav Kysela
Hi all,
I think that we need to discuss deeply the right PnP model. The
I'm confident this is the right pnp model.
Quoted 4 lines
actual changes proposed by Adam are going to be more and more complex without allowing the user interactions inside the "auto" steps. The auto-configuration might be good and bad as we all know, but having an method to skip it is necessary.
In many cases, Auto configuration can be better then manual configuration. 1.) The auto configuration engine in my patch is able to resolve almost any resource conflict and provides the greatest chance for all devices to have resources allocated.
2.) Certainly some driver developers would like to manually set resources but many may prefer the option to auto config.
3.) Drivers under the existing system are not aware of many forms of resource conflicts and could set resources incorrectly.
4.) Some users do not want to worry about manual configuration and would welcome an auto configuration system that makes intelligent choices without user input. This autoconfiguration system monitors many variables that a user would have a hard time keeping track of and never overlooks any potential conflicts in its analysis.
The above stated reasons are why I introduced these auto configuration (Resource Management) improvements.
I feel that one solution is to support both manual and auto configuration so the user can use what he or she prefers, however, I am confident that in most cases the auto configuration will be the best option.
Perhaps I didn't make this clear earlier, it was not my intent to remove support for manual resource configurations. This was only temporary and intended for the first release. Here is a patch against my other 4 patches that updates the pnp code to support manual resource configurations. It also merges the pnpbios GPF fix and addresses a few other issues.
-Adam
P.S.: The new manual config API is pnp_manual_config_dev.
P.S.: I'm currently working on an improved user interface that will allow the user to manually set resources through the sysfs interface. It will include reports on where the conflicts are in order to assist the user in making decisions.
P.S.: I intend to resolve all of these issues but my top priority is to convert pnp drivers. For example, I recently submitted pnp driver conversions and am currently working on pnp card service revisions.
This patch needs to be tested. I appreciate any and all feedback.
drivers/pnp/base.h +0 -1
@@ -4,7 +4,6 @@extern int pnp_interface_attach_device (struct pnp_dev *dev);extern void pnp_name_device (struct pnp_dev *dev);extern void pnp_fixup_device (struct pnp_dev *dev); -extern int pnp_configure_device (struct pnp_dev *dev);extern void pnp_free_resources (struct pnp_resources *resources);extern int __pnp_add_device (struct pnp_dev *dev);extern void __pnp_remove_device (struct pnp_dev *dev);
drivers/pnp/core.c +1 -1
@@ -122,7 +122,7 @@list_add_tail (&dev->global_list, &pnp_global);list_add_tail (&dev->protocol_list, &dev->protocol->devices);spin_unlock (&pnp_lock); -pnp_configure_device (dev); +pnp_auto_config_dev (dev); ret =device_register (&dev->dev);if (ret ==0 )pnp_interface_attach_device (dev);
drivers/pnp/interface.c +5 -20
@@ -232,10 +232,11 @@char *str = buf;int i; -if (!dev->active){ - str +=sprintf (str,"DISABLED\n" ); - goto done; - } + str +=sprintf (str,"state = " ); +if (dev->active) + str +=sprintf (str,"active\n" ); +else + str +=sprintf (str,"disabled\n" );for (i =0 ; i <PNP_MAX_PORT ; i++) {if (pnp_port_valid (dev, i)) { str +=sprintf (str,"io" );
@@ -280,22 +281,6 @@ num_args =sscanf (buf,"%10s %i" ,command,&depnum);if (!num_args) goto done; -if (!strnicmp (command,"lock" ,4 )) { -if (dev->active) { - dev->lock_resources =1 ; - }else { - error = -EINVAL ; - } - goto done; - } -if (!strnicmp (command,"unlock" ,6 )) { -if (dev->lock_resources) { - dev->lock_resources =0 ; - }else { - error = -EINVAL ; - } - goto done; - }if (!strnicmp (command,"disable" ,7 )) { error =pnp_disable_dev (dev); goto done;
drivers/pnp/pnpbios/core.c +18 -11
@@ -142,11 +142,13 @@set_limit (cpu_gdt_table[cpu][(selname) >>3 ], size); \ }while (0 ) +static struct desc_struct bad_bios_desc = { 0, 0x00409200 }; +/* * At some point we want to use this stack frame pointer to unwind -* after PnP BIOS oopses. +* after PnP BIOS oopses. */ - +u32 pnp_bios_fault_esp;u32 pnp_bios_fault_eip;u32 pnp_bios_is_utter_crap =0 ;
@@ -160,6 +162,8 @@ {unsigned long flags;u16 status; +struct desc_struct save_desc_40; +int cpu;/* * PnP BIOSes are generally not terribly re-entrant.
@@ -168,6 +172,10 @@if (pnp_bios_is_utter_crap)return PNP_FUNCTION_NOT_SUPPORTED ; + cpu =get_cpu (); + save_desc_40 = cpu_gdt_table[cpu][0x40 /8 ]; + cpu_gdt_table[cpu][0x40 /8 ] = bad_bios_desc; +/* On some boxes IRQ's during PnP BIOS calls are deadly. */ spin_lock_irqsave (&pnp_bios_lock, flags);
@@ -207,6 +215,9 @@ : "memory" );spin_unlock_irqrestore (&pnp_bios_lock, flags); + + cpu_gdt_table[cpu][0x40 /8 ] = save_desc_40; +put_cpu ();/* If we get here and this is set then the PnP BIOS faulted on us. */ if (pnp_bios_is_utter_crap)
@@ -236,7 +247,8 @@void *p =kmalloc ( size, f );if ( p ==NULL )printk (KERN_ERR "PnPBIOS: kmalloc() failed\n" ); -memset (p,0 , size); +else +memset (p,0 , size);return p; }
@@ -886,14 +898,7 @@for (nodenum=0 ; nodenum<0xff ; ) {u8 thisnodenum = nodenum; -/* We build the list from the "boot" config because -* we know that the resources couldn't have changed -* at this stage. Furthermore some buggy PnP BIOSes -* will crash if we request the "current" config -* from devices that are can only be static such as -* those controlled by the "system" driver. -*/ -if (pnp_bios_get_dev_node (&nodenum, (char )1 , node)) +if (pnp_bios_get_dev_node (&nodenum, (char )0 , node))break ; nodes_got++; dev =pnpbios_kmalloc (sizeof (struct pnp_dev ),GFP_KERNEL );
@@ -996,6 +1001,8 @@ pnp_bios_callpoint.segment =PNP_CS16 ; pnp_bios_hdr = check; +set_base (bad_bios_desc,__va ((unsigned long )0x40 <<4 )); +_set_limit ((char *)&bad_bios_desc,4095 - (0x40 <<4 ));for (i=0 ; i <NR_CPUS ; i++) {Q2_SET_SEL (i,PNP_CS32 , &pnp_bios_callfunc,64 *1024 );
drivers/pnp/resource.c +118 -42
228 lines not on this page · raw message
drivers/pnp/support.c +9 -9
@@ -168,7 +168,7 @@break ; } }/* switch */ - p += len +3 ; + p += len +3 ;continue ; }/* end large tag */
@@ -410,8 +410,8 @@possible_dma (p,len,depnum,dev);break ; } -case SMALL_TAG_STARTDEP : - { +case SMALL_TAG_STARTDEP : + {if (len >1 ) goto sm_err; dependent =0x100 |PNP_RES_PRIORITY_ACCEPTABLE ;
@@ -419,15 +419,15 @@ dependent =0x100 | p[1 ];pnp_build_resource (dev,dependent); depnum =pnp_get_max_depnum (dev); -break ; - } -case SMALL_TAG_ENDDEP : - { +break ; + } +case SMALL_TAG_ENDDEP : + {if (len !=0 ) goto sm_err; depnum =0 ; -break ; - } +break ; + }case SMALL_TAG_PORT : {if (len !=7 )
include/linux/pnp.h +13 -2
@@ -253,7 +253,7 @@struct pnp_resource_table res;/* contains the currently chosen resources */ struct pnp_resources * possible;/* a list of possible resources */ struct pnp_rule_table * rule;/* the current possible resource set */ -int lock_resources;/* resources are locked */ +int config_mode;/* flags that determine how the device's resources should be configured */ void * protocol_data;/* Used to store protocol specific data */ unsigned short regs;/* ISAPnP: supported registers */
@@ -300,6 +300,13 @@void (*quirk_function)(struct pnp_dev *dev);/* fixup function */ }; +/* config modes */ +#define PNP_CONFIG_AUTO 0x0001/* Use the Resource Configuration Engine to determine resource settings */ +#define PNP_CONFIG_MANUAL 0x0002/* the config has been manually specified */ +#define PNP_CONFIG_FORCE 0x0003/* disables validity checking */ +#define PNP_CONFIG_RESOLVE 0x0008/* moves other configs out of the way, use only when absolutely necessary */ +#define PNP_CONFIG_INVALID 0x0010/* If this flag is set, the pnp layer will refuse to activate the device */ +/* capabilities */ #define PNP_READ 0x0001#define PNP_WRITE 0x0002
@@ -313,7 +320,7 @@ ((dev)->capabilities & PNP_WRITE))#define pnp_can_disable (dev) (((dev)->protocol) && ((dev)->protocol->disable) && \ ((dev)->capabilities & PNP_DISABLE)) -#define pnp_can_configure (dev) ((!(dev)->active) && (!(dev)->lock_resources) && \ +#define pnp_can_configure (dev) ((!(dev)->active) && ((dev)->config_mode & PNP_CONFIG_AUTO) && \ ((dev)->capabilities & PNP_CONFIGURABLE))/* status */
@@ -377,6 +384,8 @@int pnp_activate_dev (struct pnp_dev *dev);int pnp_disable_dev (struct pnp_dev *dev);void pnp_resource_change (struct resource *resource,unsigned long start,unsigned long size); +int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode); +int pnp_auto_config_dev (struct pnp_dev *dev);/* driver */ int compare_pnp_id (struct pnp_id * pos,const char * id);
@@ -415,6 +424,8 @@static inline int pnp_activate_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_disable_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline void pnp_resource_change (struct resource *resource,unsigned long start,unsigned long size) { ; } +static inline int pnp_manual_config_dev (struct pnp_dev *dev,struct pnp_resource_table *res,int mode) {return -ENODEV ; } +static inline int pnp_auto_config_dev (struct pnp_dev *dev) {return -ENODEV ; }/* driver */ static inline int compare_pnp_id (struct list_head * id_list,const char * id) {return -ENODEV ; }
Re: PnP model
Quoted 4 lines · Adam Belay
In many cases, Auto configuration can be better then manual configuration. 1.) The auto configuration engine in my patch is able to resolve almost any resource conflict and provides the greatest chance for all devices to have resources allocated.
There is a nice problem with ISA PNP serial ports generated by this type of thing in 2.5.59.
On boot, we probe for the usual serial ports, and discover two at 0x3f8 and 0x2f8, and we request these resources. Please note that one port could be in use as a serial console from earlier in the bootup.
Then, we move on to the PNP probes. The PNP layer gives us two serial ports, and we initialise them. The PNP layer notices that the resources for 0x3f8 and 0x2f8, and re-assigns the ports to 0x3e8 and 0x2e8. The serial layer finds two extra ports at 0x3e8 and 0x2e8.
However, the ports at 0x3f8 and 0x2f8 are now gone, along with the serial console, and the boot messages claim that we have four serial ports at ttyS0, ttyS1, ttyS2, and ttyS3, when the machine in fact only has two serial ports. The serial layer likewise believes we have four serial ports.
I look forward to your thoughts on getting around this problem.
Signature · 2 lines
Russell King ([email protected]) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html
Jaroslav Kysela
maintainerRe: PnP model
Quoted 20 lines · Russell King
Quoted 4 lines · Adam Belay
In many cases, Auto configuration can be better then manual configuration. 1.) The auto configuration engine in my patch is able to resolve almost any resource conflict and provides the greatest chance for all devices to have resources allocated.
There is a nice problem with ISA PNP serial ports generated by this type of thing in 2.5.59.
On boot, we probe for the usual serial ports, and discover two at
0x3f8and0x2f8, and we request these resources. Please note that one port could be in use as a serial console from earlier in the bootup.Then, we move on to the PNP probes. The PNP layer gives us two serial ports, and we initialise them. The PNP layer notices that the resources for
0x3f8and0x2f8, and re-assigns the ports to0x3e8and0x2e8. The serial layer finds two extra ports at0x3e8and0x2e8.
Quoted 7 lines
However, the ports at
0x3f8and0x2f8are now gone, along with the serial console, and the boot messages claim that we have four serial ports at ttyS0, ttyS1, ttyS2, and ttyS3, when the machine in fact only has two serial ports. The serial layer likewise believes we have four serial ports.I look forward to your thoughts on getting around this problem.
I think that legacy devices must be probed after PnP ones, otherwise you'll get these duplications.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
Re: PnP model
Quoted 2 lines · Jaroslav Kysela
I think that legacy devices must be probed after PnP ones, otherwise you'll get these duplications.
Unfortunately, this isn't easy to do, while keeping stuff like serial consoles working from early at bootup. Alan Cox definitely does not want to see the serial console initialised any later than it is today, and he's not the only one.
In addition, the "legacy" devices are part of the 8250.c module - they have to be for serial console. The PNP devices are probed as part of the 8250_pnp.c module, and since 8250_pnp.c depends on 8250.c, the serial PNP ports will _always_ be initialised after the ISA probes.
Signature · 2 lines
Russell King ([email protected]) The developer of ARM Linux http://www.arm.linux.org.uk/personal/aboutme.html
Re: PnP model
Quoted 9 lines · Russell King
Quoted 2 lines · Jaroslav Kysela
I think that legacy devices must be probed after PnP ones, otherwise you'll get these duplications.
Unfortunately, this isn't easy to do, while keeping stuff like serial consoles working from early at bootup. Alan Cox definitely does not want to see the serial console initialised any later than it is today, and he's not the only one.
Quoted 5 lines
In addition, the "legacy" devices are part of the 8250.c module - they have to be for serial console. The PNP devices are probed as part of the
8250_pnp.cmodule, and since8250_pnp.cdepends on 8250.c, the serial PNP ports will _always_ be initialised after the ISA probes.
I think I have an alternative solution. If we add support for current resource configs and don't reset the cards, we can determine what the active configuration was when the serial driver detects the isapnp card. Because the device will remain active the resources will not be changed. Below is a patch against my previous 5 patches. This patch also contains a few fixes and cleanups. Could you please test this and let me know if it solves the problem.
Also I noticed that the serial driver legacy probe, independent of my changes, sometimes detects the incorrect irq, is proper irq detection needed by the serial driver or will it still work properly even if that information is detected incorrectly?
Thanks,
Adam
P.S.: ISAPnP MEM32 writing and reading still needs a little work. P.S.: PNPBIOS MEM32s are fully supported.
drivers/pnp/interface.c +0 -1
@@ -265,7 +265,6 @@ str +=sprintf (str," %ld \n" ,pnp_dma (dev, i)); } } - done:return (str - buf); }
drivers/pnp/isapnp/core.c +84 -19
179 lines not on this page · raw message
drivers/pnp/resource.c +113 -45
322 lines not on this page · raw message
include/linux/pnp.h +4 -3
@@ -303,9 +303,8 @@/* config modes */ #define PNP_CONFIG_AUTO 0x0001/* Use the Resource Configuration Engine to determine resource settings */ #define PNP_CONFIG_MANUAL 0x0002/* the config has been manually specified */ -#define PNP_CONFIG_FORCE 0x0003/* disables validity checking */ -#define PNP_CONFIG_RESOLVE 0x0008/* moves other configs out of the way, use only when absolutely necessary */ -#define PNP_CONFIG_INVALID 0x0010/* If this flag is set, the pnp layer will refuse to activate the device */ +#define PNP_CONFIG_FORCE 0x0004/* disables validity checking */ +#define PNP_CONFIG_INVALID 0x0008/* If this flag is set, the pnp layer will refuse to activate the device */ /* capabilities */ #define PNP_READ 0x0001
@@ -381,6 +380,7 @@int pnp_add_port_resource (struct pnp_dev *dev,int depnum,struct pnp_port *data);int pnp_add_mem_resource (struct pnp_dev *dev,int depnum,struct pnp_mem *data);void pnp_init_resource_table (struct pnp_resource_table *table); +int pnp_generate_rule (struct pnp_dev * dev,int depnum,struct pnp_rule_table * rule);int pnp_activate_dev (struct pnp_dev *dev);int pnp_disable_dev (struct pnp_dev *dev);void pnp_resource_change (struct resource *resource,unsigned long start,unsigned long size);
@@ -421,6 +421,7 @@static inline int pnp_add_port_resource (struct pnp_dev *dev,int depnum,struct pnp_irq *data) {return -ENODEV ; }static inline int pnp_add_mem_resource (struct pnp_dev *dev,int depnum,struct pnp_irq *data) {return -ENODEV ; }static inline void pnp_init_resource_table (struct pnp_resource_table *table) { ; } +static inline int pnp_generate_rule (struct pnp_dev * dev,int depnum,struct pnp_rule_table * rule) {return -ENODEV ; }static inline int pnp_activate_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline int pnp_disable_dev (struct pnp_dev *dev) {return -ENODEV ; }static inline void pnp_resource_change (struct resource *resource,unsigned long start,unsigned long size) { ; }
Re: PnP model
Quoted 29 lines · Adam Belay
Quoted 9 lines · Russell King
Quoted 2 lines · Jaroslav Kysela
I think that legacy devices must be probed after PnP ones, otherwise you'll get these duplications.
Unfortunately, this isn't easy to do, while keeping stuff like serial consoles working from early at bootup. Alan Cox definitely does not want to see the serial console initialised any later than it is today, and he's not the only one.
Quoted 5 lines
In addition, the "legacy" devices are part of the 8250.c module - they have to be for serial console. The PNP devices are probed as part of the
8250_pnp.cmodule, and since8250_pnp.cdepends on 8250.c, the serial PNP ports will _always_ be initialised after the ISA probes.I think I have an alternative solution. If we add support for current resource configs and don't reset the cards, we can determine what the active configuration was when the serial driver detects the isapnp card. Because the device will remain active the resources will not be changed. Below is a patch against my previous 5 patches. This patch also contains a few fixes and cleanups. Could you please test this and let me know if it solves the problem.
Also I noticed that the serial driver legacy probe, independent of my changes, sometimes detects the incorrect irq, is proper irq detection needed by the serial driver or will it still work properly even if that information is detected incorrectly?
drivers/pnp/isapnp/core.c line 56
Quoted 2 lines
drivers/pnp/isapnp/core.c +1
-1-int isapnp_reset =1 ;/* reset all PnP cards (deactivate) */ +int isapnp_reset =0 ;/* reset all PnP cards (deactivate) */
Please, don't do this. The default value is quite ok. I think that it's more PnP BIOS problem than ISA PnP one (I don't know about any motherboard where the standard serial ports are ISA PnP). But the parsing of active configuration when isapnp_reset == 0 is ok...
drivers/pnp/isapnp/core.c line 1056
Quoted 1 line
drivers/pnp/isapnp/core.c +1
-0+for (tmp =0 ; tmp <PNP_MAX_PORT && res->port_resource[tmp].flags &IORESOURCE_IO ; tmp++)
Again, pnp_valid_* macros are your fried. You deleted them from your tree during merge.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs
Jaroslav Kysela
maintainerRe: PnP model
In reply to Adam BelayQuoted 5 lines · Adam Belay
Quoted 3 lines · Jaroslav Kysela
Hi all,
I think that we need to discuss deeply the right PnP model. The
Quoted 8 lines
I'm confident this is the right pnp model.
Quoted 4 lines
actual changes proposed by Adam are going to be more and more complex without allowing the user interactions inside the "auto" steps. The auto-configuration might be good and bad as we all know, but having an method to skip it is necessary.
In many cases, Auto configuration can be better then manual configuration.
Autoconfiguration is better in perfect world... There are always troubles with some hardware incompatibilities.
Quoted 13 lines
1.) The auto configuration engine in my patch is able to resolve almost any resource conflict and provides the greatest chance for all devices to have resources allocated.
2.) Certainly some driver developers would like to manually set resources but many may prefer the option to auto config.
3.) Drivers under the existing system are not aware of many forms of resource conflicts and could set resources incorrectly.
4.) Some users do not want to worry about manual configuration and would welcome an auto configuration system that makes intelligent choices without user input. This autoconfiguration system monitors many variables that a user would have a hard time keeping track of and never overlooks any potential conflicts in its analysis.
Quoted 6 lines
The above stated reasons are why I introduced these auto configuration (Resource Management) improvements.
I feel that one solution is to support both manual and auto configuration so the user can use what he or she prefers, however, I am confident that in most cases the auto configuration will be the best option.
But do we have to enable the auto configuration at boot implicitly? I don't think so. Again, it's better if driver decides if auto or manual configuration will be used. The step by step configuration makes the implemenation more rebust (user will know which driver fails). Also, having legacy devices in the system, you cannot determine which resources are required for them before appropriate driver detects and initializes the device. I don't think that this algorithm will be worse than your proposed one. There are usually no resource conflicts for PnP devices so it will work at least on the same number of machines like implicit autoconfiguration at boot.
Also, imagine that PnP driver is build into the kernel: you'll no chance select the right configuration over sysfs, but there are __setup() macros allowing to pass the right resources to a driver.
Jaroslav
-----
Jaroslav Kysela <[email protected]>
Linux Kernel Sound Maintainer
ALSA Project, SuSE Labs