diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-19 17:48:32 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-19 17:48:32 -0700 |
commit | fb20871a54961b82d35303b43452928186c1361d (patch) | |
tree | 1beeb39e45eda1c8b5893090904b583fceeb07ef /drivers/staging/heci/io_heci.c | |
parent | bee89ab228e6f51c4ddd3481b9bd491859a8ee7b (diff) | |
parent | c7a5d70796379e3d51d0c652fbe1634b81d3bbd5 (diff) |
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: (342 commits)
Staging: comedi: fix build errors
Staging: udlfb: update to version 0.2.3
Staging: udlfb: fix some sparse warnings.
Staging: udlfb: clean up checkpatch warnings in udlfb.c
Staging: udlfb: clean up checkpatch warnings in udlfb.h
Staging: udlfb: add udlfb driver to build
Staging: add udlfb driver
Staging: pata_rdc: remove pointless comments
Staging: pata_rdc: remove DRIVER macros
Staging: pata_rdc: remove dbgprintf macro
Staging: pata_rdc: remove broken flag
Staging: pata_rdc: fix build warnings
Staging: pata_rdc: use PCI_DEVICE
Staging: pata_rdc: remove function prototypes
Staging: pata_rdc: coding style fixes
Staging: pata_rdc: convert code to work in 2.6.29
Staging: pata_rdc: add driver to the build system
Staging: add pata_rdc driver
Staging: remove obsolete serqt_usb driver
Staging: serqt_usb2 add the driver to the build
...
Diffstat (limited to 'drivers/staging/heci/io_heci.c')
-rw-r--r-- | drivers/staging/heci/io_heci.c | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/drivers/staging/heci/io_heci.c b/drivers/staging/heci/io_heci.c index f7544a7bbbe..1a6faf88e16 100644 --- a/drivers/staging/heci/io_heci.c +++ b/drivers/staging/heci/io_heci.c @@ -111,7 +111,7 @@ int heci_ioctl_get_version(struct iamt_heci_device *dev, int if_num, rets = file_ext->status; /* now copy the data to user space */ - if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + if (copy_to_user((void __user *)k_msg.data, res_msg.data, res_msg.size)) { rets = -EFAULT; goto end; } @@ -188,7 +188,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, /* copy the message to kernel space - * use a pointer already copied into kernel space */ - if (copy_from_user(req_msg.data, k_msg.data, k_msg.size)) { + if (copy_from_user(req_msg.data, (void __user *)k_msg.data, k_msg.size)) { rets = -EFAULT; goto end; } @@ -266,7 +266,8 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, spin_unlock_bh(&dev->device_lock); /* now copy the data to user space */ - if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + if (copy_to_user((void __user *)k_msg.data, + res_msg.data, res_msg.size)) { rets = -EFAULT; goto end; } @@ -276,14 +277,16 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, } goto end; } + spin_unlock_bh(&dev->device_lock); + spin_lock(&file_ext->file_lock); + spin_lock_bh(&dev->device_lock); if (file_ext->state != HECI_FILE_CONNECTING) { rets = -ENODEV; - spin_unlock(&file_ext->file_lock); spin_unlock_bh(&dev->device_lock); + spin_unlock(&file_ext->file_lock); goto end; } - spin_unlock(&file_ext->file_lock); /* prepare the output buffer */ client = (struct heci_client *) res_msg.data; client->max_msg_length = dev->me_clients[i].props.max_msg_length; @@ -294,6 +297,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, if (!heci_connect(dev, file_ext)) { rets = -ENODEV; spin_unlock_bh(&dev->device_lock); + spin_unlock(&file_ext->file_lock); goto end; } else { file_ext->timer_count = HECI_CONNECT_TIMEOUT; @@ -311,16 +315,20 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, &dev->ctrl_wr_list.heci_cb.cb_list); } spin_unlock_bh(&dev->device_lock); + spin_unlock(&file_ext->file_lock); err = wait_event_timeout(dev->wait_recvd_msg, (HECI_FILE_CONNECTED == file_ext->state || HECI_FILE_DISCONNECTED == file_ext->state), timeout * HZ); + spin_lock_bh(&dev->device_lock); if (HECI_FILE_CONNECTED == file_ext->state) { + spin_unlock_bh(&dev->device_lock); DBG("successfully connected to FW client.\n"); rets = file_ext->status; /* now copy the data to user space */ - if (copy_to_user(k_msg.data, res_msg.data, res_msg.size)) { + if (copy_to_user((void __user *)k_msg.data, + res_msg.data, res_msg.size)) { rets = -EFAULT; goto end; } @@ -332,6 +340,7 @@ int heci_ioctl_connect_client(struct iamt_heci_device *dev, int if_num, } else { DBG("failed to connect to FW client.file_ext->state = %d.\n", file_ext->state); + spin_unlock_bh(&dev->device_lock); if (!err) { DBG("wait_event_interruptible_timeout failed on client" " connect message fw response message.\n"); @@ -394,7 +403,8 @@ int heci_ioctl_wd(struct iamt_heci_device *dev, int if_num, /* copy the message to kernel space - use a pointer already * copied into kernel space */ - if (copy_from_user(req_msg.data, k_msg.data, req_msg.size)) { + if (copy_from_user(req_msg.data, + (void __user *)k_msg.data, req_msg.size)) { rets = -EFAULT; goto end; } @@ -464,7 +474,7 @@ int heci_ioctl_bypass_wd(struct iamt_heci_device *dev, int if_num, return -EMSGSIZE; } spin_unlock(&file_ext->file_lock); - if (copy_from_user(&flag, k_msg.data, 1)) { + if (copy_from_user(&flag, (void __user *)k_msg.data, 1)) { rets = -EFAULT; goto end; } @@ -631,28 +641,39 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num, DBG("received wrong function input param.\n"); return -ENODEV; } - if (file_ext->state != HECI_FILE_CONNECTED) - return -ENODEV; spin_lock_bh(&dev->device_lock); + if (file_ext->state != HECI_FILE_CONNECTED) { + spin_unlock_bh(&dev->device_lock); + return -ENODEV; + } + if (dev->heci_state != HECI_ENABLED) { spin_unlock_bh(&dev->device_lock); return -ENODEV; } spin_unlock_bh(&dev->device_lock); DBG("check if read is pending.\n"); + spin_lock_bh(&file_ext->read_io_lock); if ((file_ext->read_pending) || (file_ext->read_cb != NULL)) { DBG("read is pending.\n"); + spin_unlock_bh(&file_ext->read_io_lock); return -EBUSY; } + spin_unlock_bh(&file_ext->read_io_lock); + priv_cb = kzalloc(sizeof(struct heci_cb_private), GFP_KERNEL); if (!priv_cb) return -ENOMEM; + spin_lock_bh(&file_ext->read_io_lock); DBG("allocation call back success\n" "host client = %d, ME client = %d\n", file_ext->host_client_id, file_ext->me_client_id); + spin_unlock_bh(&file_ext->read_io_lock); + spin_lock_bh(&dev->device_lock); + spin_lock_bh(&file_ext->read_io_lock); for (i = 0; i < dev->num_heci_me_clients; i++) { if (dev->me_clients[i].client_id == file_ext->me_client_id) break; @@ -660,6 +681,7 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num, } BUG_ON(dev->me_clients[i].client_id != file_ext->me_client_id); + spin_unlock_bh(&file_ext->read_io_lock); if (i == dev->num_heci_me_clients) { rets = -ENODEV; goto unlock; @@ -678,12 +700,14 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num, /* make sure information is zero before we start */ priv_cb->information = 0; priv_cb->file_private = (void *) file_ext; - file_ext->read_cb = priv_cb; spin_lock_bh(&dev->device_lock); + spin_lock_bh(&file_ext->read_io_lock); + file_ext->read_cb = priv_cb; if (dev->host_buffer_is_empty) { dev->host_buffer_is_empty = 0; if (!heci_send_flow_control(dev, file_ext)) { rets = -ENODEV; + spin_unlock_bh(&file_ext->read_io_lock); goto unlock; } else { list_add_tail(&priv_cb->cb_list, @@ -693,6 +717,7 @@ int heci_start_read(struct iamt_heci_device *dev, int if_num, list_add_tail(&priv_cb->cb_list, &dev->ctrl_wr_list.heci_cb.cb_list); } + spin_unlock_bh(&file_ext->read_io_lock); spin_unlock_bh(&dev->device_lock); return rets; unlock: |