Bladeren bron

Merge of /home/davem/src/GIT/linux-2.6/.git/

David S. Miller 20 jaren geleden
bovenliggende
commit
4b463f7858

+ 1 - 1
Makefile

@@ -1,7 +1,7 @@
 VERSION = 2
 VERSION = 2
 PATCHLEVEL = 6
 PATCHLEVEL = 6
 SUBLEVEL = 12
 SUBLEVEL = 12
-EXTRAVERSION =-rc4
+EXTRAVERSION =-rc5
 NAME=Woozy Numbat
 NAME=Woozy Numbat
 
 
 # *DOCUMENTATION*
 # *DOCUMENTATION*

+ 8 - 9
arch/i386/mach-voyager/voyager_smp.c

@@ -97,7 +97,6 @@ static void ack_vic_irq(unsigned int irq);
 static void vic_enable_cpi(void);
 static void vic_enable_cpi(void);
 static void do_boot_cpu(__u8 cpuid);
 static void do_boot_cpu(__u8 cpuid);
 static void do_quad_bootstrap(void);
 static void do_quad_bootstrap(void);
-static inline void wrapper_smp_local_timer_interrupt(struct pt_regs *);
 
 
 int hard_smp_processor_id(void);
 int hard_smp_processor_id(void);
 
 
@@ -125,6 +124,14 @@ send_QIC_CPI(__u32 cpuset, __u8 cpi)
 	}
 	}
 }
 }
 
 
+static inline void
+wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
+{
+	irq_enter();
+	smp_local_timer_interrupt(regs);
+	irq_exit();
+}
+
 static inline void
 static inline void
 send_one_CPI(__u8 cpu, __u8 cpi)
 send_one_CPI(__u8 cpu, __u8 cpi)
 {
 {
@@ -1249,14 +1256,6 @@ smp_vic_timer_interrupt(struct pt_regs *regs)
 	smp_local_timer_interrupt(regs);
 	smp_local_timer_interrupt(regs);
 }
 }
 
 
-static inline void
-wrapper_smp_local_timer_interrupt(struct pt_regs *regs)
-{
-	irq_enter();
-	smp_local_timer_interrupt(regs);
-	irq_exit();
-}
-
 /* local (per CPU) timer interrupt.  It does both profiling and
 /* local (per CPU) timer interrupt.  It does both profiling and
  * process statistics/rescheduling.
  * process statistics/rescheduling.
  *
  *

+ 65 - 20
arch/ppc64/kernel/mf.c

@@ -1,7 +1,7 @@
 /*
 /*
   * mf.c
   * mf.c
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
   * Copyright (C) 2001 Troy D. Armstrong  IBM Corporation
-  * Copyright (C) 2004 Stephen Rothwell  IBM Corporation
+  * Copyright (C) 2004-2005 Stephen Rothwell  IBM Corporation
   *
   *
   * This modules exists as an interface between a Linux secondary partition
   * This modules exists as an interface between a Linux secondary partition
   * running on an iSeries and the primary partition's Virtual Service
   * running on an iSeries and the primary partition's Virtual Service
@@ -36,10 +36,12 @@
 
 
 #include <asm/time.h>
 #include <asm/time.h>
 #include <asm/uaccess.h>
 #include <asm/uaccess.h>
+#include <asm/paca.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/vio.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/mf.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/HvLpConfig.h>
 #include <asm/iSeries/ItSpCommArea.h>
 #include <asm/iSeries/ItSpCommArea.h>
+#include <asm/iSeries/ItLpQueue.h>
 
 
 /*
 /*
  * This is the structure layout for the Machine Facilites LPAR event
  * This is the structure layout for the Machine Facilites LPAR event
@@ -696,36 +698,23 @@ static void get_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
 	complete(&rtc->com);
 	complete(&rtc->com);
 }
 }
 
 
-int mf_get_rtc(struct rtc_time *tm)
+static int rtc_set_tm(int rc, u8 *ce_msg, struct rtc_time *tm)
 {
 {
-	struct ce_msg_comp_data ce_complete;
-	struct rtc_time_data rtc_data;
-	int rc;
-
-	memset(&ce_complete, 0, sizeof(ce_complete));
-	memset(&rtc_data, 0, sizeof(rtc_data));
-	init_completion(&rtc_data.com);
-	ce_complete.handler = &get_rtc_time_complete;
-	ce_complete.token = &rtc_data;
-	rc = signal_ce_msg_simple(0x40, &ce_complete);
-	if (rc)
-		return rc;
-	wait_for_completion(&rtc_data.com);
 	tm->tm_wday = 0;
 	tm->tm_wday = 0;
 	tm->tm_yday = 0;
 	tm->tm_yday = 0;
 	tm->tm_isdst = 0;
 	tm->tm_isdst = 0;
-	if (rtc_data.rc) {
+	if (rc) {
 		tm->tm_sec = 0;
 		tm->tm_sec = 0;
 		tm->tm_min = 0;
 		tm->tm_min = 0;
 		tm->tm_hour = 0;
 		tm->tm_hour = 0;
 		tm->tm_mday = 15;
 		tm->tm_mday = 15;
 		tm->tm_mon = 5;
 		tm->tm_mon = 5;
 		tm->tm_year = 52;
 		tm->tm_year = 52;
-		return rtc_data.rc;
+		return rc;
 	}
 	}
 
 
-	if ((rtc_data.ce_msg.ce_msg[2] == 0xa9) ||
-	    (rtc_data.ce_msg.ce_msg[2] == 0xaf)) {
+	if ((ce_msg[2] == 0xa9) ||
+	    (ce_msg[2] == 0xaf)) {
 		/* TOD clock is not set */
 		/* TOD clock is not set */
 		tm->tm_sec = 1;
 		tm->tm_sec = 1;
 		tm->tm_min = 1;
 		tm->tm_min = 1;
@@ -736,7 +725,6 @@ int mf_get_rtc(struct rtc_time *tm)
 		mf_set_rtc(tm);
 		mf_set_rtc(tm);
 	}
 	}
 	{
 	{
-		u8 *ce_msg = rtc_data.ce_msg.ce_msg;
 		u8 year = ce_msg[5];
 		u8 year = ce_msg[5];
 		u8 sec = ce_msg[6];
 		u8 sec = ce_msg[6];
 		u8 min = ce_msg[7];
 		u8 min = ce_msg[7];
@@ -765,6 +753,63 @@ int mf_get_rtc(struct rtc_time *tm)
 	return 0;
 	return 0;
 }
 }
 
 
+int mf_get_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	init_completion(&rtc_data.com);
+	ce_complete.handler = &get_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	wait_for_completion(&rtc_data.com);
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
+struct boot_rtc_time_data {
+	int busy;
+	struct ce_msg_data ce_msg;
+	int rc;
+};
+
+static void get_boot_rtc_time_complete(void *token, struct ce_msg_data *ce_msg)
+{
+	struct boot_rtc_time_data *rtc = token;
+
+	memcpy(&rtc->ce_msg, ce_msg, sizeof(rtc->ce_msg));
+	rtc->rc = 0;
+	rtc->busy = 0;
+}
+
+int mf_get_boot_rtc(struct rtc_time *tm)
+{
+	struct ce_msg_comp_data ce_complete;
+	struct boot_rtc_time_data rtc_data;
+	int rc;
+
+	memset(&ce_complete, 0, sizeof(ce_complete));
+	memset(&rtc_data, 0, sizeof(rtc_data));
+	rtc_data.busy = 1;
+	ce_complete.handler = &get_boot_rtc_time_complete;
+	ce_complete.token = &rtc_data;
+	rc = signal_ce_msg_simple(0x40, &ce_complete);
+	if (rc)
+		return rc;
+	/* We need to poll here as we are not yet taking interrupts */
+	while (rtc_data.busy) {
+		extern unsigned long lpevent_count;
+		struct ItLpQueue *lpq = get_paca()->lpqueue_ptr;
+		if (lpq && ItLpQueue_isLpIntPending(lpq))
+			lpevent_count += ItLpQueue_process(lpq, NULL);
+	}
+	return rtc_set_tm(rtc_data.rc, rtc_data.ce_msg.ce_msg, tm);
+}
+
 int mf_set_rtc(struct rtc_time *tm)
 int mf_set_rtc(struct rtc_time *tm)
 {
 {
 	char ce_time[12];
 	char ce_time[12];

+ 1 - 38
arch/ppc64/kernel/rtc.c

@@ -292,47 +292,10 @@ int iSeries_set_rtc_time(struct rtc_time *tm)
 
 
 void iSeries_get_boot_time(struct rtc_time *tm)
 void iSeries_get_boot_time(struct rtc_time *tm)
 {
 {
-	unsigned long time;
-	static unsigned long lastsec = 1;
-
-	u32 dataWord1 = *((u32 *)(&xSpCommArea.xBcdTimeAtIplStart));
-	u32 dataWord2 = *(((u32 *)&(xSpCommArea.xBcdTimeAtIplStart)) + 1);
-	int year = 1970;
-	int year1 = ( dataWord1 >> 24 ) & 0x000000FF;
-	int year2 = ( dataWord1 >> 16 ) & 0x000000FF;
-	int sec = ( dataWord1 >> 8 ) & 0x000000FF;
-	int min = dataWord1 & 0x000000FF;
-	int hour = ( dataWord2 >> 24 ) & 0x000000FF;
-	int day = ( dataWord2 >> 8 ) & 0x000000FF;
-	int mon = dataWord2 & 0x000000FF;
-
 	if ( piranha_simulator )
 	if ( piranha_simulator )
 		return;
 		return;
 
 
-	BCD_TO_BIN(sec);
-	BCD_TO_BIN(min);
-	BCD_TO_BIN(hour);
-	BCD_TO_BIN(day);
-	BCD_TO_BIN(mon);
-	BCD_TO_BIN(year1);
-	BCD_TO_BIN(year2);
-	year = year1 * 100 + year2;
-
-	time = mktime(year, mon, day, hour, min, sec);
-	time += ( jiffies / HZ );
-
-	/* Now THIS is a nasty hack!
-	* It ensures that the first two calls get different answers.  
-	* That way the loop in init_time (time.c) will not think
-	* the clock is stuck.
-	*/
-	if ( lastsec ) {
-		time -= lastsec;
-		--lastsec;
-	}
-
-	to_tm(time, tm); 
-	tm->tm_year -= 1900;
+	mf_get_boot_rtc(tm);
 	tm->tm_mon  -= 1;
 	tm->tm_mon  -= 1;
 }
 }
 #endif
 #endif

+ 1 - 0
arch/ppc64/kernel/time.c

@@ -515,6 +515,7 @@ void __init time_init(void)
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.varp = &do_gtod.vars[0];
 	do_gtod.var_idx = 0;
 	do_gtod.var_idx = 0;
 	do_gtod.varp->tb_orig_stamp = tb_last_stamp;
 	do_gtod.varp->tb_orig_stamp = tb_last_stamp;
+	get_paca()->next_jiffy_update_tb = tb_last_stamp + tb_ticks_per_jiffy;
 	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
 	do_gtod.varp->stamp_xsec = xtime.tv_sec * XSEC_PER_SEC;
 	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
 	do_gtod.tb_ticks_per_sec = tb_ticks_per_sec;
 	do_gtod.varp->tb_to_xs = tb_to_xs;
 	do_gtod.varp->tb_to_xs = tb_to_xs;

+ 1 - 1
drivers/ide/ide-cd.c

@@ -1933,7 +1933,7 @@ static ide_startstop_t cdrom_do_block_pc(ide_drive_t *drive, struct request *rq)
 		/*
 		/*
 		 * check if dma is safe
 		 * check if dma is safe
 		 */
 		 */
-		if ((rq->data_len & mask) || (addr & mask))
+		if ((rq->data_len & 3) || (addr & mask))
 			info->dma = 0;
 			info->dma = 0;
 	}
 	}
 
 

