diff options
28 files changed, 223 insertions, 153 deletions
diff --git a/Documentation/filesystems/ntfs.txt b/Documentation/filesystems/ntfs.txt index 13ba649bda7..81779068b09 100644 --- a/Documentation/filesystems/ntfs.txt +++ b/Documentation/filesystems/ntfs.txt @@ -457,6 +457,8 @@ ChangeLog Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. +2.1.28: + - Fix a deadlock. 2.1.27: - Implement page migration support so the kernel can move memory used by NTFS files and directories around for management purposes. diff --git a/Documentation/hwmon/w83793 b/Documentation/hwmon/w83793 index 45e5408340e..51171a83165 100644 --- a/Documentation/hwmon/w83793 +++ b/Documentation/hwmon/w83793 @@ -45,18 +45,14 @@ This driver implements support for Winbond W83793G/W83793R chips. temp5-6 have a 1 degree Celsiis resolution. * Temperature sensor types - Temp1-4 have 3 possible types. It can be read from (and written to) + Temp1-4 have 2 possible types. It can be read from (and written to) temp[1-4]_type. - - If the value of 0, the related temperature channel stops - monitoring. - If the value is 3, it starts monitoring using a remote termal diode (default). - - If the value is 5, it starts monitoring using the temperature sensor - in AMD CPU and get result by AMDSI. - If the value is 6, it starts monitoring using the temperature sensor in Intel CPU and get result by PECI. Temp5-6 can be connected to external thermistors (value of - temp[5-6]_type is 4). They can also be disabled (value is 0). + temp[5-6]_type is 4). * Alarm mechanism For voltage sensors, an alarm triggers if the measured value is below diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 802febed7df..a8b387197d5 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c @@ -261,6 +261,7 @@ void smtc_configure_tlb(void) } } write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); + ehb(); /* * Setup kernel data structures to use software total, diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 2e0e21ef433..65160d4984d 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c @@ -106,7 +106,6 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, ENTER_CRITICAL(flags); size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; size = (size + 1) >> 1; - local_irq_save(flags); if (size <= current_cpu_data.tlbsize/2) { int oldpid = read_c0_entryhi(); int newpid = cpu_asid(cpu, mm); diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 4f1813e0475..f5c160caf9f 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -293,8 +293,8 @@ static int mmap_kmem(struct file * file, struct vm_area_struct * vma) { unsigned long pfn; - /* Turn a pfn offset into an absolute pfn */ - pfn = PFN_DOWN(virt_to_phys((void *)PAGE_OFFSET)) + vma->vm_pgoff; + /* Turn a kernel-virtual address into a physical page frame */ + pfn = __pa((u64)vma->vm_pgoff << PAGE_SHIFT) >> PAGE_SHIFT; /* * RED-PEN: on some architectures there is more mapped memory diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c index 31c42002708..b80f6ed5acf 100644 --- a/drivers/hwmon/hwmon-vid.c +++ b/drivers/hwmon/hwmon-vid.c @@ -93,7 +93,7 @@ int vid_from_reg(int val, u8 vrm) case 110: /* Intel Conroe */ /* compute in uV, round to mV */ val &= 0xff; - if(((val & 0x7e) == 0xfe) || (!(val & 0x7e))) + if (val < 0x02 || val > 0xb2) return 0; return((1600000 - (val - 2) * 6250 + 500) / 1000); case 24: /* Opteron processor */ diff --git a/drivers/hwmon/w83793.c b/drivers/hwmon/w83793.c index c12ac5abc2b..253ffaf1568 100644 --- a/drivers/hwmon/w83793.c +++ b/drivers/hwmon/w83793.c @@ -117,6 +117,7 @@ static const u16 W83793_REG_IN[][3] = { /* Low Bits of Vcore A/B Vtt Read/High/Low */ static const u16 W83793_REG_IN_LOW_BITS[] = { 0x1b, 0x68, 0x69 }; static u8 scale_in[] = { 2, 2, 2, 16, 16, 16, 8, 24, 24, 16 }; +static u8 scale_in_add[] = { 0, 0, 0, 0, 0, 0, 0, 150, 150, 0 }; #define W83793_REG_FAN(index) (0x23 + 2 * (index)) /* High byte */ #define W83793_REG_FAN_MIN(index) (0x90 + 2 * (index)) /* High byte */ @@ -203,6 +204,8 @@ struct w83793_data { u8 temp_fan_map[6]; /* Temp controls which pwm fan, bit field */ u8 has_pwm; + u8 has_temp; + u8 has_vid; u8 pwm_enable; /* Register value, each Temp has 1 bit */ u8 pwm_uptime; /* Register value */ u8 pwm_downtime; /* Register value */ @@ -500,7 +503,7 @@ store_temp(struct device *dev, struct device_attribute *attr, each has 4 mode:(2 bits) 0: Stop monitor 1: Use internal temp sensor(default) - 2: Use sensor in AMD CPU and get result by AMDSI + 2: Reserved 3: Use sensor in Intel CPU and get result by PECI TR1-TR2 @@ -509,8 +512,8 @@ store_temp(struct device *dev, struct device_attribute *attr, 1: To enable temp sensors monitor */ -/* 0 disable, 5 AMDSI, 6 PECI */ -static u8 TO_TEMP_MODE[] = { 0, 0, 5, 6 }; +/* 0 disable, 6 PECI */ +static u8 TO_TEMP_MODE[] = { 0, 0, 0, 6 }; static ssize_t show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) @@ -550,11 +553,10 @@ store_temp_mode(struct device *dev, struct device_attribute *attr, u8 val = simple_strtoul(buf, NULL, 10); /* transform the sysfs interface values into table above */ - if ((val == 5 || val == 6) && (index < 4)) { + if ((val == 6) && (index < 4)) { val -= 3; } else if ((val == 3 && index < 4) - || (val == 4 && index >= 4) - || val == 0) { + || (val == 4 && index >= 4)) { /* transform diode or thermistor into internal enable */ val = !!val; } else { @@ -839,7 +841,9 @@ show_in(struct device *dev, struct device_attribute *attr, char *buf) val <<= 2; val += (data->in_low_bits[nr] >> (index * 2)) & 0x3; } - return sprintf(buf, "%d\n", val * scale_in[index]); + /* voltage inputs 5VDD and 5VSB needs 150mV offset */ + val = val * scale_in[index] + scale_in_add[index]; + return sprintf(buf, "%d\n", val); } static ssize_t @@ -859,6 +863,10 @@ store_in(struct device *dev, struct device_attribute *attr, scale_in[index] / 2) / scale_in[index]; mutex_lock(&data->update_lock); if (index > 2) { + /* fix the limit values of 5VDD and 5VSB to ALARM mechanism */ + if (1 == nr || 2 == nr) { + val -= scale_in_add[index] / scale_in[index]; + } val = SENSORS_LIMIT(val, 0, 255); } else { val = SENSORS_LIMIT(val, 0, 0x3FF); @@ -979,12 +987,6 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_IN(7), SENSOR_ATTR_IN(8), SENSOR_ATTR_IN(9), - SENSOR_ATTR_TEMP(1), - SENSOR_ATTR_TEMP(2), - SENSOR_ATTR_TEMP(3), - SENSOR_ATTR_TEMP(4), - SENSOR_ATTR_TEMP(5), - SENSOR_ATTR_TEMP(6), SENSOR_ATTR_FAN(1), SENSOR_ATTR_FAN(2), SENSOR_ATTR_FAN(3), @@ -995,6 +997,15 @@ static struct sensor_device_attribute_2 w83793_sensor_attr_2[] = { SENSOR_ATTR_PWM(3), }; +static struct sensor_device_attribute_2 w83793_temp[] = { + SENSOR_ATTR_TEMP(1), + SENSOR_ATTR_TEMP(2), + SENSOR_ATTR_TEMP(3), + SENSOR_ATTR_TEMP(4), + SENSOR_ATTR_TEMP(5), + SENSOR_ATTR_TEMP(6), +}; + /* Fan6-Fan12 */ static struct sensor_device_attribute_2 w83793_left_fan[] = { SENSOR_ATTR_FAN(6), @@ -1015,9 +1026,12 @@ static struct sensor_device_attribute_2 w83793_left_pwm[] = { SENSOR_ATTR_PWM(8), }; -static struct sensor_device_attribute_2 sda_single_files[] = { +static struct sensor_device_attribute_2 w83793_vid[] = { SENSOR_ATTR_2(cpu0_vid, S_IRUGO, show_vid, NULL, NOT_USED, 0), SENSOR_ATTR_2(cpu1_vid, S_IRUGO, show_vid, NULL, NOT_USED, 1), +}; + +static struct sensor_device_attribute_2 sda_single_files[] = { SENSOR_ATTR_2(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm, NOT_USED, NOT_USED), SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep, @@ -1070,11 +1084,17 @@ static int w83793_detach_client(struct i2c_client *client) for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); } if ((err = i2c_detach_client(client))) @@ -1187,6 +1207,7 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) struct w83793_data *data; int files_fan = ARRAY_SIZE(w83793_left_fan) / 7; int files_pwm = ARRAY_SIZE(w83793_left_pwm) / 5; + int files_temp = ARRAY_SIZE(w83793_temp) / 6; int err = 0; if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { @@ -1313,6 +1334,44 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) data->has_pwm |= 0x80; } + tmp = w83793_read_value(client, W83793_REG_FANIN_SEL); + if ((tmp & 0x01) && (val & 0x08)) { /* fan 9, second location */ + data->has_fan |= 0x100; + } + if ((tmp & 0x02) && (val & 0x10)) { /* fan 10, second location */ + data->has_fan |= 0x200; + } + if ((tmp & 0x04) && (val & 0x20)) { /* fan 11, second location */ + data->has_fan |= 0x400; + } + if ((tmp & 0x08) && (val & 0x40)) { /* fan 12, second location */ + data->has_fan |= 0x800; + } + + /* check the temp1-6 mode, ignore former AMDSI selected inputs */ + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[0]); + if (tmp & 0x01) + data->has_temp |= 0x01; + if (tmp & 0x04) + data->has_temp |= 0x02; + if (tmp & 0x10) + data->has_temp |= 0x04; + if (tmp & 0x40) + data->has_temp |= 0x08; + + tmp = w83793_read_value(client,W83793_REG_TEMP_MODE[1]); + if (tmp & 0x01) + data->has_temp |= 0x10; + if (tmp & 0x02) + data->has_temp |= 0x20; + + /* Detect the VID usage and ignore unused input */ + tmp = w83793_read_value(client, W83793_REG_MFC); + if (!(tmp & 0x29)) + data->has_vid |= 0x1; /* has VIDA */ + if (tmp & 0x80) + data->has_vid |= 0x2; /* has VIDB */ + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(w83793_sensor_attr_2); i++) { err = device_create_file(dev, @@ -1321,6 +1380,14 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) goto exit_remove; } + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) { + if (!(data->has_vid & (1 << i))) + continue; + err = device_create_file(dev, &w83793_vid[i].dev_attr); + if (err) + goto exit_remove; + } + for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { err = device_create_file(dev, &sda_single_files[i].dev_attr); if (err) @@ -1328,6 +1395,19 @@ static int w83793_detect(struct i2c_adapter *adapter, int address, int kind) } + for (i = 0; i < 6; i++) { + int j; + if (!(data->has_temp & (1 << i))) + continue; + for (j = 0; j < files_temp; j++) { + err = device_create_file(dev, + &w83793_temp[(i) * files_temp + + j].dev_attr); + if (err) + goto exit_remove; + } + } + for (i = 5; i < 12; i++) { int j; if (!(data->has_fan & (1 << i))) @@ -1371,12 +1451,18 @@ exit_remove: for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) device_remove_file(dev, &sda_single_files[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_vid); i++) + device_remove_file(dev, &w83793_vid[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_left_fan); i++) device_remove_file(dev, &w83793_left_fan[i].dev_attr); for (i = 0; i < ARRAY_SIZE(w83793_left_pwm); i++) device_remove_file(dev, &w83793_left_pwm[i].dev_attr); + for (i = 0; i < ARRAY_SIZE(w83793_temp); i++) + device_remove_file(dev, &w83793_temp[i].dev_attr); + if (data->lm75[0] != NULL) { i2c_detach_client(data->lm75[0]); kfree(data->lm75[0]); @@ -1428,6 +1514,8 @@ static void w83793_update_nonvolatile(struct device *dev) } for (i = 0; i < ARRAY_SIZE(data->temp_fan_map); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp_fan_map[i] = w83793_read_value(client, W83793_REG_TEMP_FAN_MAP(i)); for (j = 1; j < 5; j++) { @@ -1510,9 +1598,12 @@ static struct w83793_data *w83793_update_device(struct device *dev) w83793_read_value(client, W83793_REG_FAN(i) + 1); } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) + for (i = 0; i < ARRAY_SIZE(data->temp); i++) { + if (!(data->has_temp & (1 << i))) + continue; data->temp[i][TEMP_READ] = w83793_read_value(client, W83793_REG_TEMP[i][TEMP_READ]); + } data->temp_low_bits = w83793_read_value(client, W83793_REG_TEMP_LOW_BITS); @@ -1527,8 +1618,10 @@ static struct w83793_data *w83793_update_device(struct device *dev) for (i = 0; i < ARRAY_SIZE(data->alarms); i++) data->alarms[i] = w83793_read_value(client, W83793_REG_ALARM(i)); - data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); - data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); + if (data->has_vid & 0x01) + data->vid[0] = w83793_read_value(client, W83793_REG_VID_INA); + if (data->has_vid & 0x02) + data->vid[1] = w83793_read_value(client, W83793_REG_VID_INB); w83793_update_nonvolatile(dev); data->last_updated = jiffies; data->valid = 1; diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 3482e0114d4..2bd84d351a1 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -38,6 +38,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/errno.h> +#include <linux/freezer.h> #include <linux/kernel.h> #include <linux/slab.h> #include <linux/mm.h> @@ -961,6 +962,7 @@ int cx88_audio_thread(void *data) msleep_interruptible(1000); if (kthread_should_stop()) break; + try_to_freeze(); /* just monitor the audio status for now ... */ memset(&t, 0, sizeof(t)); diff --git a/drivers/media/video/ks0127.c b/drivers/media/video/ks0127.c index c1a377f797d..b6cd21e6dab 100644 --- a/drivers/media/video/ks0127.c +++ b/drivers/media/video/ks0127.c @@ -712,13 +712,13 @@ static int ks0127_command(struct i2c_client *client, *iarg = 0; status = ks0127_read(ks, KS_STAT); if (!(status & 0x20)) /* NOVID not set */ - *iarg = (*iarg & DECODER_STATUS_GOOD); + *iarg = (*iarg | DECODER_STATUS_GOOD); if ((status & 0x01)) /* CLOCK set */ - *iarg = (*iarg & DECODER_STATUS_COLOR); + *iarg = (*iarg | DECODER_STATUS_COLOR); if ((status & 0x08)) /* PALDET set */ - *iarg = (*iarg & DECODER_STATUS_PAL); + *iarg = (*iarg | DECODER_STATUS_PAL); else - *iarg = (*iarg & DECODER_STATUS_NTSC); + *iarg = (*iarg | DECODER_STATUS_NTSC); break; //Catch any unknown command diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c index 4dead84aff4..ae984bbe36b 100644 --- a/drivers/media/video/saa7134/saa7134-cards.c +++ b/drivers/media/video/saa7134/saa7134-cards.c @@ -2570,6 +2570,7 @@ struct saa7134_board saa7134_boards[] = { .radio_type = UNSET, .tuner_addr = ADDR_UNSET, .radio_addr = ADDR_UNSET, + .gpiomask = 1 << 21, .inputs = {{ .name = name_tv, .vmux = 1, @@ -2578,15 +2579,20 @@ struct saa7134_board saa7134_boards[] = { },{ .name = name_comp1, .vmux = 3, - .amux = LINE1, + .amux = LINE2, /* unconfirmed, taken from Philips driver */ + },{ + .name = name_comp2, + .vmux = 0, /* untested, Composite over S-Video */ + .amux = LINE2, },{ .name = name_svideo, - .vmux = 0, - .amux = LINE1, + .vmux = 8, + .amux = LINE2, }}, .radio = { .name = name_radio, - .amux = LINE1, + .amux = TV, + .gpio = 0x0200000, }, }, [SAA7134_BOARD_CINERGY250PCI] = { diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index 2624e3f7dd2..4e7c1fa668d 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c @@ -184,7 +184,7 @@ hauppauge_tuner[] = { TUNER_ABSENT, "Thompson DTT757"}, /* 80-89 */ { TUNER_ABSENT, "Philips FQ1216LME MK3"}, - { TUNER_ABSENT, "LG TAPC G701D"}, + { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"}, { TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"}, { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"}, { TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"}, diff --git a/drivers/media/video/usbvideo/quickcam_messenger.h b/drivers/media/video/usbvideo/quickcam_messenger.h index baab9c081b5..17ace394d98 100644 --- a/drivers/media/video/usbvideo/quickcam_messenger.h +++ b/drivers/media/video/usbvideo/quickcam_messenger.h @@ -35,27 +35,13 @@ struct rgb { }; struct bayL0 { -#ifdef __BIG_ENDIAN - u8 r; - u8 g; -#elif __LITTLE_ENDIAN u8 g; u8 r; -#else -#error not byte order defined -#endif }; struct bayL1 { -#ifdef __BIG_ENDIAN - u8 g; - u8 b; -#elif __LITTLE_ENDIAN u8 b; u8 g; -#else -#error not byte order defined -#endif }; struct cam_size { diff --git a/drivers/media/video/usbvision/usbvision-video.c b/drivers/media/video/usbvision/usbvision-video.c index 8c7eba2a728..7243337b771 100644 --- a/drivers/media/video/usbvision/usbvision-video.c +++ b/drivers/media/video/usbvision/usbvision-video.c @@ -1080,7 +1080,6 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf, int noblock = file->f_flags & O_NONBLOCK; unsigned long lock_flags; - int frmx = -1; int ret,i; struct usbvision_frame *frame; @@ -1155,7 +1154,7 @@ static ssize_t usbvision_v4l2_read(struct file *file, char *buf, frame->bytes_read = 0; /* Mark it as available to be used again. */ - usbvision->frame[frmx].grabstate = FrameState_Unused; + frame->grabstate = FrameState_Unused; /* } */ return count; diff --git a/drivers/media/video/v4l2-common.c b/drivers/media/video/v4l2-common.c index 752c82c37f5..b87d571e046 100644 --- a/drivers/media/video/v4l2-common.c +++ b/drivers/media/video/v4l2-common.c @@ -90,8 +90,15 @@ MODULE_LICENSE("GPL"); char *v4l2_norm_to_name(v4l2_std_id id) { char *name; + u32 myid = id; - switch (id) { + /* HACK: ppc32 architecture doesn't have __ucmpdi2 function to handle + 64 bit comparations. So, on that architecture, with some gcc variants, + compilation fails. Currently, the max value is 30bit wide. + */ + BUG_ON(myid != id); + + switch (myid) { case V4L2_STD_PAL: name="PAL"; break; case V4L2_STD_PAL_BG: diff --git a/drivers/media/video/video-buf.c b/drivers/media/video/video-buf.c index f429f49901b..635d102c86f 100644 --- a/drivers/media/video/video-buf.c +++ b/drivers/media/video/video-buf.c @@ -1229,7 +1229,7 @@ videobuf_vm_nopage(struct vm_area_struct *vma, unsigned long vaddr, vaddr,vma->vm_start,vma->vm_end); if (vaddr > vma->vm_end) return NOPAGE_SIGBUS; - page = alloc_page(GFP_USER); + page = alloc_page(GFP_USER | __GFP_DMA32); if (!page) return NOPAGE_OOM; clear_user_page(page_address(page), vaddr, page); diff --git a/drivers/media/video/vivi.c b/drivers/media/video/vivi.c index bacb311b4f2..d4cf5566673 100644 --- a/drivers/media/video/vivi.c +++ b/drivers/media/video/vivi.c @@ -270,10 +270,15 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, char *p,*s,*basep; struct page *pg; u8 chr,r,g,b,color; + unsigned long flags; + spinlock_t spinlock; + + spin_lock_init(&spinlock); /* Get first addr pointed to pixel position */ oldpg=get_addr_pos(pos,pages,to_addr); pg=pfn_to_page(sg_dma_address(to_addr[oldpg].sg) >> PAGE_SHIFT); + spin_lock_irqsave(&spinlock,flags); basep = kmap_atomic(pg, KM_BOUNCE_READ)+to_addr[oldpg].sg->offset; /* We will just duplicate the second pixel at the packet */ @@ -376,6 +381,8 @@ static void gen_line(struct sg_to_addr to_addr[],int inipos,int pages,int wmax, end: kunmap_atomic(basep, KM_BOUNCE_READ); + spin_unlock_irqrestore(&spinlock,flags); + } static void vivi_fillbuff(struct vivi_dev *dev,struct vivi_buffer *buf) { diff --git a/drivers/mmc/imxmmc.c b/drivers/mmc/imxmmc.c index 06e7fcd1922..bfb9ff69320 100644 --- a/drivers/mmc/imxmmc.c +++ b/drivers/mmc/imxmmc.c @@ -351,9 +351,6 @@ static void imxmci_start_cmd(struct imxmci_host *host, struct mmc_command *cmd, case MMC_RSP_R3: /* short */ cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R3; break; - case MMC_RSP_R6: /* short CRC */ - cmdat |= CMD_DAT_CONT_RESPONSE_FORMAT_R6; - break; default: break; } diff --git a/drivers/mmc/omap.c b/drivers/mmc/omap.c index 9488408308f..d30540b2761 100644 --- a/drivers/mmc/omap.c +++ b/drivers/mmc/omap.c @@ -91,7 +91,6 @@ #define DRIVER_NAME "mmci-omap" -#define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) /* Specifies how often in millisecs to poll for card status changes * when the cover switch is open */ @@ -204,18 +203,22 @@ mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd) cmdtype = 0; /* Our hardware needs to know exact type */ - switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): - /* resp 1, resp 1b */ + switch (mmc_resp_type(cmd)) { + case MMC_RSP_NONE: + break; + case MMC_RSP_R1: + case MMC_RSP_R1B: + /* resp 1, 1b, 6, 7 */ resptype = 1; break; - case RSP_TYPE(MMC_RSP_R2): + case MMC_RSP_R2: resptype = 2; break; - case RSP_TYPE(MMC_RSP_R3): + case MMC_RSP_R3: resptype = 3; break; default: + dev_err(mmc_dev(host->mmc), "Invalid response type: %04x\n", mmc_resp_type(cmd)); break; } diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index 45a9283ce49..6073d998b11 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c @@ -171,7 +171,7 @@ static void pxamci_start_cmd(struct pxamci_host *host, struct mmc_command *cmd, #define RSP_TYPE(x) ((x) & ~(MMC_RSP_BUSY|MMC_RSP_OPCODE)) switch (RSP_TYPE(mmc_resp_type(cmd))) { - case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6 */ + case RSP_TYPE(MMC_RSP_R1): /* r1, r1b, r6, r7 */ cmdat |= CMDAT_RESP_SHORT; break; case RSP_TYPE(MMC_RSP_R3): diff --git a/drivers/mmc/tifm_sd.c b/drivers/mmc/tifm_sd.c index f18ad998b3c..fa4a52886b9 100644 --- a/drivers/mmc/tifm_sd.c +++ b/drivers/mmc/tifm_sd.c @@ -173,9 +173,6 @@ static unsigned int tifm_sd_op_flags(struct mmc_command *cmd) case MMC_RSP_R3: rc |= TIFM_MMCSD_RSP_R3; break; - case MMC_RSP_R6: - rc |= TIFM_MMCSD_RSP_R6; - break; default: BUG(); } diff --git a/fs/ntfs/ChangeLog b/fs/ntfs/ChangeLog index 35cc4b1d60f..af4ef808fa9 100644 --- a/fs/ntfs/ChangeLog +++ b/fs/ntfs/ChangeLog @@ -17,6 +17,13 @@ ToDo/Notes: happen is unclear however so it is worth waiting until someone hits the problem. +2.1.28 - Fix a deadlock. + + - Fix deadlock in fs/ntfs/inode.c::ntfs_put_inode(). Thanks to Sergey + Vlasov for the report and detailed analysis of the deadlock. The fix + involved getting rid of ntfs_put_inode() altogether and hence NTFS no + longer has a ->put_inode super operation. + 2.1.27 - Various bug fixes and cleanups. - Fix two compiler warnings on Alpha. Thanks to Andrew Morton for diff --git a/fs/ntfs/Makefile b/fs/ntfs/Makefile index e27b4eacffb..82550838556 100644 --- a/fs/ntfs/Makefile +++ b/fs/ntfs/Makefile @@ -6,7 +6,7 @@ ntfs-objs := aops.o attrib.o collate.o compress.o debug.o dir.o file.o \ index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ unistr.o upcase.o -EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.27\" +EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.28\" ifeq ($(CONFIG_NTFS_DEBUG),y) EXTRA_CFLAGS += -DDEBUG diff --git a/fs/ntfs/dir.c b/fs/ntfs/dir.c index 8296c29ae3b..74f99a6a369 100644 --- a/fs/ntfs/dir.c +++ b/fs/ntfs/dir.c @@ -1,7 +1,7 @@ /** * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. * - * Copyright (c) 2001-2005 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -1249,16 +1249,12 @@ skip_index_root: /* Get the offset into the index allocation attribute. */ ia_pos = (s64)fpos - vol->mft_record_size; ia_mapping = vdir->i_mapping; - bmp_vi = ndir->itype.index.bmp_ino; - if (unlikely(!bmp_vi)) { - ntfs_debug("Inode 0x%lx, regetting index bitmap.", vdir->i_ino); - bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); - if (IS_ERR(bmp_vi)) { - ntfs_error(sb, "Failed to get bitmap attribute."); - err = PTR_ERR(bmp_vi); - goto err_out; - } - ndir->itype.index.bmp_ino = bmp_vi; + ntfs_debug("Inode 0x%lx, getting index bitmap.", vdir->i_ino); + bmp_vi = ntfs_attr_iget(vdir, AT_BITMAP, I30, 4); + if (IS_ERR(bmp_vi)) { + ntfs_error(sb, "Failed to get bitmap attribute."); + err = PTR_ERR(bmp_vi); + goto err_out; } bmp_mapping = bmp_vi->i_mapping; /* Get the starting bitmap bit position and sanity check it. */ @@ -1266,7 +1262,7 @@ skip_index_root: if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) { ntfs_error(sb, "Current index allocation position exceeds " "index bitmap size."); - goto err_out; + goto iput_err_out; } /* Get the starting bit position in the current bitmap page. */ cur_bmp_pos = bmp_pos & ((PAGE_CACHE_SIZE * 8) - 1); @@ -1282,7 +1278,7 @@ get_next_bmp_page: ntfs_error(sb, "Reading index bitmap failed."); err = PTR_ERR(bmp_page); bmp_page = NULL; - goto err_out; + goto iput_err_out; } bmp = (u8*)page_address(bmp_page); /* Find next index block in use. */ @@ -1429,6 +1425,7 @@ find_next_index_buffer: /* @ia_page is already unlocked in this case. */ ntfs_unmap_page(ia_page); ntfs_unmap_page(bmp_page); + iput(bmp_vi); goto abort; } } @@ -1439,6 +1436,7 @@ unm_EOD: ntfs_unmap_page(ia_page); } ntfs_unmap_page(bmp_page); + iput(bmp_vi); EOD: /* We are finished, set fpos to EOD. */ fpos = i_size + vol->mft_record_size; @@ -1455,8 +1453,11 @@ done: filp->f_pos = fpos; return 0; err_out: - if (bmp_page) + if (bmp_page) { ntfs_unmap_page(bmp_page); +iput_err_out: + iput(bmp_vi); + } if (ia_page) { unlock_page(ia_page); ntfs_unmap_page(ia_page); @@ -1529,14 +1530,22 @@ static int ntfs_dir_open(struct inode *vi, struct file *filp) static int ntfs_dir_fsync(struct file *filp, struct dentry *dentry, int datasync) { - struct inode *vi = dentry->d_inode; - ntfs_inode *ni = NTFS_I(vi); + struct inode *bmp_vi, *vi = dentry->d_inode; int err, ret; + ntfs_attr na; ntfs_debug("Entering for inode 0x%lx.", vi->i_ino); BUG_ON(!S_ISDIR(vi->i_mode)); - if (NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) - write_inode_now(ni->itype.index.bmp_ino, !datasync); + /* If the bitmap attribute inode is in memory sync it, too. */ + na.mft_no = vi->i_ino; + na.type = AT_BITMAP; + na.name = I30; + na.name_len = 4; + bmp_vi = ilookup5(vi->i_sb, vi->i_ino, (test_t)ntfs_test_inode, &na); + if (bmp_vi) { + write_inode_now(bmp_vi, !datasync); + iput(bmp_vi); + } ret = ntfs_write_inode(vi, 1); write_inode_now(vi, !datasync); err = sync_blockdev(vi->i_sb->s_bdev); diff --git a/fs/ntfs/inode.c b/fs/ntfs/inode.c index 247989891b4..f8bf8da67ee 100644 --- a/fs/ntfs/inode.c +++ b/fs/ntfs/inode.c @@ -1,7 +1,7 @@ /** * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. * - * Copyright (c) 2001-2006 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * * This program/include file is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as published @@ -95,7 +95,7 @@ int ntfs_test_inode(struct inode *vi, ntfs_attr *na) * If initializing the normal file/directory inode, set @na->type to AT_UNUSED. * In that case, @na->name and @na->name_len should be set to NULL and 0, * respectively. Although that is not strictly necessary as - * ntfs_read_inode_locked() will fill them in later. + * ntfs_read_locked_inode() will fill them in later. * * Return 0 on success and -errno on error. * @@ -171,8 +171,8 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *ntfs_iget(struct super_block *sb, unsigned long mft_no) { struct inode *vi; - ntfs_attr na; int err; + ntfs_attr na; na.mft_no = mft_no; na.type = AT_UNUSED; @@ -229,8 +229,8 @@ struct inode *ntfs_attr_iget(struct inode *base_vi, ATTR_TYPE type, ntfschar *name, u32 name_len) { struct inode *vi; - ntfs_attr na; int err; + ntfs_attr na; /* Make sure no one calls ntfs_attr_iget() for indices. */ BUG_ON(type == AT_INDEX_ALLOCATION); @@ -287,8 +287,8 @@ struct inode *ntfs_index_iget(struct inode *base_vi, ntfschar *name, u32 name_len) { struct inode *vi; - ntfs_attr na; int err; + ntfs_attr na; na.mft_no = base_vi->i_ino; na.type = AT_INDEX_ALLOCATION; @@ -402,7 +402,6 @@ void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) ntfs_init_runlist(&ni->attr_list_rl); lockdep_set_class(&ni->attr_list_rl.lock, &attr_list_rl_lock_class); - ni->itype.index.bmp_ino = NULL; ni->itype.index.block_size = 0; ni->itype.index.vcn_size = 0; ni->itype.index.collation_rule = 0; @@ -546,6 +545,7 @@ static int ntfs_read_locked_inode(struct inode *vi) { ntfs_volume *vol = NTFS_SB(vi->i_sb); ntfs_inode *ni; + struct inode *bvi; MFT_RECORD *m; ATTR_RECORD *a; STANDARD_INFORMATION *si; @@ -780,7 +780,6 @@ skip_attr_list_load: */ if (S_ISDIR(vi->i_mode)) { loff_t bvi_size; - struct inode *bvi; ntfs_inode *bni; INDEX_ROOT *ir; u8 *ir_end, *index_end; @@ -985,13 +984,12 @@ skip_attr_list_load: err = PTR_ERR(bvi); goto unm_err_out; } - ni->itype.index.bmp_ino = bvi; bni = NTFS_I(bvi); if (NInoCompressed(bni) || NInoEncrypted(bni) || NInoSparse(bni)) { ntfs_error(vi->i_sb, "$BITMAP attribute is compressed " "and/or encrypted and/or sparse."); - goto unm_err_out; + goto iput_unm_err_out; } /* Consistency check bitmap size vs. index allocation size. */ bvi_size = i_size_read(bvi); @@ -1000,8 +998,10 @@ skip_attr_list_load: ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) " "for index allocation (0x%llx).", bvi_size << 3, vi->i_size); - goto unm_err_out; + goto iput_unm_err_out; } + /* No longer need the bitmap attribute inode. */ + iput(bvi); skip_large_dir_stuff: /* Setup the operations for this inode. */ vi->i_op = &ntfs_dir_inode_ops; @@ -1176,7 +1176,8 @@ no_data_attr_special_case: vi->i_blocks = ni->allocated_size >> 9; ntfs_debug("Done."); return 0; - +iput_unm_err_out: + iput(bvi); unm_err_out: if (!err) err = -EIO; @@ -1697,7 +1698,7 @@ static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) vi->i_size); goto iput_unm_err_out; } - ni->itype.index.bmp_ino = bvi; + iput(bvi); skip_large_index_stuff: /* Setup the operations for this index inode. */ vi->i_op = NULL; @@ -1714,7 +1715,6 @@ skip_large_index_stuff: ntfs_debug("Done."); return 0; - iput_unm_err_out: iput(bvi); unm_err_out: @@ -2191,37 +2191,6 @@ err_out: return -1; } -/** - * ntfs_put_inode - handler for when the inode reference count is decremented - * @vi: vfs inode - * - * The VFS calls ntfs_put_inode() every time the inode reference count (i_count) - * is about to be decremented (but before the decrement itself. - * - * If the inode @vi is a directory with two references, one of which is being - * dropped, we need to put the attribute inode for the directory index bitmap, - * if it is present, otherwise the directory inode would remain pinned for - * ever. - */ -void ntfs_put_inode(struct inode *vi) -{ - if (S_ISDIR(vi->i_mode) && atomic_read(&vi->i_count) == 2) { - ntfs_inode *ni = NTFS_I(vi); - if (NInoIndexAllocPresent(ni)) { - struct inode *bvi = NULL; - mutex_lock(&vi->i_mutex); - if (atomic_read(&vi->i_count) == 2) { - bvi = ni->itype.index.bmp_ino; - if (bvi) - ni->itype.index.bmp_ino = NULL; - } - mutex_unlock(&vi->i_mutex); - if (bvi) - iput(bvi); - } - } -} - static void __ntfs_clear_inode(ntfs_inode *ni) { /* Free all alocated memory. */ @@ -2287,18 +2256,6 @@ void ntfs_clear_big_inode(struct inode *vi) { ntfs_inode *ni = NTFS_I(vi); - /* - * If the inode @vi is an index inode we need to put the attribute - * inode for the index bitmap, if it is present, otherwise the index - * inode would disappear and the attribute inode for the index bitmap - * would no longer be referenced from anywhere and thus it would remain - * pinned for ever. - */ - if (NInoAttr(ni) && (ni->type == AT_INDEX_ALLOCATION) && - NInoIndexAllocPresent(ni) && ni->itype.index.bmp_ino) { - iput(ni->itype.index.bmp_ino); - ni->itype.index.bmp_ino = NULL; - } #ifdef NTFS_RW if (NInoDirty(ni)) { bool was_bad = (is_bad_inode(vi)); diff --git a/fs/ntfs/inode.h b/fs/ntfs/inode.h index f088291e017..117eaf8032a 100644 --- a/fs/ntfs/inode.h +++ b/fs/ntfs/inode.h @@ -2,7 +2,7 @@ * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of * the Linux-NTFS project. * - * Copyright (c) 2001-2005 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (c) 2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -101,8 +101,6 @@ struct _ntfs_inode { runlist attr_list_rl; /* Run list for the attribute list value. */ union { struct { /* It is a directory, $MFT, or an index inode. */ - struct inode *bmp_ino; /* Attribute inode for the - index $BITMAP. */ u32 block_size; /* Size of an index block. */ u32 vcn_size; /* Size of a vcn in this index. */ @@ -300,8 +298,6 @@ extern void ntfs_clear_extent_inode(ntfs_inode *ni); extern int ntfs_read_inode_mount(struct inode *vi); -extern void ntfs_put_inode(struct inode *vi); - extern int ntfs_show_options(struct seq_file *sf, struct vfsmount *mnt); #ifdef NTFS_RW diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c index 03a391ac714..babf94d90de 100644 --- a/fs/ntfs/super.c +++ b/fs/ntfs/super.c @@ -1,7 +1,7 @@ /* * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. * - * Copyright (c) 2001-2006 Anton Altaparmakov + * Copyright (c) 2001-2007 Anton Altaparmakov * Copyright (c) 2001,2002 Richard Russon * * This program/include file is free software; you can redistribute it and/or @@ -2702,9 +2702,6 @@ static int ntfs_statfs(struct dentry *dentry, struct kstatfs *sfs) static struct super_operations ntfs_sops = { .alloc_inode = ntfs_alloc_big_inode, /* VFS: Allocate new inode. */ .destroy_inode = ntfs_destroy_big_inode, /* VFS: Deallocate inode. */ - .put_inode = ntfs_put_inode, /* VFS: Called just before - the inode reference count - is decreased. */ #ifdef NTFS_RW //.dirty_inode = NULL, /* VFS: Called from // __mark_inode_dirty(). */ @@ -3261,7 +3258,7 @@ static void __exit exit_ntfs_fs(void) } MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); -MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2006 Anton Altaparmakov"); +MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2007 Anton Altaparmakov"); MODULE_VERSION(NTFS_VERSION); MODULE_LICENSE("GPL"); #ifdef DEBUG diff --git a/include/linux/mmc/mmc.h b/include/linux/mmc/mmc.h index a3594dfd696..bcf24909d67 100644 --- a/include/linux/mmc/mmc.h +++ b/include/linux/mmc/mmc.h @@ -42,7 +42,7 @@ struct mmc_command { #define MMC_RSP_R1B (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE|MMC_RSP_BUSY) #define MMC_RSP_R2 (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC) #define MMC_RSP_R3 (MMC_RSP_PRESENT) -#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC) +#define MMC_RSP_R6 (MMC_RSP_PRESENT|MMC_RSP_CRC|MMC_RSP_OPCODE) #define mmc_resp_type(cmd) ((cmd)->flags & (MMC_RSP_PRESENT|MMC_RSP_136|MMC_RSP_CRC|MMC_RSP_BUSY|MMC_RSP_OPCODE)) diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h index 5cb380a559f..d94e2683be5 100644 --- a/include/linux/videodev2.h +++ b/include/linux/videodev2.h @@ -662,6 +662,15 @@ typedef __u64 v4l2_std_id; #define V4L2_STD_ATSC_8_VSB ((v4l2_std_id)0x01000000) #define V4L2_STD_ATSC_16_VSB ((v4l2_std_id)0x02000000) +/* FIXME: + Although std_id is 64 bits, there is an issue on PPC32 architecture that + makes switch(__u64) to break. So, there's a hack on v4l2-common.c rounding + this value to 32 bits. + As, currently, the max value is for V4L2_STD_ATSC_16_VSB (30 bits wide), + it should work fine. However, if needed to add more than two standards, + v4l2-common.c should be fixed. + */ + /* some merged standards */ #define V4L2_STD_MN (V4L2_STD_PAL_M|V4L2_STD_PAL_N|V4L2_STD_PAL_Nc|V4L2_STD_NTSC) #define V4L2_STD_B (V4L2_STD_PAL_B|V4L2_STD_PAL_B1|V4L2_STD_SECAM_B) |