Re: [PATCH net-next] hv_netvsc: Implement batching of receive completions
From: Haiyang ZhangDate: Fri, 19 Aug 2016 14:47:09 -0700 > From: Haiyang Zhang > > The existing code uses busy retry when unable to send out receive > completions due to full ring buffer. It also gives up retrying after limit > is reached, and causes receive buffer slots not being recycled. > This patch implements batching of receive completions. It also prevents > dropping receive completions due to full ring buffer. > > Signed-off-by: Haiyang Zhang > Reviewed-by: Stephen Hemminger Applied, thanks. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 0/7] staging: lustre: last missing patches for lustre 2.6
On Fri, 2016-08-19 at 14:07 -0400, James Simmons wrote: > Resolved the last remain bug that prevented earlier submission. > This covers the remaining patches that were missing from the > upstream client that was in Lustre 2.6 except for the work for > LU-2484. The work for LU-2484 depends on the stat infrastructure > that was removed earlier from the upstream client. That will > be done at a later date. In reality this is a pre-2.7 client > due to the landing of many patches earlier from lustre 2.7. > In any case this is a huge milestone for the lustre client in > the linux kernel. Couple things: 1: I'd like to see the lustre #include files separated into only two internal/external directories akin to the include/linux and include/uapi directories used by linux. Is this a reasonable thing? and 2: James, you seem to aggregate a lot of lustre patches and yet you are not a listed maintainer. Should you be? ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 0/7] staging: lustre: last missing patches for lustre 2.6
On Fri, 2016-08-19 at 20:44 +0100, James Simmons wrote: > > 1: I'd like to see the lustre #include files separated into > > only two internal/external directories akin to the > > include/linux and include/uapi directories used by linux. [] > For the first question yes it is reasonable and developers > have been working to cleanup and separate out the uapi headers > from the normal kernel headers. For staging/lustre/lustre we > have local headers *_internal.h which only matter for that > particular subdirectory. The rest of the headers are all in > > staging/lustre/lustre/include/* > > In that directory we have the linux subdirectory. That has > gone away in newer lustre versions so I would need to push > the patch to remove it. The other directory > > staging/lustre/lustre/include/lustre/* > > contains all our uapi headers like lustre_user.h and lustre_idl.h. > Well that is not entirely correct. We still have uapi headers > like uapi_kernelcomm.h one directory up. It just if we change those > I need to update our userland tools as well. I have a patch ready > but I need to push it to our utility branch as well. > The next lot is all the LNet/libcfs stuff. The good news for LNet > the headers have been cleaned up so separating them out is easy. > Well there can always be more improvements. Now libcfs is a bit > messy. The libcfs/linux directory needs to be removed yet. Also > libcfs_debug.h needs to broken up for uapi use. > > Thats the run down about where we are at for the headers. Also it > gives you an idea where we are heading. So how do you need this > layed out for what you want to do? Where do you want to place the > headers? Thanks. I don't _need_ anything, but I think it'd be simpler to have just 2 directories, one for lustre kernel stuff and another for lustre uapi stuff. That applies for LNet and libcfs #includes as well. To me, ideally, there'd only be 2 #include directories so that the only used #include styles could become: #include and #include and that would work regardless of lustre's layout in staging or elsewhere. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH net-next] hv_netvsc: Implement batching of receive completions
From: Haiyang ZhangThe existing code uses busy retry when unable to send out receive completions due to full ring buffer. It also gives up retrying after limit is reached, and causes receive buffer slots not being recycled. This patch implements batching of receive completions. It also prevents dropping receive completions due to full ring buffer. Signed-off-by: Haiyang Zhang Reviewed-by: Stephen Hemminger --- drivers/net/hyperv/hyperv_net.h | 17 drivers/net/hyperv/netvsc.c | 170 ++--- drivers/net/hyperv/rndis_filter.c |6 +- 3 files changed, 160 insertions(+), 33 deletions(-) diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h index fa7b1e4..ce45d68 100644 --- a/drivers/net/hyperv/hyperv_net.h +++ b/drivers/net/hyperv/hyperv_net.h @@ -634,6 +634,20 @@ struct multi_send_data { u32 count; /* counter of batched packets */ }; +struct recv_comp_data { + u64 tid; /* transaction id */ + u32 status; +}; + +/* Netvsc Receive Slots Max */ +#define NETVSC_RECVSLOT_MAX (NETVSC_RECEIVE_BUFFER_SIZE / ETH_DATA_LEN + 1) + +struct multi_recv_comp { + void *buf; /* queued receive completions */ + u32 first; /* first data entry */ + u32 next; /* next entry for writing */ +}; + struct netvsc_stats { u64 packets; u64 bytes; @@ -736,6 +750,9 @@ struct netvsc_device { u32 max_pkt; /* max number of pkt in one send, e.g. 8 */ u32 pkt_align; /* alignment bytes, e.g. 8 */ + struct multi_recv_comp mrc[VRSS_CHANNEL_MAX]; + atomic_t num_outstanding_recvs; + atomic_t open_cnt; }; diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c index 8078bc2..b15edfc 100644 --- a/drivers/net/hyperv/netvsc.c +++ b/drivers/net/hyperv/netvsc.c @@ -74,6 +74,9 @@ static struct netvsc_device *alloc_net_device(void) return NULL; } + net_device->mrc[0].buf = vzalloc(NETVSC_RECVSLOT_MAX * +sizeof(struct recv_comp_data)); + init_waitqueue_head(_device->wait_drain); net_device->destroy = false; atomic_set(_device->open_cnt, 0); @@ -85,6 +88,11 @@ static struct netvsc_device *alloc_net_device(void) static void free_netvsc_device(struct netvsc_device *nvdev) { + int i; + + for (i = 0; i < VRSS_CHANNEL_MAX; i++) + vfree(nvdev->mrc[i].buf); + kfree(nvdev->cb_buffer); kfree(nvdev); } @@ -107,7 +115,8 @@ static struct netvsc_device *get_inbound_net_device(struct hv_device *device) goto get_in_err; if (net_device->destroy && - atomic_read(_device->num_outstanding_sends) == 0) + atomic_read(_device->num_outstanding_sends) == 0 && + atomic_read(_device->num_outstanding_recvs) == 0) net_device = NULL; get_in_err: @@ -972,49 +981,121 @@ send_now: return ret; } -static void netvsc_send_recv_completion(struct hv_device *device, - struct vmbus_channel *channel, - struct netvsc_device *net_device, - u64 transaction_id, u32 status) +static int netvsc_send_recv_completion(struct vmbus_channel *channel, + u64 transaction_id, u32 status) { struct nvsp_message recvcompMessage; - int retries = 0; int ret; - struct net_device *ndev = hv_get_drvdata(device); recvcompMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE; recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status = status; -retry_send_cmplt: /* Send the completion */ ret = vmbus_sendpacket(channel, , - sizeof(struct nvsp_message), transaction_id, - VM_PKT_COMP, 0); - if (ret == 0) { - /* success */ - /* no-op */ - } else if (ret == -EAGAIN) { - /* no more room...wait a bit and attempt to retry 3 times */ - retries++; - netdev_err(ndev, "unable to send receive completion pkt" - " (tid %llx)...retrying %d\n", transaction_id, retries); - - if (retries < 4) { - udelay(100); - goto retry_send_cmplt; - } else { - netdev_err(ndev, "unable to send receive " - "completion pkt (tid %llx)...give up retrying\n", - transaction_id); - } - } else { - netdev_err(ndev, "unable to send receive " - "completion pkt - %llx\n", transaction_id); + sizeof(struct nvsp_message_header) +
Re: [PATCH 0/7] staging: lustre: last missing patches for lustre 2.6
> On Fri, 2016-08-19 at 14:07 -0400, James Simmons wrote: > > Resolved the last remain bug that prevented earlier submission. > > This covers the remaining patches that were missing from the > > upstream client that was in Lustre 2.6 except for the work for > > LU-2484. The work for LU-2484 depends on the stat infrastructure > > that was removed earlier from the upstream client. That will > > be done at a later date. In reality this is a pre-2.7 client > > due to the landing of many patches earlier from lustre 2.7. > > In any case this is a huge milestone for the lustre client in > > the linux kernel. > > Couple things: > > 1: I'd like to see the lustre #include files separated into > only two internal/external directories akin to the > include/linux and include/uapi directories used by linux. > > Is this a reasonable thing? > > and > > 2: James, you seem to aggregate a lot of lustre patches and > yet you are not a listed maintainer. Should you be? The second question is easy to answer. At this point yeah I should be listed as a maintainer. As long as Andreas and Oleg are okay with that. For the first question yes it is reasonable and developers have been working to cleanup and separate out the uapi headers from the normal kernel headers. For staging/lustre/lustre we have local headers *_internal.h which only matter for that particular subdirectory. The rest of the headers are all in staging/lustre/lustre/include/* In that directory we have the linux subdirectory. That has gone away in newer lustre versions so I would need to push the patch to remove it. The other directory staging/lustre/lustre/include/lustre/* contains all our uapi headers like lustre_user.h and lustre_idl.h. Well that is not entirely correct. We still have uapi headers like uapi_kernelcomm.h one directory up. It just if we change those I need to update our userland tools as well. I have a patch ready but I need to push it to our utility branch as well. The next lot is all the LNet/libcfs stuff. The good news for LNet the headers have been cleaned up so separating them out is easy. Well there can always be more improvements. Now libcfs is a bit messy. The libcfs/linux directory needs to be removed yet. Also libcfs_debug.h needs to broken up for uapi use. Thats the run down about where we are at for the headers. Also it gives you an idea where we are heading. So how do you need this layed out for what you want to do? Where do you want to place the headers? ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/7] staging: lustre: last missing patches for lustre 2.6
Resolved the last remain bug that prevented earlier submission. This covers the remaining patches that were missing from the upstream client that was in Lustre 2.6 except for the work for LU-2484. The work for LU-2484 depends on the stat infrastructure that was removed earlier from the upstream client. That will be done at a later date. In reality this is a pre-2.7 client due to the landing of many patches earlier from lustre 2.7. In any case this is a huge milestone for the lustre client in the linux kernel. James Simmons (1): staging: lustre: update version to 2.5.99 Jian Yu (1): staging: lustre: obd: remove unused lmv_readpages()/mdc_readpage() John L. Hammond (2): staging: lustre: obd: remove dead code staging: lustre: obd: decruft md_enqueue() and md_intent_lock() wang di (3): staging: lustre: lmv: implement lmv version of read_page staging: lustre: llite: move dir cache to MDC layer staging: lustre: mdt: add OBD_CONNECT_DIR_STRIPE flag .../lustre/lustre/include/lustre/lustre_idl.h |7 +- .../staging/lustre/lustre/include/lustre_import.h | 22 - .../staging/lustre/lustre/include/lustre_lite.h| 11 - drivers/staging/lustre/lustre/include/lustre_log.h |3 +- .../lustre/lustre/include/lustre_req_layout.h |3 - drivers/staging/lustre/lustre/include/lustre_ver.h |4 +- drivers/staging/lustre/lustre/include/obd.h| 71 +--- drivers/staging/lustre/lustre/include/obd_class.h | 67 +-- .../staging/lustre/lustre/include/obd_support.h|1 - drivers/staging/lustre/lustre/llite/dir.c | 334 + drivers/staging/lustre/lustre/llite/file.c | 39 +- .../staging/lustre/lustre/llite/llite_internal.h |2 +- drivers/staging/lustre/lustre/llite/llite_lib.c|3 +- drivers/staging/lustre/lustre/llite/namei.c|4 +- drivers/staging/lustre/lustre/llite/statahead.c| 12 +- drivers/staging/lustre/lustre/llite/xattr_cache.c | 12 +- drivers/staging/lustre/lustre/lmv/lmv_intent.c | 50 +- drivers/staging/lustre/lustre/lmv/lmv_internal.h |3 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c| 479 +++--- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 20 +- drivers/staging/lustre/lustre/mdc/mdc_lib.c| 15 - drivers/staging/lustre/lustre/mdc/mdc_locks.c | 47 +-- drivers/staging/lustre/lustre/mdc/mdc_request.c| 516 ++-- drivers/staging/lustre/lustre/obdclass/class_obd.c | 25 - .../lustre/lustre/obdclass/linux/linux-obdo.c |2 +- .../lustre/lustre/obdclass/lprocfs_status.c|2 + .../staging/lustre/lustre/obdclass/obd_config.c| 16 +- drivers/staging/lustre/lustre/obdclass/obdo.c |7 +- .../staging/lustre/lustre/obdecho/echo_client.c|1 - drivers/staging/lustre/lustre/osc/osc_request.c| 12 +- drivers/staging/lustre/lustre/ptlrpc/layout.c | 17 - drivers/staging/lustre/lustre/ptlrpc/wiretest.c|2 + 32 files changed, 912 insertions(+), 897 deletions(-) ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/7] staging: lustre: llite: move dir cache to MDC layer
From: wang diMove directory entries cache from llite to MDC, so client side dir stripe will use independent hash function(in LMV), which does not need to be tightly coupled with the backend storage dir-entry hash function. With striped directory, it will be 2-tier hash, LMV calculate hash value according to the name and hash-type in layout, then each MDT will store these entry in disk by its own hash. Signed-off-by: wang di Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-3531 Reviewed-on: http://review.whamcloud.com/7043 Reviewed-by: John L. Hammond Reviewed-by: Jinshan Xiong Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- .../staging/lustre/lustre/include/lustre_lite.h| 11 - drivers/staging/lustre/lustre/llite/dir.c | 334 + .../staging/lustre/lustre/llite/llite_internal.h |2 +- drivers/staging/lustre/lustre/llite/statahead.c| 12 +- drivers/staging/lustre/lustre/mdc/mdc_internal.h |8 + drivers/staging/lustre/lustre/mdc/mdc_request.c| 531 6 files changed, 563 insertions(+), 335 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_lite.h b/drivers/staging/lustre/lustre/include/lustre_lite.h index a3d7573..e2f3767 100644 --- a/drivers/staging/lustre/lustre/include/lustre_lite.h +++ b/drivers/staging/lustre/lustre/include/lustre_lite.h @@ -80,17 +80,6 @@ static inline void ll_dir_chain_fini(struct ll_dir_chain *chain) { } -static inline unsigned long hash_x_index(__u64 hash, int hash64) -{ - if (BITS_PER_LONG == 32 && hash64) - hash >>= 32; - /* save hash 0 as index 0 because otherwise we'll save it at -* page index end (~0UL) and it causes truncate_inode_pages_range() -* to loop forever. -*/ - return ~0UL - (hash + !hash); -} - /** @} lite */ #endif diff --git a/drivers/staging/lustre/lustre/llite/dir.c b/drivers/staging/lustre/lustre/llite/dir.c index ed09015..532047b 100644 --- a/drivers/staging/lustre/lustre/llite/dir.c +++ b/drivers/staging/lustre/lustre/llite/dir.c @@ -134,111 +134,35 @@ * for this integrated page will be adjusted. See lmv_adjust_dirpages(). * */ - -/* returns the page unlocked, but with a reference */ -static int ll_dir_filler(void *_hash, struct page *page0) +struct page *ll_get_dir_page(struct inode *dir, struct md_op_data *op_data, +__u64 offset, struct ll_dir_chain *chain) { - struct inode *inode = page0->mapping->host; - int hash64 = ll_i2sbi(inode)->ll_flags & LL_SBI_64BIT_HASH; - struct obd_export *exp = ll_i2sbi(inode)->ll_md_exp; - struct ptlrpc_request *request; - struct mdt_body *body; - struct md_op_data *op_data; - __u64 hash = *((__u64 *)_hash); - struct page **page_pool; + struct md_callback cb_op; struct page *page; - struct lu_dirpage *dp; - int max_pages = ll_i2sbi(inode)->ll_md_brw_pages; - int nrdpgs = 0; /* number of pages read actually */ - int npages; - int i; int rc; - CDEBUG(D_VFSTRACE, "VFS Op:inode="DFID"(%p) hash %llu\n", - PFID(ll_inode2fid(inode)), inode, hash); - - LASSERT(max_pages > 0 && max_pages <= MD_MAX_BRW_PAGES); - - op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0, -LUSTRE_OPC_ANY, NULL); - if (IS_ERR(op_data)) - return PTR_ERR(op_data); - - page_pool = kcalloc(max_pages, sizeof(page), GFP_NOFS); - if (page_pool) { - page_pool[0] = page0; - } else { - page_pool = - max_pages = 1; - } - for (npages = 1; npages < max_pages; npages++) { - page = page_cache_alloc_cold(inode->i_mapping); - if (!page) - break; - page_pool[npages] = page; - } - - op_data->op_npages = npages; - op_data->op_offset = hash; - rc = md_readpage(exp, op_data, page_pool, ); - ll_finish_md_op_data(op_data); - if (rc < 0) { - /* page0 is special, which was added into page cache early */ - delete_from_page_cache(page0); - } else if (rc == 0) { - body = req_capsule_server_get(>rq_pill, _MDT_BODY); - /* Checked by mdc_readpage() */ - if (body->mbo_valid & OBD_MD_FLSIZE) - i_size_write(inode, body->mbo_size); - - nrdpgs = (request->rq_bulk->bd_nob_transferred+PAGE_SIZE-1) ->> PAGE_SHIFT; - SetPageUptodate(page0); - } - unlock_page(page0); - ptlrpc_req_finished(request); - - CDEBUG(D_VFSTRACE, "read %d/%d pages\n", nrdpgs, npages); - - for
[PATCH 7/7] staging: lustre: update version to 2.5.99
With all but one of the the missing patches from the lustre 2.6 version merged upstream its time to update the upstream clients version. Signed-off-by: James Simmons--- drivers/staging/lustre/lustre/include/lustre_ver.h |4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre_ver.h b/drivers/staging/lustre/lustre/include/lustre_ver.h index 2bb59b2..414075f 100644 --- a/drivers/staging/lustre/lustre/include/lustre_ver.h +++ b/drivers/staging/lustre/lustre/include/lustre_ver.h @@ -2,10 +2,10 @@ #define _LUSTRE_VER_H_ #define LUSTRE_MAJOR 2 -#define LUSTRE_MINOR 4 +#define LUSTRE_MINOR 5 #define LUSTRE_PATCH 60 #define LUSTRE_FIX 0 -#define LUSTRE_VERSION_STRING "2.4.60" +#define LUSTRE_VERSION_STRING "2.5.99" #define OBD_OCD_VERSION(major, minor, patch, fix) \ (((major) << 24) + ((minor) << 16) + ((patch) << 8) + (fix)) -- 1.7.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 6/7] staging: lustre: obd: decruft md_enqueue() and md_intent_lock()
From: John L. HammondRemove the lmm and lmmsize parameters from both functions, storing that data in md_op_data when needed. Remove the unused lookup_flags parameter from md_intent_lock(), and the unused reqp parameter from md_enqueue(). Add a union ldlm_policy_data * parameter to md_enqueue(). Remove the unused function lmv_enqueue_remote(). Signed-off-by: John L. Hammond Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-on: http://review.whamcloud.com/10205 Reviewed-by: wangdi Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/include/obd.h |7 +- drivers/staging/lustre/lustre/include/obd_class.h | 18 ++--- drivers/staging/lustre/lustre/llite/file.c| 39 +-- drivers/staging/lustre/lustre/llite/namei.c |4 +- drivers/staging/lustre/lustre/llite/xattr_cache.c | 12 ++-- drivers/staging/lustre/lustre/lmv/lmv_intent.c| 50 ++ drivers/staging/lustre/lustre/lmv/lmv_internal.h |3 +- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 72 +--- drivers/staging/lustre/lustre/mdc/mdc_internal.h | 10 ++-- drivers/staging/lustre/lustre/mdc/mdc_locks.c | 47 + drivers/staging/lustre/lustre/mdc/mdc_request.c |2 +- 11 files changed, 90 insertions(+), 174 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/obd.h b/drivers/staging/lustre/lustre/include/obd.h index 6fc0bcc..ac620fd 100644 --- a/drivers/staging/lustre/lustre/include/obd.h +++ b/drivers/staging/lustre/lustre/include/obd.h @@ -747,6 +747,7 @@ struct md_op_data { __u32 op_fsgid; cfs_cap_t op_cap; void *op_data; + size_t op_data_size; /* iattr fields and blocks. */ struct iattrop_attr; @@ -967,15 +968,15 @@ struct md_ops { int (*done_writing)(struct obd_export *, struct md_op_data *, struct md_open_data *); int (*enqueue)(struct obd_export *, struct ldlm_enqueue_info *, + const ldlm_policy_data_t *, struct lookup_intent *, struct md_op_data *, - struct lustre_handle *, void *, int, - struct ptlrpc_request **, __u64); + struct lustre_handle *, __u64); int (*getattr)(struct obd_export *, struct md_op_data *, struct ptlrpc_request **); int (*getattr_name)(struct obd_export *, struct md_op_data *, struct ptlrpc_request **); int (*intent_lock)(struct obd_export *, struct md_op_data *, - void *, int, struct lookup_intent *, int, + struct lookup_intent *, struct ptlrpc_request **, ldlm_blocking_callback, __u64); int (*link)(struct obd_export *, struct md_op_data *, diff --git a/drivers/staging/lustre/lustre/include/obd_class.h b/drivers/staging/lustre/lustre/include/obd_class.h index fe1af94..79fc041 100644 --- a/drivers/staging/lustre/lustre/include/obd_class.h +++ b/drivers/staging/lustre/lustre/include/obd_class.h @@ -1410,19 +1410,18 @@ static inline int md_done_writing(struct obd_export *exp, static inline int md_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo, +const ldlm_policy_data_t *policy, struct lookup_intent *it, struct md_op_data *op_data, struct lustre_handle *lockh, -void *lmm, int lmmsize, -struct ptlrpc_request **req, __u64 extra_lock_flags) { int rc; EXP_CHECK_MD_OP(exp, enqueue); EXP_MD_COUNTER_INCREMENT(exp, enqueue); - rc = MDP(exp->exp_obd, enqueue)(exp, einfo, it, op_data, lockh, - lmm, lmmsize, req, extra_lock_flags); + rc = MDP(exp->exp_obd, enqueue)(exp, einfo, policy, it, op_data, lockh, + extra_lock_flags); return rc; } @@ -1439,9 +1438,9 @@ static inline int md_getattr_name(struct obd_export *exp, } static inline int md_intent_lock(struct obd_export *exp, -struct md_op_data *op_data, void *lmm, -int lmmsize, struct lookup_intent *it, -int lookup_flags, struct ptlrpc_request **reqp, +struct md_op_data *op_data, +struct lookup_intent *it, +struct ptlrpc_request **reqp,
[PATCH 3/7] staging: lustre: obd: remove unused lmv_readpages()/mdc_readpage()
From: Jian YuThis patch fixes the following compile error by removing the dead codes: "error: 'xxx_readpages' defined but not used". Now that we have md_read_page functionality we can remove all the *_readpage implementations. Signed-off-by: Jian Yu Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4669 Reviewed-on: http://review.whamcloud.com/9810 Reviewed-by: John L. Hammond Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- drivers/staging/lustre/lustre/lmv/lmv_obd.c | 146 --- drivers/staging/lustre/lustre/mdc/mdc_request.c | 82 - 2 files changed, 0 insertions(+), 228 deletions(-) diff --git a/drivers/staging/lustre/lustre/lmv/lmv_obd.c b/drivers/staging/lustre/lustre/lmv/lmv_obd.c index 1f01be4..44a334a 100644 --- a/drivers/staging/lustre/lustre/lmv/lmv_obd.c +++ b/drivers/staging/lustre/lustre/lmv/lmv_obd.c @@ -2223,151 +2223,6 @@ static int lmv_sync(struct obd_export *exp, const struct lu_fid *fid, return rc; } -/* - * Adjust a set of pages, each page containing an array of lu_dirpages, - * so that each page can be used as a single logical lu_dirpage. - * - * A lu_dirpage is laid out as follows, where s = ldp_hash_start, - * e = ldp_hash_end, f = ldp_flags, p = padding, and each "ent" is a - * struct lu_dirent. It has size up to LU_PAGE_SIZE. The ldp_hash_end - * value is used as a cookie to request the next lu_dirpage in a - * directory listing that spans multiple pages (two in this example): - * - * | | - * .|v--- -. - * |s|e|f|p|ent|ent| ... |ent| - * '--|-- -' Each CFS_PAGE contains a single - *'--.lu_dirpage. - * .-v--- -. - * |s|e|f|p|ent| 0 | ... | 0 | - * '- -' - * - * However, on hosts where the native VM page size (PAGE_SIZE) is - * larger than LU_PAGE_SIZE, a single host page may contain multiple - * lu_dirpages. After reading the lu_dirpages from the MDS, the - * ldp_hash_end of the first lu_dirpage refers to the one immediately - * after it in the same CFS_PAGE (arrows simplified for brevity, but - * in general e0==s1, e1==s2, etc.): - * - * . -. - * |s0|e0|f0|p|ent|ent| ... |ent| - * |---v -| - * |s1|e1|f1|p|ent|ent| ... |ent| - * |---v -| Here, each CFS_PAGE contains - * ... multiple lu_dirpages. - * |---v -| - * |s'|e'|f'|p|ent|ent| ... |ent| - * '---| -' - * v - * .. - * | next CFS_PAGE | - * - * This structure is transformed into a single logical lu_dirpage as follows: - * - * - Replace e0 with e' so the request for the next lu_dirpage gets the page - * labeled 'next CFS_PAGE'. - * - * - Copy the LDF_COLLIDE flag from f' to f0 to correctly reflect whether - * a hash collision with the next page exists. - * - * - Adjust the lde_reclen of the ending entry of each lu_dirpage to span - * to the first entry of the next lu_dirpage. - */ -#if PAGE_SIZE > LU_PAGE_SIZE -static void lmv_adjust_dirpages(struct page **pages, int ncfspgs, int nlupgs) -{ - int i; - - for (i = 0; i < ncfspgs; i++) { - struct lu_dirpage *dp = kmap(pages[i]); - struct lu_dirpage *first = dp; - struct lu_dirent*end_dirent = NULL; - struct lu_dirent*ent; - __u64 hash_end = dp->ldp_hash_end; - __u32 flags = dp->ldp_flags; - - while (--nlupgs > 0) { - ent = lu_dirent_start(dp); - for (end_dirent = ent; ent; -end_dirent = ent, ent = lu_dirent_next(ent)) - ; - - /* Advance dp to next lu_dirpage. */ - dp = (struct lu_dirpage *)((char *)dp + LU_PAGE_SIZE); - - /* Check if we've reached the end of the CFS_PAGE. */ - if (!((unsigned long)dp & ~PAGE_MASK)) - break; - - /* Save the hash and flags of this lu_dirpage. */ - hash_end = dp->ldp_hash_end; - flags = dp->ldp_flags; - - /* Check if lu_dirpage contains no entries. */ - if (!end_dirent) - break; - - /* Enlarge the end entry lde_reclen from 0 to -* first entry of next lu_dirpage. -*/ - LASSERT(le16_to_cpu(end_dirent->lde_reclen) == 0); - end_dirent->lde_reclen = - cpu_to_le16((char *)(dp->ldp_entries) - -
[PATCH 4/7] staging: lustre: mdt: add OBD_CONNECT_DIR_STRIPE flag
From: wang diAdd OBD_CONNECT_DIR_STRIPE to tell if the client supports striped dir, so only new client (>= 2.6) can access striped directory. Signed-off-by: wang di Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-4843 Reviewed-on: http://review.whamcloud.com/10773 Reviewed-by: Andreas Dilger Reviewed-by: John L. Hammond Reviewed-by: Bob Glossman Signed-off-by: James Simmons --- .../lustre/lustre/include/lustre/lustre_idl.h |1 + drivers/staging/lustre/lustre/llite/llite_lib.c|3 ++- .../lustre/lustre/obdclass/lprocfs_status.c|2 ++ drivers/staging/lustre/lustre/ptlrpc/wiretest.c|2 ++ 4 files changed, 7 insertions(+), 1 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index 9545451..c57231b 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -1291,6 +1291,7 @@ void lustre_swab_ptlrpc_body(struct ptlrpc_body *pb); */ #define OBD_CONNECT_LFSCK 0x40ULL/* support online LFSCK */ #define OBD_CONNECT_UNLINK_CLOSE 0x100ULL/* close file in unlink */ +#define OBD_CONNECT_DIR_STRIPE 0x400ULL/* striped DNE dir */ /* XXX README XXX: * Please DO NOT add flag values here before first ensuring that this same diff --git a/drivers/staging/lustre/lustre/llite/llite_lib.c b/drivers/staging/lustre/lustre/llite/llite_lib.c index 64c8a2b..49ed3df 100644 --- a/drivers/staging/lustre/lustre/llite/llite_lib.c +++ b/drivers/staging/lustre/lustre/llite/llite_lib.c @@ -190,7 +190,8 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt, OBD_CONNECT_MAX_EASIZE | OBD_CONNECT_FLOCK_DEAD | OBD_CONNECT_DISP_STRIPE | OBD_CONNECT_LFSCK | - OBD_CONNECT_OPEN_BY_FID; + OBD_CONNECT_OPEN_BY_FID | + OBD_CONNECT_DIR_STRIPE; if (sbi->ll_flags & LL_SBI_SOM_PREVIEW) data->ocd_connect_flags |= OBD_CONNECT_SOM; diff --git a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c index 45e3c4a..3d6da74 100644 --- a/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c +++ b/drivers/staging/lustre/lustre/obdclass/lprocfs_status.c @@ -101,6 +101,8 @@ static const char * const obd_connect_names[] = { "unknown", "unlink_close", "unknown", + "dir_stripe", + "unknown", NULL }; diff --git a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c index b428528..3748f71 100644 --- a/drivers/staging/lustre/lustre/ptlrpc/wiretest.c +++ b/drivers/staging/lustre/lustre/ptlrpc/wiretest.c @@ -1075,6 +1075,8 @@ void lustre_assert_wire_constants(void) OBD_CONNECT_LFSCK); LASSERTF(OBD_CONNECT_UNLINK_CLOSE == 0x100ULL, "found 0x%.16llxULL\n", OBD_CONNECT_UNLINK_CLOSE); + LASSERTF(OBD_CONNECT_DIR_STRIPE == 0x400ULL, "found 0x%.16llxULL\n", +OBD_CONNECT_DIR_STRIPE); LASSERTF(OBD_CKSUM_CRC32 == 0x0001UL, "found 0x%.8xUL\n", (unsigned)OBD_CKSUM_CRC32); LASSERTF(OBD_CKSUM_ADLER == 0x0002UL, "found 0x%.8xUL\n", -- 1.7.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 5/7] staging: lustre: obd: remove dead code
From: John L. HammondRemove unused OBD functions: oti_alloc_cookies(), oti_free_cookies(), class_observe_import(), class_unobserve_import(), md_is_subdir(), md_readpage(), obdo2fid(), fid2obdo(). Remove several unused, get-only, and set-only structure members. Signed-off-by: John L. Hammond Signed-off-by: James Simmons Intel-bug-id: https://jira.hpdd.intel.com/browse/LU-2675 Reviewed-on: http://review.whamcloud.com/9784 Reviewed-by: Bob Glossman Reviewed-by: Dmitry Eremin Reviewed-by: Andreas Dilger Signed-off-by: James Simmons --- .../lustre/lustre/include/lustre/lustre_idl.h |6 +- .../staging/lustre/lustre/include/lustre_import.h | 22 --- drivers/staging/lustre/lustre/include/lustre_log.h |3 +- .../lustre/lustre/include/lustre_req_layout.h |3 - drivers/staging/lustre/lustre/include/obd.h| 64 drivers/staging/lustre/lustre/include/obd_class.h | 49 +-- .../staging/lustre/lustre/include/obd_support.h|1 - drivers/staging/lustre/lustre/mdc/mdc_internal.h |2 - drivers/staging/lustre/lustre/mdc/mdc_lib.c| 15 - drivers/staging/lustre/lustre/mdc/mdc_request.c| 27 drivers/staging/lustre/lustre/obdclass/class_obd.c | 25 .../lustre/lustre/obdclass/linux/linux-obdo.c |2 +- .../staging/lustre/lustre/obdclass/obd_config.c| 16 +- drivers/staging/lustre/lustre/obdclass/obdo.c |7 +- .../staging/lustre/lustre/obdecho/echo_client.c|1 - drivers/staging/lustre/lustre/osc/osc_request.c| 12 +--- drivers/staging/lustre/lustre/ptlrpc/layout.c | 17 - 17 files changed, 18 insertions(+), 254 deletions(-) diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index c57231b..35af07e 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -1937,8 +1937,8 @@ enum mds_cmd { MDS_DISCONNECT = 39, MDS_GETSTATUS = 40, MDS_STATFS = 41, - MDS_PIN = 42, - MDS_UNPIN = 43, + MDS_PIN = 42, /* obsolete, never used in a release */ + MDS_UNPIN = 43, /* obsolete, never used in a release */ MDS_SYNC= 44, MDS_DONE_WRITING= 45, MDS_SET_INFO= 46, @@ -1947,7 +1947,7 @@ enum mds_cmd { MDS_GETXATTR= 49, MDS_SETXATTR= 50, /* obsolete, now it's MDS_REINT op */ MDS_WRITEPAGE = 51, - MDS_IS_SUBDIR = 52, + MDS_IS_SUBDIR = 52, /* obsolete, never used in a release */ MDS_GET_INFO= 53, MDS_HSM_STATE_GET = 54, MDS_HSM_STATE_SET = 55, diff --git a/drivers/staging/lustre/lustre/include/lustre_import.h b/drivers/staging/lustre/lustre/include/lustre_import.h index 4445be7..b7a7a74 100644 --- a/drivers/staging/lustre/lustre/include/lustre_import.h +++ b/drivers/staging/lustre/lustre/include/lustre_import.h @@ -305,28 +305,6 @@ struct obd_import { time64_t imp_last_reply_time;/* for health check */ }; -typedef void (*obd_import_callback)(struct obd_import *imp, void *closure, - int event, void *event_arg, void *cb_data); - -/** - * Structure for import observer. - * It is possible to register "observer" on an import and every time - * something happens to an import (like connect/evict/disconnect) - * obderver will get its callback called with event type - */ -struct obd_import_observer { - struct list_head oio_chain; - obd_import_callback oio_cb; - void*oio_cb_data; -}; - -void class_observe_import(struct obd_import *imp, obd_import_callback cb, - void *cb_data); -void class_unobserve_import(struct obd_import *imp, obd_import_callback cb, - void *cb_data); -void class_notify_import_observers(struct obd_import *imp, int event, - void *event_arg); - /* import.c */ static inline unsigned int at_est2timeout(unsigned int val) { diff --git a/drivers/staging/lustre/lustre/include/lustre_log.h b/drivers/staging/lustre/lustre/include/lustre_log.h index b96e023..995b266 100644 --- a/drivers/staging/lustre/lustre/include/lustre_log.h +++ b/drivers/staging/lustre/lustre/include/lustre_log.h @@ -277,12 +277,11 @@ static inline void llog_ctxt_put(struct llog_ctxt *ctxt) __llog_ctxt_put(NULL, ctxt); } -static inline void llog_group_init(struct obd_llog_group *olg, int group) +static inline void llog_group_init(struct obd_llog_group
[PATCH] rtlwifi: Fix missing country code for Great Britain
Some RTL8821AE devices sold in Great Britain have the country code of 0x25 encoded in their EEPROM. This value is not tested in the routine that establishes the regulatory info for the chip. The fix is to set this code to have the same capabilities as the EU countries. Signed-off-by: Larry FingerCc: Stable --- drivers/net/wireless/realtek/rtlwifi/regd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/net/wireless/realtek/rtlwifi/regd.c b/drivers/net/wireless/realtek/rtlwifi/regd.c index 3524441..6ee6bf8 100644 --- a/drivers/net/wireless/realtek/rtlwifi/regd.c +++ b/drivers/net/wireless/realtek/rtlwifi/regd.c @@ -345,9 +345,9 @@ static const struct ieee80211_regdomain *_rtl_regdomain_select( return _regdom_no_midband; case COUNTRY_CODE_IC: return _regdom_11; - case COUNTRY_CODE_ETSI: case COUNTRY_CODE_TELEC_NETGEAR: return _regdom_60_64; + case COUNTRY_CODE_ETSI: case COUNTRY_CODE_SPAIN: case COUNTRY_CODE_FRANCE: case COUNTRY_CODE_ISRAEL: @@ -406,6 +406,8 @@ static u8 channel_plan_to_country_code(u8 channelplan) return COUNTRY_CODE_WORLD_WIDE_13; case 0x22: return COUNTRY_CODE_IC; + case 0x25: + return COUNTRY_CODE_ETSI; case 0x32: return COUNTRY_CODE_TELEC_NETGEAR; case 0x41: -- 2.6.6 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 0/3] staging: most: fix aim-cdev issues
This patch set is needed to fix issues of the aim-cdev module. Christian Gromm (3): staging: most: aim-cdev: fix reported error codes staging: most: aim-cdev: report error returned by alloc_chrdev_region staging: most: aim-cdev: relocate call to ida_init() drivers/staging/most/aim-cdev/cdev.c | 24 ++-- 1 file changed, 14 insertions(+), 10 deletions(-) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 1/3] staging: most: aim-cdev: fix reported error codes
Currently, the aim-cdev is returning different error codes for the same root cause. This patch is needed to get rid of the module's inconsistency when reporting errors. Signed-off-by: Christian Gromm--- drivers/staging/most/aim-cdev/cdev.c | 19 +++ 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index de4f76a..6ca2440 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -130,7 +130,7 @@ static int aim_open(struct inode *inode, struct file *filp) if (!c->dev) { pr_info("WARN: Device is destroyed\n"); mutex_unlock(>io_mutex); - return -EBUSY; + return -ENODEV; } if (c->access_ref) { @@ -201,7 +201,7 @@ static ssize_t aim_write(struct file *filp, const char __user *buf, } if (unlikely(!c->dev)) { - ret = -EPIPE; + ret = -ENODEV; goto unlock; } @@ -256,7 +256,7 @@ aim_read(struct file *filp, char __user *buf, size_t count, loff_t *offset) /* make sure we don't submit to gone devices */ if (unlikely(!c->dev)) { mutex_unlock(>io_mutex); - return -EIO; + return -ENODEV; } to_copy = min_t(size_t, @@ -366,7 +366,7 @@ static int aim_rx_completion(struct mbo *mbo) spin_lock(>unlink); if (!c->access_ref || !c->dev) { spin_unlock(>unlink); - return -EFAULT; + return -ENODEV; } kfifo_in(>fifo, , 1); spin_unlock(>unlink); @@ -499,6 +499,8 @@ static struct most_aim cdev_aim = { static int __init mod_init(void) { + int err; + pr_info("init()\n"); INIT_LIST_HEAD(_list); @@ -506,16 +508,17 @@ static int __init mod_init(void) ida_init(_id); if (alloc_chrdev_region(_devno, 0, 50, "cdev") < 0) - return -EIO; + return -ENOMEM; major = MAJOR(aim_devno); aim_class = class_create(THIS_MODULE, "most_cdev_aim"); if (IS_ERR(aim_class)) { pr_err("no udev support\n"); + err = PTR_ERR(aim_class); goto free_cdev; } - - if (most_register_aim(_aim)) + err = most_register_aim(_aim); + if (err) goto dest_class; return 0; @@ -523,7 +526,7 @@ dest_class: class_destroy(aim_class); free_cdev: unregister_chrdev_region(aim_devno, 1); - return -EIO; + return err; } static void __exit mod_exit(void) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 3/3] staging: most: aim-cdev: relocate call to ida_init()
This patch moves the initialization of the idr structure towards the end of the module's init routine. This keeps the code compact and eliminates the need of having to call ida_destroy() in case the function exits with an exception. Signed-off-by: Christian Gromm--- drivers/staging/most/aim-cdev/cdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index db6f458..3864009 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -505,7 +505,6 @@ static int __init mod_init(void) INIT_LIST_HEAD(_list); spin_lock_init(_list_lock); - ida_init(_id); err = alloc_chrdev_region(_devno, 0, 50, "cdev"); if (err < 0) @@ -521,6 +520,7 @@ static int __init mod_init(void) err = most_register_aim(_aim); if (err) goto dest_class; + ida_init(_id); return 0; dest_class: -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 2/3] staging: most: aim-cdev: report error returned by alloc_chrdev_region
This patch forwards the error code returned by function alloc_chrdev_region(). It is needed to stop the module from hiding the actual cause of failure. Signed-off-by: Christian Gromm--- drivers/staging/most/aim-cdev/cdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/most/aim-cdev/cdev.c b/drivers/staging/most/aim-cdev/cdev.c index 6ca2440..db6f458 100644 --- a/drivers/staging/most/aim-cdev/cdev.c +++ b/drivers/staging/most/aim-cdev/cdev.c @@ -507,8 +507,9 @@ static int __init mod_init(void) spin_lock_init(_list_lock); ida_init(_id); - if (alloc_chrdev_region(_devno, 0, 50, "cdev") < 0) - return -ENOMEM; + err = alloc_chrdev_region(_devno, 0, 50, "cdev"); + if (err < 0) + return err; major = MAJOR(aim_devno); aim_class = class_create(THIS_MODULE, "most_cdev_aim"); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 10/17] staging: most: hdm-usb: fix race between enqueue and most_stop_enqueue
The "broken in pipe" handler of the USB-HDM calls most_stop_enqueue() to stop the MBO traffic before returning all MBOs back to the Mostcore. As the enqueue() call from the Mostcore may run in parallel with the most_stop_enqueue(), the HDM may run into the inconsistent state and crash the kernel. This patch synchronizes enqueue(), most_stop_enqueue() and most_resume_enqueue() with a mutex, hence avoiding the race condition. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 3 +- drivers/staging/most/mostcore/core.c | 53 -- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 7f00aaf..8d8c72c 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -415,7 +415,6 @@ static void hdm_write_completion(struct urb *urb) switch (urb->status) { case -EPIPE: dev_warn(dev, "Broken OUT pipe detected\n"); - most_stop_enqueue(>iface, channel); mdev->is_channel_healthy[channel] = false; mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; @@ -578,7 +577,6 @@ static void hdm_read_completion(struct urb *urb) switch (urb->status) { case -EPIPE: dev_warn(dev, "Broken IN pipe detected\n"); - most_stop_enqueue(>iface, channel); mdev->is_channel_healthy[channel] = false; mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; @@ -928,6 +926,7 @@ static void wq_clear_halt(struct work_struct *wq_obj) int pipe = clear_work->pipe; mutex_lock(>io_mutex); + most_stop_enqueue(>iface, channel); free_anchored_buffers(mdev, channel, MBO_E_INVAL); if (usb_clear_halt(mdev->usb_device, pipe)) dev_warn(>usb_device->dev, "Failed to reset endpoint.\n"); diff --git a/drivers/staging/most/mostcore/core.c b/drivers/staging/most/mostcore/core.c index b03cdc9..db0606ca 100644 --- a/drivers/staging/most/mostcore/core.c +++ b/drivers/staging/most/mostcore/core.c @@ -51,6 +51,7 @@ struct most_c_obj { u16 channel_id; bool is_poisoned; struct mutex start_mutex; + struct mutex nq_mutex; /* nq thread synchronization */ int is_starving; struct most_interface *iface; struct most_inst_obj *inst; @@ -1131,18 +1132,18 @@ static inline void trash_mbo(struct mbo *mbo) spin_unlock_irqrestore(>fifo_lock, flags); } -static struct mbo *get_hdm_mbo(struct most_c_obj *c) +static bool hdm_mbo_ready(struct most_c_obj *c) { - unsigned long flags; - struct mbo *mbo; + bool empty; - spin_lock_irqsave(>fifo_lock, flags); - if (c->enqueue_halt || list_empty(>halt_fifo)) - mbo = NULL; - else - mbo = list_pop_mbo(>halt_fifo); - spin_unlock_irqrestore(>fifo_lock, flags); - return mbo; + if (c->enqueue_halt) + return false; + + spin_lock_irq(>fifo_lock); + empty = list_empty(>halt_fifo); + spin_unlock_irq(>fifo_lock); + + return !empty; } static void nq_hdm_mbo(struct mbo *mbo) @@ -1160,20 +1161,32 @@ static int hdm_enqueue_thread(void *data) { struct most_c_obj *c = data; struct mbo *mbo; + int ret; typeof(c->iface->enqueue) enqueue = c->iface->enqueue; while (likely(!kthread_should_stop())) { wait_event_interruptible(c->hdm_fifo_wq, -(mbo = get_hdm_mbo(c)) || +hdm_mbo_ready(c) || kthread_should_stop()); - if (unlikely(!mbo)) + mutex_lock(>nq_mutex); + spin_lock_irq(>fifo_lock); + if (unlikely(c->enqueue_halt || list_empty(>halt_fifo))) { + spin_unlock_irq(>fifo_lock); + mutex_unlock(>nq_mutex); continue; + } + + mbo = list_pop_mbo(>halt_fifo); + spin_unlock_irq(>fifo_lock); if (c->cfg.direction == MOST_CH_RX) mbo->buffer_length = c->cfg.buffer_size; - if (unlikely(enqueue(mbo->ifp, mbo->hdm_channel_id, mbo))) { + ret = enqueue(mbo->ifp, mbo->hdm_channel_id, mbo); + mutex_unlock(>nq_mutex); + + if (unlikely(ret)) { pr_err("hdm enqueue failed\n"); nq_hdm_mbo(mbo); c->hdm_enqueue_task = NULL; @@ -1759,6
[PATCH 17/17] staging: most: hdm-usb: add support for new USB gadget
This patch is needed to make the driver support Microchip's OS81210 USB MOST network interface controller. It simply adds the gadget's product ID to the driver's ID table. Signed-off-by: Christian Gromm--- drivers/staging/most/hdm-usb/hdm_usb.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index f44f27e..08c4a3b 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -45,6 +45,7 @@ #define USB_DEV_ID_BRDG0xC001 /* PID: USB Bridge */ #define USB_DEV_ID_OS81118 0xCF18 /* PID: USB OS81118 */ #define USB_DEV_ID_OS81119 0xCF19 /* PID: USB OS81119 */ +#define USB_DEV_ID_OS81210 0xCF30 /* PID: USB OS81210 */ /* DRCI Addresses */ #define DRCI_REG_NI_STATE 0x0100 #define DRCI_REG_PACKET_BW 0x0101 @@ -935,6 +936,7 @@ static struct usb_device_id usbid[] = { { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), }, { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81118), }, { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), }, + { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81210), }, { } /* Terminating entry */ }; @@ -1304,7 +1306,8 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) mutex_lock(>io_mutex); if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || - le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119) { + le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119 || + le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81210) { /* this increments the reference count of the instance * object of the core */ -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 12/17] staging: most: hdm-usb: synchronize release of struct buf_anchor
In case a channel that is going to be destroyed has been tagged as not "healthy" by the function hdm_poison_channel() while the functions hdm_write_completion() or hdm_read_completion() are being executed, they race for destruction of buf_anchor. This patch fixes the problem. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 14 -- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 4156a30..26b5c1b 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -285,6 +285,8 @@ static unsigned int get_stream_frame_size(struct most_channel_config *cfg) static int hdm_poison_channel(struct most_interface *iface, int channel) { struct most_dev *mdev; + unsigned long flags; + spinlock_t *lock; /* temp. lock */ mdev = to_mdev(iface); if (unlikely(!iface)) { @@ -296,7 +298,10 @@ static int hdm_poison_channel(struct most_interface *iface, int channel) return -ECHRNG; } + lock = mdev->anchor_list_lock + channel; + spin_lock_irqsave(lock, flags); mdev->is_channel_healthy[channel] = false; + spin_unlock_irqrestore(lock, flags); cancel_work_sync(>clear_work[channel].ws); @@ -407,8 +412,10 @@ static void hdm_write_completion(struct urb *urb) dev = >usb_device->dev; lock = mdev->anchor_list_lock + channel; + spin_lock_irqsave(lock, flags); if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { + spin_unlock_irqrestore(lock, flags); complete(>urb_compl); return; } @@ -419,6 +426,7 @@ static void hdm_write_completion(struct urb *urb) case -EPIPE: dev_warn(dev, "Broken OUT pipe detected\n"); mdev->is_channel_healthy[channel] = false; + spin_unlock_irqrestore(lock, flags); mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); @@ -436,7 +444,6 @@ static void hdm_write_completion(struct urb *urb) mbo->processed_length = urb->actual_length; } - spin_lock_irqsave(lock, flags); list_del(>list); spin_unlock_irqrestore(lock, flags); kfree(anchor); @@ -571,8 +578,10 @@ static void hdm_read_completion(struct urb *urb) dev = >usb_device->dev; lock = mdev->anchor_list_lock + channel; + spin_lock_irqsave(lock, flags); if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { + spin_unlock_irqrestore(lock, flags); complete(>urb_compl); return; } @@ -583,6 +592,7 @@ static void hdm_read_completion(struct urb *urb) case -EPIPE: dev_warn(dev, "Broken IN pipe detected\n"); mdev->is_channel_healthy[channel] = false; + spin_unlock_irqrestore(lock, flags); mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); @@ -606,7 +616,7 @@ static void hdm_read_completion(struct urb *urb) mbo->status = MBO_E_INVAL; } } - spin_lock_irqsave(lock, flags); + list_del(>list); spin_unlock_irqrestore(lock, flags); kfree(anchor); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 13/17] staging: most: hdm-usb: remove completion object
Waiting for the urb_compl object to complete evaluates always as false. This patch removes this unnecessary completion object. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 11 +-- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 26b5c1b..29e98dc 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -72,7 +72,6 @@ struct buf_anchor { struct urb *urb; struct list_head list; - struct completion urb_compl; }; /** @@ -217,12 +216,7 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, spin_unlock_irqrestore(lock, flags); if (likely(urb)) { mbo = urb->context; - if (!irqs_disabled()) { - usb_kill_urb(urb); - } else { - usb_unlink_urb(urb); - wait_for_completion(>urb_compl); - } + usb_kill_urb(urb); if ((mbo) && (mbo->complete)) { mbo->status = status; mbo->processed_length = 0; @@ -416,7 +410,6 @@ static void hdm_write_completion(struct urb *urb) if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { spin_unlock_irqrestore(lock, flags); - complete(>urb_compl); return; } @@ -582,7 +575,6 @@ static void hdm_read_completion(struct urb *urb) if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { spin_unlock_irqrestore(lock, flags); - complete(>urb_compl); return; } @@ -678,7 +670,6 @@ static int hdm_enqueue(struct most_interface *iface, int channel, } anchor->urb = urb; - init_completion(>urb_compl); mbo->priv = anchor; if ((mdev->padding_active[channel]) && -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 16/17] staging: most: hdm-usb: remove unnecessary status assignment
The USB completion callbacks set the status field of an MBO object before scheduling the clear_work. This patch removes this redundant assignment as the work_struct does the same for all MBOs. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 453b641..f44f27e 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -412,7 +412,6 @@ static void hdm_write_completion(struct urb *urb) dev_warn(dev, "Broken OUT pipe detected\n"); mdev->is_channel_healthy[channel] = false; spin_unlock_irqrestore(lock, flags); - mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); return; @@ -570,7 +569,6 @@ static void hdm_read_completion(struct urb *urb) dev_warn(dev, "Broken IN pipe detected\n"); mdev->is_channel_healthy[channel] = false; spin_unlock_irqrestore(lock, flags); - mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); return; -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 07/17] staging: most: hdm-usb: make use of is_channel_healthy flag
This patch makes the write completion handler use the is_channel_healthy flag to prevent the hdm from scheduling a second clear_halt workqueue in case an endpoint reported a STALL condition. Signed-off-by: Christian Gromm--- drivers/staging/most/hdm-usb/hdm_usb.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index c2ba5a1..57d6c6d 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -418,6 +418,7 @@ static void hdm_write_completion(struct urb *urb) case -EPIPE: dev_warn(dev, "Broken OUT pipe detected\n"); most_stop_enqueue(>iface, channel); + mdev->is_channel_healthy[channel] = false; mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); @@ -582,6 +583,7 @@ static void hdm_read_completion(struct urb *urb) case -EPIPE: dev_warn(dev, "Broken IN pipe detected\n"); most_stop_enqueue(>iface, channel); + mdev->is_channel_healthy[channel] = false; mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); @@ -938,6 +940,7 @@ static void wq_clear_halt(struct work_struct *wq_obj) if (usb_clear_halt(mdev->usb_device, pipe)) dev_warn(>usb_device->dev, "Failed to reset endpoint.\n"); + mdev->is_channel_healthy[channel] = true; most_resume_enqueue(>iface, channel); mutex_unlock(>io_mutex); } -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 15/17] staging: most: hdm-usb: init variables at declaration time
This patch initializes variables by the time they are declared. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 72 +++--- 1 file changed, 23 insertions(+), 49 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index ffe1519..453b641 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -278,11 +278,10 @@ static unsigned int get_stream_frame_size(struct most_channel_config *cfg) */ static int hdm_poison_channel(struct most_interface *iface, int channel) { - struct most_dev *mdev; + struct most_dev *mdev = to_mdev(iface); unsigned long flags; spinlock_t *lock; /* temp. lock */ - mdev = to_mdev(iface); if (unlikely(!iface)) { dev_warn(>usb_device->dev, "Poison: Bad interface.\n"); return -EIO; @@ -391,20 +390,13 @@ static int hdm_remove_padding(struct most_dev *mdev, int channel, */ static void hdm_write_completion(struct urb *urb) { - struct mbo *mbo; - struct buf_anchor *anchor; - struct most_dev *mdev; - struct device *dev; - unsigned int channel; + struct mbo *mbo = urb->context; + struct buf_anchor *anchor = mbo->priv; + struct most_dev *mdev = to_mdev(mbo->ifp); + unsigned int channel = mbo->hdm_channel_id; + struct device *dev = >usb_device->dev; + spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */ unsigned long flags; - spinlock_t *lock; /* temp. lock */ - - mbo = urb->context; - anchor = mbo->priv; - mdev = to_mdev(mbo->ifp); - channel = mbo->hdm_channel_id; - dev = >usb_device->dev; - lock = mdev->anchor_list_lock + channel; spin_lock_irqsave(lock, flags); if (urb->status == -ENOENT || urb->status == -ECONNRESET || @@ -556,20 +548,13 @@ static void hdm_write_completion(struct urb *urb) */ static void hdm_read_completion(struct urb *urb) { - struct mbo *mbo; - struct buf_anchor *anchor; - struct most_dev *mdev; - struct device *dev; + struct mbo *mbo = urb->context; + struct buf_anchor *anchor = mbo->priv; + struct most_dev *mdev = to_mdev(mbo->ifp); + unsigned int channel = mbo->hdm_channel_id; + struct device *dev = >usb_device->dev; + spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */ unsigned long flags; - unsigned int channel; - spinlock_t *lock; /* temp. lock */ - - mbo = urb->context; - anchor = mbo->priv; - mdev = to_mdev(mbo->ifp); - channel = mbo->hdm_channel_id; - dev = >usb_device->dev; - lock = mdev->anchor_list_lock + channel; spin_lock_irqsave(lock, flags); if (urb->status == -ENOENT || urb->status == -ECONNRESET || @@ -738,15 +723,13 @@ static int hdm_configure_channel(struct most_interface *iface, int channel, unsigned int frame_size; unsigned int temp_size; unsigned int tail_space; - struct most_dev *mdev; - struct device *dev; + struct most_dev *mdev = to_mdev(iface); + struct device *dev = >usb_device->dev; - mdev = to_mdev(iface); mdev->is_channel_healthy[channel] = true; mdev->clear_work[channel].channel = channel; mdev->clear_work[channel].mdev = mdev; INIT_WORK(>clear_work[channel].ws, wq_clear_halt); - dev = >usb_device->dev; if (unlikely(!iface || !conf)) { dev_err(dev, "Bad interface or config pointer.\n"); @@ -896,13 +879,10 @@ static void link_stat_timer_handler(unsigned long data) */ static void wq_netinfo(struct work_struct *wq_obj) { - struct most_dev *mdev; - int i, prev_link_stat; + struct most_dev *mdev = to_mdev_from_work(wq_obj); + int i, prev_link_stat = mdev->link_stat; u8 prev_hw_addr[6]; - mdev = to_mdev_from_work(wq_obj); - prev_link_stat = mdev->link_stat; - for (i = 0; i < 6; i++) prev_hw_addr[i] = mdev->hw_addr[i]; @@ -1174,10 +1154,9 @@ static struct kobj_type most_dci_ktype = { static struct most_dci_obj *create_most_dci_obj(struct kobject *parent) { - struct most_dci_obj *most_dci; + struct most_dci_obj *most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL); int retval; - most_dci = kzalloc(sizeof(*most_dci), GFP_KERNEL); if (!most_dci) return NULL; @@ -1214,21 +1193,17 @@ static void destroy_most_dci_obj(struct most_dci_obj *p) static int hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) { + struct usb_host_interface *usb_iface_desc = interface->cur_altsetting; + struct usb_device *usb_dev = interface_to_usbdev(interface); +
[PATCH 08/17] staging: most: hdm-usb: remove redundant conditions
This patch removes the duplication of the expression (urb->status == -ENOENT || urb->status == -ECONNRESET). Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 8 ++-- 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 57d6c6d..ddee281 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -410,9 +410,7 @@ static void hdm_write_completion(struct urb *urb) return; } - if (unlikely(urb->status && !(urb->status == -ENOENT || - urb->status == -ECONNRESET || - urb->status == -ESHUTDOWN))) { + if (unlikely(urb->status && urb->status != -ESHUTDOWN)) { mbo->processed_length = 0; switch (urb->status) { case -EPIPE: @@ -575,9 +573,7 @@ static void hdm_read_completion(struct urb *urb) return; } - if (unlikely(urb->status && !(urb->status == -ENOENT || - urb->status == -ECONNRESET || - urb->status == -ESHUTDOWN))) { + if (unlikely(urb->status && urb->status != -ESHUTDOWN)) { mbo->processed_length = 0; switch (urb->status) { case -EPIPE: -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 11/17] staging: most: hdm-usb: assign spinlock to local variable
This patch assigns the spinlock of struct mdev to local spinlock_t variable to get rid of all the ugly dereferencing. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 31 +++ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 8d8c72c..4156a30 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -206,14 +206,15 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, { struct mbo *mbo; struct buf_anchor *anchor, *tmp; + spinlock_t *lock = mdev->anchor_list_lock + channel; /* temp. lock */ unsigned long flags; - spin_lock_irqsave(>anchor_list_lock[channel], flags); + spin_lock_irqsave(lock, flags); list_for_each_entry_safe(anchor, tmp, >anchor_list[channel], list) { struct urb *urb = anchor->urb; - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); + spin_unlock_irqrestore(lock, flags); if (likely(urb)) { mbo = urb->context; if (!irqs_disabled()) { @@ -229,11 +230,11 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, } usb_free_urb(urb); } - spin_lock_irqsave(>anchor_list_lock[channel], flags); + spin_lock_irqsave(lock, flags); list_del(>list); kfree(anchor); } - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); + spin_unlock_irqrestore(lock, flags); } /** @@ -397,12 +398,14 @@ static void hdm_write_completion(struct urb *urb) struct device *dev; unsigned int channel; unsigned long flags; + spinlock_t *lock; /* temp. lock */ mbo = urb->context; anchor = mbo->priv; mdev = to_mdev(mbo->ifp); channel = mbo->hdm_channel_id; dev = >usb_device->dev; + lock = mdev->anchor_list_lock + channel; if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { @@ -433,9 +436,9 @@ static void hdm_write_completion(struct urb *urb) mbo->processed_length = urb->actual_length; } - spin_lock_irqsave(>anchor_list_lock[channel], flags); + spin_lock_irqsave(lock, flags); list_del(>list); - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); + spin_unlock_irqrestore(lock, flags); kfree(anchor); if (likely(mbo->complete)) @@ -559,12 +562,14 @@ static void hdm_read_completion(struct urb *urb) struct device *dev; unsigned long flags; unsigned int channel; + spinlock_t *lock; /* temp. lock */ mbo = urb->context; anchor = mbo->priv; mdev = to_mdev(mbo->ifp); channel = mbo->hdm_channel_id; dev = >usb_device->dev; + lock = mdev->anchor_list_lock + channel; if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || (!mdev->is_channel_healthy[channel])) { @@ -601,9 +606,9 @@ static void hdm_read_completion(struct urb *urb) mbo->status = MBO_E_INVAL; } } - spin_lock_irqsave(>anchor_list_lock[channel], flags); + spin_lock_irqsave(lock, flags); list_del(>list); - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); + spin_unlock_irqrestore(lock, flags); kfree(anchor); if (likely(mbo->complete)) @@ -638,6 +643,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, unsigned long flags; unsigned long length; void *virt_address; + spinlock_t *lock; /* temp. lock */ if (unlikely(!iface || !mbo)) return -EIO; @@ -697,9 +703,10 @@ static int hdm_enqueue(struct most_interface *iface, int channel, } urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; - spin_lock_irqsave(>anchor_list_lock[channel], flags); + lock = mdev->anchor_list_lock + channel; + spin_lock_irqsave(lock, flags); list_add_tail(>list, >anchor_list[channel]); - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); + spin_unlock_irqrestore(lock, flags); retval = usb_submit_urb(urb, GFP_KERNEL); if (retval) { @@ -709,9 +716,9 @@ static int hdm_enqueue(struct most_interface *iface, int channel, return 0; _error_1: - spin_lock_irqsave(>anchor_list_lock[channel], flags); + spin_lock_irqsave(lock, flags); list_del(>list); - spin_unlock_irqrestore(>anchor_list_lock[channel], flags); +
[PATCH 14/17] staging: most: hdm-usb: remove redundant parenthesis
This patch removes unnecessary parenthesis in boolean expressions. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 51 +- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 29e98dc..ffe1519 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -217,7 +217,7 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, if (likely(urb)) { mbo = urb->context; usb_kill_urb(urb); - if ((mbo) && (mbo->complete)) { + if (mbo && mbo->complete) { mbo->status = status; mbo->processed_length = 0; mbo->complete(mbo); @@ -287,7 +287,7 @@ static int hdm_poison_channel(struct most_interface *iface, int channel) dev_warn(>usb_device->dev, "Poison: Bad interface.\n"); return -EIO; } - if (unlikely((channel < 0) || (channel >= iface->num_channels))) { + if (unlikely(channel < 0 || channel >= iface->num_channels)) { dev_warn(>usb_device->dev, "Channel ID out of range.\n"); return -ECHRNG; } @@ -407,8 +407,8 @@ static void hdm_write_completion(struct urb *urb) lock = mdev->anchor_list_lock + channel; spin_lock_irqsave(lock, flags); - if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || - (!mdev->is_channel_healthy[channel])) { + if (urb->status == -ENOENT || urb->status == -ECONNRESET || + !mdev->is_channel_healthy[channel]) { spin_unlock_irqrestore(lock, flags); return; } @@ -572,8 +572,8 @@ static void hdm_read_completion(struct urb *urb) lock = mdev->anchor_list_lock + channel; spin_lock_irqsave(lock, flags); - if ((urb->status == -ENOENT) || (urb->status == -ECONNRESET) || - (!mdev->is_channel_healthy[channel])) { + if (urb->status == -ENOENT || urb->status == -ECONNRESET || + !mdev->is_channel_healthy[channel]) { spin_unlock_irqrestore(lock, flags); return; } @@ -649,7 +649,7 @@ static int hdm_enqueue(struct most_interface *iface, int channel, if (unlikely(!iface || !mbo)) return -EIO; - if (unlikely(iface->num_channels <= channel) || (channel < 0)) + if (unlikely(iface->num_channels <= channel || channel < 0)) return -ECHRNG; mdev = to_mdev(iface); @@ -672,12 +672,11 @@ static int hdm_enqueue(struct most_interface *iface, int channel, anchor->urb = urb; mbo->priv = anchor; - if ((mdev->padding_active[channel]) && - (conf->direction & MOST_CH_TX)) - if (hdm_add_padding(mdev, channel, mbo)) { - retval = -EIO; - goto _error; - } + if ((conf->direction & MOST_CH_TX) && mdev->padding_active[channel] && + hdm_add_padding(mdev, channel, mbo)) { + retval = -EIO; + goto _error; + } urb->transfer_dma = mbo->bus_address; virt_address = mbo->virt_address; @@ -753,18 +752,18 @@ static int hdm_configure_channel(struct most_interface *iface, int channel, dev_err(dev, "Bad interface or config pointer.\n"); return -EINVAL; } - if (unlikely((channel < 0) || (channel >= iface->num_channels))) { + if (unlikely(channel < 0 || channel >= iface->num_channels)) { dev_err(dev, "Channel ID out of range.\n"); return -EINVAL; } - if ((!conf->num_buffers) || (!conf->buffer_size)) { + if (!conf->num_buffers || !conf->buffer_size) { dev_err(dev, "Misconfig: buffer size or #buffers zero.\n"); return -EINVAL; } - if (!(conf->data_type == MOST_CH_SYNC) && - !((conf->data_type == MOST_CH_ISOC_AVP) && - (conf->packets_per_xact != 0xFF))) { + if (conf->data_type != MOST_CH_SYNC && + !(conf->data_type == MOST_CH_ISOC_AVP && + conf->packets_per_xact != 0xFF)) { mdev->padding_active[channel] = false; goto exit; } @@ -773,7 +772,7 @@ static int hdm_configure_channel(struct most_interface *iface, int channel, temp_size = conf->buffer_size; frame_size = get_stream_frame_size(conf); - if ((frame_size == 0) || (frame_size > USB_MTU)) { + if (frame_size == 0 || frame_size > USB_MTU) { dev_warn(dev, "Misconfig: frame size wrong\n"); return
[PATCH 09/17] staging: most: hdm-usb: simplify initialization of mbo->status.
This patch simplifies the code that initializes mbo->status. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 14 +- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index ddee281..7f00aaf 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -596,15 +596,11 @@ static void hdm_read_completion(struct urb *urb) } } else { mbo->processed_length = urb->actual_length; - if (!mdev->padding_active[channel]) { - mbo->status = MBO_SUCCESS; - } else { - if (hdm_remove_padding(mdev, channel, mbo)) { - mbo->processed_length = 0; - mbo->status = MBO_E_INVAL; - } else { - mbo->status = MBO_SUCCESS; - } + mbo->status = MBO_SUCCESS; + if (mdev->padding_active[channel] && + hdm_remove_padding(mdev, channel, mbo)) { + mbo->processed_length = 0; + mbo->status = MBO_E_INVAL; } } spin_lock_irqsave(>anchor_list_lock[channel], flags); -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 06/17] staging: most: hdm-usb: rename ID_INIC for consistency
In order to have a consistent naming convention this patch renames USB_DEV_ID_INIC to USB_DEV_ID_OS81118. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index beb50cd..c2ba5a1 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -43,7 +43,7 @@ #define USB_VENDOR_ID_SMSC 0x0424 /* VID: SMSC */ #define USB_DEV_ID_BRDG0xC001 /* PID: USB Bridge */ -#define USB_DEV_ID_INIC0xCF18 /* PID: USB INIC */ +#define USB_DEV_ID_OS81118 0xCF18 /* PID: USB OS81118 */ #define USB_DEV_ID_OS81119 0xCF19 /* PID: USB OS81119 */ /* DRCI Addresses */ #define DRCI_REG_NI_STATE 0x0100 @@ -954,7 +954,7 @@ static const struct file_operations hdm_usb_fops = { */ static struct usb_device_id usbid[] = { { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), }, - { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_INIC), }, + { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81118), }, { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), }, { } /* Terminating entry */ }; @@ -1329,7 +1329,7 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) } mutex_lock(>io_mutex); - if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_INIC || + if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81118 || le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119) { /* this increments the reference count of the instance * object of the core -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 04/17] staging: most: hdm-usb: stop core from submitting buffers in case of broken pipe
This patch ensures that no more packets are submitted by the core in case an USB endpoint has reported a broken pipe (-EPIPE). Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 8f1c096..03cdd0d 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -580,6 +580,7 @@ static void hdm_read_completion(struct urb *urb) switch (urb->status) { case -EPIPE: dev_warn(dev, "Broken IN pipe detected\n"); + most_stop_enqueue(>iface, channel); mbo->status = MBO_E_INVAL; mdev->clear_work[channel].pipe = urb->pipe; schedule_work(>clear_work[channel].ws); @@ -936,8 +937,7 @@ static void wq_clear_halt(struct work_struct *wq_obj) if (usb_clear_halt(mdev->usb_device, pipe)) dev_warn(>usb_device->dev, "Failed to reset endpoint.\n"); - if (mdev->conf[channel].direction & MOST_CH_TX) - most_resume_enqueue(>iface, channel); + most_resume_enqueue(>iface, channel); mutex_unlock(>io_mutex); } -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 01/17] staging: most: hdm-usb: remove unused macro HW_RESYNC
This patch removes the macro HW_RESYNC that is not used anymore. Signed-off-by: Andrey ShvetsovSigned-off-by: Christian Gromm --- drivers/staging/most/hdm-usb/hdm_usb.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index e63784d..79277dd 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -44,7 +44,6 @@ #define USB_VENDOR_ID_SMSC 0x0424 /* VID: SMSC */ #define USB_DEV_ID_BRDG0xC001 /* PID: USB Bridge */ #define USB_DEV_ID_INIC0xCF18 /* PID: USB INIC */ -#define HW_RESYNC 0x /* DRCI Addresses */ #define DRCI_REG_NI_STATE 0x0100 #define DRCI_REG_PACKET_BW 0x0101 -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 03/17] staging: most: hdm-usb: fix clear halt processing
This patch is needed to ensure that submitted URBs get unlinked before the driver calls usb_clear_halt(). Since the halt condition of an USB endpoint is channel related, the work_struct is moved from a buffer basis to a channel basis. Signed-off-by: Christian Gromm--- drivers/staging/most/hdm-usb/hdm_usb.c | 62 -- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index bc2d174..8f1c096 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -65,19 +65,15 @@ /** * struct buf_anchor - used to create a list of pending URBs * @urb: pointer to USB request block - * @clear_work_obj: * @list: linked list * @urb_completion: */ struct buf_anchor { struct urb *urb; - struct work_struct clear_work_obj; struct list_head list; struct completion urb_compl; }; -#define to_buf_anchor(w) container_of(w, struct buf_anchor, clear_work_obj) - /** * struct most_dci_obj - Direct Communication Interface * @kobj:position in sysfs @@ -90,6 +86,17 @@ struct most_dci_obj { #define to_dci_obj(p) container_of(p, struct most_dci_obj, kobj) +struct most_dev; + +struct clear_hold_work { + struct work_struct ws; + struct most_dev *mdev; + unsigned int channel; + int pipe; +}; + +#define to_clear_hold_work(w) container_of(w, struct clear_hold_work, ws) + /** * struct most_dev - holds all usb interface specific stuff * @parent: parent object in sysfs @@ -126,6 +133,7 @@ struct most_dev { spinlock_t anchor_list_lock[MAX_NUM_ENDPOINTS]; bool padding_active[MAX_NUM_ENDPOINTS]; bool is_channel_healthy[MAX_NUM_ENDPOINTS]; + struct clear_hold_work clear_work[MAX_NUM_ENDPOINTS]; struct list_head *anchor_list; struct mutex io_mutex; struct timer_list link_stat_timer; @@ -222,7 +230,6 @@ static void free_anchored_buffers(struct most_dev *mdev, unsigned int channel, } spin_lock_irqsave(>anchor_list_lock[channel], flags); list_del(>list); - cancel_work_sync(>clear_work_obj); kfree(anchor); } spin_unlock_irqrestore(>anchor_list_lock[channel], flags); @@ -289,6 +296,8 @@ static int hdm_poison_channel(struct most_interface *iface, int channel) mdev->is_channel_healthy[channel] = false; + cancel_work_sync(>clear_work[channel].ws); + mutex_lock(>io_mutex); free_anchored_buffers(mdev, channel, MBO_E_CLOSE); if (mdev->padding_active[channel]) @@ -409,9 +418,8 @@ static void hdm_write_completion(struct urb *urb) dev_warn(dev, "Broken OUT pipe detected\n"); most_stop_enqueue(>iface, channel); mbo->status = MBO_E_INVAL; - usb_unlink_urb(urb); - INIT_WORK(>clear_work_obj, wq_clear_halt); - schedule_work(>clear_work_obj); + mdev->clear_work[channel].pipe = urb->pipe; + schedule_work(>clear_work[channel].ws); return; case -ENODEV: case -EPROTO: @@ -573,9 +581,8 @@ static void hdm_read_completion(struct urb *urb) case -EPIPE: dev_warn(dev, "Broken IN pipe detected\n"); mbo->status = MBO_E_INVAL; - usb_unlink_urb(urb); - INIT_WORK(>clear_work_obj, wq_clear_halt); - schedule_work(>clear_work_obj); + mdev->clear_work[channel].pipe = urb->pipe; + schedule_work(>clear_work[channel].ws); return; case -ENODEV: case -EPROTO: @@ -735,6 +742,9 @@ static int hdm_configure_channel(struct most_interface *iface, int channel, mdev = to_mdev(iface); mdev->is_channel_healthy[channel] = true; + mdev->clear_work[channel].channel = channel; + mdev->clear_work[channel].mdev = mdev; + INIT_WORK(>clear_work[channel].ws, wq_clear_halt); dev = >usb_device->dev; if (unlikely(!iface || !conf)) { @@ -916,33 +926,19 @@ static void wq_netinfo(struct work_struct *wq_obj) */ static void wq_clear_halt(struct work_struct *wq_obj) { - struct buf_anchor *anchor; - struct most_dev *mdev; - struct mbo *mbo; - struct urb *urb; - unsigned int channel; - unsigned long flags; + struct clear_hold_work *clear_work = to_clear_hold_work(wq_obj); + struct most_dev *mdev = clear_work->mdev; + unsigned int channel = clear_work->channel; + int pipe = clear_work->pipe; - anchor = to_buf_anchor(wq_obj); - urb = anchor->urb; - mbo = urb->context;
[PATCH 00/17] staging: most: fix hdm-usb issues
This patch set is needed to fix issues of the hdm-usb module. Christian Gromm (17): staging: most: hdm-usb: remove unused macro HW_RESYNC staging: most: hdm-usb: provide MBO status when freeing buffers staging: most: hdm-usb: fix clear halt processing staging: most: hdm-usb: stop core from submitting buffers in case of broken pipe staging: most: hdm-usb: add USB product id staging: most: hdm-usb: rename ID_INIC for consistency staging: most: hdm-usb: make use of is_channel_healthy flag staging: most: hdm-usb: remove redundant conditions staging: most: hdm-usb: simplify initialization of mbo->status. staging: most: hdm-usb: fix race between enqueue and most_stop_enqueue staging: most: hdm-usb: assign spinlock to local variable staging: most: hdm-usb: synchronize release of struct buf_anchor staging: most: hdm-usb: remove completion object staging: most: hdm-usb: remove redundant parenthesis staging: most: hdm-usb: init variables at declaration time staging: most: hdm-usb: remove unnecessary status assignment staging: most: hdm-usb: add support for new USB gadget drivers/staging/most/hdm-usb/hdm_usb.c | 282 +++-- drivers/staging/most/mostcore/core.c | 53 +-- 2 files changed, 166 insertions(+), 169 deletions(-) -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH 05/17] staging: most: hdm-usb: add USB product id
This patch adds support for the OS81119 MOST network interface controller to the driver. Signed-off-by: Christian Gromm--- drivers/staging/most/hdm-usb/hdm_usb.c | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/most/hdm-usb/hdm_usb.c b/drivers/staging/most/hdm-usb/hdm_usb.c index 03cdd0d..beb50cd 100644 --- a/drivers/staging/most/hdm-usb/hdm_usb.c +++ b/drivers/staging/most/hdm-usb/hdm_usb.c @@ -44,6 +44,7 @@ #define USB_VENDOR_ID_SMSC 0x0424 /* VID: SMSC */ #define USB_DEV_ID_BRDG0xC001 /* PID: USB Bridge */ #define USB_DEV_ID_INIC0xCF18 /* PID: USB INIC */ +#define USB_DEV_ID_OS81119 0xCF19 /* PID: USB OS81119 */ /* DRCI Addresses */ #define DRCI_REG_NI_STATE 0x0100 #define DRCI_REG_PACKET_BW 0x0101 @@ -954,6 +955,7 @@ static const struct file_operations hdm_usb_fops = { static struct usb_device_id usbid[] = { { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_BRDG), }, { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_INIC), }, + { USB_DEVICE(USB_VENDOR_ID_SMSC, USB_DEV_ID_OS81119), }, { } /* Terminating entry */ }; @@ -1327,7 +1329,8 @@ hdm_probe(struct usb_interface *interface, const struct usb_device_id *id) } mutex_lock(>io_mutex); - if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_INIC) { + if (le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_INIC || + le16_to_cpu(usb_dev->descriptor.idProduct) == USB_DEV_ID_OS81119) { /* this increments the reference count of the instance * object of the core */ -- 1.9.1 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 0/8] staging: most: fix hdm-usb issues
On Fri, Aug 19, 2016 at 09:55:33AM +0200, Christian Gromm wrote: > On Thu, 18 Aug 2016 17:18:56 +0200 > Greg KHwrote: > > > On Tue, Aug 16, 2016 at 04:10:26PM +0200, Christian Gromm wrote: > > > This patch set is needed to fix issues of the hdm-usb module. > > > > You sent me 2 patch series for this same driver right now. One 9 > > patches and one 8 patches. > > > > Which go first? Why 2 different sets? What am I supposed to do, guess? > > > I thouhgt the different patch series are going to be applied in the > chronological order like they hit your inbox. Doesn't the date *when* a > certain patch set s'been received mean anything? Nope, never trust email timestamps, they are always wrong, that's why we number patches. email can get stored on servers and delayed for random amounts of time, it's part of the protocol :) > The two sets result from our internal development progress. Not every update > on the driver gets immediately pushed upstream. That's why I ended up with two > sets for a single module. That's fine, but please put them in a single set. thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 0/8] staging: most: fix hdm-usb issues
On Thu, 18 Aug 2016 17:18:56 +0200 Greg KHwrote: > On Tue, Aug 16, 2016 at 04:10:26PM +0200, Christian Gromm wrote: > > This patch set is needed to fix issues of the hdm-usb module. > > You sent me 2 patch series for this same driver right now. One 9 > patches and one 8 patches. > > Which go first? Why 2 different sets? What am I supposed to do, guess? > I thouhgt the different patch series are going to be applied in the chronological order like they hit your inbox. Doesn't the date *when* a certain patch set s'been received mean anything? The two sets result from our internal development progress. Not every update on the driver gets immediately pushed upstream. That's why I ended up with two sets for a single module. > I'm dropping both of them, please resend _one_ set of patches, numbered, > so I know what to do. Please make it very obvious, otherwise I will get > it wrong... I'll go wrap them up again in one set. thanks, Chris > > Think about what you would want if someone were sending you patches... > > thanks, > > greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel