[kernel] r12406 - in dists/trunk/linux-2.6/debian: . patches/bugfix/all/stable patches/series

Maximilian Attems maks at alioth.debian.org
Sat Nov 22 16:11:57 UTC 2008


Author: maks
Date: Sat Nov 22 16:11:56 2008
New Revision: 12406

Log:
add stable 2.6.27.7

Added:
   dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.7
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/patches/series/1~experimental.1

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	(original)
+++ dists/trunk/linux-2.6/debian/changelog	Sat Nov 22 16:11:56 2008
@@ -13,7 +13,7 @@
     SCSI_DH_ALUA, MAC80211_HWSIM, USB_HSO.
   * [x86] set MOUSE_BCM5974.
   * [x86_64] set AMD_IOMMU, MTRR_SANITIZER.
-  * Add stable releases 2.6.27.1-2.6.27.6.
+  * Add stable releases 2.6.27.1-2.6.27.7.
 
   [ Martin Michlmayr ]
   * [mips/r4k-ip22, mips/sb1-bcm91250a] Don't build in ISO9660.

Added: dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.7
==============================================================================
--- (empty file)
+++ dists/trunk/linux-2.6/debian/patches/bugfix/all/stable/patch-2.6.27.7	Sat Nov 22 16:11:56 2008
@@ -0,0 +1,1991 @@
+diff --git a/arch/arm/mm/cache-feroceon-l2.c b/arch/arm/mm/cache-feroceon-l2.c
+index 7b5a25d..4f6cf46 100644
+--- a/arch/arm/mm/cache-feroceon-l2.c
++++ b/arch/arm/mm/cache-feroceon-l2.c
+@@ -148,7 +148,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
+ 	/*
+ 	 * Clean and invalidate partial last cache line.
+ 	 */
+-	if (end & (CACHE_LINE_SIZE - 1)) {
++	if (start < end && end & (CACHE_LINE_SIZE - 1)) {
+ 		l2_clean_inv_pa(end & ~(CACHE_LINE_SIZE - 1));
+ 		end &= ~(CACHE_LINE_SIZE - 1);
+ 	}
+@@ -156,7 +156,7 @@ static void feroceon_l2_inv_range(unsigned long start, unsigned long end)
+ 	/*
+ 	 * Invalidate all full cache lines between 'start' and 'end'.
+ 	 */
+-	while (start != end) {
++	while (start < end) {
+ 		unsigned long range_end = calc_range_end(start, end);
+ 		l2_inv_pa_range(start, range_end - CACHE_LINE_SIZE);
+ 		start = range_end;
+diff --git a/arch/m68k/kernel/ints.c b/arch/m68k/kernel/ints.c
+index ded7dd2..c4460bf 100644
+--- a/arch/m68k/kernel/ints.c
++++ b/arch/m68k/kernel/ints.c
+@@ -133,7 +133,7 @@ void __init m68k_setup_user_interrupt(unsigned int vec, unsigned int cnt,
+ {
+ 	int i;
+ 
+-	BUG_ON(IRQ_USER + cnt >= NR_IRQS);
++	BUG_ON(IRQ_USER + cnt > NR_IRQS);
+ 	m68k_first_user_vec = vec;
+ 	for (i = 0; i < cnt; i++)
+ 		irq_controller[IRQ_USER + i] = &user_irq_controller;
+diff --git a/arch/powerpc/include/asm/mpic.h b/arch/powerpc/include/asm/mpic.h
+index fe566a3..eb685ed 100644
+--- a/arch/powerpc/include/asm/mpic.h
++++ b/arch/powerpc/include/asm/mpic.h
+@@ -355,6 +355,8 @@ struct mpic
+ #define MPIC_NO_BIAS			0x00000400
+ /* Ignore NIRQS as reported by FRR */
+ #define MPIC_BROKEN_FRR_NIRQS		0x00000800
++/* Destination only supports a single CPU at a time */
++#define MPIC_SINGLE_DEST_CPU		0x00001000
+ 
+ /* MPIC HW modification ID */
+ #define MPIC_REGSET_MASK		0xf0000000
+diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+index 483b65c..613bf8c 100644
+--- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
++++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
+@@ -78,7 +78,8 @@ void __init mpc85xx_ds_pic_init(void)
+ 
+ 	mpic = mpic_alloc(np, r.start,
+ 			  MPIC_PRIMARY | MPIC_WANTS_RESET |
+-			  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
++			  MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
++			  MPIC_SINGLE_DEST_CPU,
+ 			0, 256, " OpenPIC  ");
+ 	BUG_ON(mpic == NULL);
+ 	of_node_put(np);
+diff --git a/arch/powerpc/platforms/86xx/pic.c b/arch/powerpc/platforms/86xx/pic.c
+index 8881c5d..668275d 100644
+--- a/arch/powerpc/platforms/86xx/pic.c
++++ b/arch/powerpc/platforms/86xx/pic.c
+@@ -44,7 +44,8 @@ void __init mpc86xx_init_irq(void)
+ 
+ 	mpic = mpic_alloc(np, res.start,
+ 			MPIC_PRIMARY | MPIC_WANTS_RESET |
+-			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS,
++			MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS |
++			MPIC_SINGLE_DEST_CPU,
+ 			0, 256, " MPIC     ");
+ 	of_node_put(np);
+ 	BUG_ON(mpic == NULL);
+diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
+index 8e3478c..f6299cc 100644
+--- a/arch/powerpc/sysdev/mpic.c
++++ b/arch/powerpc/sysdev/mpic.c
+@@ -563,6 +563,51 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
+ 
+ #endif /* CONFIG_MPIC_U3_HT_IRQS */
+ 
++#ifdef CONFIG_SMP
++static int irq_choose_cpu(unsigned int virt_irq)
++{
++	cpumask_t mask = irq_desc[virt_irq].affinity;
++	int cpuid;
++
++	if (cpus_equal(mask, CPU_MASK_ALL)) {
++		static int irq_rover;
++		static DEFINE_SPINLOCK(irq_rover_lock);
++		unsigned long flags;
++
++		/* Round-robin distribution... */
++	do_round_robin:
++		spin_lock_irqsave(&irq_rover_lock, flags);
++
++		while (!cpu_online(irq_rover)) {
++			if (++irq_rover >= NR_CPUS)
++				irq_rover = 0;
++		}
++		cpuid = irq_rover;
++		do {
++			if (++irq_rover >= NR_CPUS)
++				irq_rover = 0;
++		} while (!cpu_online(irq_rover));
++
++		spin_unlock_irqrestore(&irq_rover_lock, flags);
++	} else {
++		cpumask_t tmp;
++
++		cpus_and(tmp, cpu_online_map, mask);
++
++		if (cpus_empty(tmp))
++			goto do_round_robin;
++
++		cpuid = first_cpu(tmp);
++	}
++
++	return cpuid;
++}
++#else
++static int irq_choose_cpu(unsigned int virt_irq)
++{
++	return hard_smp_processor_id();
++}
++#endif
+ 
+ #define mpic_irq_to_hw(virq)	((unsigned int)irq_map[virq].hwirq)
+ 
+@@ -777,12 +822,18 @@ void mpic_set_affinity(unsigned int irq, cpumask_t cpumask)
+ 	struct mpic *mpic = mpic_from_irq(irq);
+ 	unsigned int src = mpic_irq_to_hw(irq);
+ 
+-	cpumask_t tmp;
++	if (mpic->flags & MPIC_SINGLE_DEST_CPU) {
++		int cpuid = irq_choose_cpu(irq);
+ 
+-	cpus_and(tmp, cpumask, cpu_online_map);
++		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION), 1 << cpuid);
++	} else {
++		cpumask_t tmp;
+ 
+-	mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
+-		       mpic_physmask(cpus_addr(tmp)[0]));	
++		cpus_and(tmp, cpumask, cpu_online_map);
++
++		mpic_irq_write(src, MPIC_INFO(IRQ_DESTINATION),
++			       mpic_physmask(cpus_addr(tmp)[0]));
++	}
+ }
+ 
+ static unsigned int mpic_type_to_vecpri(struct mpic *mpic, unsigned int type)
+diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
+index 632b13e..a947899 100644
+--- a/arch/s390/kernel/topology.c
++++ b/arch/s390/kernel/topology.c
+@@ -65,18 +65,21 @@ static int machine_has_topology_irq;
+ static struct timer_list topology_timer;
+ static void set_topology_timer(void);
+ static DECLARE_WORK(topology_work, topology_work_fn);
++/* topology_lock protects the core linked list */
++static DEFINE_SPINLOCK(topology_lock);
+ 
+ cpumask_t cpu_core_map[NR_CPUS];
+ 
+ cpumask_t cpu_coregroup_map(unsigned int cpu)
+ {
+ 	struct core_info *core = &core_info;
++	unsigned long flags;
+ 	cpumask_t mask;
+ 
+ 	cpus_clear(mask);
+ 	if (!machine_has_topology)
+ 		return cpu_present_map;
+-	mutex_lock(&smp_cpu_state_mutex);
++	spin_lock_irqsave(&topology_lock, flags);
+ 	while (core) {
+ 		if (cpu_isset(cpu, core->mask)) {
+ 			mask = core->mask;
+@@ -84,7 +87,7 @@ cpumask_t cpu_coregroup_map(unsigned int cpu)
+ 		}
+ 		core = core->next;
+ 	}
+-	mutex_unlock(&smp_cpu_state_mutex);
++	spin_unlock_irqrestore(&topology_lock, flags);
+ 	if (cpus_empty(mask))
+ 		mask = cpumask_of_cpu(cpu);
+ 	return mask;
+@@ -133,7 +136,7 @@ static void tl_to_cores(struct tl_info *info)
+ 	union tl_entry *tle, *end;
+ 	struct core_info *core = &core_info;
+ 
+-	mutex_lock(&smp_cpu_state_mutex);
++	spin_lock_irq(&topology_lock);
+ 	clear_cores();
+ 	tle = info->tle;
+ 	end = (union tl_entry *)((unsigned long)info + info->length);
+@@ -157,7 +160,7 @@ static void tl_to_cores(struct tl_info *info)
+ 		}
+ 		tle = next_tle(tle);
+ 	}
+-	mutex_unlock(&smp_cpu_state_mutex);
++	spin_unlock_irq(&topology_lock);
+ }
+ 
+ static void topology_update_polarization_simple(void)
+diff --git a/block/blk-merge.c b/block/blk-merge.c
+index 5efc9e7..857dce7 100644
+--- a/block/blk-merge.c
++++ b/block/blk-merge.c
+@@ -95,6 +95,9 @@ new_hw_segment:
+ 			nr_hw_segs++;
+ 		}
+ 
++		if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
++			rq->bio->bi_seg_front_size = seg_size;
++
+ 		nr_phys_segs++;
+ 		bvprv = bv;
+ 		seg_size = bv->bv_len;
+@@ -106,6 +109,10 @@ new_hw_segment:
+ 		rq->bio->bi_hw_front_size = hw_seg_size;
+ 	if (hw_seg_size > rq->biotail->bi_hw_back_size)
+ 		rq->biotail->bi_hw_back_size = hw_seg_size;
++	if (nr_phys_segs == 1 && seg_size > rq->bio->bi_seg_front_size)
++		rq->bio->bi_seg_front_size = seg_size;
++	if (seg_size > rq->biotail->bi_seg_back_size)
++		rq->biotail->bi_seg_back_size = seg_size;
+ 	rq->nr_phys_segments = nr_phys_segs;
+ 	rq->nr_hw_segments = nr_hw_segs;
+ }
+@@ -133,7 +140,8 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
+ 
+ 	if (!BIOVEC_PHYS_MERGEABLE(__BVEC_END(bio), __BVEC_START(nxt)))
+ 		return 0;
+-	if (bio->bi_size + nxt->bi_size > q->max_segment_size)
++	if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
++	    q->max_segment_size)
+ 		return 0;
+ 
+ 	/*
+@@ -377,6 +385,8 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
+ {
+ 	int total_phys_segments;
+ 	int total_hw_segments;
++	unsigned int seg_size =
++		req->biotail->bi_seg_back_size + next->bio->bi_seg_front_size;
+ 
+ 	/*
+ 	 * First check if the either of the requests are re-queued
+@@ -392,8 +402,13 @@ static int ll_merge_requests_fn(struct request_queue *q, struct request *req,
+ 		return 0;
+ 
+ 	total_phys_segments = req->nr_phys_segments + next->nr_phys_segments;
+-	if (blk_phys_contig_segment(q, req->biotail, next->bio))
++	if (blk_phys_contig_segment(q, req->biotail, next->bio)) {
++		if (req->nr_phys_segments == 1)
++			req->bio->bi_seg_front_size = seg_size;
++		if (next->nr_phys_segments == 1)
++			next->biotail->bi_seg_back_size = seg_size;
+ 		total_phys_segments--;
++	}
+ 
+ 	if (total_phys_segments > q->max_phys_segments)
+ 		return 0;
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
+index ccae305..c54f38e 100644
+--- a/drivers/acpi/bus.c
++++ b/drivers/acpi/bus.c
+@@ -95,21 +95,21 @@ int acpi_bus_get_status(struct acpi_device *device)
+ 	}
+ 
+ 	/*
+-	 * Otherwise we assume the status of our parent (unless we don't
+-	 * have one, in which case status is implied).
++	 * According to ACPI spec some device can be present and functional
++	 * even if the parent is not present but functional.
++	 * In such conditions the child device should not inherit the status
++	 * from the parent.
+ 	 */
+-	else if (device->parent)
+-		device->status = device->parent->status;
+ 	else
+ 		STRUCT_TO_INT(device->status) =
+ 		    ACPI_STA_DEVICE_PRESENT | ACPI_STA_DEVICE_ENABLED |
+ 		    ACPI_STA_DEVICE_UI      | ACPI_STA_DEVICE_FUNCTIONING;
+ 
+ 	if (device->status.functional && !device->status.present) {
+-		printk(KERN_WARNING PREFIX "Device [%s] status [%08x]: "
+-		       "functional but not present; setting present\n",
+-		       device->pnp.bus_id, (u32) STRUCT_TO_INT(device->status));
+-		device->status.present = 1;
++		ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]: "
++		       "functional but not present;\n",
++			device->pnp.bus_id,
++			(u32) STRUCT_TO_INT(device->status)));
+ 	}
+ 
+ 	ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] status [%08x]\n",
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
+index 444cd9e..41b8e7c 100644
+--- a/drivers/acpi/ec.c
++++ b/drivers/acpi/ec.c
+@@ -70,7 +70,7 @@ enum ec_command {
+ #define ACPI_EC_UDELAY_GLK	1000	/* Wait 1ms max. to get global lock */
+ #define ACPI_EC_UDELAY		100	/* Wait 100us before polling EC again */
+ 
+-#define ACPI_EC_STORM_THRESHOLD 20	/* number of false interrupts
++#define ACPI_EC_STORM_THRESHOLD 8	/* number of false interrupts
+ 					   per one transaction */
+ 
+ enum {
+@@ -100,8 +100,11 @@ struct transaction {
+ 	u8 *rdata;
+ 	unsigned short irq_count;
+ 	u8 command;
++	u8 wi;
++	u8 ri;
+ 	u8 wlen;
+ 	u8 rlen;
++	bool done;
+ };
+ 
+ static struct acpi_ec {
+@@ -178,34 +181,45 @@ static int ec_transaction_done(struct acpi_ec *ec)
+ 	unsigned long flags;
+ 	int ret = 0;
+ 	spin_lock_irqsave(&ec->curr_lock, flags);
+-	if (!ec->curr || (!ec->curr->wlen && !ec->curr->rlen))
++	if (!ec->curr || ec->curr->done)
+ 		ret = 1;
+ 	spin_unlock_irqrestore(&ec->curr_lock, flags);
+ 	return ret;
+ }
+ 
++static void start_transaction(struct acpi_ec *ec)
++{
++	ec->curr->irq_count = ec->curr->wi = ec->curr->ri = 0;
++	ec->curr->done = false;
++	acpi_ec_write_cmd(ec, ec->curr->command);
++}
++
+ static void gpe_transaction(struct acpi_ec *ec, u8 status)
+ {
+ 	unsigned long flags;
+ 	spin_lock_irqsave(&ec->curr_lock, flags);
+ 	if (!ec->curr)
+ 		goto unlock;
+-	if (ec->curr->wlen > 0) {
+-		if ((status & ACPI_EC_FLAG_IBF) == 0) {
+-			acpi_ec_write_data(ec, *(ec->curr->wdata++));
+-			--ec->curr->wlen;
+-		} else
+-			/* false interrupt, state didn't change */
+-			++ec->curr->irq_count;
+-
+-	} else if (ec->curr->rlen > 0) {
++	if (ec->curr->wlen > ec->curr->wi) {
++		if ((status & ACPI_EC_FLAG_IBF) == 0)
++			acpi_ec_write_data(ec,
++				ec->curr->wdata[ec->curr->wi++]);
++		else
++			goto err;
++	} else if (ec->curr->rlen > ec->curr->ri) {
+ 		if ((status & ACPI_EC_FLAG_OBF) == 1) {
+-			*(ec->curr->rdata++) = acpi_ec_read_data(ec);
+-			--ec->curr->rlen;
++			ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec);
++			if (ec->curr->rlen == ec->curr->ri)
++				ec->curr->done = true;
+ 		} else
+-			/* false interrupt, state didn't change */
+-			++ec->curr->irq_count;
+-	}
++			goto err;
++	} else if (ec->curr->wlen == ec->curr->wi &&
++		   (status & ACPI_EC_FLAG_IBF) == 0)
++		ec->curr->done = true;
++	goto unlock;
++err:
++	/* false interrupt, state didn't change */
++	++ec->curr->irq_count;
+ unlock:
+ 	spin_unlock_irqrestore(&ec->curr_lock, flags);
+ }
+@@ -215,6 +229,15 @@ static int acpi_ec_wait(struct acpi_ec *ec)
+ 	if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
+ 			       msecs_to_jiffies(ACPI_EC_DELAY)))
+ 		return 0;
++	/* try restart command if we get any false interrupts */
++	if (ec->curr->irq_count &&
++	    (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) {
++		pr_debug(PREFIX "controller reset, restart transaction\n");
++		start_transaction(ec);
++		if (wait_event_timeout(ec->wait, ec_transaction_done(ec),
++					msecs_to_jiffies(ACPI_EC_DELAY)))
++			return 0;
++	}
+ 	/* missing GPEs, switch back to poll mode */
+ 	if (printk_ratelimit())
+ 		pr_info(PREFIX "missing confirmations, "
+@@ -239,10 +262,10 @@ static int ec_check_sci(struct acpi_ec *ec, u8 state)
+ static int ec_poll(struct acpi_ec *ec)
+ {
+ 	unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+-	msleep(1);
++	udelay(ACPI_EC_UDELAY);
+ 	while (time_before(jiffies, delay)) {
+ 		gpe_transaction(ec, acpi_ec_read_status(ec));
+-		msleep(1);
++		udelay(ACPI_EC_UDELAY);
+ 		if (ec_transaction_done(ec))
+ 			return 0;
+ 	}
+@@ -264,9 +287,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ 	/* start transaction */
+ 	spin_lock_irqsave(&ec->curr_lock, tmp);
+ 	/* following two actions should be kept atomic */
+-	t->irq_count = 0;
+ 	ec->curr = t;
+-	acpi_ec_write_cmd(ec, ec->curr->command);
++	start_transaction(ec);
+ 	if (ec->curr->command == ACPI_EC_COMMAND_QUERY)
+ 		clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
+ 	spin_unlock_irqrestore(&ec->curr_lock, tmp);
+@@ -286,7 +308,8 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec,
+ 		acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
+ 	} else if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+ 		   t->irq_count > ACPI_EC_STORM_THRESHOLD) {
+-		pr_debug(PREFIX "GPE storm detected\n");
++		pr_info(PREFIX "GPE storm detected, "
++			"transactions will use polling mode\n");
+ 		set_bit(EC_FLAGS_GPE_STORM, &ec->flags);
+ 	}
+ 	return ret;
+@@ -558,17 +581,26 @@ static u32 acpi_ec_gpe_handler(void *data)
+ 	pr_debug(PREFIX "~~~> interrupt\n");
+ 	status = acpi_ec_read_status(ec);
+ 
+-	gpe_transaction(ec, status);
+-	if (ec_transaction_done(ec) && (status & ACPI_EC_FLAG_IBF) == 0)
+-		wake_up(&ec->wait);
++	if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) {
++		gpe_transaction(ec, status);
++		if (ec_transaction_done(ec) &&
++		    (status & ACPI_EC_FLAG_IBF) == 0)
++			wake_up(&ec->wait);
++	}
+ 
+ 	ec_check_sci(ec, status);
+ 	if (!test_bit(EC_FLAGS_GPE_MODE, &ec->flags) &&
+ 	    !test_bit(EC_FLAGS_NO_GPE, &ec->flags)) {
+ 		/* this is non-query, must be confirmation */
+-		if (printk_ratelimit())
+-			pr_info(PREFIX "non-query interrupt received,"
++		if (!test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) {
++			if (printk_ratelimit())
++				pr_info(PREFIX "non-query interrupt received,"
++					" switching to interrupt mode\n");
++		} else {
++			/* hush, STORM switches the mode every transaction */
++			pr_debug(PREFIX "non-query interrupt received,"
+ 				" switching to interrupt mode\n");
++		}
+ 		set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+ 	}
+ 	return ACPI_INTERRUPT_HANDLED;
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
+index f6f52c1..0450761 100644
+--- a/drivers/acpi/scan.c
++++ b/drivers/acpi/scan.c
+@@ -276,6 +276,13 @@ int acpi_match_device_ids(struct acpi_device *device,
+ {
+ 	const struct acpi_device_id *id;
+ 
++	/*
++	 * If the device is not present, it is unnecessary to load device
++	 * driver for it.
++	 */
++	if (!device->status.present)
++		return -ENODEV;
++
+ 	if (device->flags.hardware_id) {
+ 		for (id = ids; id->id[0]; id++) {
+ 			if (!strcmp((char*)id->id, device->pnp.hardware_id))
+@@ -1221,15 +1228,18 @@ acpi_add_single_object(struct acpi_device **child,
+ 			result = -ENODEV;
+ 			goto end;
+ 		}
+-		if (!device->status.present) {
+-			/* Bay and dock should be handled even if absent */
+-			if (!ACPI_SUCCESS(
+-			     acpi_is_child_device(device, acpi_bay_match)) &&
+-			    !ACPI_SUCCESS(
+-			     acpi_is_child_device(device, acpi_dock_match))) {
+-					result = -ENODEV;
+-					goto end;
+-			}
++		/*
++		 * When the device is neither present nor functional, the
++		 * device should not be added to Linux ACPI device tree.
++		 * When the status of the device is not present but functinal,
++		 * it should be added to Linux ACPI tree. For example : bay
++		 * device , dock device.
++		 * In such conditions it is unncessary to check whether it is
++		 * bay device or dock device.
++		 */
++		if (!device->status.present && !device->status.functional) {
++			result = -ENODEV;
++			goto end;
+ 		}
+ 		break;
+ 	default:
+@@ -1402,7 +1412,12 @@ static int acpi_bus_scan(struct acpi_device *start, struct acpi_bus_ops *ops)
+ 		 * TBD: Need notifications and other detection mechanisms
+ 		 *      in place before we can fully implement this.
+ 		 */
+-		if (child->status.present) {
++		 /*
++		 * When the device is not present but functional, it is also
++		 * necessary to scan the children of this device.
++		 */
++		if (child->status.present || (!child->status.present &&
++					child->status.functional)) {
+ 			status = acpi_get_next_object(ACPI_TYPE_ANY, chandle,
+ 						      NULL, NULL);
+ 			if (ACPI_SUCCESS(status)) {
+diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
+index 91dec44..4745792 100644
+--- a/drivers/acpi/system.c
++++ b/drivers/acpi/system.c
+@@ -78,9 +78,15 @@ static ssize_t acpi_table_show(struct kobject *kobj,
+ 	    container_of(bin_attr, struct acpi_table_attr, attr);
+ 	struct acpi_table_header *table_header = NULL;
+ 	acpi_status status;
++	char name[ACPI_NAME_SIZE];
++
++	if (strncmp(table_attr->name, "NULL", 4))
++		memcpy(name, table_attr->name, ACPI_NAME_SIZE);
++	else
++		memcpy(name, "\0\0\0\0", 4);
+ 
+ 	status =
+-	    acpi_get_table(table_attr->name, table_attr->instance,
++	    acpi_get_table(name, table_attr->instance,
+ 			   &table_header);
+ 	if (ACPI_FAILURE(status))
+ 		return -ENODEV;
+@@ -95,21 +101,24 @@ static void acpi_table_attr_init(struct acpi_table_attr *table_attr,
+ 	struct acpi_table_header *header = NULL;
+ 	struct acpi_table_attr *attr = NULL;
+ 
+-	memcpy(table_attr->name, table_header->signature, ACPI_NAME_SIZE);
++	if (table_header->signature[0] != '\0')
++		memcpy(table_attr->name, table_header->signature,
++			ACPI_NAME_SIZE);
++	else
++		memcpy(table_attr->name, "NULL", 4);
+ 
+ 	list_for_each_entry(attr, &acpi_table_attr_list, node) {
+-		if (!memcmp(table_header->signature, attr->name,
+-			    ACPI_NAME_SIZE))
++		if (!memcmp(table_attr->name, attr->name, ACPI_NAME_SIZE))
+ 			if (table_attr->instance < attr->instance)
+ 				table_attr->instance = attr->instance;
+ 	}
+ 	table_attr->instance++;
+ 
+ 	if (table_attr->instance > 1 || (table_attr->instance == 1 &&
+-					 !acpi_get_table(table_header->
+-							 signature, 2,
+-							 &header)))
+-		sprintf(table_attr->name + 4, "%d", table_attr->instance);
++					!acpi_get_table
++					(table_header->signature, 2, &header)))
++		sprintf(table_attr->name + ACPI_NAME_SIZE, "%d",
++			table_attr->instance);
+ 
+ 	table_attr->attr.size = 0;
+ 	table_attr->attr.read = acpi_table_show;
+diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
+index 8a59aaa..7a88dfd 100644
+--- a/drivers/char/ipmi/ipmi_msghandler.c
++++ b/drivers/char/ipmi/ipmi_msghandler.c
+@@ -422,9 +422,11 @@ struct ipmi_smi {
+ /**
+  * The driver model view of the IPMI messaging driver.
+  */
+-static struct device_driver ipmidriver = {
+-	.name = "ipmi",
+-	.bus = &platform_bus_type
++static struct platform_driver ipmidriver = {
++	.driver = {
++		.name = "ipmi",
++		.bus = &platform_bus_type
++	}
+ };
+ static DEFINE_MUTEX(ipmidriver_mutex);
+ 
+@@ -2384,9 +2386,9 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ 	 * representing the interfaced BMC already
+ 	 */
+ 	if (bmc->guid_set)
+-		old_bmc = ipmi_find_bmc_guid(&ipmidriver, bmc->guid);
++		old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, bmc->guid);
+ 	else
+-		old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver,
++		old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
+ 						    bmc->id.product_id,
+ 						    bmc->id.device_id);
+ 
+@@ -2416,7 +2418,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ 		snprintf(name, sizeof(name),
+ 			 "ipmi_bmc.%4.4x", bmc->id.product_id);
+ 
+-		while (ipmi_find_bmc_prod_dev_id(&ipmidriver,
++		while (ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
+ 						 bmc->id.product_id,
+ 						 bmc->id.device_id)) {
+ 			if (!warn_printed) {
+@@ -2446,7 +2448,7 @@ static int ipmi_bmc_register(ipmi_smi_t intf, int ifnum,
+ 			       " Unable to allocate platform device\n");
+ 			return -ENOMEM;
+ 		}
+-		bmc->dev->dev.driver = &ipmidriver;
++		bmc->dev->dev.driver = &ipmidriver.driver;
+ 		dev_set_drvdata(&bmc->dev->dev, bmc);
+ 		kref_init(&bmc->refcount);
+ 
+@@ -4247,7 +4249,7 @@ static int ipmi_init_msghandler(void)
+ 	if (initialized)
+ 		return 0;
+ 
+-	rv = driver_register(&ipmidriver);
++	rv = driver_register(&ipmidriver.driver);
+ 	if (rv) {
+ 		printk(KERN_ERR PFX "Could not register IPMI driver\n");
+ 		return rv;
+@@ -4308,7 +4310,7 @@ static __exit void cleanup_ipmi(void)
+ 	remove_proc_entry(proc_ipmi_root->name, NULL);
+ #endif /* CONFIG_PROC_FS */
+ 
+-	driver_unregister(&ipmidriver);
++	driver_unregister(&ipmidriver.driver);
+ 
+ 	initialized = 0;
+ 
+diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
+index 8e8afb6..7e860da 100644
+--- a/drivers/char/ipmi/ipmi_si_intf.c
++++ b/drivers/char/ipmi/ipmi_si_intf.c
+@@ -114,9 +114,11 @@ static char *si_to_str[] = { "kcs", "smic", "bt" };
+ 
+ #define DEVICE_NAME "ipmi_si"
+ 
+-static struct device_driver ipmi_driver = {
+-	.name = DEVICE_NAME,
+-	.bus = &platform_bus_type
++static struct platform_driver ipmi_driver = {
++	.driver = {
++		.name = DEVICE_NAME,
++		.bus = &platform_bus_type
++	}
+ };
+ 
+ 
+@@ -2868,7 +2870,7 @@ static int try_smi_init(struct smi_info *new_smi)
+ 			goto out_err;
+ 		}
+ 		new_smi->dev = &new_smi->pdev->dev;
+-		new_smi->dev->driver = &ipmi_driver;
++		new_smi->dev->driver = &ipmi_driver.driver;
+ 
+ 		rv = platform_device_add(new_smi->pdev);
+ 		if (rv) {
+@@ -2983,7 +2985,7 @@ static __devinit int init_ipmi_si(void)
+ 	initialized = 1;
+ 
+ 	/* Register the device drivers. */
+-	rv = driver_register(&ipmi_driver);
++	rv = driver_register(&ipmi_driver.driver);
+ 	if (rv) {
+ 		printk(KERN_ERR
+ 		       "init_ipmi_si: Unable to register driver: %d\n",
+@@ -3052,7 +3054,7 @@ static __devinit int init_ipmi_si(void)
+ #ifdef CONFIG_PPC_OF
+ 		of_unregister_platform_driver(&ipmi_of_platform_driver);
+ #endif
+-		driver_unregister(&ipmi_driver);
++		driver_unregister(&ipmi_driver.driver);
+ 		printk(KERN_WARNING
+ 		       "ipmi_si: Unable to find any System Interface(s)\n");
+ 		return -ENODEV;
+@@ -3151,7 +3153,7 @@ static __exit void cleanup_ipmi_si(void)
+ 		cleanup_one_si(e);
+ 	mutex_unlock(&smi_infos_lock);
+ 
+-	driver_unregister(&ipmi_driver);
++	driver_unregister(&ipmi_driver.driver);
+ }
+ module_exit(cleanup_ipmi_si);
+ 
+diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
+index 0f70dc2..7e909e8 100644
+--- a/drivers/hwmon/ibmaem.c
++++ b/drivers/hwmon/ibmaem.c
+@@ -88,9 +88,11 @@
+ static DEFINE_IDR(aem_idr);
+ static DEFINE_SPINLOCK(aem_idr_lock);
+ 
+-static struct device_driver aem_driver = {
+-	.name = DRVNAME,
+-	.bus = &platform_bus_type,
++static struct platform_driver aem_driver = {
++	.driver = {
++		.name = DRVNAME,
++		.bus = &platform_bus_type,
++	}
+ };
+ 
+ struct aem_ipmi_data {
+@@ -583,7 +585,7 @@ static int aem_init_aem1_inst(struct aem_ipmi_data *probe, u8 module_handle)
+ 	data->pdev = platform_device_alloc(DRVNAME, data->id);
+ 	if (!data->pdev)
+ 		goto dev_err;
+-	data->pdev->dev.driver = &aem_driver;
++	data->pdev->dev.driver = &aem_driver.driver;
+ 
+ 	res = platform_device_add(data->pdev);
+ 	if (res)
+@@ -716,7 +718,7 @@ static int aem_init_aem2_inst(struct aem_ipmi_data *probe,
+ 	data->pdev = platform_device_alloc(DRVNAME, data->id);
+ 	if (!data->pdev)
+ 		goto dev_err;
+-	data->pdev->dev.driver = &aem_driver;
++	data->pdev->dev.driver = &aem_driver.driver;
+ 
+ 	res = platform_device_add(data->pdev);
+ 	if (res)
+@@ -1085,7 +1087,7 @@ static int __init aem_init(void)
+ {
+ 	int res;
+ 
+-	res = driver_register(&aem_driver);
++	res = driver_register(&aem_driver.driver);
+ 	if (res) {
+ 		printk(KERN_ERR "Can't register aem driver\n");
+ 		return res;
+@@ -1097,7 +1099,7 @@ static int __init aem_init(void)
+ 	return 0;
+ 
+ ipmi_reg_err:
+-	driver_unregister(&aem_driver);
++	driver_unregister(&aem_driver.driver);
+ 	return res;
+ 
+ }
+@@ -1107,7 +1109,7 @@ static void __exit aem_exit(void)
+ 	struct aem_data *p1, *next1;
+ 
+ 	ipmi_smi_watcher_unregister(&driver_data.bmc_events);
+-	driver_unregister(&aem_driver);
++	driver_unregister(&aem_driver.driver);
+ 	list_for_each_entry_safe(p1, next1, &driver_data.aem_devices, list)
+ 		aem_delete(p1);
+ }
+diff --git a/drivers/input/mouse/alps.c b/drivers/input/mouse/alps.c
+index 385e32b..cbedf95 100644
+--- a/drivers/input/mouse/alps.c
++++ b/drivers/input/mouse/alps.c
+@@ -54,6 +54,7 @@ static const struct alps_model_info alps_model_data[] = {
+ 	{ { 0x20, 0x02, 0x0e },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT }, /* XXX */
+ 	{ { 0x22, 0x02, 0x0a },	0xf8, 0xf8, ALPS_PASS | ALPS_DUALPOINT },
+ 	{ { 0x22, 0x02, 0x14 }, 0xff, 0xff, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude D600 */
++	{ { 0x62, 0x02, 0x14 }, 0xcf, 0xcf, ALPS_PASS | ALPS_DUALPOINT }, /* Dell Latitude E6500 */
+ 	{ { 0x73, 0x02, 0x50 }, 0xcf, 0xcf, ALPS_FW_BK_1 } /* Dell Vostro 1400 */
+ };
+ 
+diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
+index ff05fe8..97ef945 100644
+--- a/drivers/md/dm-raid1.c
++++ b/drivers/md/dm-raid1.c
+@@ -1598,6 +1598,7 @@ static void mirror_dtr(struct dm_target *ti)
+ 
+ 	del_timer_sync(&ms->timer);
+ 	flush_workqueue(ms->kmirrord_wq);
++	flush_scheduled_work();
+ 	dm_kcopyd_client_destroy(ms->kcopyd_client);
+ 	destroy_workqueue(ms->kmirrord_wq);
+ 	free_context(ms, ti, ms->nr_mirrors);
+diff --git a/drivers/media/video/tvaudio.c b/drivers/media/video/tvaudio.c
+index b59e472..d74df58 100644
+--- a/drivers/media/video/tvaudio.c
++++ b/drivers/media/video/tvaudio.c
+@@ -1576,13 +1576,13 @@ static int tvaudio_get_ctrl(struct CHIPSTATE *chip,
+ 		return 0;
+ 	}
+ 	case V4L2_CID_AUDIO_BASS:
+-		if (desc->flags & CHIP_HAS_BASSTREBLE)
++		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ 			break;
+ 		ctrl->value = chip->bass;
+ 		return 0;
+ 	case V4L2_CID_AUDIO_TREBLE:
+-		if (desc->flags & CHIP_HAS_BASSTREBLE)
+-			return -EINVAL;
++		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
++			break;
+ 		ctrl->value = chip->treble;
+ 		return 0;
+ 	}
+@@ -1642,16 +1642,15 @@ static int tvaudio_set_ctrl(struct CHIPSTATE *chip,
+ 		return 0;
+ 	}
+ 	case V4L2_CID_AUDIO_BASS:
+-		if (desc->flags & CHIP_HAS_BASSTREBLE)
++		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ 			break;
+ 		chip->bass = ctrl->value;
+ 		chip_write(chip,desc->bassreg,desc->bassfunc(chip->bass));
+ 
+ 		return 0;
+ 	case V4L2_CID_AUDIO_TREBLE:
+-		if (desc->flags & CHIP_HAS_BASSTREBLE)
+-			return -EINVAL;
+-
++		if (!(desc->flags & CHIP_HAS_BASSTREBLE))
++			break;
+ 		chip->treble = ctrl->value;
+ 		chip_write(chip,desc->treblereg,desc->treblefunc(chip->treble));
+ 
+@@ -1695,7 +1694,7 @@ static int chip_command(struct i2c_client *client,
+ 				break;
+ 			case V4L2_CID_AUDIO_BASS:
+ 			case V4L2_CID_AUDIO_TREBLE:
+-				if (desc->flags & CHIP_HAS_BASSTREBLE)
++				if (!(desc->flags & CHIP_HAS_BASSTREBLE))
+ 					return -EINVAL;
+ 				break;
+ 			default:
+diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
+index 60775be..b35eb92 100644
+--- a/drivers/misc/sony-laptop.c
++++ b/drivers/misc/sony-laptop.c
+@@ -2315,8 +2315,10 @@ end:
+  */
+ static int sony_pic_disable(struct acpi_device *device)
+ {
+-	if (ACPI_FAILURE(acpi_evaluate_object(device->handle,
+-			"_DIS", NULL, NULL)))
++	acpi_status ret = acpi_evaluate_object(device->handle, "_DIS", NULL,
++					       NULL);
++
++	if (ACPI_FAILURE(ret) && ret != AE_NOT_FOUND)
+ 		return -ENXIO;
+ 
+ 	dprintk("Device disabled\n");
+diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
+index 4a11296..60a0453 100644
+--- a/drivers/net/Kconfig
++++ b/drivers/net/Kconfig
+@@ -2046,6 +2046,7 @@ config R8169
+ 	tristate "Realtek 8169 gigabit ethernet support"
+ 	depends on PCI
+ 	select CRC32
++	select MII
+ 	---help---
+ 	  Say Y here if you have a Realtek 8169 PCI Gigabit Ethernet adapter.
+ 
+diff --git a/drivers/net/bnx2x_init.h b/drivers/net/bnx2x_init.h
+index 130927c..a6c0b3a 100644
+--- a/drivers/net/bnx2x_init.h
++++ b/drivers/net/bnx2x_init.h
+@@ -564,14 +564,15 @@ static const struct arb_line write_arb_addr[NUM_WR_Q-1] = {
+ 
+ static void bnx2x_init_pxp(struct bnx2x *bp)
+ {
++	u16 devctl;
+ 	int r_order, w_order;
+ 	u32 val, i;
+ 
+ 	pci_read_config_word(bp->pdev,
+-			     bp->pcie_cap + PCI_EXP_DEVCTL, (u16 *)&val);
+-	DP(NETIF_MSG_HW, "read 0x%x from devctl\n", (u16)val);
+-	w_order = ((val & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+-	r_order = ((val & PCI_EXP_DEVCTL_READRQ) >> 12);
++			     bp->pcie_cap + PCI_EXP_DEVCTL, &devctl);
++	DP(NETIF_MSG_HW, "read 0x%x from devctl\n", devctl);
++	w_order = ((devctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
++	r_order = ((devctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+ 
+ 	if (r_order > MAX_RD_ORD) {
+ 		DP(NETIF_MSG_HW, "read order of %d  order adjusted to %d\n",
+diff --git a/drivers/net/bnx2x_main.c b/drivers/net/bnx2x_main.c
+index a8eb3c4..53459db 100644
+--- a/drivers/net/bnx2x_main.c
++++ b/drivers/net/bnx2x_main.c
+@@ -6480,6 +6480,7 @@ load_int_disable:
+ 	bnx2x_free_irq(bp);
+ load_error:
+ 	bnx2x_free_mem(bp);
++	bp->port.pmf = 0;
+ 
+ 	/* TBD we really need to reset the chip
+ 	   if we want to recover from this */
+@@ -6790,6 +6791,7 @@ unload_error:
+ 	/* Report UNLOAD_DONE to MCP */
+ 	if (!BP_NOMCP(bp))
+ 		bnx2x_fw_command(bp, DRV_MSG_CODE_UNLOAD_DONE);
++	bp->port.pmf = 0;
+ 
+ 	/* Free SKBs, SGEs, TPA pool and driver internals */
+ 	bnx2x_free_skbs(bp);
+@@ -10203,8 +10205,6 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+ 		return -ENOMEM;
+ 	}
+ 
+-	netif_carrier_off(dev);
+-
+ 	bp = netdev_priv(dev);
+ 	bp->msglevel = debug;
+ 
+@@ -10228,6 +10228,8 @@ static int __devinit bnx2x_init_one(struct pci_dev *pdev,
+ 		goto init_one_exit;
+ 	}
+ 
++	netif_carrier_off(dev);
++
+ 	bp->common.name = board_info[ent->driver_data].name;
+ 	printk(KERN_INFO "%s: %s (%c%d) PCI-E x%d %s found at mem %lx,"
+ 	       " IRQ %d, ", dev->name, bp->common.name,
+diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
+index 0676c6d..a225827 100644
+--- a/drivers/net/wireless/ath5k/base.c
++++ b/drivers/net/wireless/ath5k/base.c
+@@ -294,9 +294,9 @@ static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
+ }
+ 
+ /* Interrupt handling */
+-static int 	ath5k_init(struct ath5k_softc *sc);
++static int 	ath5k_init(struct ath5k_softc *sc, bool is_resume);
+ static int 	ath5k_stop_locked(struct ath5k_softc *sc);
+-static int 	ath5k_stop_hw(struct ath5k_softc *sc);
++static int 	ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend);
+ static irqreturn_t ath5k_intr(int irq, void *dev_id);
+ static void 	ath5k_tasklet_reset(unsigned long data);
+ 
+@@ -584,7 +584,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
+ 
+ 	ath5k_led_off(sc);
+ 
+-	ath5k_stop_hw(sc);
++	ath5k_stop_hw(sc, true);
+ 
+ 	free_irq(pdev->irq, sc);
+ 	pci_save_state(pdev);
+@@ -599,8 +599,7 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ {
+ 	struct ieee80211_hw *hw = pci_get_drvdata(pdev);
+ 	struct ath5k_softc *sc = hw->priv;
+-	struct ath5k_hw *ah = sc->ah;
+-	int i, err;
++	int err;
+ 
+ 	pci_restore_state(pdev);
+ 
+@@ -621,21 +620,11 @@ ath5k_pci_resume(struct pci_dev *pdev)
+ 		goto err_no_irq;
+ 	}
+ 
+-	err = ath5k_init(sc);
++	err = ath5k_init(sc, true);
+ 	if (err)
+ 		goto err_irq;
+ 	ath5k_led_enable(sc);
+ 
+-	/*
+-	 * Reset the key cache since some parts do not
+-	 * reset the contents on initial power up or resume.
+-	 *
+-	 * FIXME: This may need to be revisited when mac80211 becomes
+-	 *        aware of suspend/resume.
+-	 */
+-	for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+-		ath5k_hw_reset_key(ah, i);
+-
+ 	return 0;
+ err_irq:
+ 	free_irq(pdev->irq, sc);
+@@ -657,7 +646,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ 	struct ath5k_softc *sc = hw->priv;
+ 	struct ath5k_hw *ah = sc->ah;
+ 	u8 mac[ETH_ALEN];
+-	unsigned int i;
+ 	int ret;
+ 
+ 	ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
+@@ -676,13 +664,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
+ 		__set_bit(ATH_STAT_MRRETRY, sc->status);
+ 
+ 	/*
+-	 * Reset the key cache since some parts do not
+-	 * reset the contents on initial power up.
+-	 */
+-	for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
+-		ath5k_hw_reset_key(ah, i);
+-
+-	/*
+ 	 * Collect the channel list.  The 802.11 layer
+ 	 * is resposible for filtering this list based
+ 	 * on settings like the phy mode and regulatory
+@@ -2197,12 +2178,18 @@ ath5k_beacon_config(struct ath5k_softc *sc)
+ \********************/
+ 
+ static int
+-ath5k_init(struct ath5k_softc *sc)
++ath5k_init(struct ath5k_softc *sc, bool is_resume)
+ {
+-	int ret;
++	struct ath5k_hw *ah = sc->ah;
++	int ret, i;
+ 
+ 	mutex_lock(&sc->lock);
+ 
++	if (is_resume && !test_bit(ATH_STAT_STARTED, sc->status))
++		goto out_ok;
++
++	__clear_bit(ATH_STAT_STARTED, sc->status);
++
+ 	ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
+ 
+ 	/*
+@@ -2220,7 +2207,7 @@ ath5k_init(struct ath5k_softc *sc)
+ 	 */
+ 	sc->curchan = sc->hw->conf.channel;
+ 	sc->curband = &sc->sbands[sc->curchan->band];
+-	ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
++	ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, false);
+ 	if (ret) {
+ 		ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
+ 		goto done;
+@@ -2229,7 +2216,14 @@ ath5k_init(struct ath5k_softc *sc)
+ 	 * This is needed only to setup initial state
+ 	 * but it's best done after a reset.
+ 	 */
+-	ath5k_hw_set_txpower_limit(sc->ah, 0);
++	ath5k_hw_set_txpower_limit(ah, 0);
++
++	/*
++	 * Reset the key cache since some parts do not reset the
++	 * contents on initial power up or resume from suspend.
++	 */
++	for (i = 0; i < AR5K_KEYTABLE_SIZE; i++)
++		ath5k_hw_reset_key(ah, i);
+ 
+ 	/*
+ 	 * Setup the hardware after reset: the key cache
+@@ -2249,13 +2243,17 @@ ath5k_init(struct ath5k_softc *sc)
+ 		AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL |
+ 		AR5K_INT_MIB;
+ 
+-	ath5k_hw_set_intr(sc->ah, sc->imask);
++	ath5k_hw_set_intr(ah, sc->imask);
++
++	__set_bit(ATH_STAT_STARTED, sc->status);
++
+ 	/* Set ack to be sent at low bit-rates */
+-	ath5k_hw_set_ack_bitrate_high(sc->ah, false);
++	ath5k_hw_set_ack_bitrate_high(ah, false);
+ 
+ 	mod_timer(&sc->calib_tim, round_jiffies(jiffies +
+ 			msecs_to_jiffies(ath5k_calinterval * 1000)));
+ 
++out_ok:
+ 	ret = 0;
+ done:
+ 	mmiowb();
+@@ -2310,7 +2308,7 @@ ath5k_stop_locked(struct ath5k_softc *sc)
+  * stop is preempted).
+  */
+ static int
+-ath5k_stop_hw(struct ath5k_softc *sc)
++ath5k_stop_hw(struct ath5k_softc *sc, bool is_suspend)
+ {
+ 	int ret;
+ 
+@@ -2341,6 +2339,9 @@ ath5k_stop_hw(struct ath5k_softc *sc)
+ 		}
+ 	}
+ 	ath5k_txbuf_free(sc, sc->bbuf);
++	if (!is_suspend)
++		__clear_bit(ATH_STAT_STARTED, sc->status);
++
+ 	mmiowb();
+ 	mutex_unlock(&sc->lock);
+ 
+@@ -2719,12 +2720,12 @@ err:
+ 
+ static int ath5k_start(struct ieee80211_hw *hw)
+ {
+-	return ath5k_init(hw->priv);
++	return ath5k_init(hw->priv, false);
+ }
+ 
+ static void ath5k_stop(struct ieee80211_hw *hw)
+ {
+-	ath5k_stop_hw(hw->priv);
++	ath5k_stop_hw(hw->priv, false);
+ }
+ 
+ static int ath5k_add_interface(struct ieee80211_hw *hw,
+diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
+index 7ec2f37..214a565 100644
+--- a/drivers/net/wireless/ath5k/base.h
++++ b/drivers/net/wireless/ath5k/base.h
+@@ -132,11 +132,12 @@ struct ath5k_softc {
+ 	size_t			desc_len;	/* size of TX/RX descriptors */
+ 	u16			cachelsz;	/* cache line size */
+ 
+-	DECLARE_BITMAP(status, 4);
++	DECLARE_BITMAP(status, 5);
+ #define ATH_STAT_INVALID	0		/* disable hardware accesses */
+ #define ATH_STAT_MRRETRY	1		/* multi-rate retry support */
+ #define ATH_STAT_PROMISC	2
+ #define ATH_STAT_LEDSOFT	3		/* enable LED gpio status */
++#define ATH_STAT_STARTED	4		/* opened & irqs enabled */
+ 
+ 	unsigned int		filter_flags;	/* HW flags, AR5K_RX_FILTER_* */
+ 	unsigned int		curmode;	/* current phy mode */
+diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
+index ad1a5b4..9b40cbe 100644
+--- a/drivers/net/wireless/ath5k/hw.c
++++ b/drivers/net/wireless/ath5k/hw.c
+@@ -826,9 +826,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
+ 		mdelay(1);
+ 
+ 		/*
+-		 * Write some more initial register settings
++		 * Write some more initial register settings for revised chips
+ 		 */
+-		if (ah->ah_version == AR5K_AR5212) {
++		if (ah->ah_version == AR5K_AR5212 &&
++		    ah->ah_phy_revision > 0x41) {
+ 			ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
+ 
+ 			if (channel->hw_value == CHANNEL_G)
+@@ -847,19 +848,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
+ 			else
+ 				ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
+ 
+-			/* Some bits are disabled here, we know nothing about
+-			 * register 0xa228 yet, most of the times this ends up
+-			 * with a value 0x9b5 -haven't seen any dump with
+-			 * a different value- */
+-			/* Got this from decompiling binary HAL */
+-			data = ath5k_hw_reg_read(ah, 0xa228);
+-			data &= 0xfffffdff;
+-			ath5k_hw_reg_write(ah, data, 0xa228);
+-
+-			data = ath5k_hw_reg_read(ah, 0xa228);
+-			data &= 0xfffe03ff;
+-			ath5k_hw_reg_write(ah, data, 0xa228);
+-			data = 0;
++			/* Got this from legacy-hal */
++			AR5K_REG_DISABLE_BITS(ah, 0xa228, 0x200);
++
++			AR5K_REG_MASKED_BITS(ah, 0xa228, 2 << 10, ~0x1fc00);
+ 
+ 			/* Just write 0x9b5 ? */
+ 			/* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
+diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
+index 2806b21..cf7ebd1 100644
+--- a/drivers/net/wireless/ath5k/initvals.c
++++ b/drivers/net/wireless/ath5k/initvals.c
+@@ -810,6 +810,8 @@ static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
+ 		{ 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
+ 	{ AR5K_PHY(642),
+ 		{ 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
++	{ 0xa228,
++		{ 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
+ 	{ 0xa23c,
+ 		{ 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
+ };
+diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
+index ffdf487..a68f97c 100644
+--- a/drivers/net/wireless/hostap/hostap_wlan.h
++++ b/drivers/net/wireless/hostap/hostap_wlan.h
+@@ -918,9 +918,12 @@ struct hostap_interface {
+ 
+ /*
+  * TX meta data - stored in skb->cb buffer, so this must not be increased over
+- * the 40-byte limit
++ * the 48-byte limit.
++ * THE PADDING THIS STARTS WITH IS A HORRIBLE HACK THAT SHOULD NOT LIVE
++ * TO SEE THE DAY.
+  */
+ struct hostap_skb_tx_data {
++	unsigned int __padding_for_default_qdiscs;
+ 	u32 magic; /* HOSTAP_SKB_TX_DATA_MAGIC */
+ 	u8 rate; /* transmit rate */
+ #define HOSTAP_TX_FLAGS_WDS BIT(0)
+diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
+index 72a6743..cf7056e 100644
+--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
++++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
+@@ -3275,7 +3275,11 @@ static void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
+ 		return;
+ 	}
+ 
+-	iwl_scan_cancel_timeout(priv, 100);
++	if (iwl_scan_cancel(priv)) {
++		/* cancel scan failed, just live w/ bad key and rely
++		   briefly on SW decryption */
++		return;
++	}
+ 
+ 	key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
+ 	key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
+diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c
+index ca5deb6..0cebbc4 100644
+--- a/drivers/net/wireless/rtl8187_dev.c
++++ b/drivers/net/wireless/rtl8187_dev.c
+@@ -45,6 +45,9 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
+ 	{USB_DEVICE(0x03f0, 0xca02), .driver_info = DEVICE_RTL8187},
+ 	/* Sitecom */
+ 	{USB_DEVICE(0x0df6, 0x000d), .driver_info = DEVICE_RTL8187},
++	{USB_DEVICE(0x0df6, 0x0028), .driver_info = DEVICE_RTL8187B},
++	/* Abocom */
++	{USB_DEVICE(0x13d1, 0xabe6), .driver_info = DEVICE_RTL8187},
+ 	{}
+ };
+ 
+diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c
+index c1b9ea3..98b9df7 100644
+--- a/drivers/pnp/pnpacpi/core.c
++++ b/drivers/pnp/pnpacpi/core.c
+@@ -148,9 +148,13 @@ static int __init pnpacpi_add_device(struct acpi_device *device)
+ 	acpi_status status;
+ 	struct pnp_dev *dev;
+ 
++	/*
++	 * If a PnPacpi device is not present , the device
++	 * driver should not be loaded.
++	 */
+ 	status = acpi_get_handle(device->handle, "_CRS", &temp);
+ 	if (ACPI_FAILURE(status) || !ispnpidacpi(acpi_device_hid(device)) ||
+-	    is_exclusive_device(device))
++	    is_exclusive_device(device) || (!device->status.present))
+ 		return 0;
+ 
+ 	dev = pnp_alloc_dev(&pnpacpi_protocol, num, acpi_device_hid(device));
+diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
+index 1fe0901..7716145 100644
+--- a/drivers/scsi/dpt_i2o.c
++++ b/drivers/scsi/dpt_i2o.c
+@@ -2445,7 +2445,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
+ 	hba_status = detailed_status >> 8;
+ 
+ 	// calculate resid for sg 
+-	scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
++	scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+20));
+ 
+ 	pHba = (adpt_hba*) cmd->device->host->hostdata[0];
+ 
+@@ -2456,7 +2456,7 @@ static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
+ 		case I2O_SCSI_DSC_SUCCESS:
+ 			cmd->result = (DID_OK << 16);
+ 			// handle underflow
+-			if(readl(reply+5) < cmd->underflow ) {
++			if (readl(reply+20) < cmd->underflow) {
+ 				cmd->result = (DID_ERROR <<16);
+ 				printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
+ 			}
+diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h
+index 94a720e..00f6780 100644
+--- a/drivers/scsi/qla2xxx/qla_def.h
++++ b/drivers/scsi/qla2xxx/qla_def.h
+@@ -2546,7 +2546,6 @@ typedef struct scsi_qla_host {
+ 	uint8_t		fcode_revision[16];
+ 	uint32_t	fw_revision[4];
+ 
+-	uint16_t	fdt_odd_index;
+ 	uint32_t	fdt_wrt_disable;
+ 	uint32_t	fdt_erase_cmd;
+ 	uint32_t	fdt_block_size;
+diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c
+index ee89ddd..3a0a178 100644
+--- a/drivers/scsi/qla2xxx/qla_init.c
++++ b/drivers/scsi/qla2xxx/qla_init.c
+@@ -974,7 +974,6 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ 				    &ha->fw_minor_version,
+ 				    &ha->fw_subminor_version,
+ 				    &ha->fw_attributes, &ha->fw_memory_size);
+-				qla2x00_resize_request_q(ha);
+ 				ha->flags.npiv_supported = 0;
+ 				if ((IS_QLA24XX(ha) || IS_QLA25XX(ha) ||
+ 				     IS_QLA84XX(ha)) &&
+@@ -986,6 +985,7 @@ qla2x00_setup_chip(scsi_qla_host_t *ha)
+ 						ha->max_npiv_vports =
+ 						    MIN_MULTI_ID_FABRIC - 1;
+ 				}
++				qla2x00_resize_request_q(ha);
+ 
+ 				if (ql2xallocfwdump)
+ 					qla2x00_alloc_fw_dump(ha);
+diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c
+index 813bc77..c07e879 100644
+--- a/drivers/scsi/qla2xxx/qla_mbx.c
++++ b/drivers/scsi/qla2xxx/qla_mbx.c
+@@ -1964,7 +1964,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
+ 			*cur_iocb_cnt = mcp->mb[7];
+ 		if (orig_iocb_cnt)
+ 			*orig_iocb_cnt = mcp->mb[10];
+-		if (max_npiv_vports)
++		if (ha->flags.npiv_supported && max_npiv_vports)
+ 			*max_npiv_vports = mcp->mb[11];
+ 	}
+ 
+diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
+index 6d0f0e5..86e143c 100644
+--- a/drivers/scsi/qla2xxx/qla_os.c
++++ b/drivers/scsi/qla2xxx/qla_os.c
+@@ -730,6 +730,7 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
+ 		if (ha->isp_ops->abort_command(ha, sp)) {
+ 			DEBUG2(printk("%s(%ld): abort_command "
+ 			    "mbx failed.\n", __func__, ha->host_no));
++			ret = FAILED;
+ 		} else {
+ 			DEBUG3(printk("%s(%ld): abort_command "
+ 			    "mbx success.\n", __func__, ha->host_no));
+diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c
+index 1bca744..910c3b3 100644
+--- a/drivers/scsi/qla2xxx/qla_sup.c
++++ b/drivers/scsi/qla2xxx/qla_sup.c
+@@ -546,6 +546,7 @@ qla24xx_get_flash_manufacturer(scsi_qla_host_t *ha, uint8_t *man_id,
+ void
+ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ {
++#define FLASH_BLK_SIZE_4K	0x1000
+ #define FLASH_BLK_SIZE_32K	0x8000
+ #define FLASH_BLK_SIZE_64K	0x10000
+ 	uint16_t cnt, chksum;
+@@ -577,7 +578,6 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ 		goto no_flash_data;
+ 	}
+ 
+-	ha->fdt_odd_index = le16_to_cpu(fdt->man_id) == 0x1f;
+ 	ha->fdt_wrt_disable = fdt->wrt_disable_bits;
+ 	ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0300 | fdt->erase_cmd);
+ 	ha->fdt_block_size = le32_to_cpu(fdt->block_size);
+@@ -590,10 +590,10 @@ qla2xxx_get_flash_info(scsi_qla_host_t *ha)
+ 	}
+ 
+ 	DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[FDT]: (0x%x/0x%x) erase=0x%x "
+-	    "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n",
++	    "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n",
+ 	    le16_to_cpu(fdt->man_id), le16_to_cpu(fdt->id), ha->fdt_erase_cmd,
+ 	    ha->fdt_protect_sec_cmd, ha->fdt_unprotect_sec_cmd,
+-	    ha->fdt_odd_index, ha->fdt_wrt_disable, ha->fdt_block_size));
++	    ha->fdt_wrt_disable, ha->fdt_block_size));
+ 	return;
+ 
+ no_flash_data:
+@@ -614,8 +614,7 @@ no_flash_data:
+ 		ha->fdt_block_size = FLASH_BLK_SIZE_64K;
+ 		break;
+ 	case 0x1f: /* Atmel 26DF081A. */
+-		ha->fdt_odd_index = 1;
+-		ha->fdt_block_size = FLASH_BLK_SIZE_64K;
++		ha->fdt_block_size = FLASH_BLK_SIZE_4K;
+ 		ha->fdt_erase_cmd = flash_conf_to_access_addr(0x0320);
+ 		ha->fdt_unprotect_sec_cmd = flash_conf_to_access_addr(0x0339);
+ 		ha->fdt_protect_sec_cmd = flash_conf_to_access_addr(0x0336);
+@@ -627,9 +626,9 @@ no_flash_data:
+ 	}
+ 
+ 	DEBUG2(qla_printk(KERN_DEBUG, ha, "Flash[MID]: (0x%x/0x%x) erase=0x%x "
+-	    "pro=%x upro=%x idx=%d wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
++	    "pro=%x upro=%x wrtd=0x%x blk=0x%x.\n", man_id, flash_id,
+ 	    ha->fdt_erase_cmd, ha->fdt_protect_sec_cmd,
+-	    ha->fdt_unprotect_sec_cmd, ha->fdt_odd_index, ha->fdt_wrt_disable,
++	    ha->fdt_unprotect_sec_cmd, ha->fdt_wrt_disable,
+ 	    ha->fdt_block_size));
+ }
+ 
+@@ -710,13 +709,9 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr,
+ 	qla24xx_unprotect_flash(ha);
+ 
+ 	for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) {
+-		if (ha->fdt_odd_index) {
+-			findex = faddr << 2;
+-			fdata = findex & sec_mask;
+-		} else {
+-			findex = faddr;
+-			fdata = (findex & sec_mask) << 2;
+-		}
++
++		findex = faddr;
++		fdata = (findex & sec_mask) << 2;
+ 
+ 		/* Are we at the beginning of a sector? */
+ 		if ((findex & rest_addr) == 0) {
+diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
+index d996a61..61524fc 100644
+--- a/drivers/usb/class/cdc-acm.c
++++ b/drivers/usb/class/cdc-acm.c
+@@ -158,16 +158,12 @@ static int acm_wb_is_avail(struct acm *acm)
+ }
+ 
+ /*
+- * Finish write.
++ * Finish write. Caller must hold acm->write_lock
+  */
+ static void acm_write_done(struct acm *acm, struct acm_wb *wb)
+ {
+-	unsigned long flags;
+-
+-	spin_lock_irqsave(&acm->write_lock, flags);
+ 	wb->use = 0;
+ 	acm->transmitting--;
+-	spin_unlock_irqrestore(&acm->write_lock, flags);
+ }
+ 
+ /*
+@@ -482,6 +478,7 @@ static void acm_write_bulk(struct urb *urb)
+ {
+ 	struct acm_wb *wb = urb->context;
+ 	struct acm *acm = wb->instance;
++	unsigned long flags;
+ 
+ 	if (verbose || urb->status
+ 			|| (urb->actual_length != urb->transfer_buffer_length))
+@@ -490,7 +487,9 @@ static void acm_write_bulk(struct urb *urb)
+ 			urb->transfer_buffer_length,
+ 			urb->status);
+ 
++	spin_lock_irqsave(&acm->write_lock, flags);
+ 	acm_write_done(acm, wb);
++	spin_unlock_irqrestore(&acm->write_lock, flags);
+ 	if (ACM_READY(acm))
+ 		schedule_work(&acm->work);
+ 	else
+diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
+index 286b443..9cfa366 100644
+--- a/drivers/usb/core/message.c
++++ b/drivers/usb/core/message.c
+@@ -1091,6 +1091,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0)
+ 				continue;
+ 			dev_dbg(&dev->dev, "unregistering interface %s\n",
+ 				dev_name(&interface->dev));
++			interface->unregistering = 1;
+ 			usb_remove_sysfs_intf_files(interface);
+ 			device_del(&interface->dev);
+ 		}
+diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
+index 5e1f5d5..668a6d6 100644
+--- a/drivers/usb/core/sysfs.c
++++ b/drivers/usb/core/sysfs.c
+@@ -816,7 +816,7 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf)
+ 	struct usb_host_interface *alt = intf->cur_altsetting;
+ 	int retval;
+ 
+-	if (intf->sysfs_files_created)
++	if (intf->sysfs_files_created || intf->unregistering)
+ 		return 0;
+ 
+ 	/* The interface string may be present in some altsettings
+diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c
+index 5ee1590..c1d34df 100644
+--- a/drivers/usb/gadget/f_acm.c
++++ b/drivers/usb/gadget/f_acm.c
+@@ -463,7 +463,11 @@ static int acm_cdc_notify(struct f_acm *acm, u8 type, u16 value,
+ 	notify->wLength = cpu_to_le16(length);
+ 	memcpy(buf, data, length);
+ 
++	/* ep_queue() can complete immediately if it fills the fifo... */
++	spin_unlock(&acm->lock);
+ 	status = usb_ep_queue(ep, req, GFP_ATOMIC);
++	spin_lock(&acm->lock);
++
+ 	if (status < 0) {
+ 		ERROR(acm->port.func.config->cdev,
+ 				"acm ttyGS%d can't notify serial state, %d\n",
+diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
+index 228797e..a657c94 100644
+--- a/drivers/usb/host/Kconfig
++++ b/drivers/usb/host/Kconfig
+@@ -110,29 +110,18 @@ config USB_ISP116X_HCD
+ 
+ config USB_ISP1760_HCD
+ 	tristate "ISP 1760 HCD support"
+-	depends on USB && EXPERIMENTAL
++	depends on USB && EXPERIMENTAL && (PCI || PPC_OF)
+ 	---help---
+ 	  The ISP1760 chip is a USB 2.0 host controller.
+ 
+ 	  This driver does not support isochronous transfers or OTG.
++	  This USB controller is usually attached to a non-DMA-Master
++	  capable bus. NXP's eval kit brings this chip on PCI card
++	  where the chip itself is behind a PLB to simulate such
++	  a bus.
+ 
+ 	  To compile this driver as a module, choose M here: the
+-	  module will be called isp1760-hcd.
+-
+-config USB_ISP1760_PCI
+-	bool "Support for the PCI bus"
+-	depends on USB_ISP1760_HCD && PCI
+-	---help---
+-	  Enables support for the device present on the PCI bus.
+-	  This should only be required if you happen to have the eval kit from
+-	  NXP and you are going to test it.
+-
+-config USB_ISP1760_OF
+-	bool "Support for the OF platform bus"
+-	depends on USB_ISP1760_HCD && PPC_OF
+-	---help---
+-	  Enables support for the device present on the PowerPC
+-	  OpenFirmware platform bus.
++	  module will be called isp1760.
+ 
+ config USB_OHCI_HCD
+ 	tristate "OHCI HCD support"
+diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
+index 86e38b0..dc21ade 100644
+--- a/drivers/usb/host/ehci-hcd.c
++++ b/drivers/usb/host/ehci-hcd.c
+@@ -643,7 +643,7 @@ static int ehci_run (struct usb_hcd *hcd)
+ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+ {
+ 	struct ehci_hcd		*ehci = hcd_to_ehci (hcd);
+-	u32			status, pcd_status = 0, cmd;
++	u32			status, masked_status, pcd_status = 0, cmd;
+ 	int			bh;
+ 
+ 	spin_lock (&ehci->lock);
+@@ -656,14 +656,14 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+ 		goto dead;
+ 	}
+ 
+-	status &= INTR_MASK;
+-	if (!status) {			/* irq sharing? */
++	masked_status = status & INTR_MASK;
++	if (!masked_status) {		/* irq sharing? */
+ 		spin_unlock(&ehci->lock);
+ 		return IRQ_NONE;
+ 	}
+ 
+ 	/* clear (just) interrupts */
+-	ehci_writel(ehci, status, &ehci->regs->status);
++	ehci_writel(ehci, masked_status, &ehci->regs->status);
+ 	cmd = ehci_readl(ehci, &ehci->regs->command);
+ 	bh = 0;
+ 
+@@ -731,19 +731,18 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd)
+ 
+ 	/* PCI errors [4.15.2.4] */
+ 	if (unlikely ((status & STS_FATAL) != 0)) {
++		ehci_err(ehci, "fatal error\n");
+ 		dbg_cmd (ehci, "fatal", ehci_readl(ehci,
+ 						   &ehci->regs->command));
+ 		dbg_status (ehci, "fatal", status);
+-		if (status & STS_HALT) {
+-			ehci_err (ehci, "fatal error\n");
++		ehci_halt(ehci);
+ dead:
+-			ehci_reset (ehci);
+-			ehci_writel(ehci, 0, &ehci->regs->configured_flag);
+-			/* generic layer kills/unlinks all urbs, then
+-			 * uses ehci_stop to clean up the rest
+-			 */
+-			bh = 1;
+-		}
++		ehci_reset(ehci);
++		ehci_writel(ehci, 0, &ehci->regs->configured_flag);
++		/* generic layer kills/unlinks all urbs, then
++		 * uses ehci_stop to clean up the rest
++		 */
++		bh = 1;
+ 	}
+ 
+ 	if (bh)
+diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c
+index 0eba894..9c9da35 100644
+--- a/drivers/usb/host/ehci-ps3.c
++++ b/drivers/usb/host/ehci-ps3.c
+@@ -205,6 +205,7 @@ static int ps3_ehci_remove(struct ps3_system_bus_device *dev)
+ 
+ 	tmp = hcd->irq;
+ 
++	ehci_shutdown(hcd);
+ 	usb_remove_hcd(hcd);
+ 
+ 	ps3_system_bus_set_driver_data(dev, NULL);
+diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c
+index 4a0c5a7..a081ee6 100644
+--- a/drivers/usb/host/ehci-sched.c
++++ b/drivers/usb/host/ehci-sched.c
+@@ -918,7 +918,7 @@ iso_stream_init (
+ 		 */
+ 		stream->usecs = HS_USECS_ISO (maxp);
+ 		bandwidth = stream->usecs * 8;
+-		bandwidth /= 1 << (interval - 1);
++		bandwidth /= interval;
+ 
+ 	} else {
+ 		u32		addr;
+@@ -951,7 +951,7 @@ iso_stream_init (
+ 		} else
+ 			stream->raw_mask = smask_out [hs_transfers - 1];
+ 		bandwidth = stream->usecs + stream->c_usecs;
+-		bandwidth /= 1 << (interval + 2);
++		bandwidth /= interval << 3;
+ 
+ 		/* stream->splits gets created from raw_mask later */
+ 		stream->address = cpu_to_hc32(ehci, addr);
+diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c
+index 051ef7b..78b8aaa 100644
+--- a/drivers/usb/host/isp1760-if.c
++++ b/drivers/usb/host/isp1760-if.c
+@@ -14,16 +14,16 @@
+ #include "../core/hcd.h"
+ #include "isp1760-hcd.h"
+ 
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ #include <linux/of.h>
+ #include <linux/of_platform.h>
+ #endif
+ 
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ #include <linux/pci.h>
+ #endif
+ 
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ static int of_isp1760_probe(struct of_device *dev,
+ 		const struct of_device_id *match)
+ {
+@@ -128,7 +128,7 @@ static struct of_platform_driver isp1760_of_driver = {
+ };
+ #endif
+ 
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ static u32 nxp_pci_io_base;
+ static u32 iolength;
+ static u32 pci_mem_phy0;
+@@ -287,28 +287,28 @@ static struct pci_driver isp1761_pci_driver = {
+ 
+ static int __init isp1760_init(void)
+ {
+-	int ret = -ENODEV;
++	int ret;
+ 
+ 	init_kmem_once();
+ 
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ 	ret = of_register_platform_driver(&isp1760_of_driver);
+ 	if (ret) {
+ 		deinit_kmem_cache();
+ 		return ret;
+ 	}
+ #endif
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ 	ret = pci_register_driver(&isp1761_pci_driver);
+ 	if (ret)
+ 		goto unreg_of;
+ #endif
+ 	return ret;
+ 
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ unreg_of:
+ #endif
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ 	of_unregister_platform_driver(&isp1760_of_driver);
+ #endif
+ 	deinit_kmem_cache();
+@@ -318,10 +318,10 @@ module_init(isp1760_init);
+ 
+ static void __exit isp1760_exit(void)
+ {
+-#ifdef CONFIG_USB_ISP1760_OF
++#ifdef CONFIG_PPC_OF
+ 	of_unregister_platform_driver(&isp1760_of_driver);
+ #endif
+-#ifdef CONFIG_USB_ISP1760_PCI
++#ifdef CONFIG_PCI
+ 	pci_unregister_driver(&isp1761_pci_driver);
+ #endif
+ 	deinit_kmem_cache();
+diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c
+index 2089d8a..3c1a3b5 100644
+--- a/drivers/usb/host/ohci-ps3.c
++++ b/drivers/usb/host/ohci-ps3.c
+@@ -192,7 +192,7 @@ fail_start:
+ 	return result;
+ }
+ 
+-static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
++static int ps3_ohci_remove(struct ps3_system_bus_device *dev)
+ {
+ 	unsigned int tmp;
+ 	struct usb_hcd *hcd =
+@@ -205,6 +205,7 @@ static int ps3_ohci_remove (struct ps3_system_bus_device *dev)
+ 
+ 	tmp = hcd->irq;
+ 
++	ohci_shutdown(hcd);
+ 	usb_remove_hcd(hcd);
+ 
+ 	ps3_system_bus_set_driver_data(dev, NULL);
+diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
+index 061df9b..ccebf89 100644
+--- a/drivers/usb/storage/unusual_devs.h
++++ b/drivers/usb/storage/unusual_devs.h
+@@ -1251,6 +1251,13 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
+ 		US_SC_DEVICE, US_PR_DEVICE, NULL,
+ 		US_FL_FIX_INQUIRY),
+ 
++/* Reported by Luciano Rocha <luciano at eurotux.com> */
++UNUSUAL_DEV( 0x0840, 0x0082, 0x0001, 0x0001,
++		"Argosy",
++		"Storage",
++		US_SC_DEVICE, US_PR_DEVICE, NULL,
++		US_FL_FIX_CAPACITY),
++
+ /* Entry and supporting patch by Theodore Kilgore <kilgota at auburn.edu>.
+  * Flag will support Bulk devices which use a standards-violating 32-byte
+  * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with
+diff --git a/fs/namespace.c b/fs/namespace.c
+index 6e283c9..1bd5ba2 100644
+--- a/fs/namespace.c
++++ b/fs/namespace.c
+@@ -1553,8 +1553,13 @@ static noinline int do_remount(struct nameidata *nd, int flags, int mnt_flags,
+ 	if (!err)
+ 		nd->path.mnt->mnt_flags = mnt_flags;
+ 	up_write(&sb->s_umount);
+-	if (!err)
++	if (!err) {
+ 		security_sb_post_remount(nd->path.mnt, flags, data);
++
++		spin_lock(&vfsmount_lock);
++		touch_mnt_namespace(nd->path.mnt->mnt_ns);
++		spin_unlock(&vfsmount_lock);
++	}
+ 	return err;
+ }
+ 
+diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
+index f9a8b89..7a510a6 100644
+--- a/fs/proc/proc_sysctl.c
++++ b/fs/proc/proc_sysctl.c
+@@ -31,6 +31,7 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
+ 	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
+ 	inode->i_flags |= S_PRIVATE; /* tell selinux to ignore this inode */
+ 	inode->i_mode = table->mode;
++	inode->i_uid = inode->i_gid = 0;
+ 	if (!table->child) {
+ 		inode->i_mode |= S_IFREG;
+ 		inode->i_op = &proc_sys_inode_operations;
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index 0933a14..3d83947 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -98,6 +98,13 @@ struct bio {
+ 	unsigned int		bi_size;	/* residual I/O count */
+ 
+ 	/*
++	 * To keep track of the max segment size, we account for the
++	 * sizes of the first and last mergeable segments in this bio.
++	 */
++	unsigned int            bi_seg_front_size;
++	unsigned int            bi_seg_back_size;
++
++	/*
+ 	 * To keep track of the max hw size, we account for the
+ 	 * sizes of the first and last virtually mergeable segments
+ 	 * in this bio
+diff --git a/include/linux/usb.h b/include/linux/usb.h
+index 94ac74a..2e434dc 100644
+--- a/include/linux/usb.h
++++ b/include/linux/usb.h
+@@ -108,6 +108,7 @@ enum usb_interface_condition {
+  *	(in probe()), bound to a driver, or unbinding (in disconnect())
+  * @is_active: flag set when the interface is bound and not suspended.
+  * @sysfs_files_created: sysfs attributes exist
++ * @unregistering: flag set when the interface is being unregistered
+  * @needs_remote_wakeup: flag set when the driver requires remote-wakeup
+  *	capability during autosuspend.
+  * @needs_altsetting0: flag set when a set-interface request for altsetting 0
+@@ -163,6 +164,7 @@ struct usb_interface {
+ 	enum usb_interface_condition condition;		/* state of binding */
+ 	unsigned is_active:1;		/* the interface is not suspended */
+ 	unsigned sysfs_files_created:1;	/* the sysfs attributes exist */
++	unsigned unregistering:1;	/* unregistration is in progress */
+ 	unsigned needs_remote_wakeup:1;	/* driver requires remote wakeup */
+ 	unsigned needs_altsetting0:1;	/* switch to altsetting 0 is pending */
+ 	unsigned needs_binding:1;	/* needs delayed unbind/rebind */
+diff --git a/mm/hugetlb.c b/mm/hugetlb.c
+index 77427c8..81e9a82 100644
+--- a/mm/hugetlb.c
++++ b/mm/hugetlb.c
+@@ -1797,6 +1797,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ 					struct page *page,
+ 					unsigned long address)
+ {
++	struct hstate *h = hstate_vma(vma);
+ 	struct vm_area_struct *iter_vma;
+ 	struct address_space *mapping;
+ 	struct prio_tree_iter iter;
+@@ -1806,7 +1807,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ 	 * vm_pgoff is in PAGE_SIZE units, hence the different calculation
+ 	 * from page cache lookup which is in HPAGE_SIZE units.
+ 	 */
+-	address = address & huge_page_mask(hstate_vma(vma));
++	address = address & huge_page_mask(h);
+ 	pgoff = ((address - vma->vm_start) >> PAGE_SHIFT)
+ 		+ (vma->vm_pgoff >> PAGE_SHIFT);
+ 	mapping = (struct address_space *)page_private(page);
+@@ -1825,7 +1826,7 @@ int unmap_ref_private(struct mm_struct *mm,
+ 		 */
+ 		if (!is_vma_resv_set(iter_vma, HPAGE_RESV_OWNER))
+ 			unmap_hugepage_range(iter_vma,
+-				address, address + HPAGE_SIZE,
++				address, address + huge_page_size(h),
+ 				page);
+ 	}
+ 
+diff --git a/mm/page_isolation.c b/mm/page_isolation.c
+index b70a7fe..5e0ffd9 100644
+--- a/mm/page_isolation.c
++++ b/mm/page_isolation.c
+@@ -130,10 +130,11 @@ int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
+ 		if (page && get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
+ 			break;
+ 	}
+-	if (pfn < end_pfn)
++	page = __first_valid_page(start_pfn, end_pfn - start_pfn);
++	if ((pfn < end_pfn) || !page)
+ 		return -EBUSY;
+ 	/* Check all pages are free or Marked as ISOLATED */
+-	zone = page_zone(pfn_to_page(pfn));
++	zone = page_zone(page);
+ 	spin_lock_irqsave(&zone->lock, flags);
+ 	ret = __test_page_isolated_in_pageblock(start_pfn, end_pfn);
+ 	spin_unlock_irqrestore(&zone->lock, flags);
+diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
+index 8f5a403..a631a1f 100644
+--- a/net/ipv4/proc.c
++++ b/net/ipv4/proc.c
+@@ -237,43 +237,45 @@ static const struct snmp_mib snmp4_net_list[] = {
+ 	SNMP_MIB_SENTINEL
+ };
+ 
++static void icmpmsg_put_line(struct seq_file *seq, unsigned long *vals,
++			     unsigned short *type, int count)
++{
++	int j;
++
++	if (count) {
++		seq_printf(seq, "\nIcmpMsg:");
++		for (j = 0; j < count; ++j)
++			seq_printf(seq, " %sType%u",
++				type[j] & 0x100 ? "Out" : "In",
++				type[j] & 0xff);
++		seq_printf(seq, "\nIcmpMsg:");
++		for (j = 0; j < count; ++j)
++			seq_printf(seq, " %lu", vals[j]);
++	}
++}
++
+ static void icmpmsg_put(struct seq_file *seq)
+ {
+ #define PERLINE	16
+ 
+-	int j, i, count;
+-	static int out[PERLINE];
++	int i, count;
++	unsigned short type[PERLINE];
++	unsigned long vals[PERLINE], val;
+ 	struct net *net = seq->private;
+ 
+ 	count = 0;
+ 	for (i = 0; i < ICMPMSG_MIB_MAX; i++) {
+-
+-		if (snmp_fold_field((void **) net->mib.icmpmsg_statistics, i))
+-			out[count++] = i;
+-		if (count < PERLINE)
+-			continue;
+-
+-		seq_printf(seq, "\nIcmpMsg:");
+-		for (j = 0; j < PERLINE; ++j)
+-			seq_printf(seq, " %sType%u", i & 0x100 ? "Out" : "In",
+-					i & 0xff);
+-		seq_printf(seq, "\nIcmpMsg: ");
+-		for (j = 0; j < PERLINE; ++j)
+-			seq_printf(seq, " %lu",
+-				snmp_fold_field((void **) net->mib.icmpmsg_statistics,
+-				out[j]));
+-		seq_putc(seq, '\n');
+-	}
+-	if (count) {
+-		seq_printf(seq, "\nIcmpMsg:");
+-		for (j = 0; j < count; ++j)
+-			seq_printf(seq, " %sType%u", out[j] & 0x100 ? "Out" :
+-				"In", out[j] & 0xff);
+-		seq_printf(seq, "\nIcmpMsg:");
+-		for (j = 0; j < count; ++j)
+-			seq_printf(seq, " %lu", snmp_fold_field((void **)
+-				net->mib.icmpmsg_statistics, out[j]));
++		val = snmp_fold_field((void **) net->mib.icmpmsg_statistics, i);
++		if (val) {
++			type[count] = i;
++			vals[count++] = val;
++		}
++		if (count == PERLINE) {
++			icmpmsg_put_line(seq, vals, type, count);
++			count = 0;
++		}
+ 	}
++	icmpmsg_put_line(seq, vals, type, count);
+ 
+ #undef PERLINE
+ }
+diff --git a/scripts/package/builddeb b/scripts/package/builddeb
+index ba6bf5d..1264b8e 100644
+--- a/scripts/package/builddeb
++++ b/scripts/package/builddeb
+@@ -15,15 +15,18 @@ set -e
+ version=$KERNELRELEASE
+ revision=`cat .version`
+ tmpdir="$objtree/debian/tmp"
++fwdir="$objtree/debian/fwtmp"
+ packagename=linux-$version
++fwpackagename=linux-firmware-image
+ 
+ if [ "$ARCH" == "um" ] ; then
+ 	packagename=user-mode-linux-$version
+ fi
+ 
+ # Setup the directory structure
+-rm -rf "$tmpdir"
++rm -rf "$tmpdir" "$fwdir"
+ mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot"
++mkdir -p "$fwdir/DEBIAN" "$fwdir/lib"
+ if [ "$ARCH" == "um" ] ; then
+ 	mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/share/doc/$packagename" "$tmpdir/usr/bin"
+ fi
+@@ -107,6 +110,7 @@ Standards-Version: 3.6.1
+ 
+ Package: $packagename
+ Provides: kernel-image-$version, linux-image-$version
++Suggests: $fwpackagename
+ Architecture: any
+ Description: Linux kernel, version $version
+  This package contains the Linux kernel, modules and corresponding other
+@@ -118,8 +122,24 @@ fi
+ chown -R root:root "$tmpdir"
+ chmod -R go-w "$tmpdir"
+ 
++# Do we have firmware? Move it out of the way and build it into a package.
++if [ -e "$tmpdir/lib/firmware" ]; then
++	mv "$tmpdir/lib/firmware" "$fwdir/lib/"
++
++	cat <<EOF >> debian/control
++
++Package: $fwpackagename
++Architecture: all
++Description: Linux kernel firmware, version $version
++ This package contains firmware from the Linux kernel, version $version
++EOF
++
++	dpkg-gencontrol -isp -p$fwpackagename -P"$fwdir"
++	dpkg --build "$fwdir" ..
++fi
++
+ # Perform the final magic
+-dpkg-gencontrol -isp
++dpkg-gencontrol -isp -p$packagename
+ dpkg --build "$tmpdir" ..
+ 
+ exit 0

Modified: dists/trunk/linux-2.6/debian/patches/series/1~experimental.1
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	(original)
+++ dists/trunk/linux-2.6/debian/patches/series/1~experimental.1	Sat Nov 22 16:11:56 2008
@@ -31,3 +31,4 @@
 + bugfix/all/stable/patch-2.6.27.4
 + bugfix/all/stable/patch-2.6.27.5
 + bugfix/all/stable/patch-2.6.27.6
++ bugfix/all/stable/patch-2.6.27.7



More information about the Kernel-svn-changes mailing list