Commit 4caca5f9 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging-2.6:
  Staging: hv: fix smp problems in the hyperv core code
  Staging: et131x: Fix 2.6.33rc1 regression in et131x
  Staging: asus_oled: fix oops in 2.6.32.2
parents f8c7e6c2 7692fd4d
...@@ -194,9 +194,11 @@ static ssize_t set_enabled(struct device *dev, struct device_attribute *attr, ...@@ -194,9 +194,11 @@ static ssize_t set_enabled(struct device *dev, struct device_attribute *attr,
{ {
struct usb_interface *intf = to_usb_interface(dev); struct usb_interface *intf = to_usb_interface(dev);
struct asus_oled_dev *odev = usb_get_intfdata(intf); struct asus_oled_dev *odev = usb_get_intfdata(intf);
int temp = strict_strtoul(buf, 10, NULL); unsigned long value;
if (strict_strtoul(buf, 10, &value))
return -EINVAL;
enable_oled(odev, temp); enable_oled(odev, value);
return count; return count;
} }
...@@ -207,10 +209,12 @@ static ssize_t class_set_enabled(struct device *device, ...@@ -207,10 +209,12 @@ static ssize_t class_set_enabled(struct device *device,
{ {
struct asus_oled_dev *odev = struct asus_oled_dev *odev =
(struct asus_oled_dev *) dev_get_drvdata(device); (struct asus_oled_dev *) dev_get_drvdata(device);
unsigned long value;
int temp = strict_strtoul(buf, 10, NULL); if (strict_strtoul(buf, 10, &value))
return -EINVAL;
enable_oled(odev, temp); enable_oled(odev, value);
return count; return count;
} }
......
...@@ -203,11 +203,14 @@ typedef struct _GLOBAL_t { /* Location: */ ...@@ -203,11 +203,14 @@ typedef struct _GLOBAL_t { /* Location: */
* 9-0: pr ndes * 9-0: pr ndes
*/ */
#define ET_DMA10_MASK 0x3FF /* 10 bit mask for DMA10W types */ #define ET_DMA12_MASK 0x0FFF /* 12 bit mask for DMA12W types */
#define ET_DMA10_WRAP 0x400 #define ET_DMA12_WRAP 0x1000
#define ET_DMA4_MASK 0x00F /* 4 bit mask for DMA4W types */ #define ET_DMA10_MASK 0x03FF /* 10 bit mask for DMA10W types */
#define ET_DMA4_WRAP 0x010 #define ET_DMA10_WRAP 0x0400
#define ET_DMA4_MASK 0x000F /* 4 bit mask for DMA4W types */
#define ET_DMA4_WRAP 0x0010
#define INDEX12(x) ((x) & ET_DMA12_MASK)
#define INDEX10(x) ((x) & ET_DMA10_MASK) #define INDEX10(x) ((x) & ET_DMA10_MASK)
#define INDEX4(x) ((x) & ET_DMA4_MASK) #define INDEX4(x) ((x) & ET_DMA4_MASK)
...@@ -216,6 +219,11 @@ extern inline void add_10bit(u32 *v, int n) ...@@ -216,6 +219,11 @@ extern inline void add_10bit(u32 *v, int n)
*v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP); *v = INDEX10(*v + n) | (*v & ET_DMA10_WRAP);
} }
extern inline void add_12bit(u32 *v, int n)
{
*v = INDEX12(*v + n) | (*v & ET_DMA12_WRAP);
}
/* /*
* 10bit DMA with wrap * 10bit DMA with wrap
* txdma tx queue write address reg in txdma address map at 0x1010 * txdma tx queue write address reg in txdma address map at 0x1010
......
...@@ -831,10 +831,10 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev) ...@@ -831,10 +831,10 @@ PMP_RFD nic_rx_pkts(struct et131x_adapter *etdev)
/* Indicate that we have used this PSR entry. */ /* Indicate that we have used this PSR entry. */
/* FIXME wrap 12 */ /* FIXME wrap 12 */
rx_local->local_psr_full = (rx_local->local_psr_full + 1) & 0xFFF; add_12bit(&rx_local->local_psr_full, 1);
if (rx_local->local_psr_full > rx_local->PsrNumEntries - 1) { if ((rx_local->local_psr_full & 0xFFF) > rx_local->PsrNumEntries - 1) {
/* Clear psr full and toggle the wrap bit */ /* Clear psr full and toggle the wrap bit */
rx_local->local_psr_full &= 0xFFF; rx_local->local_psr_full &= ~0xFFF;
rx_local->local_psr_full ^= 0x1000; rx_local->local_psr_full ^= 0x1000;
} }
......
...@@ -386,7 +386,7 @@ u16 HvSignalEvent(void) ...@@ -386,7 +386,7 @@ u16 HvSignalEvent(void)
* retrieve the initialized message and event pages. Otherwise, we create and * retrieve the initialized message and event pages. Otherwise, we create and
* initialize the message and event pages. * initialize the message and event pages.
*/ */
int HvSynicInit(u32 irqVector) void HvSynicInit(void *irqarg)
{ {
u64 version; u64 version;
union hv_synic_simp simp; union hv_synic_simp simp;
...@@ -394,13 +394,14 @@ int HvSynicInit(u32 irqVector) ...@@ -394,13 +394,14 @@ int HvSynicInit(u32 irqVector)
union hv_synic_sint sharedSint; union hv_synic_sint sharedSint;
union hv_synic_scontrol sctrl; union hv_synic_scontrol sctrl;
u64 guestID; u64 guestID;
int ret = 0; u32 irqVector = *((u32 *)(irqarg));
int cpu = smp_processor_id();
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
if (!gHvContext.HypercallPage) { if (!gHvContext.HypercallPage) {
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return;
} }
/* Check the version */ /* Check the version */
...@@ -425,27 +426,27 @@ int HvSynicInit(u32 irqVector) ...@@ -425,27 +426,27 @@ int HvSynicInit(u32 irqVector)
*/ */
rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID); rdmsrl(HV_X64_MSR_GUEST_OS_ID, guestID);
if (guestID == HV_LINUX_GUEST_ID) { if (guestID == HV_LINUX_GUEST_ID) {
gHvContext.synICMessagePage[0] = gHvContext.synICMessagePage[cpu] =
phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT); phys_to_virt(simp.BaseSimpGpa << PAGE_SHIFT);
gHvContext.synICEventPage[0] = gHvContext.synICEventPage[cpu] =
phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT); phys_to_virt(siefp.BaseSiefpGpa << PAGE_SHIFT);
} else { } else {
DPRINT_ERR(VMBUS, "unknown guest id!!"); DPRINT_ERR(VMBUS, "unknown guest id!!");
goto Cleanup; goto Cleanup;
} }
DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p", DPRINT_DBG(VMBUS, "MAPPED: Simp: %p, Sifep: %p",
gHvContext.synICMessagePage[0], gHvContext.synICMessagePage[cpu],
gHvContext.synICEventPage[0]); gHvContext.synICEventPage[cpu]);
} else { } else {
gHvContext.synICMessagePage[0] = osd_PageAlloc(1); gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
if (gHvContext.synICMessagePage[0] == NULL) { if (gHvContext.synICMessagePage[cpu] == NULL) {
DPRINT_ERR(VMBUS, DPRINT_ERR(VMBUS,
"unable to allocate SYNIC message page!!"); "unable to allocate SYNIC message page!!");
goto Cleanup; goto Cleanup;
} }
gHvContext.synICEventPage[0] = osd_PageAlloc(1); gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC);
if (gHvContext.synICEventPage[0] == NULL) { if (gHvContext.synICEventPage[cpu] == NULL) {
DPRINT_ERR(VMBUS, DPRINT_ERR(VMBUS,
"unable to allocate SYNIC event page!!"); "unable to allocate SYNIC event page!!");
goto Cleanup; goto Cleanup;
...@@ -454,7 +455,7 @@ int HvSynicInit(u32 irqVector) ...@@ -454,7 +455,7 @@ int HvSynicInit(u32 irqVector)
/* Setup the Synic's message page */ /* Setup the Synic's message page */
rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64);
simp.SimpEnabled = 1; simp.SimpEnabled = 1;
simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[0]) simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu])
>> PAGE_SHIFT; >> PAGE_SHIFT;
DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx",
...@@ -465,7 +466,7 @@ int HvSynicInit(u32 irqVector) ...@@ -465,7 +466,7 @@ int HvSynicInit(u32 irqVector)
/* Setup the Synic's event page */ /* Setup the Synic's event page */
rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
siefp.SiefpEnabled = 1; siefp.SiefpEnabled = 1;
siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[0]) siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu])
>> PAGE_SHIFT; >> PAGE_SHIFT;
DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx",
...@@ -501,32 +502,30 @@ int HvSynicInit(u32 irqVector) ...@@ -501,32 +502,30 @@ int HvSynicInit(u32 irqVector)
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return;
Cleanup: Cleanup:
ret = -1;
if (gHvContext.GuestId == HV_LINUX_GUEST_ID) { if (gHvContext.GuestId == HV_LINUX_GUEST_ID) {
if (gHvContext.synICEventPage[0]) if (gHvContext.synICEventPage[cpu])
osd_PageFree(gHvContext.synICEventPage[0], 1); osd_PageFree(gHvContext.synICEventPage[cpu], 1);
if (gHvContext.synICMessagePage[0]) if (gHvContext.synICMessagePage[cpu])
osd_PageFree(gHvContext.synICMessagePage[0], 1); osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
} }
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return;
return ret;
} }
/** /**
* HvSynicCleanup - Cleanup routine for HvSynicInit(). * HvSynicCleanup - Cleanup routine for HvSynicInit().
*/ */
void HvSynicCleanup(void) void HvSynicCleanup(void *arg)
{ {
union hv_synic_sint sharedSint; union hv_synic_sint sharedSint;
union hv_synic_simp simp; union hv_synic_simp simp;
union hv_synic_siefp siefp; union hv_synic_siefp siefp;
int cpu = smp_processor_id();
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
...@@ -539,6 +538,7 @@ void HvSynicCleanup(void) ...@@ -539,6 +538,7 @@ void HvSynicCleanup(void)
sharedSint.Masked = 1; sharedSint.Masked = 1;
/* Need to correctly cleanup in the case of SMP!!! */
/* Disable the interrupt */ /* Disable the interrupt */
wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64);
...@@ -560,8 +560,8 @@ void HvSynicCleanup(void) ...@@ -560,8 +560,8 @@ void HvSynicCleanup(void)
wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64);
osd_PageFree(gHvContext.synICMessagePage[0], 1); osd_PageFree(gHvContext.synICMessagePage[cpu], 1);
osd_PageFree(gHvContext.synICEventPage[0], 1); osd_PageFree(gHvContext.synICEventPage[cpu], 1);
} }
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
......
...@@ -93,7 +93,7 @@ static const struct hv_guid VMBUS_SERVICE_ID = { ...@@ -93,7 +93,7 @@ static const struct hv_guid VMBUS_SERVICE_ID = {
}, },
}; };
#define MAX_NUM_CPUS 1 #define MAX_NUM_CPUS 32
struct hv_input_signal_event_buffer { struct hv_input_signal_event_buffer {
...@@ -137,8 +137,8 @@ extern u16 HvPostMessage(union hv_connection_id connectionId, ...@@ -137,8 +137,8 @@ extern u16 HvPostMessage(union hv_connection_id connectionId,
extern u16 HvSignalEvent(void); extern u16 HvSignalEvent(void);
extern int HvSynicInit(u32 irqVector); extern void HvSynicInit(void *irqarg);
extern void HvSynicCleanup(void); extern void HvSynicCleanup(void *arg);
#endif /* __HV_H__ */ #endif /* __HV_H__ */
...@@ -129,7 +129,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) ...@@ -129,7 +129,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo)
/* strcpy(dev->name, "vmbus"); */ /* strcpy(dev->name, "vmbus"); */
/* SynIC setup... */ /* SynIC setup... */
ret = HvSynicInit(*irqvector); on_each_cpu(HvSynicInit, (void *)irqvector, 1);
/* Connect to VMBus in the root partition */ /* Connect to VMBus in the root partition */
ret = VmbusConnect(); ret = VmbusConnect();
...@@ -150,7 +150,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) ...@@ -150,7 +150,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev)
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
VmbusChannelReleaseUnattachedChannels(); VmbusChannelReleaseUnattachedChannels();
VmbusDisconnect(); VmbusDisconnect();
HvSynicCleanup(); on_each_cpu(HvSynicCleanup, NULL, 1);
DPRINT_EXIT(VMBUS); DPRINT_EXIT(VMBUS);
return ret; return ret;
...@@ -173,7 +173,8 @@ static void VmbusOnCleanup(struct hv_driver *drv) ...@@ -173,7 +173,8 @@ static void VmbusOnCleanup(struct hv_driver *drv)
*/ */
static void VmbusOnMsgDPC(struct hv_driver *drv) static void VmbusOnMsgDPC(struct hv_driver *drv)
{ {
void *page_addr = gHvContext.synICMessagePage[0]; int cpu = smp_processor_id();
void *page_addr = gHvContext.synICMessagePage[cpu];
struct hv_message *msg = (struct hv_message *)page_addr + struct hv_message *msg = (struct hv_message *)page_addr +
VMBUS_MESSAGE_SINT; VMBUS_MESSAGE_SINT;
struct hv_message *copied; struct hv_message *copied;
...@@ -230,11 +231,12 @@ static void VmbusOnEventDPC(struct hv_driver *drv) ...@@ -230,11 +231,12 @@ static void VmbusOnEventDPC(struct hv_driver *drv)
static int VmbusOnISR(struct hv_driver *drv) static int VmbusOnISR(struct hv_driver *drv)
{ {
int ret = 0; int ret = 0;
int cpu = smp_processor_id();
void *page_addr; void *page_addr;
struct hv_message *msg; struct hv_message *msg;
union hv_synic_event_flags *event; union hv_synic_event_flags *event;
page_addr = gHvContext.synICMessagePage[0]; page_addr = gHvContext.synICMessagePage[cpu];
msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT;
DPRINT_ENTER(VMBUS); DPRINT_ENTER(VMBUS);
...@@ -248,7 +250,7 @@ static int VmbusOnISR(struct hv_driver *drv) ...@@ -248,7 +250,7 @@ static int VmbusOnISR(struct hv_driver *drv)
} }
/* TODO: Check if there are events to be process */ /* TODO: Check if there are events to be process */
page_addr = gHvContext.synICEventPage[0]; page_addr = gHvContext.synICEventPage[cpu];
event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT;
/* Since we are a child, we only need to check bit 0 */ /* Since we are a child, we only need to check bit 0 */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment