driver core fixes against 2.6.25-rc5 git
PATCH 1/1 driver core fixes against 2.6.25-rc5 git
Here are 4 fixes fixes against your current git tree that fix some more problems that have cropped up:
- nozomi driver fixes for oopses found by users
- resource calculation problem found by the scsi people
- sysdev fixes for oopses for kvm and ooprofile code
- firmware.h gets stubs for when the config option is not enabled, fixing build errors.
Please pull from:
master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6.git/
Patches will be sent as a follow-on to this message to lkml for people to see.
thanks,
greg k-h
------------
drivers/base/platform.c | 2 +- drivers/base/sys.c | 4 +++ drivers/char/nozomi.c | 61 ++++++++++++++++++++++++++++++++------------- include/linux/firmware.h | 23 +++++++++++++++++ 4 files changed, 71 insertions(+), 19 deletions(-)
---------------
Frank Seidel (1):
nozomi: fix initialization and early flow control access
Greg Kroah-Hartman (1):
sysdev: fix problem with sysdev_class being re-registered
James Bottomley (2):
firmware: provide stubs for the FW_LOADER=n case
drivers: fix dma_get_required_mask
PATCH 1/4 sysdev: fix problem with sysdev_class being re-registered
We need to initialize the kobject for a sysdev_class as it could have been recycled (stupid static kobjects...)
We also do the same thing in case sysdev devices are being re-registered.
Thanks to Balaji Rao <[email protected]> for pointing out the problem.
--- drivers/base/sys.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-)
drivers/base/sys.c +4 -0
@@ -133,6 +133,7 @@ int sysdev_class_register(struct sysdev_class * cls)pr_debug ("Registering sysdev class '%s'\n" ,kobject_name (&cls->kset.kobj));INIT_LIST_HEAD (&cls->drivers); +memset (&cls->kset.kobj,0x00 ,sizeof (struct kobject )); cls->kset.kobj.parent = &system_kset->kobj; cls->kset.kobj.ktype = &ktype_sysdev_class; cls->kset.kobj.kset = system_kset;
@@ -227,6 +228,9 @@ int sysdev_register(struct sys_device * sysdev)pr_debug ("Registering sys device '%s'\n" ,kobject_name (&sysdev->kobj)); +/* initialize the kobject to 0, in case it had previously been used */ +memset (&sysdev->kobj,0x00 ,sizeof (struct kobject )); +/* Make sure the kset is set */ sysdev->kobj.kset = &cls->kset;
Signature · 1 line
1.5.4.3
PATCH 2/4 nozomi: fix initialization and early flow control access
In reply to Greg KHFrom: Frank Seidel <[email protected]>
Due to some flaws in the initialization and flow control code kernel oopses could be triggered e.g. when accessing the card too early after insertion.
See e.g. kernel.org bug #10077.
The main part of the fix is a trivial state management making sure the card is realy ready to use before allowing any access.
--- drivers/char/nozomi.c | 61 ++++++++++++++++++++++++++++++++++-------------- 1 files changed, 43 insertions(+), 18 deletions(-)
drivers/char/nozomi.c +43 -18
@@ -190,6 +190,14 @@ enum card_type { F32_8 = 8192, /* 3072 bytes downl. + 1024 bytes uplink * 2 -> 8192 */ }; +/* Initialization states a card can be in */ +enum card_state { +NOZOMI_STATE_UKNOWN =0 , +NOZOMI_STATE_ENABLED =1 ,/* pci device enabled */ +NOZOMI_STATE_ALLOCATED =2 ,/* config setup done */ +NOZOMI_STATE_READY =3 ,/* flowcontrols received */ +}; +/* Two different toggle channels exist */ enum channel_type {CH_A =0 ,
@@ -385,6 +393,7 @@ struct nozomi {spinlock_t spin_mutex;/* secures access to registers and tty */ unsigned int index_start; +enum card_state state;u32 open_ttys; };
@@ -686,6 +695,7 @@ static int nozomi_read_config_table(struct nozomi *dc) dc->last_ier = dc->last_ier |CTRL_DL ;writew (dc->last_ier, dc->reg_ier); + dc->state =NOZOMI_STATE_ALLOCATED ;dev_info (&dc->pdev->dev,"Initialization OK!\n" );return 1 ; }
@@ -944,6 +954,14 @@ static int receive_flow_control(struct nozomi *dc)case CTRL_APP2 : port =PORT_APP2 ; enable_ier =APP2_DL ; +if (dc->state ==NOZOMI_STATE_ALLOCATED ) { +/* +* After card initialization the flow control +* received for APP2 is always the last +*/ + dc->state =NOZOMI_STATE_READY ; +dev_info (&dc->pdev->dev,"Device READY!\n" ); + }break ;default : dev_err(&dc->pdev->dev,
@@ -1366,22 +1384,12 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, dc->pdev = pdev; -/* Find out what card type it is */ -nozomi_get_card_type (dc); - ret =pci_enable_device (dc->pdev);if (ret) {dev_err (&pdev->dev,"Failed to enable PCI Device\n" ); goto err_free; } - start =pci_resource_start (dc->pdev,0 ); -if (start ==0 ) { -dev_err (&pdev->dev,"No I/O address for card detected\n" ); - ret = -ENODEV ; - goto err_disable_device; - } - ret =pci_request_regions (dc->pdev,NOZOMI_NAME );if (ret) { dev_err(&pdev->dev, "I/O address 0x%04x already in use\n",
@@ -1389,6 +1397,16 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, goto err_disable_device; } + start =pci_resource_start (dc->pdev,0 ); +if (start ==0 ) { +dev_err (&pdev->dev,"No I/O address for card detected\n" ); + ret = -ENODEV ; + goto err_rel_regs; + } + +/* Find out what card type it is */ +nozomi_get_card_type (dc); + dc->base_addr =ioremap (start, dc->card_type);if (!dc->base_addr) {dev_err (&pdev->dev,"Unable to map card MMIO\n" );
@@ -1425,6 +1443,14 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, dc->index_start = ndev_idx *MAX_PORT ; ndevs[ndev_idx] = dc; +pci_set_drvdata (pdev, dc); + +/* Enable RESET interrupt */ + dc->last_ier =RESET ; +iowrite16 (dc->last_ier, dc->reg_ier); + + dc->state =NOZOMI_STATE_ENABLED ; +for (i =0 ; i <MAX_PORT ; i++) {mutex_init (&dc->port[i].tty_sem); dc->port[i].tty_open_count =0 ;
@@ -1433,12 +1459,6 @@ static int __devinit nozomi_card_init(struct pci_dev *pdev, &pdev->dev); } -/* Enable RESET interrupt. */ - dc->last_ier =RESET ; -writew (dc->last_ier, dc->reg_ier); - -pci_set_drvdata (pdev, dc); -return 0 ; err_free_sbuf:
@@ -1553,7 +1573,7 @@ static int ntty_open(struct tty_struct *tty, struct file *file)struct nozomi *dc =get_dc_by_tty (tty);unsigned long flags; -if (!port || !dc) +if (!port || !dc || dc->state !=NOZOMI_STATE_READY )return -ENODEV ;if (mutex_lock_interruptible (&port->tty_sem))
@@ -1716,6 +1736,10 @@ static int ntty_tiocmget(struct tty_struct *tty, struct file *file)static int ntty_tiocmset (struct tty_struct *tty,struct file *file,unsigned int set,unsigned int clear) { +struct nozomi *dc =get_dc_by_tty (tty); +unsigned long flags; + +spin_lock_irqsave (&dc->spin_mutex, flags);if (set &TIOCM_RTS )set_rts (tty,1 );else if (clear &TIOCM_RTS )
@@ -1725,6 +1749,7 @@ static int ntty_tiocmset(struct tty_struct *tty, struct file *file,set_dtr (tty,1 ); else if (clear & TIOCM_DTR) set_dtr(tty, 0); +spin_unlock_irqrestore (&dc->spin_mutex, flags);return 0 ; }
@@ -1762,7 +1787,7 @@ static int ntty_ioctl_tiocgicount(struct port *port, void __user *argp) icount.brk = cnow.brk; icount.buf_overrun = cnow.buf_overrun; -return copy_to_user (argp, &icount,sizeof (icount)); +return copy_to_user (argp, &icount,sizeof (icount)) ? -EFAULT :0 ; } static int ntty_ioctl(struct tty_struct *tty, struct file *file,
Signature · 1 line
1.5.4.3
PATCH 3/4 firmware: provide stubs for the FW_LOADER=n case
In reply to Greg KHFrom: James Bottomley <[email protected]>
libsas has a case where it uses the firmware loader to provide services, but doesn't want to select it all the time. This currently causes a compile failure in libsas if FW_LOADER=n. Fix this by providing error stubs for the firmware loader API in the FW_LOADER=n case.
--- include/linux/firmware.h | 23 +++++++++++++++++++++++ 1 files changed, 23 insertions(+), 0 deletions(-)
include/linux/firmware.h +23 -0
@@ -10,7 +10,10 @@ struct firmware {size_t size;u8 *data; }; +struct device ; + +#if defined(CONFIG_FW_LOADER ) || defined(CONFIG_FW_LOADER_MODULE )int request_firmware (const struct firmware **fw,const char *name,struct device *device); int request_firmware_nowait(
@@ -19,4 +22,24 @@ int request_firmware_nowait( void (*cont)(const struct firmware *fw, void *context));void release_firmware (const struct firmware *fw); +#else +static inline int request_firmware (const struct firmware **fw, +const char *name, +struct device *device) +{ +return -EINVAL ; +} +static inline int request_firmware_nowait ( +struct module *module,int uevent, +const char *name,struct device *device,void *context, +void (*cont)(const struct firmware *fw,void *context)) +{ +return -EINVAL ; +} + +static inline void release_firmware (const struct firmware *fw) +{ +} +#endif +#endif
Signature · 1 line
1.5.4.3
PATCH 4/4 drivers: fix dma_get_required_mask
In reply to Greg KHFrom: James Bottomley <[email protected]>
There's a bug in the current implementation of dma_get_required_mask() where it ands the returned mask with the current device mask. This rather defeats the purpose if you're using the call to determine what your mask should be (since you will at that time have the default DMA_32BIT_MASK). This bug results in any driver that uses this function *always* getting a 32 bit mask, which is wrong.
Fix by removing the and with dev->dma_mask.
--- drivers/base/platform.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/base/platform.c +1 -1
@@ -648,7 +648,7 @@ u64 dma_get_required_mask(struct device *dev) high_totalram += high_totalram -1 ; mask = (((u64)high_totalram) << 32) + 0xffffffff; } -return mask & *dev->dma_mask; +return mask; }EXPORT_SYMBOL_GPL (dma_get_required_mask);#endif
Signature · 1 line
1.5.4.3