diff options
Diffstat (limited to 'drivers')
56 files changed, 645 insertions, 392 deletions
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index c2d62163238..3ef9d514b91 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c @@ -139,7 +139,7 @@ static int __cpuinit topology_sysfs_init(void) (void *)(long)i); } - register_cpu_notifier(&topology_cpu_notifier); + register_hotcpu_notifier(&topology_cpu_notifier); return 0; } diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 1c4df22dfd2..7b0eca703a6 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -1233,6 +1233,50 @@ static inline void complete_buffers(struct bio *bio, int status) } } +static void cciss_check_queues(ctlr_info_t *h) +{ + int start_queue = h->next_to_run; + int i; + + /* check to see if we have maxed out the number of commands that can + * be placed on the queue. If so then exit. We do this check here + * in case the interrupt we serviced was from an ioctl and did not + * free any new commands. + */ + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) + return; + + /* We have room on the queue for more commands. Now we need to queue + * them up. We will also keep track of the next queue to run so + * that every queue gets a chance to be started first. + */ + for (i = 0; i < h->highest_lun + 1; i++) { + int curr_queue = (start_queue + i) % (h->highest_lun + 1); + /* make sure the disk has been added and the drive is real + * because this can be called from the middle of init_one. + */ + if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) + continue; + blk_start_queue(h->gendisk[curr_queue]->queue); + + /* check to see if we have maxed out the number of commands + * that can be placed on the queue. + */ + if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { + if (curr_queue == start_queue) { + h->next_to_run = + (start_queue + 1) % (h->highest_lun + 1); + break; + } else { + h->next_to_run = curr_queue; + break; + } + } else { + curr_queue = (curr_queue + 1) % (h->highest_lun + 1); + } + } +} + static void cciss_softirq_done(struct request *rq) { CommandList_struct *cmd = rq->completion_data; @@ -1264,6 +1308,7 @@ static void cciss_softirq_done(struct request *rq) spin_lock_irqsave(&h->lock, flags); end_that_request_last(rq, rq->errors); cmd_free(h, cmd, 1); + cciss_check_queues(h); spin_unlock_irqrestore(&h->lock, flags); } @@ -2528,8 +2573,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) CommandList_struct *c; unsigned long flags; __u32 a, a1, a2; - int j; - int start_queue = h->next_to_run; if (interrupt_not_for_us(h)) return IRQ_NONE; @@ -2588,45 +2631,6 @@ static irqreturn_t do_cciss_intr(int irq, void *dev_id, struct pt_regs *regs) } } - /* check to see if we have maxed out the number of commands that can - * be placed on the queue. If so then exit. We do this check here - * in case the interrupt we serviced was from an ioctl and did not - * free any new commands. - */ - if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) - goto cleanup; - - /* We have room on the queue for more commands. Now we need to queue - * them up. We will also keep track of the next queue to run so - * that every queue gets a chance to be started first. - */ - for (j = 0; j < h->highest_lun + 1; j++) { - int curr_queue = (start_queue + j) % (h->highest_lun + 1); - /* make sure the disk has been added and the drive is real - * because this can be called from the middle of init_one. - */ - if (!(h->drv[curr_queue].queue) || !(h->drv[curr_queue].heads)) - continue; - blk_start_queue(h->gendisk[curr_queue]->queue); - - /* check to see if we have maxed out the number of commands - * that can be placed on the queue. - */ - if ((find_first_zero_bit(h->cmd_pool_bits, NR_CMDS)) == NR_CMDS) { - if (curr_queue == start_queue) { - h->next_to_run = - (start_queue + 1) % (h->highest_lun + 1); - goto cleanup; - } else { - h->next_to_run = curr_queue; - goto cleanup; - } - } else { - curr_queue = (curr_queue + 1) % (h->highest_lun + 1); - } - } - - cleanup: spin_unlock_irqrestore(CCISS_LOCK(h->ctlr), flags); return IRQ_HANDLED; } diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c index 0a1b1ea36dd..bdbade9a5cf 100644 --- a/drivers/block/nbd.c +++ b/drivers/block/nbd.c @@ -300,6 +300,15 @@ static struct request *nbd_read_stat(struct nbd_device *lo) lo->disk->disk_name, result); goto harderror; } + + if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { + printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", + lo->disk->disk_name, + (unsigned long)ntohl(reply.magic)); + result = -EPROTO; + goto harderror; + } + req = nbd_find_request(lo, reply.handle); if (unlikely(IS_ERR(req))) { result = PTR_ERR(req); @@ -312,13 +321,6 @@ static struct request *nbd_read_stat(struct nbd_device *lo) goto harderror; } - if (ntohl(reply.magic) != NBD_REPLY_MAGIC) { - printk(KERN_ERR "%s: Wrong magic (0x%lx)\n", - lo->disk->disk_name, - (unsigned long)ntohl(reply.magic)); - result = -EPROTO; - goto harderror; - } if (ntohl(reply.error)) { printk(KERN_ERR "%s: Other side returned error (%d)\n", lo->disk->disk_name, ntohl(reply.error)); @@ -339,7 +341,8 @@ static struct request *nbd_read_stat(struct nbd_device *lo) printk(KERN_ERR "%s: Receive data failed (result %d)\n", lo->disk->disk_name, result); - goto harderror; + req->errors++; + return req; } dprintk(DBG_RX, "%s: request %p: got %d bytes data\n", lo->disk->disk_name, req, bvec->bv_len); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index bde2c64b634..451b996bba9 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2577,19 +2577,19 @@ static int pkt_ctl_ioctl(struct inode *inode, struct file *file, unsigned int cm case PKT_CTRL_CMD_SETUP: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - mutex_lock(&ctl_mutex); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); ret = pkt_setup_dev(&ctrl_cmd); mutex_unlock(&ctl_mutex); break; case PKT_CTRL_CMD_TEARDOWN: if (!capable(CAP_SYS_ADMIN)) return -EPERM; - mutex_lock(&ctl_mutex); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); ret = pkt_remove_dev(&ctrl_cmd); mutex_unlock(&ctl_mutex); break; case PKT_CTRL_CMD_STATUS: - mutex_lock(&ctl_mutex); + mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING); pkt_get_status(&ctrl_cmd); mutex_unlock(&ctl_mutex); break; diff --git a/drivers/char/hw_random/geode-rng.c b/drivers/char/hw_random/geode-rng.c index be61f22ee7b..d37ced0d132 100644 --- a/drivers/char/hw_random/geode-rng.c +++ b/drivers/char/hw_random/geode-rng.c @@ -107,10 +107,14 @@ found: if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); - goto out; + goto err_unmap; } out: return err; + +err_unmap: + iounmap(mem); + goto out; } static void __exit mod_exit(void) diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index 6594bd5645f..ccd7e710223 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c @@ -164,7 +164,7 @@ static int __init mod_init(void) if (err) { printk(KERN_ERR PFX "RNG registering failed (%d)\n", err); - goto out; + goto err_unmap; } out: return err; diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index 645eb81cb5a..84e5a68635f 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -221,7 +221,6 @@ static struct nsc_gpio_ops pc8736x_gpio_ops = { .gpio_change = pc8736x_gpio_change, .gpio_current = pc8736x_gpio_current }; -EXPORT_SYMBOL(pc8736x_gpio_ops); static int pc8736x_gpio_open(struct inode *inode, struct file *file) { diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 498aa37bca2..3ece6923134 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c @@ -51,6 +51,7 @@ void proc_fork_connector(struct task_struct *task) struct cn_msg *msg; struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; + struct timespec ts; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -58,7 +59,8 @@ void proc_fork_connector(struct task_struct *task) msg = (struct cn_msg*)buffer; ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); - ktime_get_ts(&ev->timestamp); /* get high res monotonic timestamp */ + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + ev->timestamp_ns = timespec_to_ns(&ts); ev->what = PROC_EVENT_FORK; ev->event_data.fork.parent_pid = task->real_parent->pid; ev->event_data.fork.parent_tgid = task->real_parent->tgid; @@ -76,6 +78,7 @@ void proc_exec_connector(struct task_struct *task) { struct cn_msg *msg; struct proc_event *ev; + struct timespec ts; __u8 buffer[CN_PROC_MSG_SIZE]; if (atomic_read(&proc_event_num_listeners) < 1) @@ -84,7 +87,8 @@ void proc_exec_connector(struct task_struct *task) msg = (struct cn_msg*)buffer; ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); - ktime_get_ts(&ev->timestamp); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + ev->timestamp_ns = timespec_to_ns(&ts); ev->what = PROC_EVENT_EXEC; ev->event_data.exec.process_pid = task->pid; ev->event_data.exec.process_tgid = task->tgid; @@ -100,6 +104,7 @@ void proc_id_connector(struct task_struct *task, int which_id) struct cn_msg *msg; struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; + struct timespec ts; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -118,7 +123,8 @@ void proc_id_connector(struct task_struct *task, int which_id) } else return; get_seq(&msg->seq, &ev->cpu); - ktime_get_ts(&ev->timestamp); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + ev->timestamp_ns = timespec_to_ns(&ts); memcpy(&msg->id, &cn_proc_event_id, sizeof(msg->id)); msg->ack = 0; /* not used */ @@ -131,6 +137,7 @@ void proc_exit_connector(struct task_struct *task) struct cn_msg *msg; struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; + struct timespec ts; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -138,7 +145,8 @@ void proc_exit_connector(struct task_struct *task) msg = (struct cn_msg*)buffer; ev = (struct proc_event*)msg->data; get_seq(&msg->seq, &ev->cpu); - ktime_get_ts(&ev->timestamp); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + ev->timestamp_ns = timespec_to_ns(&ts); ev->what = PROC_EVENT_EXIT; ev->event_data.exit.process_pid = task->pid; ev->event_data.exit.process_tgid = task->tgid; @@ -164,6 +172,7 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) struct cn_msg *msg; struct proc_event *ev; __u8 buffer[CN_PROC_MSG_SIZE]; + struct timespec ts; if (atomic_read(&proc_event_num_listeners) < 1) return; @@ -171,7 +180,8 @@ static void cn_proc_ack(int err, int rcvd_seq, int rcvd_ack) msg = (struct cn_msg*)buffer; ev = (struct proc_event*)msg->data; msg->seq = rcvd_seq; - ktime_get_ts(&ev->timestamp); + ktime_get_ts(&ts); /* get high res monotonic timestamp */ + ev->timestamp_ns = timespec_to_ns(&ts); ev->cpu = -1; ev->what = PROC_EVENT_NONE; ev->event_data.ack.err = err; diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 8d328186f77..bc1088d9b37 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c @@ -364,10 +364,12 @@ static ssize_t store_##file_name \ if (ret != 1) \ return -EINVAL; \ \ + lock_cpu_hotplug(); \ mutex_lock(&policy->lock); \ ret = __cpufreq_set_policy(policy, &new_policy); \ policy->user_policy.object = policy->object; \ mutex_unlock(&policy->lock); \ + unlock_cpu_hotplug(); \ \ return ret ? ret : count; \ } @@ -1197,20 +1199,18 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); *********************************************************************/ +/* Must be called with lock_cpu_hotplug held */ int __cpufreq_driver_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { int retval = -EINVAL; - lock_cpu_hotplug(); dprintk("target for CPU %u: %u kHz, relation %u\n", policy->cpu, target_freq, relation); if (cpu_online(policy->cpu) && cpufreq_driver->target) retval = cpufreq_driver->target(policy, target_freq, relation); - unlock_cpu_hotplug(); - return retval; } EXPORT_SYMBOL_GPL(__cpufreq_driver_target); @@ -1225,17 +1225,23 @@ int cpufreq_driver_target(struct cpufreq_policy *policy, if (!policy) return -EINVAL; + lock_cpu_hotplug(); mutex_lock(&policy->lock); ret = __cpufreq_driver_target(policy, target_freq, relation); mutex_unlock(&policy->lock); + unlock_cpu_hotplug(); cpufreq_cpu_put(policy); return ret; } EXPORT_SYMBOL_GPL(cpufreq_driver_target); +/* + * Locking: Must be called with the lock_cpu_hotplug() lock held + * when "event" is CPUFREQ_GOV_LIMITS + */ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) { @@ -1257,24 +1263,6 @@ static int __cpufreq_governor(struct cpufreq_policy *policy, unsigned int event) } -int cpufreq_governor(unsigned int cpu, unsigned int event) -{ - int ret = 0; - struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); - - if (!policy) - return -EINVAL; - - mutex_lock(&policy->lock); - ret = __cpufreq_governor(policy, event); - mutex_unlock(&policy->lock); - - cpufreq_cpu_put(policy); - return ret; -} -EXPORT_SYMBOL_GPL(cpufreq_governor); - - int cpufreq_register_governor(struct cpufreq_governor *governor) { struct cpufreq_governor *t; @@ -1342,6 +1330,9 @@ int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu) EXPORT_SYMBOL(cpufreq_get_policy); +/* + * Locking: Must be called with the lock_cpu_hotplug() lock held + */ static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy) { int ret = 0; @@ -1436,6 +1427,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) if (!data) return -EINVAL; + lock_cpu_hotplug(); + /* lock this CPU */ mutex_lock(&data->lock); @@ -1446,6 +1439,8 @@ int cpufreq_set_policy(struct cpufreq_policy *policy) data->user_policy.governor = data->governor; mutex_unlock(&data->lock); + + unlock_cpu_hotplug(); cpufreq_cpu_put(data); return ret; @@ -1469,6 +1464,7 @@ int cpufreq_update_policy(unsigned int cpu) if (!data) return -ENODEV; + lock_cpu_hotplug(); mutex_lock(&data->lock); dprintk("updating policy for CPU %u\n", cpu); @@ -1494,7 +1490,7 @@ int cpufreq_update_policy(unsigned int cpu) ret = __cpufreq_set_policy(data, &policy); mutex_unlock(&data->lock); - + unlock_cpu_hotplug(); cpufreq_cpu_put(data); return ret; } diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index b3ebc8f0197..c4c578defab 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c @@ -525,7 +525,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target( @@ -536,7 +535,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, this_dbs_info->cur_policy, policy->min, CPUFREQ_RELATION_L); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); break; } return 0; diff --git a/drivers/cpufreq/cpufreq_ondemand.c b/drivers/cpufreq/cpufreq_ondemand.c index 178f0c547eb..52cf1f02182 100644 --- a/drivers/cpufreq/cpufreq_ondemand.c +++ b/drivers/cpufreq/cpufreq_ondemand.c @@ -309,7 +309,9 @@ static void do_dbs_timer(void *data) if (!dbs_info->enable) return; + lock_cpu_hotplug(); dbs_check_cpu(dbs_info); + unlock_cpu_hotplug(); queue_delayed_work_on(cpu, kondemand_wq, &dbs_info->work, usecs_to_jiffies(dbs_tuners_ins.sampling_rate)); } @@ -412,7 +414,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, break; case CPUFREQ_GOV_LIMITS: - lock_cpu_hotplug(); mutex_lock(&dbs_mutex); if (policy->max < this_dbs_info->cur_policy->cur) __cpufreq_driver_target(this_dbs_info->cur_policy, @@ -423,7 +424,6 @@ static int cpufreq_governor_dbs(struct cpufreq_policy *policy, policy->min, CPUFREQ_RELATION_L); mutex_unlock(&dbs_mutex); - unlock_cpu_hotplug(); break; } return 0; diff --git a/drivers/cpufreq/cpufreq_userspace.c b/drivers/cpufreq/cpufreq_userspace.c index 44ae5e5b94c..a06c204589c 100644 --- a/drivers/cpufreq/cpufreq_userspace.c +++ b/drivers/cpufreq/cpufreq_userspace.c @@ -18,6 +18,7 @@ #include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/cpufreq.h> +#include <linux/cpu.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/sysfs.h> @@ -70,6 +71,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) dprintk("cpufreq_set for cpu %u, freq %u kHz\n", policy->cpu, freq); + lock_cpu_hotplug(); mutex_lock(&userspace_mutex); if (!cpu_is_managed[policy->cpu]) goto err; @@ -92,6 +94,7 @@ static int cpufreq_set(unsigned int freq, struct cpufreq_policy *policy) err: mutex_unlock(&userspace_mutex); + unlock_cpu_hotplug(); return ret; } diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index 53bba41f29b..b6fb167e20f 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -682,6 +682,7 @@ config BLK_DEV_SVWKS config BLK_DEV_SGIIOC4 tristate "Silicon Graphics IOC4 chipset ATA/ATAPI support" depends on (IA64_SGI_SN2 || IA64_GENERIC) && SGI_IOC4 + select IDEPCI_SHARE_IRQ help This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 chipset, which has one channel and can support two devices. diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index f712e4cfd9d..7cf3eb02352 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -776,7 +776,7 @@ static void update_ordered(ide_drive_t *drive) * not available so we don't need to recheck that. */ capacity = idedisk_capacity(drive); - barrier = ide_id_has_flush_cache(id) && + barrier = ide_id_has_flush_cache(id) && !drive->noflush && (drive->addressing == 0 || capacity <= (1ULL << 28) || ide_id_has_flush_cache_ext(id)); diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 98918fb6b2c..7c3a13e1cf6 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -750,7 +750,7 @@ void ide_dma_verbose(ide_drive_t *drive) goto bug_dma_off; printk(", DMA"); } else if (id->field_valid & 1) { - printk(", BUG"); + goto bug_dma_off; } return; bug_dma_off: diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 657165297dc..77703acaec1 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -23,6 +23,7 @@ #include <linux/hdreg.h> #include <linux/ide.h> #include <linux/bitops.h> +#include <linux/nmi.h> #include <asm/byteorder.h> #include <asm/irq.h> @@ -1243,6 +1244,7 @@ int ide_wait_not_busy(ide_hwif_t *hwif, unsigned long timeout) if (stat == 0xff) return -ENODEV; touch_softlockup_watchdog(); + touch_nmi_watchdog(); } return -EBUSY; } diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c index 05fbd9298db..defd4b4bd37 100644 --- a/drivers/ide/ide.c +++ b/drivers/ide/ide.c @@ -1539,7 +1539,7 @@ static int __init ide_setup(char *s) const char *hd_words[] = { "none", "noprobe", "nowerr", "cdrom", "serialize", "autotune", "noautotune", "minus8", "swapdata", "bswap", - "minus11", "remap", "remap63", "scsi", NULL }; + "noflush", "remap", "remap63", "scsi", NULL }; unit = s[2] - 'a'; hw = unit / MAX_DRIVES; unit = unit % MAX_DRIVES; @@ -1578,6 +1578,9 @@ static int __init ide_setup(char *s) case -10: /* "bswap" */ drive->bswap = 1; goto done; + case -11: /* noflush */ + drive->noflush = 1; + goto done; case -12: /* "remap" */ drive->remap_0_to_1 = 1; goto done; diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c index 3cb04424d35..e9bad185968 100644 --- a/drivers/ide/pci/it821x.c +++ b/drivers/ide/pci/it821x.c @@ -498,9 +498,14 @@ static int config_chipset_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, it821x_ratemask(drive)); - config_it821x_chipset_for_pio(drive, !speed); - it821x_tune_chipset(drive, speed); - return ide_dma_enable(drive); + if (speed) { + config_it821x_chipset_for_pio(drive, 0); + it821x_tune_chipset(drive, speed); + + return ide_dma_enable(drive); + } + + return 0; } /** diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index 44708b5e582..d5d649f5ccd 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -124,8 +124,6 @@ config PMAC_BACKLIGHT bool "Backlight control for LCD screens" depends on ADB_PMU && FB = y && (BROKEN || !PPC64) select FB_BACKLIGHT - select BACKLIGHT_CLASS_DEVICE - select BACKLIGHT_LCD_SUPPORT help Say Y here to enable Macintosh specific extensions of the generic backlight code. With this enabled, the brightness keys on older diff --git a/drivers/macintosh/adbhid.c b/drivers/macintosh/adbhid.c index 545be1ed692..c69d23bb255 100644 --- a/drivers/macintosh/adbhid.c +++ b/drivers/macintosh/adbhid.c @@ -45,14 +45,11 @@ #include <linux/pmu.h> #include <asm/machdep.h> +#include <asm/backlight.h> #ifdef CONFIG_PPC_PMAC #include <asm/pmac_feature.h> #endif -#ifdef CONFIG_PMAC_BACKLIGHT -#include <asm/backlight.h> -#endif - MODULE_AUTHOR("Franz Sirl <Franz.Sirl-kernel@lauterbach.com>"); #define KEYB_KEYREG 0 /* register # for key up/down data */ @@ -237,11 +234,6 @@ static struct adb_ids keyboard_ids; static struct adb_ids mouse_ids; static struct adb_ids buttons_ids; -#ifdef CONFIG_PMAC_BACKLIGHT -/* Exported to via-pmu.c */ -int disable_kernel_backlight = 0; -#endif /* CONFIG_PMAC_BACKLIGHT */ - /* Kind of keyboard, see Apple technote 1152 */ #define ADB_KEYBOARD_UNKNOWN 0 #define ADB_KEYBOARD_ANSI 0x0100 @@ -527,7 +519,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto case 0xa: /* brightness decrease */ #ifdef CONFIG_PMAC_BACKLIGHT - if (!disable_kernel_backlight && down) + if (down) pmac_backlight_key_down(); #endif input_report_key(adbhid[id]->input, KEY_BRIGHTNESSDOWN, down); @@ -535,7 +527,7 @@ adbhid_buttons_input(unsigned char *data, int nb, struct pt_regs *regs, int auto case 0x9: /* brightness increase */ #ifdef CONFIG_PMAC_BACKLIGHT - if (!disable_kernel_backlight && down) + if (down) pmac_backlight_key_up(); #endif input_report_key(adbhid[id]->input, KEY_BRIGHTNESSUP, down); diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index b42d05f2aaf..d3f8d75bcbb 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -15,8 +15,9 @@ #define MAX_PMU_LEVEL 0xFF -static struct device_node *vias; static struct backlight_properties pmu_backlight_data; +static spinlock_t pmu_backlight_lock; +static int sleeping; static int pmu_backlight_get_level_brightness(struct fb_info *info, int level) @@ -40,23 +41,36 @@ static int pmu_backlight_update_status(struct backlight_device *bd) { struct fb_info *info = class_get_devdata(&bd->class_dev); struct adb_request req; - int pmulevel, level = bd->props->brightness; + unsigned long flags; + int level = bd->props->brightness; - if (vias == NULL) - return -ENODEV; + spin_lock_irqsave(&pmu_backlight_lock, flags); + + /* Don't update brightness when sleeping */ + if (sleeping) + goto out; if (bd->props->power != FB_BLANK_UNBLANK || bd->props->fb_blank != FB_BLANK_UNBLANK) level = 0; - pmulevel = pmu_backlight_get_level_brightness(info, level); + if (level > 0) { + int pmulevel = pmu_backlight_get_level_brightness(info, level); - pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); - pmu_wait_complete(&req); + pmu_request(&req, NULL, 2, PMU_BACKLIGHT_BRIGHT, pmulevel); + pmu_wait_complete(&req); - pmu_request(&req, NULL, 2, PMU_POWER_CTRL, - PMU_POW_BACKLIGHT | (level > 0 ? PMU_POW_ON : PMU_POW_OFF)); - pmu_wait_complete(&req); + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_BACKLIGHT | PMU_POW_ON); + pmu_wait_complete(&req); + } else { + pmu_request(&req, NULL, 2, PMU_POWER_CTRL, + PMU_POW_BACKLIGHT | PMU_POW_OFF); + pmu_wait_complete(&req); + } + +out: + spin_unlock_irqrestore(&pmu_backlight_lock, flags); return 0; } @@ -73,15 +87,39 @@ static struct backlight_properties pmu_backlight_data = { .max_brightness = (FB_BACKLIGHT_LEVELS - 1), }; -void __init pmu_backlight_init(struct device_node *in_vias) +#ifdef CONFIG_PM +static int pmu_backlight_sleep_call(struct pmu_sleep_notifier *self, int when) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_backlight_lock, flags); + + switch (when) { + case PBOOK_SLEEP_REQUEST: + sleeping = 1; + break; + case PBOOK_WAKE: + sleeping = 0; + break; + } + + spin_unlock_irqrestore(&pmu_backlight_lock, flags); + + return PBOOK_SLEEP_OK; +} + +static struct pmu_sleep_notifier pmu_backlight_sleep_notif = { + .notifier_call = pmu_backlight_sleep_call, +}; +#endif + +void __init pmu_backlight_init() { struct backlight_device *bd; struct fb_info *info; char name[10]; int level, autosave; - vias = in_vias; - /* Special case for the old PowerBook since I can't test on it */ autosave = machine_is_compatible("AAPL,3400/2400") || @@ -141,6 +179,10 @@ void __init pmu_backlight_init(struct device_node *in_vias) pmac_backlight = bd; mutex_unlock(&pmac_backlight_mutex); +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&pmu_backlight_sleep_notif); +#endif + printk("pmubl: Backlight initialized (%s)\n", name); return; diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 06ca80bfd6b..ea386801e21 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -16,7 +16,6 @@ * a sleep or a freq. switch * - Move sleep code out of here to pmac_pm, merge into new * common PM infrastructure - * - Move backlight code out as well * - Save/Restore PCI space properly * */ @@ -60,9 +59,7 @@ #include <asm/mmu_context.h> #include <asm/cputable.h> #include <asm/time.h> -#ifdef CONFIG_PMAC_BACKLIGHT #include <asm/backlight.h> -#endif #include "via-pmu-event.h" @@ -177,10 +174,6 @@ static int query_batt_timer = BATTERY_POLLING_COUNT; static struct adb_request batt_req; static struct proc_dir_entry *proc_pmu_batt[PMU_MAX_BATTERIES]; -#if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) -extern int disable_kernel_backlight; -#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ - int __fake_sleep; int asleep; BLOCKING_NOTIFIER_HEAD(sleep_notifier_list); @@ -466,7 +459,7 @@ static int __init via_pmu_dev_init(void) #ifdef CONFIG_PMAC_BACKLIGHT /* Initialize backlight */ - pmu_backlight_init(vias); + pmu_backlight_init(); #endif #ifdef CONFIG_PPC32 @@ -1403,11 +1396,8 @@ next: else if ((1 << pirq) & PMU_INT_SNDBRT) { #ifdef CONFIG_PMAC_BACKLIGHT if (len == 3) -#ifdef CONFIG_INPUT_ADBHID - if (!disable_kernel_backlight) -#endif /* CONFIG_INPUT_ADBHID */ - pmac_backlight_set_legacy_brightness(data[1] >> 4); -#endif /* CONFIG_PMAC_BACKLIGHT */ + pmac_backlight_set_legacy_brightness_pmu(data[1] >> 4); +#endif } /* Tick interrupt */ else if ((1 << pirq) & PMU_INT_TICK) { @@ -2414,7 +2404,7 @@ struct pmu_private { spinlock_t lock; #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) int backlight_locker; -#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ +#endif }; static LIST_HEAD(all_pmu_pvt); @@ -2464,7 +2454,7 @@ pmu_open(struct inode *inode, struct file *file) spin_lock_irqsave(&all_pvt_lock, flags); #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) pp->backlight_locker = 0; -#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ +#endif list_add(&pp->list, &all_pmu_pvt); spin_unlock_irqrestore(&all_pvt_lock, flags); file->private_data = pp; @@ -2559,13 +2549,12 @@ pmu_release(struct inode *inode, struct file *file) spin_lock_irqsave(&all_pvt_lock, flags); list_del(&pp->list); spin_unlock_irqrestore(&all_pvt_lock, flags); + #if defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) - if (pp->backlight_locker) { - spin_lock_irqsave(&pmu_lock, flags); - disable_kernel_backlight--; - spin_unlock_irqrestore(&pmu_lock, flags); - } -#endif /* defined(CONFIG_INPUT_ADBHID) && defined(CONFIG_PMAC_BACKLIGHT) */ + if (pp->backlight_locker) + pmac_backlight_enable(); +#endif + kfree(pp); } unlock_kernel(); @@ -2642,18 +2631,18 @@ pmu_ioctl(struct inode * inode, struct file *filp, #ifdef CONFIG_INPUT_ADBHID case PMU_IOC_GRAB_BACKLIGHT: { struct pmu_private *pp = filp->private_data; - unsigned long flags; if (pp->backlight_locker) return 0; + pp->backlight_locker = 1; - spin_lock_irqsave(&pmu_lock, flags); - disable_kernel_backlight++; - spin_unlock_irqrestore(&pmu_lock, flags); + pmac_backlight_disable(); + return 0; } #endif /* CONFIG_INPUT_ADBHID */ #endif /* CONFIG_PMAC_BACKLIGHT_LEGACY */ + case PMU_IOC_GET_MODEL: return put_user(pmu_kind, argp); case PMU_IOC_HAS_ADB: diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 07ca9480a6f..c3e52c806b1 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -620,7 +620,7 @@ static int myri10ge_load_firmware(struct myri10ge_priv *mgp) return -ENXIO; } dev_info(&mgp->pdev->dev, "handoff confirmed\n"); - myri10ge_dummy_rdma(mgp, mgp->tx.boundary != 4096); + myri10ge_dummy_rdma(mgp, 1); return 0; } diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 82200bfaa8e..7de9a07b2ac 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -516,10 +516,7 @@ static int skge_set_pauseparam(struct net_device *dev, /* Chip internal frequency for clock calculations */ static inline u32 hwkhz(const struct skge_hw *hw) { - if (hw->chip_id == CHIP_ID_GENESIS) - return 53215; /* or: 53.125 MHz */ - else - return 78215; /* or: 78.125 MHz */ + return (hw->chip_id == CHIP_ID_GENESIS) ? 53125 : 78125; } /* Chip HZ to microseconds */ diff --git a/drivers/net/sunlance.c b/drivers/net/sunlance.c index 1ef9fd39a79..0e3fdf7c6dd 100644 --- a/drivers/net/sunlance.c +++ b/drivers/net/sunlance.c @@ -1537,7 +1537,7 @@ static int __init sparc_lance_init(void) { if ((idprom->id_machtype == (SM_SUN4|SM_4_330)) || (idprom->id_machtype == (SM_SUN4|SM_4_470))) { - memset(&sun4_sdev, 0, sizeof(sdev)); + memset(&sun4_sdev, 0, sizeof(struct sbus_dev)); sun4_sdev.reg_addrs[0].phys_addr = sun4_eth_physaddr; sun4_sdev.irqs[0] = 6; return sparc_lance_probe_one(&sun4_sdev, NULL, NULL); @@ -1547,16 +1547,16 @@ static int __init sparc_lance_init(void) static int __exit sunlance_sun4_remove(void) { - struct lance_private *lp = dev_get_drvdata(&sun4_sdev->dev); + struct lance_private *lp = dev_get_drvdata(&sun4_sdev.ofdev.dev); struct net_device *net_dev = lp->dev; unregister_netdevice(net_dev); - lance_free_hwresources(root_lance_dev); + lance_free_hwresources(lp); free_netdev(net_dev); - dev_set_drvdata(&sun4_sdev->dev, NULL); + dev_set_drvdata(&sun4_sdev.ofdev.dev, NULL); return 0; } diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index ce6f3be86da..1b8138f641e 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -68,8 +68,8 @@ #define DRV_MODULE_NAME "tg3" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "3.62" -#define DRV_MODULE_RELDATE "June 30, 2006" +#define DRV_MODULE_VERSION "3.63" +#define DRV_MODULE_RELDATE "July 25, 2006" #define TG3_DEF_MAC_MODE 0 #define TG3_DEF_RX_MODE 0 @@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, static int tg3_init_hw(struct tg3 *, int); static int tg3_halt(struct tg3 *, int, int); +/* Restart hardware after configuration changes, self-test, etc. + * Invoked with tp->lock held. + */ +static int tg3_restart_hw(struct tg3 *tp, int reset_phy) +{ + int err; + + err = tg3_init_hw(tp, reset_phy); + if (err) { + printk(KERN_ERR PFX "%s: Failed to re-initialize device, " + "aborting.\n", tp->dev->name); + tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); + tg3_full_unlock(tp); + del_timer_sync(&tp->timer); + tp->irq_sync = 0; + netif_poll_enable(tp->dev); + dev_close(tp->dev); + tg3_full_lock(tp, 0); + } + return err; +} + #ifdef CONFIG_NET_POLL_CONTROLLER static void tg3_poll_controller(struct net_device *dev) { @@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data) } tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); - tg3_init_hw(tp, 1); + if (tg3_init_hw(tp, 1)) + goto out; tg3_netif_start(tp); if (restart_timer) mod_timer(&tp->timer, jiffies + 1); +out: tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; tg3_full_unlock(tp); @@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, static int tg3_change_mtu(struct net_device *dev, int new_mtu) { struct tg3 *tp = netdev_priv(dev); + int err; if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) return -EINVAL; @@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) tg3_set_mtu(dev, tp, new_mtu); - tg3_init_hw(tp, 0); + err = tg3_restart_hw(tp, 0); - tg3_netif_start(tp); + if (!err) + tg3_netif_start(tp); tg3_full_unlock(tp); - return 0; + return err; } /* Free up pending packets in all rx/tx rings. @@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp) * end up in the driver. tp->{tx,}lock are held and thus * we may not sleep. */ -static void tg3_init_rings(struct tg3 *tp) +static int tg3_init_rings(struct tg3 *tp) { u32 i; @@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp) /* Now allocate fresh SKBs for each rx ring. */ for (i = 0; i < tp->rx_pending; i++) { - if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, - -1, i) < 0) + if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) { + printk(KERN_WARNING PFX + "%s: Using a smaller RX standard ring, " + "only %d out of %d buffers were allocated " + "successfully.\n", + tp->dev->name, i, tp->rx_pending); + if (i == 0) + return -ENOMEM; + tp->rx_pending = i; break; + } } if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { for (i = 0; i < tp->rx_jumbo_pending; i++) { if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, - -1, i) < 0) + -1, i) < 0) { + printk(KERN_WARNING PFX + "%s: Using a smaller RX jumbo ring, " + "only %d out of %d buffers were " + "allocated successfully.\n", + tp->dev->name, i, tp->rx_jumbo_pending); + if (i == 0) { + tg3_free_rings(tp); + return -ENOMEM; + } + tp->rx_jumbo_pending = i; break; + } } } + return 0; } /* @@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) { struct tg3 *tp = netdev_priv(dev); struct sockaddr *addr = p; + int err = 0; if (!is_valid_ether_addr(addr->sa_data)) return -EINVAL; @@ -5832,9 +5879,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) tg3_full_lock(tp, 1); tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 0); - - tg3_netif_start(tp); + err = tg3_restart_hw(tp, 0); + if (!err) + tg3_netif_start(tp); tg3_full_unlock(tp); } else { spin_lock_bh(&tp->lock); @@ -5842,7 +5889,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) spin_unlock_bh(&tp->lock); } - return 0; + return err; } /* tp->lock is held. */ @@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) * can only do this after the hardware has been * successfully reset. */ - tg3_init_rings(tp); + err = tg3_init_rings(tp); + if (err) + return err; /* This value is determined during the probe time DMA * engine test, tg3_test_dma. @@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) { struct tg3 *tp = netdev_priv(dev); - int irq_sync = 0; + int irq_sync = 0, err = 0; if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || @@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 1); - tg3_netif_start(tp); + err = tg3_restart_hw(tp, 1); + if (!err) + tg3_netif_start(tp); } tg3_full_unlock(tp); - return 0; + return err; } static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) @@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) { struct tg3 *tp = netdev_priv(dev); - int irq_sync = 0; + int irq_sync = 0, err = 0; if (netif_running(dev)) { tg3_netif_stop(tp); @@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam if (netif_running(dev)) { tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); - tg3_init_hw(tp, 1); - tg3_netif_start(tp); + err = tg3_restart_hw(tp, 1); + if (!err) + tg3_netif_start(tp); } tg3_full_unlock(tp); - return 0; + return err; } static u32 tg3_get_rx_csum(struct net_device *dev) @@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp) if (!netif_running(tp->dev)) return TG3_LOOPBACK_FAILED; - tg3_reset_hw(tp, 1); + err = tg3_reset_hw(tp, 1); + if (err) + return TG3_LOOPBACK_FAILED; if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) err |= TG3_MAC_LOOPBACK_FAILED; @@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); if (netif_running(dev)) { tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); - tg3_netif_start(tp); + if (!tg3_restart_hw(tp, 1)) + tg3_netif_start(tp); } tg3_full_unlock(tp); @@ -11699,7 +11752,8 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); + if (tg3_restart_hw(tp, 1)) + goto out; tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); @@ -11707,6 +11761,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_attach(dev); tg3_netif_start(tp); +out: tg3_full_unlock(tp); } @@ -11733,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev) tg3_full_lock(tp, 0); tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; - tg3_init_hw(tp, 1); + err = tg3_restart_hw(tp, 1); + if (err) + goto out; tp->timer.expires = jiffies + tp->timer_offset; add_timer(&tp->timer); tg3_netif_start(tp); +out: tg3_full_unlock(tp); - return 0; + return err; } static struct pci_driver tg3_driver = { diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index f5b0078eb4a..aa9cd92f46b 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -2742,7 +2742,7 @@ static u32 check_connection_type(struct mac_regs __iomem * regs) if (PHYSR0 & PHYSR0_SPDG) status |= VELOCITY_SPEED_1000; - if (PHYSR0 & PHYSR0_SPD10) + else if (PHYSR0 & PHYSR0_SPD10) status |= VELOCITY_SPEED_10; else status |= VELOCITY_SPEED_100; @@ -2851,8 +2851,17 @@ static int velocity_get_settings(struct net_device *dev, struct ethtool_cmd *cmd u32 status; status = check_connection_type(vptr->mac_regs); - cmd->supported = SUPPORTED_TP | SUPPORTED_Autoneg | SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full; - if (status & VELOCITY_SPEED_100) + cmd->supported = SUPPORTED_TP | + SUPPORTED_Autoneg | + SUPPORTED_10baseT_Half | + SUPPORTED_10baseT_Full | + SUPPORTED_100baseT_Half | + SUPPORTED_100baseT_Full | + SUPPORTED_1000baseT_Half | + SUPPORTED_1000baseT_Full; + if (status & VELOCITY_SPEED_1000) + cmd->speed = SPEED_1000; + else if (status & VELOCITY_SPEED_100) cmd->speed = SPEED_100; else cmd->speed = SPEED_10; @@ -2896,7 +2905,7 @@ static u32 velocity_get_link(struct net_device *dev) { struct velocity_info *vptr = netdev_priv(dev); struct mac_regs __iomem * regs = vptr->mac_regs; - return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 0 : 1; + return BYTE_REG_BITS_IS_ON(PHYSR0_LINKGD, ®s->PHYSR0) ? 1 : 0; } static void velocity_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index fa9d2c4edc9..2e8ac995d56 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -447,6 +447,7 @@ config AIRO_CS tristate "Cisco/Aironet 34X/35X/4500/4800 PCMCIA cards" depends on NET_RADIO && PCMCIA && (BROKEN || !M32R) select CRYPTO + select CRYPTO_AES ---help--- This is the standard Linux driver to support Cisco/Aironet PCMCIA 802.11 wireless cards. This driver is the same as the Aironet diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index 3889f79e712..df317c1e12a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c @@ -3701,7 +3701,7 @@ static void bcm43xx_ieee80211_set_security(struct net_device *net_dev, } if (sec->flags & SEC_AUTH_MODE) { secinfo->auth_mode = sec->auth_mode; - dprintk(", .auth_mode = %d\n", sec->auth_mode); + dprintk(", .auth_mode = %d", sec->auth_mode); } dprintk("\n"); if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED && diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index d6ed5781b93..317ace7f9aa 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c @@ -2875,7 +2875,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, if (orinoco_lock(priv, &flags) != 0) return -EBUSY; - if (erq->pointer) { + if (erq->length > 0) { if ((index < 0) || (index >= ORINOCO_MAX_KEYS)) index = priv->tx_key; @@ -2918,7 +2918,7 @@ static int orinoco_ioctl_setiwencode(struct net_device *dev, if (erq->flags & IW_ENCODE_RESTRICTED) restricted = 1; - if (erq->pointer) { + if (erq->pointer && erq->length > 0) { priv->keys[index].len = cpu_to_le16(xlen); memset(priv->keys[index].data, 0, sizeof(priv->keys[index].data)); diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index 662ecc8a33f..c52e9bcf8d0 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c @@ -1820,6 +1820,8 @@ static int zd1201_probe(struct usb_interface *interface, zd->dev->name); usb_set_intfdata(interface, zd); + zd1201_enable(zd); /* zd1201 likes to startup enabled, */ + zd1201_disable(zd); /* interfering with all the wifis in range */ return 0; err_net: diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 622b3f8ba82..f8ae2b7db0a 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -61,7 +61,7 @@ struct pci_bus * __devinit pci_find_bus(int domain, int busnr) * @from: Previous PCI bus found, or %NULL for new search. * * Iterates through the list of known PCI busses. A new search is - * initiated by passing %NULL to the @from argument. Otherwise if + * initiated by passing %NULL as the @from argument. Otherwise if * @from is not %NULL, searches continue from next device on the * global list. */ @@ -148,13 +148,14 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) * @from: Previous PCI device found in search, or %NULL for new search. * * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its - * device structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device on the global list. + * found with a matching @vendor, @device, @ss_vendor and @ss_device, a + * pointer to its device structure is returned. Otherwise, %NULL is returned. + * A new search is initiated by passing %NULL as the @from argument. + * Otherwise if @from is not %NULL, searches continue from next device + * on the global list. * - * NOTE: Do not use this function anymore, use pci_get_subsys() instead, as - * the pci device returned by this function can disappear at any moment in + * NOTE: Do not use this function any more; use pci_get_subsys() instead, as + * the PCI device returned by this function can disappear at any moment in * time. */ static struct pci_dev * pci_find_subsys(unsigned int vendor, @@ -191,14 +192,15 @@ exit: * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor and @device, a pointer to its device structure is + * Iterates through the list of known PCI devices. If a PCI device is found + * with a matching @vendor and @device, a pointer to its device structure is * returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from next device on the global list. + * A new search is initiated by passing %NULL as the @from argument. + * Otherwise if @from is not %NULL, searches continue from next device + * on the global list. * - * NOTE: Do not use this function anymore, use pci_get_device() instead, as - * the pci device returned by this function can disappear at any moment in + * NOTE: Do not use this function any more; use pci_get_device() instead, as + * the PCI device returned by this function can disappear at any moment in * time. */ struct pci_dev * @@ -215,11 +217,11 @@ pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev * * @ss_device: PCI subsystem device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices. If a PCI device is - * found with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its + * Iterates through the list of known PCI devices. If a PCI device is found + * with a matching @vendor, @device, @ss_vendor and @ss_device, a pointer to its * device structure is returned, and the reference count to the device is * incremented. Otherwise, %NULL is returned. A new search is initiated by - * passing %NULL to the @from argument. Otherwise if @from is not %NULL, + * passing %NULL as the @from argument. Otherwise if @from is not %NULL, * searches continue from next device on the global list. * The reference count for @from is always decremented if it is not %NULL. */ @@ -262,7 +264,7 @@ exit: * found with a matching @vendor and @device, the reference count to the * device is incremented and a pointer to its device structure is returned. * Otherwise, %NULL is returned. A new search is initiated by passing %NULL - * to the @from argument. Otherwise if @from is not %NULL, searches continue + * as the @from argument. Otherwise if @from is not %NULL, searches continue * from next device on the global list. The reference count for @from is * always decremented if it is not %NULL. */ @@ -279,11 +281,13 @@ pci_get_device(unsigned int vendor, unsigned int device, struct pci_dev *from) * @device: PCI device id to match, or %PCI_ANY_ID to match all device ids * @from: Previous PCI device found in search, or %NULL for new search. * - * Iterates through the list of known PCI devices in the reverse order of pci_find_device(). + * Iterates through the list of known PCI devices in the reverse order of + * pci_find_device(). * If a PCI device is found with a matching @vendor and @device, a pointer to * its device structure is returned. Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. - * Otherwise if @from is not %NULL, searches continue from previous device on the global list. + * A new search is initiated by passing %NULL as the @from argument. + * Otherwise if @from is not %NULL, searches continue from previous device + * on the global list. */ struct pci_dev * pci_find_device_reverse(unsigned int vendor, unsigned int device, const struct pci_dev *from) @@ -317,7 +321,7 @@ exit: * found with a matching @class, the reference count to the device is * incremented and a pointer to its device structure is returned. * Otherwise, %NULL is returned. - * A new search is initiated by passing %NULL to the @from argument. + * A new search is initiated by passing %NULL as the @from argument. * Otherwise if @from is not %NULL, searches continue from next device * on the global list. The reference count for @from is always decremented * if it is not %NULL. diff --git a/drivers/pcmcia/pcmcia_ioctl.c b/drivers/pcmcia/pcmcia_ioctl.c index 738b1ef595a..9ad18e62658 100644 --- a/drivers/pcmcia/pcmcia_ioctl.c +++ b/drivers/pcmcia/pcmcia_ioctl.c @@ -601,12 +601,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->config.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_configuration_info(s, p_dev, &buf->config); - pcmcia_put_dev(p_dev); - } + ret = pccard_get_configuration_info(s, p_dev, &buf->config); + pcmcia_put_dev(p_dev); } break; case DS_GET_FIRST_TUPLE: @@ -636,12 +632,8 @@ static int ds_ioctl(struct inode * inode, struct file * file, ret = CS_BAD_ARGS; else { struct pcmcia_device *p_dev = get_pcmcia_device(s, buf->status.Function); - if (p_dev == NULL) - ret = CS_BAD_ARGS; - else { - ret = pccard_get_status(s, p_dev, &buf->status); - pcmcia_put_dev(p_dev); - } + ret = pccard_get_status(s, p_dev, &buf->status); + pcmcia_put_dev(p_dev); } break; case DS_VALIDATE_CIS: diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 7bf25b88ea3..c8323399e9e 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c @@ -245,10 +245,17 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, return CS_SUCCESS; } - /* !!! This is a hack !!! */ - memcpy(&config->Attributes, &c->Attributes, sizeof(config_t)); - config->Attributes |= CONF_VALID_CLIENT; - config->CardValues = c->CardValues; + config->Attributes = c->Attributes | CONF_VALID_CLIENT; + config->Vcc = s->socket.Vcc; + config->Vpp1 = config->Vpp2 = s->socket.Vpp; + config->IntType = c->IntType; + config->ConfigBase = c->ConfigBase; + config->Status = c->Status; + config->Pin = c->Pin; + config->Copy = c->Copy; + config->Option = c->Option; + config->ExtStatus = c->ExtStatus; + config->Present = config->CardValues = c->CardValues; config->IRQAttributes = c->irq.Attributes; config->AssignedIRQ = s->irq.AssignedIRQ; config->BasePort1 = c->io.BasePort1; diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index b154b3f52cb..551f58e2981 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -346,7 +346,7 @@ static int insert_device(struct pnp_dev *dev, struct pnp_bios_node * node) dev->flags = node->flags; if (!(dev->flags & PNPBIOS_NO_CONFIG)) dev->capabilities |= PNP_CONFIGURABLE; - if (!(dev->flags & PNPBIOS_NO_DISABLE)) + if (!(dev->flags & PNPBIOS_NO_DISABLE) && pnpbios_is_dynamic(dev)) dev->capabilities |= PNP_DISABLE; dev->capabilities |= PNP_READ; if (pnpbios_is_dynamic(dev)) diff --git a/drivers/s390/cio/ccwgroup.c b/drivers/s390/cio/ccwgroup.c index f26a2ee3aad..3cba6c9fab1 100644 --- a/drivers/s390/cio/ccwgroup.c +++ b/drivers/s390/cio/ccwgroup.c @@ -152,7 +152,6 @@ ccwgroup_create(struct device *root, struct ccwgroup_device *gdev; int i; int rc; - int del_drvdata; if (argc > 256) /* disallow dumb users */ return -EINVAL; @@ -163,7 +162,6 @@ ccwgroup_create(struct device *root, atomic_set(&gdev->onoff, 0); - del_drvdata = 0; for (i = 0; i < argc; i++) { gdev->cdev[i] = get_ccwdev_by_busid(cdrv, argv[i]); @@ -180,10 +178,8 @@ ccwgroup_create(struct device *root, rc = -EINVAL; goto free_dev; } - } - for (i = 0; i < argc; i++) gdev->cdev[i]->dev.driver_data = gdev; - del_drvdata = 1; + } gdev->creator_id = creator_id; gdev->count = argc; @@ -226,9 +222,9 @@ error: free_dev: for (i = 0; i < argc; i++) if (gdev->cdev[i]) { - put_device(&gdev->cdev[i]->dev); - if (del_drvdata) + if (gdev->cdev[i]->dev.driver_data == gdev) gdev->cdev[i]->dev.driver_data = NULL; + put_device(&gdev->cdev[i]->dev); } kfree(gdev); return rc; diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c index ac6e0c7e43d..7a39e0b0386 100644 --- a/drivers/s390/cio/device_fsm.c +++ b/drivers/s390/cio/device_fsm.c @@ -152,7 +152,8 @@ ccw_device_cancel_halt_clear(struct ccw_device *cdev) if (cdev->private->iretry) { cdev->private->iretry--; ret = cio_halt(sch); - return (ret == 0) ? -EBUSY : ret; + if (ret != -EBUSY) + return (ret == 0) ? -EBUSY : ret; } /* halt io unsuccessful. */ cdev->private->iretry = 255; /* 255 clear retries. */ diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 085db4826e0..bdc6bb262bc 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c @@ -2152,29 +2152,23 @@ static int esp_do_data_finale(struct NCR_ESP *esp, */ static int esp_should_clear_sync(Scsi_Cmnd *sp) { - unchar cmd1 = sp->cmnd[0]; - unchar cmd2 = sp->data_cmnd[0]; + unchar cmd = sp->cmnd[0]; /* These cases are for spinning up a disk and * waiting for that spinup to complete. */ - if(cmd1 == START_STOP || - cmd2 == START_STOP) + if(cmd == START_STOP) return 0; - if(cmd1 == TEST_UNIT_READY || - cmd2 == TEST_UNIT_READY) + if(cmd == TEST_UNIT_READY) return 0; /* One more special case for SCSI tape drives, * this is what is used to probe the device for * completion of a rewind or tape load operation. */ - if(sp->device->type == TYPE_TAPE) { - if(cmd1 == MODE_SENSE || - cmd2 == MODE_SENSE) - return 0; - } + if(sp->device->type == TYPE_TAPE && cmd == MODE_SENSE) + return 0; return 1; } diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index 3e1053f111d..4cf7afc31cc 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2427,7 +2427,7 @@ int fas216_eh_abort(Scsi_Cmnd *SCpnt) info->stats.aborts += 1; printk(KERN_WARNING "scsi%d: abort command ", info->host->host_no); - __scsi_print_command(SCpnt->data_cmnd); + __scsi_print_command(SCpnt->cmnd); print_debug_list(); fas216_dumpstate(info); diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index eaf64c7e54e..98bd22714d0 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -2754,18 +2754,15 @@ static int esp_do_data_finale(struct esp *esp) */ static int esp_should_clear_sync(struct scsi_cmnd *sp) { - u8 cmd1 = sp->cmnd[0]; - u8 cmd2 = sp->data_cmnd[0]; + u8 cmd = sp->cmnd[0]; /* These cases are for spinning up a disk and * waiting for that spinup to complete. */ - if (cmd1 == START_STOP || - cmd2 == START_STOP) + if (cmd == START_STOP) return 0; - if (cmd1 == TEST_UNIT_READY || - cmd2 == TEST_UNIT_READY) + if (cmd == TEST_UNIT_READY) return 0; /* One more special case for SCSI tape drives, @@ -2773,8 +2770,7 @@ static int esp_should_clear_sync(struct scsi_cmnd *sp) * completion of a rewind or tape load operation. */ if (sp->device->type == TYPE_TAPE) { - if (cmd1 == MODE_SENSE || - cmd2 == MODE_SENSE) + if (cmd == MODE_SENSE) return 0; } diff --git a/drivers/scsi/libata-eh.c b/drivers/scsi/libata-eh.c index 4b6aa30f4d6..29f59345305 100644 --- a/drivers/scsi/libata-eh.c +++ b/drivers/scsi/libata-eh.c @@ -764,12 +764,27 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, unsigned int action) { unsigned long flags; + struct ata_eh_info *ehi = &ap->eh_info; + struct ata_eh_context *ehc = &ap->eh_context; spin_lock_irqsave(ap->lock, flags); - ata_eh_clear_action(dev, &ap->eh_info, action); + /* Reset is represented by combination of actions and EHI + * flags. Suck in all related bits before clearing eh_info to + * avoid losing requested action. + */ + if (action & ATA_EH_RESET_MASK) { + ehc->i.action |= ehi->action & ATA_EH_RESET_MASK; + ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK; + + /* make sure all reset actions are cleared & clear EHI flags */ + action |= ATA_EH_RESET_MASK; + ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK; + } + + ata_eh_clear_action(dev, ehi, action); - if (!(ap->eh_context.i.flags & ATA_EHI_QUIET)) + if (!(ehc->i.flags & ATA_EHI_QUIET)) ap->pflags |= ATA_PFLAG_RECOVERED; spin_unlock_irqrestore(ap->lock, flags); @@ -790,6 +805,12 @@ static void ata_eh_about_to_do(struct ata_port *ap, struct ata_device *dev, static void ata_eh_done(struct ata_port *ap, struct ata_device *dev, unsigned int action) { + /* if reset is complete, clear all reset actions & reset modifier */ + if (action & ATA_EH_RESET_MASK) { + action |= ATA_EH_RESET_MASK; + ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK; + } + ata_eh_clear_action(dev, &ap->eh_context.i, action); } @@ -1276,8 +1297,6 @@ static int ata_eh_speed_down(struct ata_device *dev, int is_io, static void ata_eh_autopsy(struct ata_port *ap) { struct ata_eh_context *ehc = &ap->eh_context; - unsigned int action = ehc->i.action; - struct ata_device *failed_dev = NULL; unsigned int all_err_mask = 0; int tag, is_io = 0; u32 serror; @@ -1294,7 +1313,7 @@ static void ata_eh_autopsy(struct ata_port *ap) ehc->i.serror |= serror; ata_eh_analyze_serror(ap); } else if (rc != -EOPNOTSUPP) - action |= ATA_EH_HARDRESET; + ehc->i.action |= ATA_EH_HARDRESET; /* analyze NCQ failure */ ata_eh_analyze_ncq_error(ap); @@ -1315,7 +1334,7 @@ static void ata_eh_autopsy(struct ata_port *ap) qc->err_mask |= ehc->i.err_mask; /* analyze TF */ - action |= ata_eh_analyze_tf(qc, &qc->result_tf); + ehc->i.action |= ata_eh_analyze_tf(qc, &qc->result_tf); /* DEV errors are probably spurious in case of ATA_BUS error */ if (qc->err_mask & AC_ERR_ATA_BUS) @@ -1329,11 +1348,11 @@ static void ata_eh_autopsy(struct ata_port *ap) /* SENSE_VALID trumps dev/unknown error and revalidation */ if (qc->flags & ATA_QCFLAG_SENSE_VALID) { qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER); - action &= ~ATA_EH_REVALIDATE; + ehc->i.action &= ~ATA_EH_REVALIDATE; } /* accumulate error info */ - failed_dev = qc->dev; + ehc->i.dev = qc->dev; all_err_mask |= qc->err_mask; if (qc->flags & ATA_QCFLAG_IO) is_io = 1; @@ -1342,25 +1361,22 @@ static void ata_eh_autopsy(struct ata_port *ap) /* enforce default EH actions */ if (ap->pflags & ATA_PFLAG_FROZEN || all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT)) - action |= ATA_EH_SOFTRESET; + ehc->i.action |= ATA_EH_SOFTRESET; else if (all_err_mask) - action |= ATA_EH_REVALIDATE; + ehc->i.action |= ATA_EH_REVALIDATE; /* if we have offending qcs and the associated failed device */ - if (failed_dev) { + if (ehc->i.dev) { /* speed down */ - action |= ata_eh_speed_down(failed_dev, is_io, all_err_mask); + ehc->i.action |= ata_eh_speed_down(ehc->i.dev, is_io, + all_err_mask); /* perform per-dev EH action only on the offending device */ - ehc->i.dev_action[failed_dev->devno] |= - action & ATA_EH_PERDEV_MASK; - action &= ~ATA_EH_PERDEV_MASK; + ehc->i.dev_action[ehc->i.dev->devno] |= + ehc->i.action & ATA_EH_PERDEV_MASK; + ehc->i.action &= ~ATA_EH_PERDEV_MASK; } - /* record autopsy result */ - ehc->i.dev = failed_dev; - ehc->i.action |= action; - DPRINTK("EXIT\n"); } @@ -1483,6 +1499,9 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_reset_fn_t reset; int i, did_followup_srst, rc; + /* about to reset */ + ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); + /* Determine which reset to use and record in ehc->i.action. * prereset() may examine and modify it. */ @@ -1531,8 +1550,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, ata_port_printk(ap, KERN_INFO, "%s resetting port\n", reset == softreset ? "soft" : "hard"); - /* reset */ - ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK); + /* mark that this EH session started with reset */ ehc->i.flags |= ATA_EHI_DID_RESET; rc = ata_do_reset(ap, reset, classes); @@ -1595,7 +1613,7 @@ static int ata_eh_reset(struct ata_port *ap, int classify, postreset(ap, classes); /* reset successful, schedule revalidation */ - ata_eh_done(ap, NULL, ATA_EH_RESET_MASK); + ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK); ehc->i.action |= ATA_EH_REVALIDATE; } @@ -1848,15 +1866,16 @@ static int ata_eh_skip_recovery(struct ata_port *ap) for (i = 0; i < ata_port_max_devices(ap); i++) { struct ata_device *dev = &ap->device[i]; - if (ata_dev_absent(dev) || ata_dev_ready(dev)) + if (!(dev->flags & ATA_DFLAG_SUSPENDED)) break; } if (i == ata_port_max_devices(ap)) return 1; - /* always thaw frozen port and recover failed devices */ - if (ap->pflags & ATA_PFLAG_FROZEN || ata_port_nr_enabled(ap)) + /* thaw frozen port, resume link and recover failed devices */ + if ((ap->pflags & ATA_PFLAG_FROZEN) || + (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_port_nr_enabled(ap)) return 0; /* skip if class codes for all vacant slots are ATA_DEV_NONE */ diff --git a/drivers/scsi/sata_promise.c b/drivers/scsi/sata_promise.c index 64631bd3895..4776f4e5583 100644 --- a/drivers/scsi/sata_promise.c +++ b/drivers/scsi/sata_promise.c @@ -269,8 +269,15 @@ static const struct pci_device_id pdc_ata_pci_tbl[] = { { PCI_VENDOR_ID_PROMISE, 0x6629, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20619 }, +/* TODO: remove all associated board_20771 code, as it completely + * duplicates board_2037x code, unless reason for separation can be + * divined. + */ +#if 0 { PCI_VENDOR_ID_PROMISE, 0x3570, PCI_ANY_ID, PCI_ANY_ID, 0, 0, board_20771 }, +#endif + { } /* terminate list */ }; diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index a89c4115cfb..32293f45166 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -110,11 +110,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, sshdr.asc, sshdr.ascq); break; case NOT_READY: /* This happens if there is no disc in drive */ - if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) { - printk(KERN_INFO "Device not ready. Make sure" - " there is a disc in the drive.\n"); + if (sdev->removable) break; - } case UNIT_ATTENTION: if (sdev->removable) { sdev->changed = 1; diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6533b0f3923..c40b9b8b1e7 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -86,9 +86,11 @@ config FB_MACMODES default n config FB_BACKLIGHT - bool - depends on FB - default n + bool + depends on FB + select BACKLIGHT_LCD_SUPPORT + select BACKLIGHT_CLASS_DEVICE + default n config FB_MODE_HELPERS bool "Enable Video Mode Handling Helpers" @@ -420,7 +422,7 @@ config FB_OF config FB_CONTROL bool "Apple \"control\" display support" - depends on (FB = y) && PPC_PMAC + depends on (FB = y) && PPC_PMAC && PPC32 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -431,7 +433,7 @@ config FB_CONTROL config FB_PLATINUM bool "Apple \"platinum\" display support" - depends on (FB = y) && PPC_PMAC + depends on (FB = y) && PPC_PMAC && PPC32 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -442,7 +444,7 @@ config FB_PLATINUM config FB_VALKYRIE bool "Apple \"valkyrie\" display support" - depends on (FB = y) && (MAC || PPC_PMAC) + depends on (FB = y) && (MAC || (PPC_PMAC && PPC32)) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -453,7 +455,7 @@ config FB_VALKYRIE config FB_CT65550 bool "Chips 65550 display support" - depends on (FB = y) && PPC + depends on (FB = y) && PPC32 select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT @@ -721,10 +723,8 @@ config FB_NVIDIA_I2C config FB_NVIDIA_BACKLIGHT bool "Support for backlight control" - depends on FB_NVIDIA && PPC_PMAC + depends on FB_NVIDIA && PMAC_BACKLIGHT select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -769,10 +769,8 @@ config FB_RIVA_DEBUG config FB_RIVA_BACKLIGHT bool "Support for backlight control" - depends on FB_RIVA && PPC_PMAC + depends on FB_RIVA && PMAC_BACKLIGHT select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1025,10 +1023,8 @@ config FB_RADEON_I2C config FB_RADEON_BACKLIGHT bool "Support for backlight control" - depends on FB_RADEON && PPC_PMAC + depends on FB_RADEON && PMAC_BACKLIGHT select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1059,10 +1055,8 @@ config FB_ATY128 config FB_ATY128_BACKLIGHT bool "Support for backlight control" - depends on FB_ATY128 && PPC_PMAC + depends on FB_ATY128 && PMAC_BACKLIGHT select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1111,10 +1105,8 @@ config FB_ATY_GX config FB_ATY_BACKLIGHT bool "Support for backlight control" - depends on FB_ATY && PPC_PMAC + depends on FB_ATY && PMAC_BACKLIGHT select FB_BACKLIGHT - select BACKLIGHT_LCD_SUPPORT - select BACKLIGHT_CLASS_DEVICE default y help Say Y here if you want to control the backlight of your display. @@ -1620,7 +1612,7 @@ if FB || SGI_NEWPORT_CONSOLE source "drivers/video/logo/Kconfig" endif -if FB && SYSFS +if SYSFS source "drivers/video/backlight/Kconfig" endif diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 95563c9c6b9..481c6c9695f 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -4,6 +4,7 @@ # Each configuration option enables a list of files. +obj-y += fb_notify.o obj-$(CONFIG_FB) += fb.o fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \ modedb.o fbcvt.o diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index c64a717e2d4..8b08121b390 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -455,7 +455,10 @@ static void do_wait_for_fifo(u16 entries, struct aty128fb_par *par); static void wait_for_fifo(u16 entries, struct aty128fb_par *par); static void wait_for_idle(struct aty128fb_par *par); static u32 depth_to_dst(u32 depth); + +#ifdef CONFIG_FB_ATY128_BACKLIGHT static void aty128_bl_set_power(struct fb_info *info, int power); +#endif #define BIOS_IN8(v) (readb(bios + (v))) #define BIOS_IN16(v) (readb(bios + (v)) | \ diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 1507d19f481..053ff63365b 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2812,7 +2812,7 @@ static int atyfb_blank(int blank, struct fb_info *info) if (par->lock_blank || par->asleep) return 0; -#ifdef CONFIG_PMAC_BACKLIGHT +#ifdef CONFIG_FB_ATY_BACKLIGHT if (machine_is(powermac) && blank > FB_BLANK_NORMAL) aty_bl_set_power(info, FB_BLANK_POWERDOWN); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) @@ -2844,7 +2844,7 @@ static int atyfb_blank(int blank, struct fb_info *info) } aty_st_le32(CRTC_GEN_CNTL, gen_cntl, par); -#ifdef CONFIG_PMAC_BACKLIGHT +#ifdef CONFIG_FB_ATY_BACKLIGHT if (machine_is(powermac) && blank <= FB_BLANK_NORMAL) aty_bl_set_power(info, FB_BLANK_UNBLANK); #elif defined(CONFIG_FB_ATY_GENERIC_LCD) diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 8d85fc58142..8e3400d5dd2 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c @@ -266,6 +266,8 @@ static int force_measure_pll = 0; #ifdef CONFIG_MTRR static int nomtrr = 0; #endif +static int force_sleep; +static int ignore_devlist; /* * prototypes @@ -2327,9 +2329,9 @@ static int __devinit radeonfb_pci_register (struct pci_dev *pdev, /* -2 is special: means ON on mobility chips and do not * change on others */ - radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1); + radeonfb_pm_init(rinfo, rinfo->is_mobility ? 1 : -1, ignore_devlist, force_sleep); } else - radeonfb_pm_init(rinfo, default_dynclk); + radeonfb_pm_init(rinfo, default_dynclk, ignore_devlist, force_sleep); pci_set_drvdata(pdev, info); @@ -2477,6 +2479,12 @@ static int __init radeonfb_setup (char *options) force_measure_pll = 1; } else if (!strncmp(this_opt, "ignore_edid", 11)) { ignore_edid = 1; +#if defined(CONFIG_PM) && defined(CONFIG_X86) + } else if (!strncmp(this_opt, "force_sleep", 11)) { + force_sleep = 1; + } else if (!strncmp(this_opt, "ignore_devlist", 14)) { + ignore_devlist = 1; +#endif } else mode_option = this_opt; } @@ -2532,3 +2540,9 @@ module_param(panel_yres, int, 0); MODULE_PARM_DESC(panel_yres, "int: set panel yres"); module_param(mode_option, charp, 0); MODULE_PARM_DESC(mode_option, "Specify resolution as \"<xres>x<yres>[-<bpp>][@<refresh>]\" "); +#if defined(CONFIG_PM) && defined(CONFIG_X86) +module_param(force_sleep, bool, 0); +MODULE_PARM_DESC(force_sleep, "bool: force D2 sleep mode on all hardware"); +module_param(ignore_devlist, bool, 0); +MODULE_PARM_DESC(ignore_devlist, "bool: ignore workarounds for bugs in specific laptops"); +#endif diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/aty/radeon_pm.c index c7091761cef..f31e606a2de 100644 --- a/drivers/video/aty/radeon_pm.c +++ b/drivers/video/aty/radeon_pm.c @@ -27,6 +27,99 @@ #include "ati_ids.h" +static void radeon_reinitialize_M10(struct radeonfb_info *rinfo); + +/* + * Workarounds for bugs in PC laptops: + * - enable D2 sleep in some IBM Thinkpads + * - special case for Samsung P35 + * + * Whitelist by subsystem vendor/device because + * its the subsystem vendor's fault! + */ + +#if defined(CONFIG_PM) && defined(CONFIG_X86) +struct radeon_device_id { + const char *ident; /* (arbitrary) Name */ + const unsigned short subsystem_vendor; /* Subsystem Vendor ID */ + const unsigned short subsystem_device; /* Subsystem Device ID */ + const enum radeon_pm_mode pm_mode_modifier; /* modify pm_mode */ + const reinit_function_ptr new_reinit_func; /* changed reinit_func */ +}; + +#define BUGFIX(model, sv, sd, pm, fn) { \ + .ident = model, \ + .subsystem_vendor = sv, \ + .subsystem_device = sd, \ + .pm_mode_modifier = pm, \ + .new_reinit_func = fn \ +} + +static struct radeon_device_id radeon_workaround_list[] = { + BUGFIX("IBM Thinkpad R32", + PCI_VENDOR_ID_IBM, 0x1905, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad R40", + PCI_VENDOR_ID_IBM, 0x0526, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad R40", + PCI_VENDOR_ID_IBM, 0x0527, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad R50/R51/T40/T41", + PCI_VENDOR_ID_IBM, 0x0531, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad R51/T40/T41/T42", + PCI_VENDOR_ID_IBM, 0x0530, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad T30", + PCI_VENDOR_ID_IBM, 0x0517, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad T40p", + PCI_VENDOR_ID_IBM, 0x054d, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad T42", + PCI_VENDOR_ID_IBM, 0x0550, + radeon_pm_d2, NULL), + BUGFIX("IBM Thinkpad X31/X32", + PCI_VENDOR_ID_IBM, 0x052f, + radeon_pm_d2, NULL), + BUGFIX("Samsung P35", + PCI_VENDOR_ID_SAMSUNG, 0xc00c, + radeon_pm_off, radeon_reinitialize_M10), + { .ident = NULL } +}; + +static int radeon_apply_workarounds(struct radeonfb_info *rinfo) +{ + struct radeon_device_id *id; + + for (id = radeon_workaround_list; id->ident != NULL; id++ ) + if ((id->subsystem_vendor == rinfo->pdev->subsystem_vendor ) && + (id->subsystem_device == rinfo->pdev->subsystem_device )) { + + /* we found a device that requires workaround */ + printk(KERN_DEBUG "radeonfb: %s detected" + ", enabling workaround\n", id->ident); + + rinfo->pm_mode |= id->pm_mode_modifier; + + if (id->new_reinit_func != NULL) + rinfo->reinit_func = id->new_reinit_func; + + return 1; + } + return 0; /* not found */ +} + +#else /* defined(CONFIG_PM) && defined(CONFIG_X86) */ +static inline int radeon_apply_workarounds(struct radeonfb_info *rinfo) +{ + return 0; +} +#endif /* defined(CONFIG_PM) && defined(CONFIG_X86) */ + + + static void radeon_pm_disable_dynamic_mode(struct radeonfb_info *rinfo) { u32 tmp; @@ -852,18 +945,26 @@ static void radeon_pm_setup_for_suspend(struct radeonfb_info *rinfo) /* because both INPLL and OUTPLL take the same lock, that's why. */ tmp = INPLL( pllMCLK_MISC) | MCLK_MISC__EN_MCLK_TRISTATE_IN_SUSPEND; OUTPLL( pllMCLK_MISC, tmp); - - /* AGP PLL control */ - if (rinfo->family <= CHIP_FAMILY_RV280) { - OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); - OUTREG(BUS_CNTL1, - (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) - | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX - } else { - OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); - OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); + /* BUS_CNTL1__MOBILE_PLATORM_SEL setting is northbridge chipset + * and radeon chip dependent. Thus we only enable it on Mac for + * now (until we get more info on how to compute the correct + * value for various X86 bridges). + */ +#ifdef CONFIG_PPC_PMAC + if (machine_is(powermac)) { + /* AGP PLL control */ + if (rinfo->family <= CHIP_FAMILY_RV280) { + OUTREG(BUS_CNTL1, INREG(BUS_CNTL1) | BUS_CNTL1__AGPCLK_VALID); + OUTREG(BUS_CNTL1, + (INREG(BUS_CNTL1) & ~BUS_CNTL1__MOBILE_PLATFORM_SEL_MASK) + | (2<<BUS_CNTL1__MOBILE_PLATFORM_SEL__SHIFT)); // 440BX + } else { + OUTREG(BUS_CNTL1, INREG(BUS_CNTL1)); + OUTREG(BUS_CNTL1, (INREG(BUS_CNTL1) & ~0x4000) | 0x8000); + } } +#endif OUTREG(CRTC_OFFSET_CNTL, (INREG(CRTC_OFFSET_CNTL) & ~CRTC_OFFSET_CNTL__CRTC_STEREO_SYNC_OUT_EN)); @@ -2713,7 +2814,7 @@ static void radeonfb_early_resume(void *data) #endif /* CONFIG_PM */ -void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) +void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep) { /* Find PM registers in config space if any*/ rinfo->pm_reg = pci_find_capability(rinfo->pdev, PCI_CAP_ID_PM); @@ -2729,22 +2830,13 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) } #if defined(CONFIG_PM) +#if defined(CONFIG_PPC_PMAC) /* Check if we can power manage on suspend/resume. We can do * D2 on M6, M7 and M9, and we can resume from D3 cold a few other * "Mac" cards, but that's all. We need more infos about what the * BIOS does tho. Right now, all this PM stuff is pmac-only for that * reason. --BenH */ - /* Special case for Samsung P35 laptops - */ - if ((rinfo->pdev->vendor == PCI_VENDOR_ID_ATI) && - (rinfo->pdev->device == PCI_CHIP_RV350_NP) && - (rinfo->pdev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG) && - (rinfo->pdev->subsystem_device == 0xc00c)) { - rinfo->reinit_func = radeon_reinitialize_M10; - rinfo->pm_mode |= radeon_pm_off; - } -#if defined(CONFIG_PPC_PMAC) if (machine_is(powermac) && rinfo->of_node) { if (rinfo->is_mobility && rinfo->pm_reg && rinfo->family <= CHIP_FAMILY_RV250) @@ -2790,6 +2882,18 @@ void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk) } #endif /* defined(CONFIG_PPC_PMAC) */ #endif /* defined(CONFIG_PM) */ + + if (ignore_devlist) + printk(KERN_DEBUG + "radeonfb: skipping test for device workarounds\n"); + else + radeon_apply_workarounds(rinfo); + + if (force_sleep) { + printk(KERN_DEBUG + "radeonfb: forcefully enabling D2 sleep mode\n"); + rinfo->pm_mode |= radeon_pm_d2; + } } void radeonfb_pm_exit(struct radeonfb_info *rinfo) diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h index 38657b2d10e..d5ff224a625 100644 --- a/drivers/video/aty/radeonfb.h +++ b/drivers/video/aty/radeonfb.h @@ -273,6 +273,8 @@ enum radeon_pm_mode { radeon_pm_off = 0x00000002, /* Can resume from D3 cold */ }; +typedef void (*reinit_function_ptr)(struct radeonfb_info *rinfo); + struct radeonfb_info { struct fb_info *info; @@ -338,7 +340,7 @@ struct radeonfb_info { int dynclk; int no_schedule; enum radeon_pm_mode pm_mode; - void (*reinit_func)(struct radeonfb_info *rinfo); + reinit_function_ptr reinit_func; /* Lock on register access */ spinlock_t reg_lock; @@ -600,7 +602,7 @@ extern int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 /* PM Functions */ extern int radeonfb_pci_suspend(struct pci_dev *pdev, pm_message_t state); extern int radeonfb_pci_resume(struct pci_dev *pdev); -extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk); +extern void radeonfb_pm_init(struct radeonfb_info *rinfo, int dynclk, int ignore_devlist, int force_sleep); extern void radeonfb_pm_exit(struct radeonfb_info *rinfo); /* Monitor probe functions */ diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig index 022f9d3473f..02f15297a02 100644 --- a/drivers/video/backlight/Kconfig +++ b/drivers/video/backlight/Kconfig @@ -10,7 +10,7 @@ menuconfig BACKLIGHT_LCD_SUPPORT config BACKLIGHT_CLASS_DEVICE tristate "Lowlevel Backlight controls" - depends on BACKLIGHT_LCD_SUPPORT && FB + depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of the LCD @@ -26,7 +26,7 @@ config BACKLIGHT_DEVICE config LCD_CLASS_DEVICE tristate "Lowlevel LCD controls" - depends on BACKLIGHT_LCD_SUPPORT && FB + depends on BACKLIGHT_LCD_SUPPORT default m help This framework adds support for low-level control of LCD. diff --git a/drivers/video/console/mdacon.c b/drivers/video/console/mdacon.c index 52ed12b12ac..eb4d03fa539 100644 --- a/drivers/video/console/mdacon.c +++ b/drivers/video/console/mdacon.c @@ -197,7 +197,7 @@ static int __init mdacon_setup(char *str) __setup("mdacon=", mdacon_setup); #endif -static int __init mda_detect(void) +static int mda_detect(void) { int count=0; u16 *p, p_save; @@ -282,7 +282,7 @@ static int __init mda_detect(void) return 1; } -static void __init mda_initialize(void) +static void mda_initialize(void) { write_mda_b(97, 0x00); /* horizontal total */ write_mda_b(80, 0x01); /* horizontal displayed */ diff --git a/drivers/video/fb_notify.c b/drivers/video/fb_notify.c new file mode 100644 index 00000000000..8c020389e4f --- /dev/null +++ b/drivers/video/fb_notify.c @@ -0,0 +1,46 @@ +/* + * linux/drivers/video/fb_notify.c + * + * Copyright (C) 2006 Antonino Daplas <adaplas@pol.net> + * + * 2001 - Documented with DocBook + * - Brad Douglas <brad@neruo.com> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + */ +#include <linux/fb.h> +#include <linux/notifier.h> + +static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); + +/** + * fb_register_client - register a client notifier + * @nb: notifier block to callback on events + */ +int fb_register_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_register(&fb_notifier_list, nb); +} +EXPORT_SYMBOL(fb_register_client); + +/** + * fb_unregister_client - unregister a client notifier + * @nb: notifier block to callback on events + */ +int fb_unregister_client(struct notifier_block *nb) +{ + return blocking_notifier_chain_unregister(&fb_notifier_list, nb); +} +EXPORT_SYMBOL(fb_unregister_client); + +/** + * fb_notifier_call_chain - notify clients of fb_events + * + */ +int fb_notifier_call_chain(unsigned long val, void *v) +{ + return blocking_notifier_call_chain(&fb_notifier_list, val, v); +} +EXPORT_SYMBOL_GPL(fb_notifier_call_chain); diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 4fc9df426c1..17961e3ecaa 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -52,7 +52,6 @@ #define FBPIXMAPSIZE (1024 * 8) -static BLOCKING_NOTIFIER_HEAD(fb_notifier_list); struct fb_info *registered_fb[FB_MAX]; int num_registered_fb; @@ -791,8 +790,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) event.info = info; event.data = &mode1; - ret = blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_MODE_DELETE, &event); + ret = fb_notifier_call_chain(FB_EVENT_MODE_DELETE, &event); } if (!ret) @@ -837,8 +835,7 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) info->flags &= ~FBINFO_MISC_USEREVENT; event.info = info; - blocking_notifier_call_chain(&fb_notifier_list, - evnt, &event); + fb_notifier_call_chain(evnt, &event); } } } @@ -861,8 +858,7 @@ fb_blank(struct fb_info *info, int blank) event.info = info; event.data = ␣ - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_BLANK, &event); + fb_notifier_call_chain(FB_EVENT_BLANK, &event); } return ret; @@ -933,8 +929,7 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, con2fb.framebuffer = -1; event.info = info; event.data = &con2fb; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_GET_CONSOLE_MAP, &event); + fb_notifier_call_chain(FB_EVENT_GET_CONSOLE_MAP, &event); return copy_to_user(argp, &con2fb, sizeof(con2fb)) ? -EFAULT : 0; case FBIOPUT_CON2FBMAP: @@ -952,9 +947,8 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, return -EINVAL; event.info = info; event.data = &con2fb; - return blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_SET_CONSOLE_MAP, - &event); + return fb_notifier_call_chain(FB_EVENT_SET_CONSOLE_MAP, + &event); case FBIOBLANK: acquire_console_sem(); info->flags |= FBINFO_MISC_USEREVENT; @@ -1330,8 +1324,7 @@ register_framebuffer(struct fb_info *fb_info) registered_fb[i] = fb_info; event.info = fb_info; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_FB_REGISTERED, &event); + fb_notifier_call_chain(FB_EVENT_FB_REGISTERED, &event); return 0; } @@ -1365,30 +1358,11 @@ unregister_framebuffer(struct fb_info *fb_info) fb_cleanup_class_device(fb_info); class_device_destroy(fb_class, MKDEV(FB_MAJOR, i)); event.info = fb_info; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_FB_UNREGISTERED, &event); + fb_notifier_call_chain(FB_EVENT_FB_UNREGISTERED, &event); return 0; } /** - * fb_register_client - register a client notifier - * @nb: notifier block to callback on events - */ -int fb_register_client(struct notifier_block *nb) -{ - return blocking_notifier_chain_register(&fb_notifier_list, nb); -} - -/** - * fb_unregister_client - unregister a client notifier - * @nb: notifier block to callback on events - */ -int fb_unregister_client(struct notifier_block *nb) -{ - return blocking_notifier_chain_unregister(&fb_notifier_list, nb); -} - -/** * fb_set_suspend - low level driver signals suspend * @info: framebuffer affected * @state: 0 = resuming, !=0 = suspending @@ -1403,13 +1377,11 @@ void fb_set_suspend(struct fb_info *info, int state) event.info = info; if (state) { - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_SUSPEND, &event); + fb_notifier_call_chain(FB_EVENT_SUSPEND, &event); info->state = FBINFO_STATE_SUSPENDED; } else { info->state = FBINFO_STATE_RUNNING; - blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_RESUME, &event); + fb_notifier_call_chain(FB_EVENT_RESUME, &event); } } @@ -1480,9 +1452,7 @@ int fb_new_modelist(struct fb_info *info) if (!list_empty(&info->modelist)) { event.info = info; - err = blocking_notifier_call_chain(&fb_notifier_list, - FB_EVENT_NEW_MODELIST, - &event); + err = fb_notifier_call_chain(FB_EVENT_NEW_MODELIST, &event); } return err; @@ -1594,8 +1564,6 @@ EXPORT_SYMBOL(fb_blank); EXPORT_SYMBOL(fb_pan_display); EXPORT_SYMBOL(fb_get_buffer_offset); EXPORT_SYMBOL(fb_set_suspend); -EXPORT_SYMBOL(fb_register_client); -EXPORT_SYMBOL(fb_unregister_client); EXPORT_SYMBOL(fb_get_options); MODULE_LICENSE("GPL"); diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c index 9f2066f0745..d4f85011787 100644 --- a/drivers/video/nvidia/nvidia.c +++ b/drivers/video/nvidia/nvidia.c @@ -34,10 +34,6 @@ #include "nv_proto.h" #include "nv_dma.h" -#ifndef CONFIG_PCI /* sanity check */ -#error This driver requires PCI support. -#endif - #undef CONFIG_FB_NVIDIA_DEBUG #ifdef CONFIG_FB_NVIDIA_DEBUG #define NVTRACE printk @@ -1303,20 +1299,19 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd, nvidia_save_vga(par, &par->SavedReg); + pci_set_drvdata(pd, info); + nvidia_bl_init(par); if (register_framebuffer(info) < 0) { printk(KERN_ERR PFX "error registering nVidia framebuffer\n"); goto err_out_iounmap_fb; } - pci_set_drvdata(pd, info); printk(KERN_INFO PFX "PCI nVidia %s framebuffer (%dMB @ 0x%lX)\n", info->fix.id, par->FbMapSize / (1024 * 1024), info->fix.smem_start); - nvidia_bl_init(par); - NVTRACE_LEAVE(); return 0; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 33dddbae542..76fc9d355eb 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -2132,6 +2132,9 @@ static int __devinit rivafb_probe(struct pci_dev *pd, fb_destroy_modedb(info->monspecs.modedb); info->monspecs.modedb = NULL; + + pci_set_drvdata(pd, info); + riva_bl_init(info->par); ret = register_framebuffer(info); if (ret < 0) { printk(KERN_ERR PFX @@ -2139,8 +2142,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, goto err_iounmap_screen_base; } - pci_set_drvdata(pd, info); - printk(KERN_INFO PFX "PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n", info->fix.id, @@ -2148,8 +2149,6 @@ static int __devinit rivafb_probe(struct pci_dev *pd, info->fix.smem_len / (1024 * 1024), info->fix.smem_start); - riva_bl_init(info->par); - NVTRACE_LEAVE(); return 0; |