+ 5 - 5
drivers/media/video/saa7134/saa6752hs.c

@@ -43,15 +43,15 @@ enum saa6752hs_videoformat {
 static const struct v4l2_format v4l2_format_table[] =
 static const struct v4l2_format v4l2_format_table[] =
 {
 {
 	[SAA6752HS_VF_D1] = {
 	[SAA6752HS_VF_D1] = {
-		.fmt.pix.width = 720, .fmt.pix.height = 576 },
+		.fmt = { .pix = { .width = 720, .height = 576 }, }, },
 	[SAA6752HS_VF_2_3_D1] = {
 	[SAA6752HS_VF_2_3_D1] = {
-		.fmt.pix.width = 480, .fmt.pix.height = 576 },
+		.fmt = { .pix = { .width = 480, .height = 576 }, }, },
 	[SAA6752HS_VF_1_2_D1] = {
 	[SAA6752HS_VF_1_2_D1] = {
-		.fmt.pix.width = 352, .fmt.pix.height = 576 },
+		.fmt = { .pix = { .width = 352, .height = 576 }, }, },
 	[SAA6752HS_VF_SIF] = {
 	[SAA6752HS_VF_SIF] = {
-		.fmt.pix.width = 352, .fmt.pix.height = 288 },
+		.fmt = { .pix = { .width = 352, .height = 288 }, }, },
 	[SAA6752HS_VF_UNKNOWN] = {
 	[SAA6752HS_VF_UNKNOWN] = {
-		.fmt.pix.width = 0, .fmt.pix.height = 0},
+		.fmt = { .pix = { .width = 0, .height = 0 }, }, },
 };
 };
 
 
 struct saa6752hs_state {
 struct saa6752hs_state {

+ 5 - 2
drivers/scsi/aic7xxx/aic7xxx_osm.c

@@ -659,8 +659,11 @@ ahc_linux_slave_alloc(struct scsi_device *device)
 	ahc_lock(ahc, &flags);
 	ahc_lock(ahc, &flags);
 	targ = ahc->platform_data->targets[target_offset];
 	targ = ahc->platform_data->targets[target_offset];
 	if (targ == NULL) {
 	if (targ == NULL) {
-		targ = ahc_linux_alloc_target(ahc, starget->channel, starget->id);
-		struct seeprom_config *sc = ahc->seep_config;
+		struct seeprom_config *sc;
+
+		targ = ahc_linux_alloc_target(ahc, starget->channel,
+						starget->id);
+		sc = ahc->seep_config;
 		if (targ == NULL)
 		if (targ == NULL)
 			goto out;
 			goto out;
 
 

+ 2 - 0
drivers/usb/atm/speedtch.c

@@ -386,6 +386,8 @@ static void speedtch_poll_status(struct speedtch_instance_data *instance)
 		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
 		if (instance->u.atm_dev->signal != ATM_PHY_SIG_LOST) {
 			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
 			instance->u.atm_dev->signal = ATM_PHY_SIG_LOST;
 			printk(KERN_NOTICE "ADSL line is down\n");
 			printk(KERN_NOTICE "ADSL line is down\n");
+			/* It'll never resync again unless we ask it to... */
+			speedtch_start_synchro(instance);
 		}
 		}
 		break;
 		break;
 
 

+ 1 - 0
include/asm-ppc64/iSeries/mf.h

@@ -52,6 +52,7 @@ extern void mf_clear_src(void);
 extern void mf_init(void);
 extern void mf_init(void);
 
 
 extern int mf_get_rtc(struct rtc_time *tm);
 extern int mf_get_rtc(struct rtc_time *tm);
+extern int mf_get_boot_rtc(struct rtc_time *tm);
 extern int mf_set_rtc(struct rtc_time *tm);
 extern int mf_set_rtc(struct rtc_time *tm);
 
 
 #endif /* _ASM_PPC64_ISERIES_MF_H */
 #endif /* _ASM_PPC64_ISERIES_MF_H */

+ 10 - 1
kernel/signal.c

@@ -522,7 +522,16 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask,
 {
 {
 	int sig = 0;
 	int sig = 0;
 
 
-	sig = next_signal(pending, mask);
+	/* SIGKILL must have priority, otherwise it is quite easy
+	 * to create an unkillable process, sending sig < SIGKILL
+	 * to self */
+	if (unlikely(sigismember(&pending->signal, SIGKILL))) {
+		if (!sigismember(mask, SIGKILL))
+			sig = SIGKILL;
+	}
+
+	if (likely(!sig))
+		sig = next_signal(pending, mask);
 	if (sig) {
 	if (sig) {
 		if (current->notifier) {
 		if (current->notifier) {
 			if (sigismember(current->notifier_mask, sig)) {
 			if (sigismember(current->notifier_mask, sig)) {

+ 3 - 3
mm/rmap.c

@@ -626,7 +626,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
 	pgd_t *pgd;
 	pgd_t *pgd;
 	pud_t *pud;
 	pud_t *pud;
 	pmd_t *pmd;
 	pmd_t *pmd;
-	pte_t *pte;
+	pte_t *pte, *original_pte;
 	pte_t pteval;
 	pte_t pteval;
 	struct page *page;
 	struct page *page;
 	unsigned long address;
 	unsigned long address;
@@ -658,7 +658,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
 	if (!pmd_present(*pmd))
 	if (!pmd_present(*pmd))
 		goto out_unlock;
 		goto out_unlock;
 
 
-	for (pte = pte_offset_map(pmd, address);
+	for (original_pte = pte = pte_offset_map(pmd, address);
 			address < end; pte++, address += PAGE_SIZE) {
 			address < end; pte++, address += PAGE_SIZE) {
 
 
 		if (!pte_present(*pte))
 		if (!pte_present(*pte))
@@ -694,7 +694,7 @@ static void try_to_unmap_cluster(unsigned long cursor,
 		(*mapcount)--;
 		(*mapcount)--;
 	}
 	}
 
 
-	pte_unmap(pte);
+	pte_unmap(original_pte);
 out_unlock:
 out_unlock:
 	spin_unlock(&mm->page_table_lock);
 	spin_unlock(&mm->page_table_lock);
 }
 }