mirror of https://gitee.com/openkylin/linux.git
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: rtl8192u_usb: Add LG device ID 043e:7a01 Staging: rtl8192s_usb: Remove duplicate device ID Staging: rt2870: add device id for Zyxel NWD-270N Staging: comedi: fix read past end of array in cb_pcidda_attach() Staging: rtl8192su: add device ids Staging: rtl8192su: remove device ids Staging: rtl8187se: Fix compile warnings in 2.6.35-rc2 Staging: wlags49_h2: Fix build error when CONFIG_SYSFS is not set Staging: wlags49_h2: add missing <linux/string.h> for strlen Staging: hv: fix hv_utils module to properly autoload staging: hv: Fix race condition on vmbus channel initialization Staging: comedi: drivers: adl_pci9111: Fix AI commands in TRIG_FOLLOW case Staging: mrst-touchscreen: fix dereferencing free memory Staging: batman-adv: fix function prototype Staging: batman-adv: return -EFAULT on copy_to_user errors staging: usbip: usbip_common: kill rx thread on tx thread creation error.
This commit is contained in:
commit
980019d74e
|
@ -225,9 +225,9 @@ static struct bat_attribute *mesh_attrs[] = {
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
static ssize_t transtable_local_read(struct kobject *kobj,
|
static ssize_t transtable_local_read(struct file *filp, struct kobject *kobj,
|
||||||
struct bin_attribute *bin_attr,
|
struct bin_attribute *bin_attr,
|
||||||
char *buff, loff_t off, size_t count)
|
char *buff, loff_t off, size_t count)
|
||||||
{
|
{
|
||||||
struct device *dev = to_dev(kobj->parent);
|
struct device *dev = to_dev(kobj->parent);
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
struct net_device *net_dev = to_net_dev(dev);
|
||||||
|
@ -235,9 +235,9 @@ static ssize_t transtable_local_read(struct kobject *kobj,
|
||||||
return hna_local_fill_buffer_text(net_dev, buff, count, off);
|
return hna_local_fill_buffer_text(net_dev, buff, count, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t transtable_global_read(struct kobject *kobj,
|
static ssize_t transtable_global_read(struct file *filp, struct kobject *kobj,
|
||||||
struct bin_attribute *bin_attr,
|
struct bin_attribute *bin_attr,
|
||||||
char *buff, loff_t off, size_t count)
|
char *buff, loff_t off, size_t count)
|
||||||
{
|
{
|
||||||
struct device *dev = to_dev(kobj->parent);
|
struct device *dev = to_dev(kobj->parent);
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
struct net_device *net_dev = to_net_dev(dev);
|
||||||
|
@ -245,9 +245,9 @@ static ssize_t transtable_global_read(struct kobject *kobj,
|
||||||
return hna_global_fill_buffer_text(net_dev, buff, count, off);
|
return hna_global_fill_buffer_text(net_dev, buff, count, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t originators_read(struct kobject *kobj,
|
static ssize_t originators_read(struct file *filp, struct kobject *kobj,
|
||||||
struct bin_attribute *bin_attr,
|
struct bin_attribute *bin_attr,
|
||||||
char *buff, loff_t off, size_t count)
|
char *buff, loff_t off, size_t count)
|
||||||
{
|
{
|
||||||
struct device *dev = to_dev(kobj->parent);
|
struct device *dev = to_dev(kobj->parent);
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
struct net_device *net_dev = to_net_dev(dev);
|
||||||
|
@ -255,9 +255,9 @@ static ssize_t originators_read(struct kobject *kobj,
|
||||||
return orig_fill_buffer_text(net_dev, buff, count, off);
|
return orig_fill_buffer_text(net_dev, buff, count, off);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t vis_data_read(struct kobject *kobj,
|
static ssize_t vis_data_read(struct file *filp, struct kobject *kobj,
|
||||||
struct bin_attribute *bin_attr,
|
struct bin_attribute *bin_attr,
|
||||||
char *buff, loff_t off, size_t count)
|
char *buff, loff_t off, size_t count)
|
||||||
{
|
{
|
||||||
struct device *dev = to_dev(kobj->parent);
|
struct device *dev = to_dev(kobj->parent);
|
||||||
struct net_device *net_dev = to_net_dev(dev);
|
struct net_device *net_dev = to_net_dev(dev);
|
||||||
|
|
|
@ -196,7 +196,7 @@ ssize_t bat_device_read(struct file *file, char __user *buf, size_t count,
|
||||||
kfree(device_packet);
|
kfree(device_packet);
|
||||||
|
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return -EFAULT;
|
||||||
|
|
||||||
return sizeof(struct icmp_packet);
|
return sizeof(struct icmp_packet);
|
||||||
}
|
}
|
||||||
|
|
|
@ -824,9 +824,12 @@ static int pci9111_ai_do_cmd(struct comedi_device *dev,
|
||||||
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
|
plx9050_interrupt_control(dev_private->lcr_io_base, true, true,
|
||||||
false, true, true);
|
false, true, true);
|
||||||
|
|
||||||
dev_private->scan_delay =
|
if (async_cmd->scan_begin_src == TRIG_TIMER) {
|
||||||
(async_cmd->scan_begin_arg / (async_cmd->convert_arg *
|
dev_private->scan_delay =
|
||||||
async_cmd->chanlist_len)) - 1;
|
(async_cmd->scan_begin_arg /
|
||||||
|
(async_cmd->convert_arg *
|
||||||
|
async_cmd->chanlist_len)) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,6 @@ Please report success/failure with other different cards to
|
||||||
#include "8255.h"
|
#include "8255.h"
|
||||||
|
|
||||||
#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */
|
#define PCI_VENDOR_ID_CB 0x1307 /* PCI vendor number of ComputerBoards */
|
||||||
#define N_BOARDS 10 /* Number of boards in cb_pcidda_boards */
|
|
||||||
#define EEPROM_SIZE 128 /* number of entries in eeprom */
|
#define EEPROM_SIZE 128 /* number of entries in eeprom */
|
||||||
#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */
|
#define MAX_AO_CHANNELS 8 /* maximum number of ao channels for supported boards */
|
||||||
|
|
||||||
|
@ -307,7 +306,7 @@ static int cb_pcidda_attach(struct comedi_device *dev,
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (index = 0; index < N_BOARDS; index++) {
|
for (index = 0; index < ARRAY_SIZE(cb_pcidda_boards); index++) {
|
||||||
if (cb_pcidda_boards[index].device_id ==
|
if (cb_pcidda_boards[index].device_id ==
|
||||||
pcidev->device) {
|
pcidev->device) {
|
||||||
goto found;
|
goto found;
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "vmbus_private.h"
|
#include "vmbus_private.h"
|
||||||
|
@ -293,6 +294,25 @@ void FreeVmbusChannel(struct vmbus_channel *Channel)
|
||||||
Channel);
|
Channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
DECLARE_COMPLETION(hv_channel_ready);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Count initialized channels, and ensure all channels are ready when hv_vmbus
|
||||||
|
* module loading completes.
|
||||||
|
*/
|
||||||
|
static void count_hv_channel(void)
|
||||||
|
{
|
||||||
|
static int counter;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&gVmbusConnection.channel_lock, flags);
|
||||||
|
if (++counter == MAX_MSG_TYPES)
|
||||||
|
complete(&hv_channel_ready);
|
||||||
|
spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* VmbusChannelProcessOffer - Process the offer by creating a channel/device
|
* VmbusChannelProcessOffer - Process the offer by creating a channel/device
|
||||||
* associated with this offer
|
* associated with this offer
|
||||||
|
@ -373,22 +393,21 @@ static void VmbusChannelProcessOffer(void *context)
|
||||||
* can cleanup properly
|
* can cleanup properly
|
||||||
*/
|
*/
|
||||||
newChannel->State = CHANNEL_OPEN_STATE;
|
newChannel->State = CHANNEL_OPEN_STATE;
|
||||||
cnt = 0;
|
|
||||||
|
|
||||||
while (cnt != MAX_MSG_TYPES) {
|
/* Open IC channels */
|
||||||
|
for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) {
|
||||||
if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType,
|
if (memcmp(&newChannel->OfferMsg.Offer.InterfaceType,
|
||||||
&hv_cb_utils[cnt].data,
|
&hv_cb_utils[cnt].data,
|
||||||
sizeof(struct hv_guid)) == 0) {
|
sizeof(struct hv_guid)) == 0 &&
|
||||||
|
VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
|
||||||
|
2 * PAGE_SIZE, NULL, 0,
|
||||||
|
hv_cb_utils[cnt].callback,
|
||||||
|
newChannel) == 0) {
|
||||||
|
hv_cb_utils[cnt].channel = newChannel;
|
||||||
DPRINT_INFO(VMBUS, "%s",
|
DPRINT_INFO(VMBUS, "%s",
|
||||||
hv_cb_utils[cnt].log_msg);
|
hv_cb_utils[cnt].log_msg);
|
||||||
|
count_hv_channel();
|
||||||
if (VmbusChannelOpen(newChannel, 2 * PAGE_SIZE,
|
|
||||||
2 * PAGE_SIZE, NULL, 0,
|
|
||||||
hv_cb_utils[cnt].callback,
|
|
||||||
newChannel) == 0)
|
|
||||||
hv_cb_utils[cnt].channel = newChannel;
|
|
||||||
}
|
}
|
||||||
cnt++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DPRINT_EXIT(VMBUS);
|
DPRINT_EXIT(VMBUS);
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/sysctl.h>
|
#include <linux/sysctl.h>
|
||||||
#include <linux/reboot.h>
|
#include <linux/reboot.h>
|
||||||
|
#include <linux/dmi.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
|
@ -251,10 +253,36 @@ static void heartbeat_onchannelcallback(void *context)
|
||||||
DPRINT_EXIT(VMBUS);
|
DPRINT_EXIT(VMBUS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct pci_device_id __initconst
|
||||||
|
hv_utils_pci_table[] __maybe_unused = {
|
||||||
|
{ PCI_DEVICE(0x1414, 0x5353) }, /* Hyper-V emulated VGA controller */
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(pci, hv_utils_pci_table);
|
||||||
|
|
||||||
|
|
||||||
|
static const struct dmi_system_id __initconst
|
||||||
|
hv_utils_dmi_table[] __maybe_unused = {
|
||||||
|
{
|
||||||
|
.ident = "Hyper-V",
|
||||||
|
.matches = {
|
||||||
|
DMI_MATCH(DMI_SYS_VENDOR, "Microsoft Corporation"),
|
||||||
|
DMI_MATCH(DMI_PRODUCT_NAME, "Virtual Machine"),
|
||||||
|
DMI_MATCH(DMI_BOARD_NAME, "Virtual Machine"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(dmi, hv_utils_dmi_table);
|
||||||
|
|
||||||
|
|
||||||
static int __init init_hyperv_utils(void)
|
static int __init init_hyperv_utils(void)
|
||||||
{
|
{
|
||||||
printk(KERN_INFO "Registering HyperV Utility Driver\n");
|
printk(KERN_INFO "Registering HyperV Utility Driver\n");
|
||||||
|
|
||||||
|
if (!dmi_check_system(hv_utils_dmi_table))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
|
hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback =
|
||||||
&shutdown_onchannelcallback;
|
&shutdown_onchannelcallback;
|
||||||
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
|
hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback;
|
||||||
|
|
|
@ -74,4 +74,6 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx);
|
||||||
void vmbus_child_driver_unregister(struct driver_context *driver_ctx);
|
void vmbus_child_driver_unregister(struct driver_context *driver_ctx);
|
||||||
void vmbus_get_interface(struct vmbus_channel_interface *interface);
|
void vmbus_get_interface(struct vmbus_channel_interface *interface);
|
||||||
|
|
||||||
|
extern struct completion hv_channel_ready;
|
||||||
|
|
||||||
#endif /* _VMBUS_H_ */
|
#endif /* _VMBUS_H_ */
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/dmi.h>
|
#include <linux/dmi.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/completion.h>
|
||||||
#include "version_info.h"
|
#include "version_info.h"
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
|
@ -356,6 +357,8 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv))
|
||||||
|
|
||||||
vmbus_drv_obj->GetChannelOffers();
|
vmbus_drv_obj->GetChannelOffers();
|
||||||
|
|
||||||
|
wait_for_completion(&hv_channel_ready);
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
DPRINT_EXIT(VMBUS_DRV);
|
DPRINT_EXIT(VMBUS_DRV);
|
||||||
|
|
||||||
|
|
|
@ -817,9 +817,9 @@ static int mrstouch_remove(struct spi_device *spi)
|
||||||
free_irq(mrstouchdevp->irq, mrstouchdevp);
|
free_irq(mrstouchdevp->irq, mrstouchdevp);
|
||||||
input_unregister_device(mrstouchdevp->input);
|
input_unregister_device(mrstouchdevp->input);
|
||||||
input_free_device(mrstouchdevp->input);
|
input_free_device(mrstouchdevp->input);
|
||||||
kfree(mrstouchdevp);
|
|
||||||
if (mrstouchdevp->pendet_thrd)
|
if (mrstouchdevp->pendet_thrd)
|
||||||
kthread_stop(mrstouchdevp->pendet_thrd);
|
kthread_stop(mrstouchdevp->pendet_thrd);
|
||||||
|
kfree(mrstouchdevp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,6 +77,7 @@ struct usb_device_id rtusb_usb_id[] = {
|
||||||
{USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */
|
{USB_DEVICE(0x083A, 0x7522)}, /* Arcadyan */
|
||||||
{USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */
|
{USB_DEVICE(0x0CDE, 0x0022)}, /* ZCOM */
|
||||||
{USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */
|
{USB_DEVICE(0x0586, 0x3416)}, /* Zyxel */
|
||||||
|
{USB_DEVICE(0x0586, 0x341a)}, /* Zyxel NWD-270N */
|
||||||
{USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */
|
{USB_DEVICE(0x0CDE, 0x0025)}, /* Zyxel */
|
||||||
{USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */
|
{USB_DEVICE(0x1740, 0x9701)}, /* EnGenius */
|
||||||
{USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */
|
{USB_DEVICE(0x1740, 0x9702)}, /* EnGenius */
|
||||||
|
|
|
@ -66,8 +66,6 @@ static int hwseqnum = 0;
|
||||||
static int hwwep = 0;
|
static int hwwep = 0;
|
||||||
static int channels = 0x3fff;
|
static int channels = 0x3fff;
|
||||||
|
|
||||||
#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1 : 0)
|
|
||||||
#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
|
MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
|
||||||
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
|
MODULE_AUTHOR("Andrea Merello <andreamrl@tiscali.it>");
|
||||||
|
|
|
@ -112,28 +112,29 @@ u32 rt_global_debug_component = \
|
||||||
#define CAM_CONTENT_COUNT 8
|
#define CAM_CONTENT_COUNT 8
|
||||||
|
|
||||||
static const struct usb_device_id rtl8192_usb_id_tbl[] = {
|
static const struct usb_device_id rtl8192_usb_id_tbl[] = {
|
||||||
/* Realtek */
|
{USB_DEVICE(0x0bda, 0x8171)}, /* Realtek */
|
||||||
{USB_DEVICE(0x0bda, 0x8171)},
|
|
||||||
{USB_DEVICE(0x0bda, 0x8192)},
|
|
||||||
{USB_DEVICE(0x0bda, 0x8709)},
|
|
||||||
/* Corega */
|
|
||||||
{USB_DEVICE(0x07aa, 0x0043)},
|
|
||||||
/* Belkin */
|
|
||||||
{USB_DEVICE(0x050d, 0x805E)},
|
|
||||||
{USB_DEVICE(0x050d, 0x815F)}, /* Belkin F5D8053 v6 */
|
|
||||||
/* Sitecom */
|
|
||||||
{USB_DEVICE(0x0df6, 0x0031)},
|
|
||||||
{USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
|
|
||||||
/* EnGenius */
|
|
||||||
{USB_DEVICE(0x1740, 0x9201)},
|
|
||||||
/* Dlink */
|
|
||||||
{USB_DEVICE(0x2001, 0x3301)},
|
|
||||||
/* Zinwell */
|
|
||||||
{USB_DEVICE(0x5a57, 0x0290)},
|
|
||||||
/* Guillemot */
|
|
||||||
{USB_DEVICE(0x06f8, 0xe031)},
|
|
||||||
//92SU
|
|
||||||
{USB_DEVICE(0x0bda, 0x8172)},
|
{USB_DEVICE(0x0bda, 0x8172)},
|
||||||
|
{USB_DEVICE(0x0bda, 0x8173)},
|
||||||
|
{USB_DEVICE(0x0bda, 0x8174)},
|
||||||
|
{USB_DEVICE(0x0bda, 0x8712)},
|
||||||
|
{USB_DEVICE(0x0bda, 0x8713)},
|
||||||
|
{USB_DEVICE(0x07aa, 0x0047)},
|
||||||
|
{USB_DEVICE(0x07d1, 0x3303)},
|
||||||
|
{USB_DEVICE(0x07d1, 0x3302)},
|
||||||
|
{USB_DEVICE(0x07d1, 0x3300)},
|
||||||
|
{USB_DEVICE(0x1740, 0x9603)},
|
||||||
|
{USB_DEVICE(0x1740, 0x9605)},
|
||||||
|
{USB_DEVICE(0x050d, 0x815F)},
|
||||||
|
{USB_DEVICE(0x06f8, 0xe031)},
|
||||||
|
{USB_DEVICE(0x7392, 0x7611)},
|
||||||
|
{USB_DEVICE(0x7392, 0x7612)},
|
||||||
|
{USB_DEVICE(0x7392, 0x7622)},
|
||||||
|
{USB_DEVICE(0x0DF6, 0x0045)},
|
||||||
|
{USB_DEVICE(0x0E66, 0x0015)},
|
||||||
|
{USB_DEVICE(0x0E66, 0x0016)},
|
||||||
|
{USB_DEVICE(0x0b05, 0x1786)},
|
||||||
|
/* these are not in the official list */
|
||||||
|
{USB_DEVICE(0x0df6, 0x004b)}, /* WL-349 */
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -121,6 +121,8 @@ static const struct usb_device_id rtl8192_usb_id_tbl[] = {
|
||||||
{USB_DEVICE(0x2001, 0x3301)},
|
{USB_DEVICE(0x2001, 0x3301)},
|
||||||
/* Zinwell */
|
/* Zinwell */
|
||||||
{USB_DEVICE(0x5a57, 0x0290)},
|
{USB_DEVICE(0x5a57, 0x0290)},
|
||||||
|
/* LG */
|
||||||
|
{USB_DEVICE(0x043e, 0x7a01)},
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -378,47 +378,67 @@ int usbip_thread(void *param)
|
||||||
complete_and_exit(&ut->thread_done, 0);
|
complete_and_exit(&ut->thread_done, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void stop_rx_thread(struct usbip_device *ud)
|
||||||
|
{
|
||||||
|
if (ud->tcp_rx.thread != NULL) {
|
||||||
|
send_sig(SIGKILL, ud->tcp_rx.thread, 1);
|
||||||
|
wait_for_completion(&ud->tcp_rx.thread_done);
|
||||||
|
usbip_udbg("rx_thread for ud %p has finished\n", ud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void stop_tx_thread(struct usbip_device *ud)
|
||||||
|
{
|
||||||
|
if (ud->tcp_tx.thread != NULL) {
|
||||||
|
send_sig(SIGKILL, ud->tcp_tx.thread, 1);
|
||||||
|
wait_for_completion(&ud->tcp_tx.thread_done);
|
||||||
|
usbip_udbg("tx_thread for ud %p has finished\n", ud);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int usbip_start_threads(struct usbip_device *ud)
|
int usbip_start_threads(struct usbip_device *ud)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* threads are invoked per one device (per one connection).
|
* threads are invoked per one device (per one connection).
|
||||||
*/
|
*/
|
||||||
struct task_struct *th;
|
struct task_struct *th;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
|
th = kthread_run(usbip_thread, (void *)&ud->tcp_rx, "usbip");
|
||||||
if (IS_ERR(th)) {
|
if (IS_ERR(th)) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Unable to start control thread\n");
|
"Unable to start control thread\n");
|
||||||
return PTR_ERR(th);
|
err = PTR_ERR(th);
|
||||||
|
goto ust_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
|
th = kthread_run(usbip_thread, (void *)&ud->tcp_tx, "usbip");
|
||||||
if (IS_ERR(th)) {
|
if (IS_ERR(th)) {
|
||||||
printk(KERN_WARNING
|
printk(KERN_WARNING
|
||||||
"Unable to start control thread\n");
|
"Unable to start control thread\n");
|
||||||
return PTR_ERR(th);
|
err = PTR_ERR(th);
|
||||||
|
goto tx_thread_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* confirm threads are starting */
|
/* confirm threads are starting */
|
||||||
wait_for_completion(&ud->tcp_rx.thread_done);
|
wait_for_completion(&ud->tcp_rx.thread_done);
|
||||||
wait_for_completion(&ud->tcp_tx.thread_done);
|
wait_for_completion(&ud->tcp_tx.thread_done);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
tx_thread_err:
|
||||||
|
stop_rx_thread(ud);
|
||||||
|
|
||||||
|
ust_exit:
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usbip_start_threads);
|
EXPORT_SYMBOL_GPL(usbip_start_threads);
|
||||||
|
|
||||||
void usbip_stop_threads(struct usbip_device *ud)
|
void usbip_stop_threads(struct usbip_device *ud)
|
||||||
{
|
{
|
||||||
/* kill threads related to this sdev, if v.c. exists */
|
/* kill threads related to this sdev, if v.c. exists */
|
||||||
if (ud->tcp_rx.thread != NULL) {
|
stop_rx_thread(ud);
|
||||||
send_sig(SIGKILL, ud->tcp_rx.thread, 1);
|
stop_tx_thread(ud);
|
||||||
wait_for_completion(&ud->tcp_rx.thread_done);
|
|
||||||
usbip_udbg("rx_thread for ud %p has finished\n", ud);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ud->tcp_tx.thread != NULL) {
|
|
||||||
send_sig(SIGKILL, ud->tcp_tx.thread, 1);
|
|
||||||
wait_for_completion(&ud->tcp_tx.thread_done);
|
|
||||||
usbip_udbg("tx_thread for ud %p has finished\n", ud);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(usbip_stop_threads);
|
EXPORT_SYMBOL_GPL(usbip_stop_threads);
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* include files
|
* include files
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
#include <linux/string.h>
|
||||||
#include <wl_version.h>
|
#include <wl_version.h>
|
||||||
|
|
||||||
#include <debug.h>
|
#include <debug.h>
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
extern void register_wlags_sysfs(struct net_device *);
|
extern void register_wlags_sysfs(struct net_device *);
|
||||||
extern void unregister_wlags_sysfs(struct net_device *);
|
extern void unregister_wlags_sysfs(struct net_device *);
|
||||||
#else
|
#else
|
||||||
static void register_wlags_sysfs(struct net_device *) { return; };
|
static inline void register_wlags_sysfs(struct net_device *net) { }
|
||||||
static void unregister_wlags_sysfs(struct net_device *) { return; };
|
static inline void unregister_wlags_sysfs(struct net_device *net) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue