From 7ea4d4bd5e21380f028c3a6e2500655090a3f932 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 23 Jul 2007 10:00:51 +0200 Subject: drm_rmmap_ioctl(): remove dead code This patch removes some obviously dead code spotted by the Coverity checker. Signed-off-by: Adrian Bunk Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 923174c54a1c..3d1ec8234b8b 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -479,11 +479,6 @@ int drm_rmmap_ioctl(struct inode *inode, struct file *filp, return -EINVAL; } - if (!map) { - mutex_unlock(&dev->struct_mutex); - return -EINVAL; - } - /* Register and framebuffer maps are permanent */ if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) { mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From 22c806c23fe17f9c744d19edfe650cfd6496bc2a Mon Sep 17 00:00:00 2001 From: Simon Farnsworth Date: Mon, 23 Jul 2007 18:32:01 +1000 Subject: drm/via: Fix dmablit when blit queue is full fd.o bug 11542 Acked-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/char/drm/via_dmablit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c index 832de1d9ba7e..3dd1ed3d1bf5 100644 --- a/drivers/char/drm/via_dmablit.c +++ b/drivers/char/drm/via_dmablit.c @@ -560,7 +560,7 @@ via_init_dmablit(struct drm_device *dev) blitq->head = 0; blitq->cur = 0; blitq->serviced = 0; - blitq->num_free = VIA_NUM_BLIT_SLOTS; + blitq->num_free = VIA_NUM_BLIT_SLOTS - 1; blitq->num_outstanding = 0; blitq->is_active = 0; blitq->aborting = 0; -- cgit v1.2.3 From 36026ecc20e5df722bbe2ea9e451c73d686ef107 Mon Sep 17 00:00:00 2001 From: Moni Shoua Date: Mon, 23 Jul 2007 10:07:42 +0300 Subject: IB/core: Ignore membership bit in ib_find_pkey() ib_find_pkey() is used as a replacement for ib_find_cached_pkey(), and the original function ignored the membership bit when searching for a P_Key, so ib_find_pkey() should ignore the bit too. In particular, IPoIB turns on the P_Key membership bit of limited membership P_Keys when creating a child interface and looks for the full membership P_key. This broke if a port was a partial member of a partition when IPoIB switched from ib_find_cached_pkey() to ib_find_pkey(), and this change fixes things again. Signed-off-by: Moni Shoua Signed-off-by: Roland Dreier --- drivers/infiniband/core/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index 3ada17c0f239..2506c43ba041 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -702,7 +702,7 @@ int ib_find_pkey(struct ib_device *device, if (ret) return ret; - if (pkey == tmp_pkey) { + if ((pkey & 0x7fff) == (tmp_pkey & 0x7fff)) { *index = i; return 0; } -- cgit v1.2.3 From 5399891052badf97948098d01772113801f6ef58 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/sa: Don't need to check for default P_Key twice Now that ib_find_pkey() ignores the membership bit of P_Keys, there's no need for ib_sa to look for both 0x7fff and 0xffff in a port's P_Key table. Signed-off-by: Roland Dreier --- drivers/infiniband/core/sa_query.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 20ab6b3e484d..d271bd715c12 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -385,9 +385,7 @@ static void update_sm_ah(struct work_struct *work) new_ah->pkey_index = 0; if (ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index) && - ib_find_pkey(port->agent->device, port->port_num, - IB_DEFAULT_PKEY_PARTIAL, &new_ah->pkey_index)) + IB_DEFAULT_PKEY_FULL, &new_ah->pkey_index)) printk(KERN_ERR "Couldn't find index for default PKey\n"); memset(&ah_attr, 0, sizeof ah_attr); -- cgit v1.2.3 From 445d68070c9c02acdda38e6d69bd43096f521035 Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: Fix error path if response alloc fails in ib_mad_recv_done_handler() If ib_mad_recv_done_handler() fails to allocate response, then it just printed a warning and continued, which leads to an oops if the MAD is being handled for a switch device, because the switch code uses response without checking for NULL. Fix this by bailing out of the function if the allocation fails. Signed-off-by: Suresh Shelvapille Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index bc547f1d34ba..969785762052 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1842,16 +1842,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, { struct ib_mad_qp_info *qp_info; struct ib_mad_private_header *mad_priv_hdr; - struct ib_mad_private *recv, *response; + struct ib_mad_private *recv, *response = NULL; struct ib_mad_list_head *mad_list; struct ib_mad_agent_private *mad_agent; int port_num; - response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); - if (!response) - printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " - "for response buffer\n"); - mad_list = (struct ib_mad_list_head *)(unsigned long)wc->wr_id; qp_info = mad_list->mad_queue->qp_info; dequeue_mad(mad_list); @@ -1879,6 +1874,13 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, if (!validate_mad(&recv->mad.mad, qp_info->qp->qp_num)) goto out; + response = kmem_cache_alloc(ib_mad_cache, GFP_KERNEL); + if (!response) { + printk(KERN_ERR PFX "ib_mad_recv_done_handler no memory " + "for response buffer\n"); + goto out; + } + if (port_priv->device->node_type == RDMA_NODE_IB_SWITCH) port_num = wc->port_num; else -- cgit v1.2.3 From 86dfbecdea733a6e940b958e94a85af45b89a0b9 Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: Fix memory leak in switch handling in ib_mad_recv_done_handler() If agent_send_response() returns an error, we shouldn't do anything differently than if it succeeds; setting response to NULL just means that the response buffer gets leaked. Signed-off-by: Suresh Shelvapille Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 969785762052..6f4287716ab1 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c @@ -1916,12 +1916,11 @@ static void ib_mad_recv_done_handler(struct ib_mad_port_private *port_priv, response->header.recv_wc.recv_buf.mad = &response->mad.mad; response->header.recv_wc.recv_buf.grh = &response->grh; - if (!agent_send_response(&response->mad.mad, - &response->grh, wc, - port_priv->device, - smi_get_fwd_port(&recv->mad.smp), - qp_info->qp->qp_num)) - response = NULL; + agent_send_response(&response->mad.mad, + &response->grh, wc, + port_priv->device, + smi_get_fwd_port(&recv->mad.smp), + qp_info->qp->qp_num); goto out; } -- cgit v1.2.3 From 8fc394b1971241999ef9b022feabf6a164791e3f Mon Sep 17 00:00:00 2001 From: Hal Rosenstock Date: Fri, 3 Aug 2007 10:45:17 -0700 Subject: IB/mad: agent_send_response() should be void Nothing looks at the return value of agent_send_response(), so there's no point in returning anything. Signed-off-by: Hal Rosenstock Signed-off-by: Roland Dreier --- drivers/infiniband/core/agent.c | 24 ++++++++++-------------- drivers/infiniband/core/agent.h | 6 +++--- 2 files changed, 13 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/agent.c b/drivers/infiniband/core/agent.c index db2633e4aae6..ae7c2880e624 100644 --- a/drivers/infiniband/core/agent.c +++ b/drivers/infiniband/core/agent.c @@ -78,15 +78,14 @@ ib_get_agent_port(struct ib_device *device, int port_num) return entry; } -int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn) +void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn) { struct ib_agent_port_private *port_priv; struct ib_mad_agent *agent; struct ib_mad_send_buf *send_buf; struct ib_ah *ah; - int ret; struct ib_mad_send_wr_private *mad_send_wr; if (device->node_type == RDMA_NODE_IB_SWITCH) @@ -96,23 +95,21 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, if (!port_priv) { printk(KERN_ERR SPFX "Unable to find port agent\n"); - return -ENODEV; + return; } agent = port_priv->agent[qpn]; ah = ib_create_ah_from_wc(agent->qp->pd, wc, grh, port_num); if (IS_ERR(ah)) { - ret = PTR_ERR(ah); - printk(KERN_ERR SPFX "ib_create_ah_from_wc error:%d\n", ret); - return ret; + printk(KERN_ERR SPFX "ib_create_ah_from_wc error\n"); + return; } send_buf = ib_create_send_mad(agent, wc->src_qp, wc->pkey_index, 0, IB_MGMT_MAD_HDR, IB_MGMT_MAD_DATA, GFP_KERNEL); if (IS_ERR(send_buf)) { - ret = PTR_ERR(send_buf); - printk(KERN_ERR SPFX "ib_create_send_mad error:%d\n", ret); + printk(KERN_ERR SPFX "ib_create_send_mad error\n"); goto err1; } @@ -126,16 +123,15 @@ int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, mad_send_wr->send_wr.wr.ud.port_num = port_num; } - if ((ret = ib_post_send_mad(send_buf, NULL))) { - printk(KERN_ERR SPFX "ib_post_send_mad error:%d\n", ret); + if (ib_post_send_mad(send_buf, NULL)) { + printk(KERN_ERR SPFX "ib_post_send_mad error\n"); goto err2; } - return 0; + return; err2: ib_free_send_mad(send_buf); err1: ib_destroy_ah(ah); - return ret; } static void agent_send_handler(struct ib_mad_agent *mad_agent, diff --git a/drivers/infiniband/core/agent.h b/drivers/infiniband/core/agent.h index 86d72fab37b0..fb9ed1489f95 100644 --- a/drivers/infiniband/core/agent.h +++ b/drivers/infiniband/core/agent.h @@ -46,8 +46,8 @@ extern int ib_agent_port_open(struct ib_device *device, int port_num); extern int ib_agent_port_close(struct ib_device *device, int port_num); -extern int agent_send_response(struct ib_mad *mad, struct ib_grh *grh, - struct ib_wc *wc, struct ib_device *device, - int port_num, int qpn); +extern void agent_send_response(struct ib_mad *mad, struct ib_grh *grh, + struct ib_wc *wc, struct ib_device *device, + int port_num, int qpn); #endif /* __AGENT_H_ */ -- cgit v1.2.3 From 38d5af9565f3fa1bf258f3eaeb47c4a95fd7a2b2 Mon Sep 17 00:00:00 2001 From: Sean Hefty Date: Tue, 31 Jul 2007 15:10:54 -0700 Subject: IB/mad: Fix address handle leak in mad_rmpp The address handle associated with dual-sided RMPP direction switch ACKs is never destroyed. Free the AH for ACKs which fall into this category. Problem was reported by Dotan Barak . Signed-off-by: Sean Hefty Signed-off-by: Roland Dreier --- drivers/infiniband/core/mad_rmpp.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/mad_rmpp.c b/drivers/infiniband/core/mad_rmpp.c index 3663fd7022be..d43bc62005b3 100644 --- a/drivers/infiniband/core/mad_rmpp.c +++ b/drivers/infiniband/core/mad_rmpp.c @@ -163,8 +163,10 @@ static struct ib_mad_send_buf *alloc_response_msg(struct ib_mad_agent *agent, hdr_len, 0, GFP_KERNEL); if (IS_ERR(msg)) ib_destroy_ah(ah); - else + else { msg->ah = ah; + msg->context[0] = ah; + } return msg; } @@ -197,9 +199,7 @@ static void ack_ds_ack(struct ib_mad_agent_private *agent, void ib_rmpp_send_handler(struct ib_mad_send_wc *mad_send_wc) { - struct ib_rmpp_mad *rmpp_mad = mad_send_wc->send_buf->mad; - - if (rmpp_mad->rmpp_hdr.rmpp_type != IB_MGMT_RMPP_TYPE_ACK) + if (mad_send_wc->send_buf->context[0] == mad_send_wc->send_buf->ah) ib_destroy_ah(mad_send_wc->send_buf->ah); ib_free_send_mad(mad_send_wc->send_buf); } -- cgit v1.2.3 From 92ddc447ce7382e36b72a240697c00bf4beb8d75 Mon Sep 17 00:00:00 2001 From: Dotan Barak Date: Wed, 1 Aug 2007 13:33:56 +0300 Subject: IB: Move the macro IB_UMEM_MAX_PAGE_CHUNK() to umem.c After moving the definition of struct ib_umem_chunk from ib_verbs.h to ib_umem.h there isn't any reason for the macro IB_UMEM_MAX_PAGE_CHUNK to stay in ib_verbs.h. Move the macro to umem.c, the only place where it is used. Signed-off-by: Dotan Barak Signed-off-by: Roland Dreier --- drivers/infiniband/core/umem.c | 5 +++++ include/rdma/ib_verbs.h | 5 ----- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c index 26d0470eef6e..664d2faa9e74 100644 --- a/drivers/infiniband/core/umem.c +++ b/drivers/infiniband/core/umem.c @@ -40,6 +40,11 @@ #include "uverbs.h" +#define IB_UMEM_MAX_PAGE_CHUNK \ + ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ + ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ + (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) + static void __ib_umem_release(struct ib_device *dev, struct ib_umem *umem, int dirty) { struct ib_umem_chunk *chunk, *tmp; diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 7a99f1125d24..4bea182d7116 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -733,11 +733,6 @@ struct ib_udata { size_t outlen; }; -#define IB_UMEM_MAX_PAGE_CHUNK \ - ((PAGE_SIZE - offsetof(struct ib_umem_chunk, page_list)) / \ - ((void *) &((struct ib_umem_chunk *) 0)->page_list[1] - \ - (void *) &((struct ib_umem_chunk *) 0)->page_list[0])) - struct ib_pd { struct ib_device *device; struct ib_uobject *uobject; -- cgit v1.2.3 From 699924b1e1ea3c9307eb582b9cc386e4af88aaae Mon Sep 17 00:00:00 2001 From: Steve Wise Date: Sun, 29 Jul 2007 15:12:29 -0500 Subject: RDMA/cxgb3: Always call low level send function via cxgb3_ofld_send() This avoids deadlocks. Signed-off-by: Steve Wise Signed-off-by: Roland Dreier --- drivers/infiniband/hw/cxgb3/iwch_cm.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 9574088f0d4e..1cdfcd43b0bc 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c @@ -139,7 +139,7 @@ static void release_tid(struct t3cdev *tdev, u32 hwtid, struct sk_buff *skb) req->wr.wr_hi = htonl(V_WR_OP(FW_WROPCODE_FORWARD)); OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_TID_RELEASE, hwtid)); skb->priority = CPL_PRIORITY_SETUP; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); return; } @@ -161,7 +161,7 @@ int iwch_quiesce_tid(struct iwch_ep *ep) req->val = cpu_to_be64(1 << S_TCB_RX_QUIESCE); skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -183,7 +183,7 @@ int iwch_resume_tid(struct iwch_ep *ep) req->val = 0; skb->priority = CPL_PRIORITY_DATA; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -784,7 +784,7 @@ static int update_rx_credits(struct iwch_ep *ep, u32 credits) OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_RX_DATA_ACK, ep->hwtid)); req->credit_dack = htonl(V_RX_CREDITS(credits) | V_RX_FORCE_ACK(1)); skb->priority = CPL_PRIORITY_ACK; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return credits; } @@ -1152,7 +1152,7 @@ static int listen_start(struct iwch_listen_ep *ep) req->opt1 = htonl(V_CONN_POLICY(CPL_CONN_POLICY_ASK)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1186,7 +1186,7 @@ static int listen_stop(struct iwch_listen_ep *ep) req->cpu_idx = 0; OPCODE_TID(req) = htonl(MK_OPCODE_TID(CPL_CLOSE_LISTSRV_REQ, ep->stid)); skb->priority = 1; - ep->com.tdev->send(ep->com.tdev, skb); + cxgb3_ofld_send(ep->com.tdev, skb); return 0; } @@ -1264,7 +1264,7 @@ static void reject_cr(struct t3cdev *tdev, u32 hwtid, __be32 peer_ip, rpl->opt0l_status = htonl(CPL_PASS_OPEN_REJECT); rpl->opt2 = 0; rpl->rsvd = rpl->opt2; - tdev->send(tdev, skb); + cxgb3_ofld_send(tdev, skb); } } @@ -1557,7 +1557,7 @@ static int peer_abort(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) rpl->wr.wr_lo = htonl(V_WR_TID(ep->hwtid)); OPCODE_TID(rpl) = htonl(MK_OPCODE_TID(CPL_ABORT_RPL, ep->hwtid)); rpl->cmd = CPL_ABORT_NO_RST; - ep->com.tdev->send(ep->com.tdev, rpl_skb); + cxgb3_ofld_send(ep->com.tdev, rpl_skb); if (state != ABORTING) { state_set(&ep->com, DEAD); release_ep_resources(ep); -- cgit v1.2.3 From 5d7cbfd63136e4469a896acfadb33e19ed62f068 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Fri, 3 Aug 2007 10:45:18 -0700 Subject: IB/srp: Wrap OUI checking for workarounds in helper functions Wrap the checking for Mellanox and Topspin OUIs to decide whether to use a workaround into helper functions. This will make it cleaner to add a new OUI to check (as we need to do now that some targets with a Cisco OUI still need the Topspin workarounds). Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index f01ca182f226..fb6c5798daf3 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -75,16 +75,12 @@ module_param(topspin_workarounds, int, 0444); MODULE_PARM_DESC(topspin_workarounds, "Enable workarounds for Topspin/Cisco SRP target bugs if != 0"); -static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; - static int mellanox_workarounds = 1; module_param(mellanox_workarounds, int, 0444); MODULE_PARM_DESC(mellanox_workarounds, "Enable workarounds for Mellanox SRP target bugs if != 0"); -static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; - static void srp_add_one(struct ib_device *device); static void srp_remove_one(struct ib_device *device); static void srp_completion(struct ib_cq *cq, void *target_ptr); @@ -108,6 +104,22 @@ static const char *srp_target_info(struct Scsi_Host *host) return host_to_target(host)->target_name; } +static int srp_target_is_topspin(struct srp_target_port *target) +{ + static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; + + return topspin_workarounds && + !memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui); +} + +static int srp_target_is_mellanox(struct srp_target_port *target) +{ + static const u8 mellanox_oui[3] = { 0x00, 0x02, 0xc9 }; + + return mellanox_workarounds && + !memcmp(&target->ioc_guid, mellanox_oui, sizeof mellanox_oui); +} + static struct srp_iu *srp_alloc_iu(struct srp_host *host, size_t size, gfp_t gfp_mask, enum dma_data_direction direction) @@ -360,7 +372,7 @@ static int srp_send_req(struct srp_target_port *target) * zero out the first 8 bytes of our initiator port ID and set * the second 8 bytes to the local node GUID. */ - if (topspin_workarounds && !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { printk(KERN_DEBUG PFX "Topspin/Cisco initiator port ID workaround " "activated for target GUID %016llx\n", (unsigned long long) be64_to_cpu(target->ioc_guid)); @@ -585,8 +597,8 @@ static int srp_map_fmr(struct srp_target_port *target, struct scatterlist *scat, if (!dev->fmr_pool) return -ENODEV; - if ((ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask) && - mellanox_workarounds && !memcmp(&target->ioc_guid, mellanox_oui, 3)) + if (srp_target_is_mellanox(target) && + (ib_sg_dma_address(ibdev, &scat[0]) & ~dev->fmr_page_mask)) return -EINVAL; len = page_cnt = 0; @@ -1087,8 +1099,7 @@ static void srp_cm_rej_handler(struct ib_cm_id *cm_id, break; case IB_CM_REJ_PORT_REDIRECT: - if (topspin_workarounds && - !memcmp(&target->ioc_guid, topspin_oui, 3)) { + if (srp_target_is_topspin(target)) { /* * Topspin/Cisco SRP gateways incorrectly send * reject reason code 25 when they mean 24 -- cgit v1.2.3 From 3d1ff48da760968793f3c36672961ffd23088787 Mon Sep 17 00:00:00 2001 From: Raghava Kondapalli Date: Fri, 3 Aug 2007 10:45:18 -0700 Subject: IB/srp: Add OUI for new Cisco targets New Cisco IB SRP targets use the Cisco OUI 00-1b-0d but still need the Topspin workarounds. Add this OUI to srp_target_is_topspin(). Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/srp/ib_srp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index fb6c5798daf3..f6a051428144 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -107,9 +107,11 @@ static const char *srp_target_info(struct Scsi_Host *host) static int srp_target_is_topspin(struct srp_target_port *target) { static const u8 topspin_oui[3] = { 0x00, 0x05, 0xad }; + static const u8 cisco_oui[3] = { 0x00, 0x1b, 0x0d }; return topspin_workarounds && - !memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui); + (!memcmp(&target->ioc_guid, topspin_oui, sizeof topspin_oui) || + !memcmp(&target->ioc_guid, cisco_oui, sizeof cisco_oui)); } static int srp_target_is_mellanox(struct srp_target_port *target) -- cgit v1.2.3 From 198919151dea65d83dd0fb66979b1df28402f2b0 Mon Sep 17 00:00:00 2001 From: Vu Pham Date: Fri, 3 Aug 2007 14:25:48 -0700 Subject: IB/mlx4: Fix opcode returned in RDMA read completion Current code has a cut-and-paste error and returns IB_WC_SEND when it should return IB_WC_RDMA_READ. Signed-off-by: Vu Pham Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/cq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/cq.c b/drivers/infiniband/hw/mlx4/cq.c index 660b27aecae5..8bf44daf45ec 100644 --- a/drivers/infiniband/hw/mlx4/cq.c +++ b/drivers/infiniband/hw/mlx4/cq.c @@ -389,7 +389,7 @@ static int mlx4_ib_poll_one(struct mlx4_ib_cq *cq, wc->opcode = IB_WC_SEND; break; case MLX4_OPCODE_RDMA_READ: - wc->opcode = IB_WC_SEND; + wc->opcode = IB_WC_RDMA_READ; wc->byte_len = be32_to_cpu(cqe->byte_cnt); break; case MLX4_OPCODE_ATOMIC_CS: -- cgit v1.2.3 From db7f3ded8d42c60b0d0a4f71d621e105790b872b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 4 Aug 2007 20:30:58 +0200 Subject: efficeon-agp leaks 'struct agp_bridge_data' in error paths of agp_efficeon_probe() (This is a resend of a patch originally submitted on 24-Jul-2007 00:14) Ok, this is something the coverity checker found (CID: 1813). I'm not at all intimate with this code, so I'm not sure if this attempt at a fix is correct (but at least it compiles). Please look it over and NACK if bad or merge if good ;-) Signed-off-by: Jesper Juhl Signed-off-by: Dave Airlie --- drivers/char/agp/efficeon-agp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index df8da7262853..d78cd09186aa 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -375,6 +375,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, if (!r->start && r->end) { if (pci_assign_resource(pdev, 0)) { printk(KERN_ERR PFX "could not assign resource 0\n"); + agp_put_bridge(bridge); return -ENODEV; } } @@ -386,6 +387,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, */ if (pci_enable_device(pdev)) { printk(KERN_ERR PFX "Unable to Enable PCI device\n"); + agp_put_bridge(bridge); return -ENODEV; } -- cgit v1.2.3 From 6958e827f187c9c5cd39af075567f74f02bf3dd1 Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Mon, 6 Aug 2007 17:09:09 +0300 Subject: IPoIB: Fix leak in ipoib_transport_dev_init() error path ipoib_transport_dev_init() calls ipoib_cm_dev_init(), so it needs to call ipoib_cm_dev_cleanup() to unwind that on the error path. Found by Dotan Barak of Mellanox. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/infiniband/ulp/ipoib/ipoib_verbs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c index 982eb88e27ec..563aeacf9e14 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_verbs.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_verbs.c @@ -211,6 +211,7 @@ out_free_cq: out_free_mr: ib_dereg_mr(priv->mr); + ipoib_cm_dev_cleanup(dev); out_free_pd: ib_dealloc_pd(priv->pd); -- cgit v1.2.3 From 393cdad6267bc2abf75973d15310168ff3e15441 Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Thu, 9 Aug 2007 08:12:46 -0400 Subject: hwmon: fix w83781d temp sensor type setting Commit 348753379a7704087603dad403603e825422fd9a introduced a regression that caused temp2 and temp3 sensor type settings to be written to temp1 instead. The result is that temp sensor readings could be way off. Signed-off-by: Mark M. Hoffman --- drivers/hwmon/w83781d.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index f85b48fea1c4..c95909cc1d21 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c @@ -740,9 +740,9 @@ store_sensor(struct device *dev, struct device_attribute *da, static SENSOR_DEVICE_ATTR(temp1_type, S_IRUGO | S_IWUSR, show_sensor, store_sensor, 0); static SENSOR_DEVICE_ATTR(temp2_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 1); static SENSOR_DEVICE_ATTR(temp3_type, S_IRUGO | S_IWUSR, - show_sensor, store_sensor, 0); + show_sensor, store_sensor, 2); /* I2C devices get this name attribute automatically, but for ISA devices we must create it by ourselves. */ -- cgit v1.2.3 From 1e6a20c9c7848fefa64731ac3d1d88279c447371 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Tue, 7 Aug 2007 19:03:27 +0100 Subject: [ARM] 4544/1: arm: fix section mismatch in pxa fb Fix following section mismatch warning: WARNING: drivers/built-in.o(.text+0x73d0): Section mismatch: reference to .init.data: (between 'pxafb_setup' and 'pxafb_init') The warning are caused by __devinit pxafb_setup() that refers to a variable marked __initdata. In a hotplug scenario we would have a reference to the freed .init.data section. Fix this by declaring g_options __devinitdata. Signed-off-by: Sam Ravnborg Signed-off-by: Russell King --- drivers/video/pxafb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index 81e571d59b50..a280a52f8efe 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c @@ -66,7 +66,7 @@ static void set_ctrlr_state(struct pxafb_info *fbi, u_int state); #ifdef CONFIG_FB_PXA_PARAMETERS #define PXAFB_OPTIONS_SIZE 256 -static char g_options[PXAFB_OPTIONS_SIZE] __initdata = ""; +static char g_options[PXAFB_OPTIONS_SIZE] __devinitdata = ""; #endif static inline void pxafb_schedule_work(struct pxafb_info *fbi, u_int state) -- cgit v1.2.3 From ea7be66c44e56b6b7f1d61befc300871e855d43a Mon Sep 17 00:00:00 2001 From: "Mark M. Hoffman" Date: Sun, 5 Aug 2007 12:19:01 -0400 Subject: hwmon: (w83627ehf) read fan_div values during probe This patch forces the driver to read the fan divider values during early init. Otherwise, a call to store_fan_min() could access uninitialized variables. Signed-off-by: Mark M. Hoffman Signed-off-by: Jean Delvare --- drivers/hwmon/w83627ehf.c | 48 ++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index c51ae2e17758..bca7fbcfbece 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -421,6 +421,31 @@ static void w83627ehf_write_fan_div(struct w83627ehf_data *data, int nr) } } +static void w83627ehf_update_fan_div(struct w83627ehf_data *data) +{ + int i; + + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); + data->fan_div[0] = (i >> 4) & 0x03; + data->fan_div[1] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); + data->fan_div[2] = (i >> 6) & 0x03; + i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); + data->fan_div[0] |= (i >> 3) & 0x04; + data->fan_div[1] |= (i >> 4) & 0x04; + data->fan_div[2] |= (i >> 5) & 0x04; + if (data->has_fan & ((1 << 3) | (1 << 4))) { + i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); + data->fan_div[3] = i & 0x03; + data->fan_div[4] = ((i >> 2) & 0x03) + | ((i >> 5) & 0x04); + } + if (data->has_fan & (1 << 3)) { + i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); + data->fan_div[3] |= (i >> 5) & 0x04; + } +} + static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) { struct w83627ehf_data *data = dev_get_drvdata(dev); @@ -432,25 +457,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev) if (time_after(jiffies, data->last_updated + HZ + HZ/2) || !data->valid) { /* Fan clock dividers */ - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); - data->fan_div[0] = (i >> 4) & 0x03; - data->fan_div[1] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV2); - data->fan_div[2] = (i >> 6) & 0x03; - i = w83627ehf_read_value(data, W83627EHF_REG_VBAT); - data->fan_div[0] |= (i >> 3) & 0x04; - data->fan_div[1] |= (i >> 4) & 0x04; - data->fan_div[2] |= (i >> 5) & 0x04; - if (data->has_fan & ((1 << 3) | (1 << 4))) { - i = w83627ehf_read_value(data, W83627EHF_REG_DIODE); - data->fan_div[3] = i & 0x03; - data->fan_div[4] = ((i >> 2) & 0x03) - | ((i >> 5) & 0x04); - } - if (data->has_fan & (1 << 3)) { - i = w83627ehf_read_value(data, W83627EHF_REG_SMI_OVT); - data->fan_div[3] |= (i >> 5) & 0x04; - } + w83627ehf_update_fan_div(data); /* Measured voltages and limits */ for (i = 0; i < data->in_num; i++) { @@ -1312,6 +1319,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev) if (!(i & (1 << 1)) && (!fan5pin)) data->has_fan |= (1 << 4); + /* Read fan clock dividers immediately */ + w83627ehf_update_fan_div(data); + /* Register sysfs hooks */ for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays); i++) if ((err = device_create_file(dev, -- cgit v1.2.3 From 0956895aa6f8dc6a33210967252fd7787652537d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 11 Aug 2007 13:57:05 +0200 Subject: hwmon: (w83627ehf) don't assume bank 0 Don't assume that the default bank is 0. For one thing, we don't even set it to 0 when the driver is loaded, so the initial state might be different. For another, something (say, the BIOS) might access the chip and leave with the bank set to something different, so assuming that the bank value is 0 is not safe. Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/w83627ehf.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c index bca7fbcfbece..d9a9ec7dd84a 100644 --- a/drivers/hwmon/w83627ehf.c +++ b/drivers/hwmon/w83627ehf.c @@ -309,18 +309,16 @@ static inline int is_word_sized(u16 reg) || (reg & 0x00ff) == 0x55)); } -/* We assume that the default bank is 0, thus the following two functions do - nothing for registers which live in bank 0. For others, they respectively - set the bank register to the correct value (before the register is - accessed), and back to 0 (afterwards). */ +/* Registers 0x50-0x5f are banked */ static inline void w83627ehf_set_bank(struct w83627ehf_data *data, u16 reg) { - if (reg & 0xff00) { + if ((reg & 0x00f0) == 0x50) { outb_p(W83627EHF_REG_BANK, data->addr + ADDR_REG_OFFSET); outb_p(reg >> 8, data->addr + DATA_REG_OFFSET); } } +/* Not strictly necessary, but play it safe for now */ static inline void w83627ehf_reset_bank(struct w83627ehf_data *data, u16 reg) { if (reg & 0xff00) { -- cgit v1.2.3 From 68a50b567895ea677645ca3cebc484674123532d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 12 Aug 2007 13:58:50 +0200 Subject: hwmon: (smsc47m1) restore missing name attribute The smsc47m1 driver no longer creates the name attribute used by libsensors to identify chip types. It was lost during the conversion to a platform driver. I was fooled by the fact that we do have a group with all attributes, but only to delete them all at once. The group is not used to create the attributes, so we have to explicitly create the name attribute. This fixes lm-sensors ticket #2236: http://lm-sensors.org/ticket/2236 Signed-off-by: Jean Delvare Signed-off-by: Mark M. Hoffman --- drivers/hwmon/smsc47m1.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c index 338ee4f54614..d3181967f167 100644 --- a/drivers/hwmon/smsc47m1.c +++ b/drivers/hwmon/smsc47m1.c @@ -585,6 +585,8 @@ static int __devinit smsc47m1_probe(struct platform_device *pdev) if ((err = device_create_file(dev, &dev_attr_alarms))) goto error_remove_files; + if ((err = device_create_file(dev, &dev_attr_name))) + goto error_remove_files; data->class_dev = hwmon_device_register(dev); if (IS_ERR(data->class_dev)) { -- cgit v1.2.3 From 947b2a8083a03e6fff448ce8928956015614855e Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Mon, 13 Aug 2007 17:57:03 +0300 Subject: mlx4_core: Wait 1 second after reset before accessing device Put a 1000 msec delay after resetting the device before attempting to do config cycles on it. Not waiting causes system hangs on some chipsets, e.g. Intel E7520, when the driver is loaded. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier --- drivers/net/mlx4/reset.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/net/mlx4/reset.c b/drivers/net/mlx4/reset.c index e4dfd4b11a4a..e199715fabd0 100644 --- a/drivers/net/mlx4/reset.c +++ b/drivers/net/mlx4/reset.c @@ -119,6 +119,9 @@ int mlx4_reset(struct mlx4_dev *dev) writel(MLX4_RESET_VALUE, reset + MLX4_RESET_OFFSET); iounmap(reset); + /* Docs say to wait one second before accessing device */ + msleep(1000); + end = jiffies + MLX4_RESET_TIMEOUT_JIFFIES; do { if (!pci_read_config_word(dev->pdev, PCI_VENDOR_ID, &vendor) && -- cgit v1.2.3 From 3c1d36da1d5ed36979340efd233ddaacc45b0a02 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 14 Aug 2007 15:12:56 -0400 Subject: ACPI: thermal: clean up MODULE_PARM_DESC newlines Reported-by: Randy Dunlap Signed-off-by: Len Brown --- drivers/acpi/thermal.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 1e06159fd9c4..9b31f36481d2 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -77,23 +77,23 @@ MODULE_LICENSE("GPL"); static int act; module_param(act, int, 0644); -MODULE_PARM_DESC(act, "Disable or override all lowest active trip points.\n"); +MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); static int tzp; module_param(tzp, int, 0444); -MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds.\n"); +MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); static int nocrt; module_param(nocrt, int, 0); -MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips.\n"); +MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips."); static int off; module_param(off, int, 0); -MODULE_PARM_DESC(off, "Set to disable ACPI thermal support.\n"); +MODULE_PARM_DESC(off, "Set to disable ACPI thermal support."); static int psv; module_param(psv, int, 0644); -MODULE_PARM_DESC(psv, "Disable or override all passive trip points.\n"); +MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); static int acpi_thermal_add(struct acpi_device *device); static int acpi_thermal_remove(struct acpi_device *device, int type); -- cgit v1.2.3 From c52a7419af18594426bc601d1ea346dbbcf71e28 Mon Sep 17 00:00:00 2001 From: Len Brown Date: Tue, 14 Aug 2007 15:49:32 -0400 Subject: ACPI: thermal: create "thermal.crt=C" bootparam Some hardware will malfunction at a temperature below the BIOS provided critical shutdown threshold. This hook allows moving the critical trip points down to a temperature which provokes a graceful shutdown before the hardware malfunction. http://bugzilla.kernel.org/show_bug.cgi?id=8884 WARNING: A trip-point override will not get noticed until the system delivers a temperature change event, or unless thermal zone polling is enabled. eg. "thermal.tzp=10" Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 4 ++++ drivers/acpi/thermal.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) (limited to 'drivers') diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 975f029be25c..18dcfdd29df0 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -1826,6 +1826,10 @@ and is between 256 and 4096 characters. It is defined in the file -1: disable all active trip points in all thermal zones : override all lowest active trip points + thermal.crt= [HW,ACPI] + -1: disable all critical trip points in all thermal zones + : lower all critical trip points + thermal.nocrt= [HW,ACPI] Set to disable actions on ACPI thermal zone critical and hot trip points. diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9b31f36481d2..4c420feba207 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -79,6 +79,10 @@ static int act; module_param(act, int, 0644); MODULE_PARM_DESC(act, "Disable or override all lowest active trip points."); +static int crt; +module_param(crt, int, 0644); +MODULE_PARM_DESC(crt, "Disable or lower all critical trip points."); + static int tzp; module_param(tzp, int, 0444); MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); @@ -340,6 +344,20 @@ static int acpi_thermal_get_trip_points(struct acpi_thermal *tz) tz->trips.critical.temperature)); } + if (tz->trips.critical.flags.valid == 1) { + if (crt == -1) { + tz->trips.critical.flags.valid = 0; + } else if (crt > 0) { + unsigned long crt_k = CELSIUS_TO_KELVIN(crt); + + /* + * Allow override to lower critical threshold + */ + if (crt_k < tz->trips.critical.temperature) + tz->trips.critical.temperature = crt_k; + } + } + /* Critical Sleep (optional) */ status = -- cgit v1.2.3 From 54a09feb0ebb018dadaebeb51e860154198abc83 Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Tue, 14 Aug 2007 17:36:31 -0700 Subject: [IOAT]: Remove redundant struct member to avoid descriptor cache miss The layout for struct ioat_desc_sw is non-optimal and causes an extra cache hit for every descriptor processed. By tightening up the struct layout and removing one item, we pull in the fields that get used in the speedpath and get a little better performance. Before: ------- struct ioat_desc_sw { struct ioat_dma_descriptor * hw; /* 0 8 */ struct list_head node; /* 8 16 */ int tx_cnt; /* 24 4 */ /* XXX 4 bytes hole, try to pack */ dma_addr_t src; /* 32 8 */ __u32 src_len; /* 40 4 */ /* XXX 4 bytes hole, try to pack */ dma_addr_t dst; /* 48 8 */ __u32 dst_len; /* 56 4 */ /* XXX 4 bytes hole, try to pack */ /* --- cacheline 1 boundary (64 bytes) --- */ struct dma_async_tx_descriptor async_tx; /* 64 144 */ /* --- cacheline 3 boundary (192 bytes) was 16 bytes ago --- */ /* size: 208, cachelines: 4 */ /* sum members: 196, holes: 3, sum holes: 12 */ /* last cacheline: 16 bytes */ }; /* definitions: 1 */ After: ------ struct ioat_desc_sw { struct ioat_dma_descriptor * hw; /* 0 8 */ struct list_head node; /* 8 16 */ int tx_cnt; /* 24 4 */ __u32 len; /* 28 4 */ dma_addr_t src; /* 32 8 */ dma_addr_t dst; /* 40 8 */ struct dma_async_tx_descriptor async_tx; /* 48 144 */ /* --- cacheline 3 boundary (192 bytes) --- */ /* size: 192, cachelines: 3 */ }; /* definitions: 1 */ Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/dma/ioatdma.c | 7 +++---- drivers/dma/ioatdma.h | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 5fbe56b5cea0..2d1f17865b64 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -347,8 +347,7 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en) new->async_tx.ack = 0; /* client is in control of this ack */ new->async_tx.cookie = -EBUSY; - pci_unmap_len_set(new, src_len, orig_len); - pci_unmap_len_set(new, dst_len, orig_len); + pci_unmap_len_set(new, len, orig_len); spin_unlock_bh(&ioat_chan->desc_lock); return new ? &new->async_tx : NULL; @@ -423,11 +422,11 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) */ pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, dst), - pci_unmap_len(desc, dst_len), + pci_unmap_len(desc, len), PCI_DMA_FROMDEVICE); pci_unmap_page(chan->device->pdev, pci_unmap_addr(desc, src), - pci_unmap_len(desc, src_len), + pci_unmap_len(desc, len), PCI_DMA_TODEVICE); } diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h index d3726478031a..bf4dad70e0f5 100644 --- a/drivers/dma/ioatdma.h +++ b/drivers/dma/ioatdma.h @@ -111,10 +111,9 @@ struct ioat_desc_sw { struct ioat_dma_descriptor *hw; struct list_head node; int tx_cnt; + DECLARE_PCI_UNMAP_LEN(len) DECLARE_PCI_UNMAP_ADDR(src) - DECLARE_PCI_UNMAP_LEN(src_len) DECLARE_PCI_UNMAP_ADDR(dst) - DECLARE_PCI_UNMAP_LEN(dst_len) struct dma_async_tx_descriptor async_tx; }; -- cgit v1.2.3 From 5b31d895874f56174e4d885c065c9fc4b24b28bb Mon Sep 17 00:00:00 2001 From: Len Brown Date: Wed, 15 Aug 2007 00:19:26 -0400 Subject: Revert "ACPI: Battery: Synchronize battery operations." This reverts commit 3bd92ba19a89fe61ebf58804f9c8675372f50c1c. It is no longer necessary, and it opens up a race. Acked-by: Vladimir Lebedev Acked-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/battery.c | 47 ++++++++++++++++++++++++++++++----------------- 1 file changed, 30 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d7b499fe0cd9..81651032791b 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -113,7 +113,7 @@ struct acpi_battery_info { acpi_string oem_info; }; -enum acpi_battery_files { +enum acpi_battery_files{ ACPI_BATTERY_INFO = 0, ACPI_BATTERY_STATE, ACPI_BATTERY_ALARM, @@ -129,14 +129,13 @@ struct acpi_battery_flags { }; struct acpi_battery { + struct mutex mutex; struct acpi_device *device; struct acpi_battery_flags flags; struct acpi_buffer bif_data; struct acpi_buffer bst_data; - struct mutex lock; unsigned long alarm; unsigned long update_time[ACPI_BATTERY_NUMFILES]; - }; inline int acpi_battery_present(struct acpi_battery *battery) @@ -236,10 +235,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) return 0; /* Evaluate _BIF */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BIF", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BIF")); return -ENODEV; @@ -286,10 +285,10 @@ static int acpi_battery_get_state(struct acpi_battery *battery) return 0; /* Evaluate _BST */ - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BST", - NULL, &buffer); - mutex_unlock(&battery->lock); + + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BST", NULL, + &buffer); if (ACPI_FAILURE(status)) { ACPI_EXCEPTION((AE_INFO, status, "Evaluating _BST")); return -ENODEV; @@ -337,10 +336,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, arg0.integer.value = alarm; - mutex_lock(&battery->lock); - status = acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", + status = + acpi_evaluate_object(acpi_battery_handle(battery), "_BTP", &arg_list, NULL); - mutex_unlock(&battery->lock); if (ACPI_FAILURE(status)) return -ENODEV; @@ -660,6 +658,8 @@ acpi_battery_write_alarm(struct file *file, if (!battery || (count > sizeof(alarm_string) - 1)) return -EINVAL; + mutex_lock(&battery->mutex); + result = acpi_battery_update(battery, 1, &update_result); if (result) { result = -ENODEV; @@ -688,7 +688,9 @@ acpi_battery_write_alarm(struct file *file, acpi_battery_check_result(battery, result); if (!result) - return count; + result = count; + + mutex_unlock(&battery->mutex); return result; } @@ -712,6 +714,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq) int update_result = ACPI_BATTERY_NONE_UPDATE; int update = 0; + mutex_lock(&battery->mutex); + update = (get_seconds() - battery->update_time[fid] >= update_time); update = (update | battery->flags.update[fid]); @@ -729,6 +733,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) result = acpi_read_funcs[fid].print(seq, result); acpi_battery_check_result(battery, result); battery->flags.update[fid] = result; + mutex_unlock(&battery->mutex); return result; } @@ -892,7 +897,10 @@ static int acpi_battery_add(struct acpi_device *device) if (!battery) return -ENOMEM; - mutex_init(&battery->lock); + mutex_init(&battery->mutex); + + mutex_lock(&battery->mutex); + battery->device = device; strcpy(acpi_device_name(device), ACPI_BATTERY_DEVICE_NAME); strcpy(acpi_device_class(device), ACPI_BATTERY_CLASS); @@ -928,6 +936,7 @@ static int acpi_battery_add(struct acpi_device *device) kfree(battery); } + mutex_unlock(&battery->mutex); return result; } @@ -942,6 +951,8 @@ static int acpi_battery_remove(struct acpi_device *device, int type) battery = acpi_driver_data(device); + mutex_lock(&battery->mutex); + status = acpi_remove_notify_handler(device->handle, ACPI_ALL_NOTIFY, acpi_battery_notify); @@ -952,7 +963,9 @@ static int acpi_battery_remove(struct acpi_device *device, int type) kfree(battery->bst_data.pointer); - mutex_destroy(&battery->lock); + mutex_unlock(&battery->mutex); + + mutex_destroy(&battery->mutex); kfree(battery); -- cgit v1.2.3 From 6a286a6d85bb0da687011b15f268c0e52e8eaba4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Fri, 3 Aug 2007 11:25:50 -0400 Subject: [libata] pata_isapnp: replace missing module device table Signed-off-by: Jeff Garzik --- drivers/ata/pata_isapnp.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c index 5525518204e6..91a396fa5b20 100644 --- a/drivers/ata/pata_isapnp.c +++ b/drivers/ata/pata_isapnp.c @@ -139,6 +139,8 @@ static struct pnp_device_id isapnp_devices[] = { {.id = ""} }; +MODULE_DEVICE_TABLE(pnp, isapnp_devices); + static struct pnp_driver isapnp_driver = { .name = DRV_NAME, .id_table = isapnp_devices, -- cgit v1.2.3 From cfbf723eb7928879292ee71fa0d118fc4e37b8c9 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 9 Jul 2007 14:38:41 +0100 Subject: sata_mv: PCI IDs for Hightpoint RocketRaid 1740/1742 Underneath all the HPT packaging, PCI identifiers, binary driver modules and stuff you find that ... Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/sata_mv.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 8ec520885b95..3acf65e75eb2 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c @@ -621,6 +621,9 @@ static const struct pci_device_id mv_pci_tbl[] = { { PCI_VDEVICE(MARVELL, 0x5041), chip_504x }, { PCI_VDEVICE(MARVELL, 0x5080), chip_5080 }, { PCI_VDEVICE(MARVELL, 0x5081), chip_508x }, + /* RocketRAID 1740/174x have different identifiers */ + { PCI_VDEVICE(TTI, 0x1740), chip_508x }, + { PCI_VDEVICE(TTI, 0x1742), chip_508x }, { PCI_VDEVICE(MARVELL, 0x6040), chip_604x }, { PCI_VDEVICE(MARVELL, 0x6041), chip_604x }, -- cgit v1.2.3 From ac2b04371fffd964b0d1c3369a9972bed7a5c5d9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 7 Aug 2007 02:43:27 +0900 Subject: ata_piix: update map 10b for ich8m Fix map entry 10b for ich8. It's [P0 P2 IDE IDE] like ich6 / ich6m. Signed-off-by: Tejun Heo Cc: kristen.c.accardi@intel.com Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index a78832ea81fa..c5b4509c93f4 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -436,7 +436,7 @@ static const struct piix_map_db ich8_map_db = { /* PM PS SM SS MAP */ { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ { RV, RV, RV, RV }, - { IDE, IDE, NA, NA }, /* 10b (IDE mode) */ + { P0, P2, IDE, IDE }, /* 10b (IDE mode) */ { RV, RV, RV, RV }, }, }; -- cgit v1.2.3 From be456b77ffbd3983b5da8eff49a70a701333f68b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Thu, 9 Aug 2007 23:19:34 +0200 Subject: pata_artop: fix UDMA5 for AEC6280[R] and UDMA6 for AEC6880[R] Maximum supported UDMA mode for AEC6280[R] is UDMA5 (not UDMA4) and for AEC6880[R] it is UDMA6 (not UDMA5): * Fix the problem by adding missing struct ata_port_info to artop_init_one(). * Use the right naming (s/626/628/). * Bump driver version. Fixes IDE->libata regression, problem was never present in IDE aec62xx driver. Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz Signed-off-by: Jeff Garzik --- drivers/ata/pata_artop.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c index ce589d96ca42..b5352ebecef9 100644 --- a/drivers/ata/pata_artop.c +++ b/drivers/ata/pata_artop.c @@ -2,6 +2,7 @@ * pata_artop.c - ARTOP ATA controller driver * * (C) 2006 Red Hat + * (C) 2007 Bartlomiej Zolnierkiewicz * * Based in part on drivers/ide/pci/aec62xx.c * Copyright (C) 1999-2002 Andre Hedrick @@ -28,7 +29,7 @@ #include #define DRV_NAME "pata_artop" -#define DRV_VERSION "0.4.3" +#define DRV_VERSION "0.4.4" /* * The ARTOP has 33 Mhz and "over clocked" timing tables. Until we @@ -430,7 +431,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA4, .port_ops = &artop6260_ops, }; - static const struct ata_port_info info_626x_fast = { + static const struct ata_port_info info_628x = { .sht = &artop_sht, .flags = ATA_FLAG_SLAVE_POSS, .pio_mask = 0x1f, /* pio0-4 */ @@ -438,6 +439,14 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) .udma_mask = ATA_UDMA5, .port_ops = &artop6260_ops, }; + static const struct ata_port_info info_628x_fast = { + .sht = &artop_sht, + .flags = ATA_FLAG_SLAVE_POSS, + .pio_mask = 0x1f, /* pio0-4 */ + .mwdma_mask = 0x07, /* mwdma0-2 */ + .udma_mask = ATA_UDMA6, + .port_ops = &artop6260_ops, + }; const struct ata_port_info *ppi[] = { NULL, NULL }; if (!printed_version++) @@ -455,13 +464,13 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id) } else if (id->driver_data == 1) /* 6260 */ ppi[0] = &info_626x; - else if (id->driver_data == 2) { /* 6260 or 6260 + fast */ + else if (id->driver_data == 2) { /* 6280 or 6280 + fast */ unsigned long io = pci_resource_start(pdev, 4); u8 reg; - ppi[0] = &info_626x; + ppi[0] = &info_628x; if (inb(io) & 0x10) - ppi[0] = &info_626x_fast; + ppi[0] = &info_628x_fast; /* Mac systems come up with some registers not set as we will need them */ -- cgit v1.2.3 From d44a65f7bb0dae0bcc78de336b55a75b30ec2d2a Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 10 Aug 2007 20:58:46 +0400 Subject: pata_hpt37x: actually clock HPT374 with 50 MHz DPLL (take 2) The DPLL tuning code always set up it for 66 MHz due to wrong UltraDMA mask including mode 5 used to check for the necessity of 66 MHz clocking -- this caused 66 MHz clock to be used for HPT374 chip that does not tolerate it. While fixing this, also remove PLL mode from the TODO list -- I don't think it's still a relevant item. Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 84d9c5568567..96bbe7c39bee 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -8,12 +8,10 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * TODO - * PLL mode - * Look into engine reset on timeout errors. Should not be - * required. + * Look into engine reset on timeout errors. Should not be required. */ #include @@ -26,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.7" +#define DRV_VERSION "0.6.8" struct hpt_clock { u8 xfer_speed; @@ -1092,9 +1090,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) int dpll, adjust; /* Compute DPLL */ - dpll = 2; - if (port->udma_mask & 0xE0) - dpll = 3; + dpll = (port->udma_mask & 0xC0) ? 3 : 2; f_low = (MHz[clock_slot] * 48) / MHz[dpll]; f_high = f_low + 2; -- cgit v1.2.3 From 80b8987c8feaf07a070f7cdcd55db024e9e200ec Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Fri, 10 Aug 2007 21:02:15 +0400 Subject: pata_hpt{37x|3x2n}: fix clock reporting (take 2) Fix several inconsistencies in these drivers WRT reporting the clocks: - when using DPLL mode, 'pata_hpt37x' driver reported the DPLL frequency as the PCI clock -- make it properly report both clocks and add the same ability to the 'pata_hpt3x2n' driver; - both drivers sometimes use "pata_hpt3*:" and sometimes "hpt3*:" in the messages -- make them use only the former one; - the message about failed DPLL stablizatios deserves KERN_ERR and a bang. :-) Signed-off-by: Sergei Shtylyov Signed-off-by: Jeff Garzik --- drivers/ata/pata_hpt37x.c | 10 ++++++---- drivers/ata/pata_hpt3x2n.c | 8 +++++--- 2 files changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c index 96bbe7c39bee..c5ddd937dbf2 100644 --- a/drivers/ata/pata_hpt37x.c +++ b/drivers/ata/pata_hpt37x.c @@ -24,7 +24,7 @@ #include #define DRV_NAME "pata_hpt37x" -#define DRV_VERSION "0.6.8" +#define DRV_VERSION "0.6.9" struct hpt_clock { u8 xfer_speed; @@ -1112,7 +1112,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low | 0x100); } if (adjust == 8) { - printk(KERN_WARNING "hpt37x: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt37x: DPLL did not stabilize!\n"); return -ENODEV; } if (dpll == 3) @@ -1120,7 +1120,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) else private_data = (void *)hpt37x_timings_50; - printk(KERN_INFO "hpt37x: Bus clock %dMHz, using DPLL.\n", MHz[dpll]); + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using %dMHz DPLL.\n", + MHz[clock_slot], MHz[dpll]); } else { private_data = (void *)chip_table->clocks[clock_slot]; /* @@ -1133,7 +1134,8 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id) port = &info_hpt370_33; if (clock_slot < 2 && port == &info_hpt370a) port = &info_hpt370a_33; - printk(KERN_INFO "hpt37x: %s: Bus clock %dMHz.\n", chip_table->name, MHz[clock_slot]); + printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n", + chip_table->name, MHz[clock_slot]); } /* Now kick off ATA set up */ diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c index aa29cde09f8b..f8f234bfc8ce 100644 --- a/drivers/ata/pata_hpt3x2n.c +++ b/drivers/ata/pata_hpt3x2n.c @@ -8,7 +8,7 @@ * Copyright (C) 1999-2003 Andre Hedrick * Portions Copyright (C) 2001 Sun Microsystems, Inc. * Portions Copyright (C) 2003 Red Hat Inc - * Portions Copyright (C) 2005-2006 MontaVista Software, Inc. + * Portions Copyright (C) 2005-2007 MontaVista Software, Inc. * * * TODO @@ -25,7 +25,7 @@ #include #define DRV_NAME "pata_hpt3x2n" -#define DRV_VERSION "0.3.3" +#define DRV_VERSION "0.3.4" enum { HPT_PCI_FAST = (1 << 31), @@ -579,10 +579,12 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id) pci_write_config_dword(dev, 0x5C, (f_high << 16) | f_low); } if (adjust == 8) { - printk(KERN_WARNING "hpt3x2n: DPLL did not stabilize.\n"); + printk(KERN_ERR "pata_hpt3x2n: DPLL did not stabilize!\n"); return -ENODEV; } + printk(KERN_INFO "pata_hpt37x: bus clock %dMHz, using 66MHz DPLL.\n", + pci_mhz); /* Set our private data up. We only need a few flags so we use it directly */ port.private_data = NULL; -- cgit v1.2.3 From 5c08ea019198230a62c601ddf97d0319ae246ad8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 14 Aug 2007 19:56:04 +0900 Subject: ata_piix: add TECRA M7 to broken suspend list Add TECRA M7 to broken suspend list. Reported by Marie Koreen. Signed-off-by: Tejun Heo Cc: Marie Koreen Signed-off-by: Jeff Garzik --- drivers/ata/ata_piix.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index c5b4509c93f4..071d274afaab 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c @@ -900,6 +900,13 @@ static int piix_broken_suspend(void) DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M5"), }, }, + { + .ident = "TECRA M7", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA M7"), + }, + }, { .ident = "Satellite U205", .matches = { -- cgit v1.2.3 From fb0582f91fdd62b67bf54a440d7c79b19ed84da8 Mon Sep 17 00:00:00 2001 From: Ryan Power Date: Fri, 10 Aug 2007 13:59:35 -0700 Subject: libata: adjust libata to ignore errors after spinup Adjust libata to ignore errors after spinup This patch is to ignore errors from the spinup attempt if the drive is in the "standby id" state. Signed-off-by: Ryan Power Acked-by: Mark Lord Cc: Jeff Garzik Cc: Tejun Heo Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 60e78bef469f..99d4fbffb0df 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1723,7 +1723,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, tf.protocol = ATA_PROT_NODATA; tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0); - if (err_mask) { + if (err_mask && id[2] != 0x738c) { rc = -EIO; reason = "SPINUP failed"; goto err_out; -- cgit v1.2.3 From fe11cb6ba40afff15efb053fd0bcba45274636e0 Mon Sep 17 00:00:00 2001 From: Ilpo Järvinen Date: Thu, 16 Aug 2007 01:02:07 +0300 Subject: IB/mlx4: Incorrect semicolon after if statement MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A stray semicolon makes us inadvertently ignore the value of err. Signed-off-by: Ilpo Järvinen Signed-off-by: Roland Dreier --- drivers/infiniband/hw/mlx4/mad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index 333091787c5f..0ed02b7834da 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c @@ -109,7 +109,7 @@ int mlx4_MAD_IFC(struct mlx4_ib_dev *dev, int ignore_mkey, int ignore_bkey, in_modifier, op_modifier, MLX4_CMD_MAD_IFC, MLX4_CMD_TIME_CLASS_C); - if (!err); + if (!err) memcpy(response_mad, outmailbox->buf, 256); mlx4_free_cmd_mailbox(dev->dev, inmailbox); -- cgit v1.2.3 From 0f112a86a36b91afe30e1cc8d4bc000402dde127 Mon Sep 17 00:00:00 2001 From: Wim Van Sebroeck Date: Thu, 9 Aug 2007 19:38:00 +0000 Subject: [WATCHDOG] Eurotechwdt.c - clean-up comments Clean-up history and add a comment about the fact that the watchdog is actually part of the SMSC FDC 37B782 super I/O chipset. Signed-off-by: Wim Van Sebroeck --- drivers/char/watchdog/eurotechwdt.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/eurotechwdt.c b/drivers/char/watchdog/eurotechwdt.c index b070324e27a6..b14e9d1f164d 100644 --- a/drivers/char/watchdog/eurotechwdt.c +++ b/drivers/char/watchdog/eurotechwdt.c @@ -1,5 +1,5 @@ /* - * Eurotech CPU-1220/1410 on board WDT driver + * Eurotech CPU-1220/1410/1420 on board WDT driver * * (c) Copyright 2001 Ascensit * (c) Copyright 2001 Rodolfo Giometti @@ -24,6 +24,9 @@ */ /* Changelog: + * + * 2001 - Rodolfo Giometti + * Initial release * * 2002/04/25 - Rob Radez * clean up #includes @@ -33,13 +36,15 @@ * add WDIOC_GETSTATUS and WDIOC_SETOPTIONS ioctls * add expect_close support * - * 2001 - Rodolfo Giometti - * Initial release - * * 2002.05.30 - Joel Becker * Added Matt Domsch's nowayout module option. */ +/* + * The eurotech CPU-1220/1410/1420's watchdog is a part + * of the on-board SUPER I/O device SMSC FDC 37B782. + */ + #include #include #include -- cgit v1.2.3 From 6e420b7e26dd539f1f78fe920d295b022a2d99c8 Mon Sep 17 00:00:00 2001 From: Andrey Borzenkov Date: Thu, 16 Aug 2007 19:32:19 +0000 Subject: [WATCHDOG] Add support for 1533 bridge to alim1535_wdt From: Andrey Borzenkov They are apparently pretty close (even lspci combines them). The patch adds support for 0x1533 bridge in addition to 0x1535. Tested on Toshiba Portege 4000 with 00:07.0 ISA bridge [0601]: ALi Corporation M1533/M1535 PCI to ISA Bridge [Aladdin IV/V/V+] [10b9:1533] 00:08.0 Bridge [0680]: ALi Corporation M7101 Power Management Controller [PMU] [10b9:7101] with result [ 2090.906736] PCI: Enabling device 0000:00:08.0 (0000 -> 0001) [ 2090.914034] ALi_M1535: initialized. timeout=3D60 sec (nowayout=3D0) Signed-off-by: Andrey Borzenkov Signed-off-by: Wim Van Sebroeck Signed-off-by: Andrew Morton --- drivers/char/watchdog/alim1535_wdt.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/char/watchdog/alim1535_wdt.c b/drivers/char/watchdog/alim1535_wdt.c index e3f6a7d0c83d..c404fc69e7e6 100644 --- a/drivers/char/watchdog/alim1535_wdt.c +++ b/drivers/char/watchdog/alim1535_wdt.c @@ -312,6 +312,7 @@ static int ali_notify_sys(struct notifier_block *this, unsigned long code, void */ static struct pci_device_id ali_pci_tbl[] = { + { PCI_VENDOR_ID_AL, 0x1533, PCI_ANY_ID, PCI_ANY_ID,}, { PCI_VENDOR_ID_AL, 0x1535, PCI_ANY_ID, PCI_ANY_ID,}, { 0, }, }; @@ -329,9 +330,11 @@ static int __init ali_find_watchdog(void) struct pci_dev *pdev; u32 wdog; - /* Check for a 1535 series bridge */ + /* Check for a 1533/1535 series bridge */ pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1535, NULL); - if(pdev == NULL) + if (pdev == NULL) + pdev = pci_get_device(PCI_VENDOR_ID_AL, 0x1533, NULL); + if (pdev == NULL) return -ENODEV; pci_dev_put(pdev); -- cgit v1.2.3 From 9ef7ad22965fcd817b20c1332286f02362266534 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 17 Aug 2007 14:05:27 +1000 Subject: Enable partitions for lguest block device The lguest block device only requests one minor, which means partitions don't work (eg "root=/dev/lgba1"). Let's follow the crowd and ask for 16. Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/block/lguest_blk.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/block/lguest_blk.c b/drivers/block/lguest_blk.c index 93e3c4001bf5..160cf14431ac 100644 --- a/drivers/block/lguest_blk.c +++ b/drivers/block/lguest_blk.c @@ -308,9 +308,12 @@ static int lguestblk_probe(struct lguest_device *lgdev) } /* This allocates a "struct gendisk" where we pack all the information - * about the disk which the rest of Linux sees. We ask for one minor - * number; I do wonder if we should be asking for more. */ - bd->disk = alloc_disk(1); + * about the disk which the rest of Linux sees. The argument is the + * number of minor devices desired: we need one minor for the main + * disk, and one for each partition. Of course, we can't possibly know + * how many partitions are on the disk (add_disk does that). + */ + bd->disk = alloc_disk(16); if (!bd->disk) { err = -ENOMEM; goto out_unregister_blkdev; -- cgit v1.2.3 From 06bfb7eb1535822a3338ffea9918e22215abed90 Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Sat, 18 Aug 2007 12:56:21 +0200 Subject: Add some help texts to recently-introduced kconfig items Signed-off-by: Jan Engelhardt Signed-off-by: Stefan Richter (edited MACINTOSH_DRIVERS per Geert Uytterhoeven's remark) Signed-off-by: Linus Torvalds --- arch/i386/Kconfig | 5 +++++ drivers/atm/Kconfig | 5 +++++ drivers/auxdisplay/Kconfig | 5 +++++ drivers/block/Kconfig | 6 ++++++ drivers/crypto/Kconfig | 5 +++++ drivers/hid/Kconfig | 5 +++++ drivers/kvm/Kconfig | 5 +++++ drivers/macintosh/Kconfig | 5 +++++ drivers/misc/Kconfig | 5 +++++ drivers/net/Kconfig | 15 +++++++++++++++ drivers/usb/Kconfig | 3 +++ 11 files changed, 64 insertions(+) (limited to 'drivers') diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index f9524933258a..f16a46e8849c 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1228,6 +1228,11 @@ menuconfig INSTRUMENTATION bool "Instrumentation Support" depends on EXPERIMENTAL default y + ---help--- + Say Y here to get to see options related to performance measurement, + debugging, and testing. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if INSTRUMENTATION diff --git a/drivers/atm/Kconfig b/drivers/atm/Kconfig index bed9f58c2d5a..b554edac1ced 100644 --- a/drivers/atm/Kconfig +++ b/drivers/atm/Kconfig @@ -6,6 +6,11 @@ menuconfig ATM_DRIVERS bool "ATM drivers" depends on NETDEVICES && ATM default y + ---help--- + Say Y here to get to see options for Asynchronous Transfer Mode + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if ATM_DRIVERS && NETDEVICES && ATM diff --git a/drivers/auxdisplay/Kconfig b/drivers/auxdisplay/Kconfig index de2fcce10ba5..043353bd0600 100644 --- a/drivers/auxdisplay/Kconfig +++ b/drivers/auxdisplay/Kconfig @@ -8,6 +8,11 @@ menuconfig AUXDISPLAY depends on PARPORT bool "Auxiliary Display support" + ---help--- + Say Y here to get to see options for auxiliary display drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if AUXDISPLAY && PARPORT diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index a4a311992408..ef32e977d307 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -6,6 +6,12 @@ menuconfig BLK_DEV bool "Block devices" depends on BLOCK default y + ---help--- + Say Y here to get to see options for various different block device + drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled; + only do this if you know what you are doing. if BLK_DEV diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 84ebfcc1ffb4..c0fc4aeb8596 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -2,6 +2,11 @@ menuconfig CRYPTO_HW bool "Hardware crypto devices" default y + ---help--- + Say Y here to get to see options for hardware crypto devices and + processors. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if CRYPTO_HW diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3b63b0b78122..19667fcc722a 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -5,6 +5,11 @@ menuconfig HID_SUPPORT bool "HID Devices" depends on INPUT default y + ---help--- + Say Y here to get to see options for various computer-human interface + device drivers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if HID_SUPPORT diff --git a/drivers/kvm/Kconfig b/drivers/kvm/Kconfig index 6cecc396e040..7b64fd4aa2f3 100644 --- a/drivers/kvm/Kconfig +++ b/drivers/kvm/Kconfig @@ -5,6 +5,11 @@ menuconfig VIRTUALIZATION bool "Virtualization" depends on X86 default y + ---help--- + Say Y here to get to see options for virtualization guest drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if VIRTUALIZATION diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig index dbe96268866e..56cd8998fe4b 100644 --- a/drivers/macintosh/Kconfig +++ b/drivers/macintosh/Kconfig @@ -3,6 +3,11 @@ menuconfig MACINTOSH_DRIVERS bool "Macintosh device drivers" depends on PPC || MAC || X86 default y if (PPC_PMAC || MAC) + ---help--- + Say Y here to get to see options for devices used with Macintosh + computers. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MACINTOSH_DRIVERS diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 518d5d335464..a26655881e6a 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -5,6 +5,11 @@ menuconfig MISC_DEVICES bool "Misc devices" default y + ---help--- + Say Y here to get to see options for device drivers from various + different categories. This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if MISC_DEVICES diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 81ef81c9a584..5b9e17bf1749 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1968,6 +1968,16 @@ menuconfig NETDEV_1000 bool "Ethernet (1000 Mbit)" depends on !UML default y + ---help--- + Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common + type of Local Area Network (LAN) in universities and companies. + + Say Y here to get to see options for Gigabit Ethernet drivers. + This option alone does not add any kernel code. + Note that drivers supporting both 100 and 1000 MBit may be listed + under "Ethernet (10 or 100MBit)" instead. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_1000 @@ -2339,6 +2349,11 @@ menuconfig NETDEV_10000 bool "Ethernet (10000 Mbit)" depends on !UML default y + ---help--- + Say Y here to get to see options for 10 Gigabit Ethernet drivers. + This option alone does not add any kernel code. + + If you say N, all options in this submenu will be skipped and disabled. if NETDEV_10000 diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7dd73546bf43..63436892688c 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -6,6 +6,9 @@ menuconfig USB_SUPPORT bool "USB support" depends on HAS_IOMEM default y + ---help--- + This option adds core support for Universal Serial Bus (USB). + You will also need drivers from the following menu to make use of it. if USB_SUPPORT -- cgit v1.2.3 From 1a2b73302aacddf2543f9d7a25936e4323fa1486 Mon Sep 17 00:00:00 2001 From: Timo Jantunen Date: Tue, 14 Aug 2007 21:56:57 +0300 Subject: fix random hang in forcedeth driver when using netconsole If the forcedeth driver receives too much work in an interrupt, it assumes it has a broken hardware with stuck IRQ. It works around the problem by disabling interrupts on the nic but makes a printk while holding device spinlog - which isn't smart thing to do if you have netconsole on the same nic. This patch moves the printk's out of the spinlock protected area. Without this patch the machine hangs hard. With this patch everything still works even when there is significant increase on CPU usage while using the nic. Signed-off-by: Timo Jantunen Signed-off-by: Linus Torvalds --- drivers/net/forcedeth.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 69f5f365239a..10f4e3b55168 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -3068,8 +3068,8 @@ static irqreturn_t nv_nic_irq(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3186,8 +3186,8 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data) np->nic_poll_irq = np->irqmask; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); spin_unlock(&np->lock); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i); break; } @@ -3233,8 +3233,8 @@ static irqreturn_t nv_nic_irq_tx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_TX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i); break; } @@ -3348,8 +3348,8 @@ static irqreturn_t nv_nic_irq_rx(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_RX_ALL; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i); break; } } @@ -3421,8 +3421,8 @@ static irqreturn_t nv_nic_irq_other(int foo, void *data) np->nic_poll_irq |= NVREG_IRQ_OTHER; mod_timer(&np->nic_poll, jiffies + POLL_WAIT); } - printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); spin_unlock_irqrestore(&np->lock, flags); + printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i); break; } -- cgit v1.2.3 From 6ec8a856e4097d42ece9b0b9459bbca1586f13d7 Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Sun, 19 Aug 2007 15:57:26 +0300 Subject: KVM: Avoid calling smp_call_function_single() with interrupts disabled When taking a cpu down, we need to hardware_disable() it. Unfortunately, the CPU_DYING notifier is called with interrupts disabled, which means we can't use smp_call_function_single(). Fortunately, the CPU_DYING notifier is always called on the dying cpu, so we don't need to use the function at all and can simply call hardware_disable() directly. Tested-by: Paolo Ornati Signed-off-by: Avi Kivity Signed-off-by: Linus Torvalds --- drivers/kvm/kvm_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 96856097d15b..cd0557954e50 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c @@ -2974,6 +2974,10 @@ static int kvm_cpu_hotplug(struct notifier_block *notifier, unsigned long val, switch (val) { case CPU_DYING: case CPU_DYING_FROZEN: + printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", + cpu); + hardware_disable(NULL); + break; case CPU_UP_CANCELED: case CPU_UP_CANCELED_FROZEN: printk(KERN_INFO "kvm: disabling virtualization on CPU%d\n", -- cgit v1.2.3 From c3624f99a8c06cfe75e0b06f23a7f7cea9d2d5ff Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 31 Jul 2007 07:15:56 -0300 Subject: V4L/DVB (5967): ivtv: fix VIDIOC_S_FBUF:new OSD values where never set ivtv: fix VIDIOC_S_FBUF support: new OSD values where never actually set. The values set with VIDIOC_S_FBUF were not actually used until the next VIDIOC_S_FMT. Fixed. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index 047624b9e271..f2310b775fad 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1190,6 +1190,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0; itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0; + ivtv_set_osd_alpha(itv); break; } -- cgit v1.2.3 From de23084a85f6f5030e6760f6e494a9f2a19013d4 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 3 Aug 2007 09:33:38 -0300 Subject: V4L/DVB (5969): ivtv: report ivtv version in status log Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/ivtv/ivtv-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c index f2310b775fad..5977a79619c2 100644 --- a/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/drivers/media/video/ivtv/ivtv-ioctl.c @@ -1235,7 +1235,7 @@ int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void IVTV_INFO("Tuner: %s\n", test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); cx2341x_log_status(&itv->params, itv->name); - IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); + IVTV_INFO("Version: %s Status flags: 0x%08lx\n", IVTV_VERSION, itv->i_flags); for (i = 0; i < IVTV_MAX_STREAMS; i++) { struct ivtv_stream *s = &itv->streams[i]; -- cgit v1.2.3 From 0d84a62b38bab2e15ddc44ea6dcd8ce49199b299 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Fri, 17 Aug 2007 18:36:44 -0300 Subject: V4L/DVB (5991): dvb-pll: Set minimum and maximum frequency properly The tuner maximum frequency wasn't being set, while the minimum frequency was set to what the maximum should have been. If a future patch were to enforce these limits, dvb-pll would be effectively broken. Signed-off-by: Trent Piepho Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/dvb-pll.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index ca99e439c97c..11f7d5939bd9 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -784,7 +784,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, strncpy(fe->ops.tuner_ops.info.name, desc->name, sizeof(fe->ops.tuner_ops.info.name)); fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; + fe->ops.tuner_ops.info.frequency_max = desc->max; if (!desc->initdata) fe->ops.tuner_ops.init = NULL; if (!desc->sleepdata) -- cgit v1.2.3 From 01659f2a0067d855089811529fa596cbc40f1e75 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Fri, 17 Aug 2007 01:01:33 -0300 Subject: V4L/DVB (6026): Avoid powering up the camera on resume Signed-off-by: Chris Ball Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index c08f650df423..88090107cd44 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2233,12 +2233,21 @@ static int cafe_pci_resume(struct pci_dev *pdev) if (ret) return ret; ret = pci_enable_device(pdev); + if (ret) { cam_warn(cam, "Unable to re-enable device on resume!\n"); return ret; } cafe_ctlr_init(cam); - cafe_ctlr_power_up(cam); + cafe_ctlr_power_down(cam); + + mutex_lock(&cam->s_mutex); + if (cam->users > 0) { + cafe_ctlr_power_up(cam); + __cafe_cam_reset(cam); + } + mutex_unlock(&cam->s_mutex); + set_bit(CF_CONFIG_NEEDED, &cam->flags); if (cam->state == S_SPECREAD) cam->state = S_IDLE; /* Don't bother restarting */ -- cgit v1.2.3 From 6d77444aca298b43a88086be446f943cd0442ef7 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Fri, 17 Aug 2007 01:02:33 -0300 Subject: V4L/DVB (6027): Get rid of an ill-behaved msleep in i2c write Configuring the OLPC camera requires something over 150 register writes. Unfortunately, querying the CAFE i2c controller too soon after a write causes the hardware to flake. The problem had been "solved" with an msleep() call, but, between the number of registers and how msleep() behaves, that resulted in a 3-second delay on camera initialization. Instead, we hand-code a wait for the completion interrupt which avoids reading the status registers. Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 22 +++++++++++++++++++++- drivers/media/video/ov7670.c | 5 ++++- 2 files changed, 25 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 88090107cd44..acf64b19730e 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -356,6 +356,7 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, { unsigned int rval; unsigned long flags; + DEFINE_WAIT(the_wait); spin_lock_irqsave(&cam->dev_lock, flags); rval = TWSIC0_EN | ((addr << TWSIC0_SID_SHIFT) & TWSIC0_SID); @@ -369,10 +370,29 @@ static int cafe_smbus_write_data(struct cafe_camera *cam, rval = value | ((command << TWSIC1_ADDR_SHIFT) & TWSIC1_ADDR); cafe_reg_write(cam, REG_TWSIC1, rval); spin_unlock_irqrestore(&cam->dev_lock, flags); - msleep(2); /* Required or things flake */ + /* + * Time to wait for the write to complete. THIS IS A RACY + * WAY TO DO IT, but the sad fact is that reading the TWSIC1 + * register too quickly after starting the operation sends + * the device into a place that may be kinder and better, but + * which is absolutely useless for controlling the sensor. In + * practice we have plenty of time to get into our sleep state + * before the interrupt hits, and the worst case is that we + * time out and then see that things completed, so this seems + * the best way for now. + */ + do { + prepare_to_wait(&cam->smbus_wait, &the_wait, + TASK_UNINTERRUPTIBLE); + schedule_timeout(1); /* even 1 jiffy is too long */ + finish_wait(&cam->smbus_wait, &the_wait); + } while (!cafe_smbus_write_done(cam)); + +#ifdef IF_THE_CAFE_HARDWARE_WORKED_RIGHT wait_event_timeout(cam->smbus_wait, cafe_smbus_write_done(cam), CAFE_SMBUS_TIMEOUT); +#endif spin_lock_irqsave(&cam->dev_lock, flags); rval = cafe_reg_read(cam, REG_TWSIC1); spin_unlock_irqrestore(&cam->dev_lock, flags); diff --git a/drivers/media/video/ov7670.c b/drivers/media/video/ov7670.c index f8f21ddd9843..c4c5bd67f795 100644 --- a/drivers/media/video/ov7670.c +++ b/drivers/media/video/ov7670.c @@ -416,7 +416,10 @@ static int ov7670_read(struct i2c_client *c, unsigned char reg, static int ov7670_write(struct i2c_client *c, unsigned char reg, unsigned char value) { - return i2c_smbus_write_byte_data(c, reg, value); + int ret = i2c_smbus_write_byte_data(c, reg, value); + if (reg == REG_COM7 && (value & COM7_RESET)) + msleep(2); /* Wait for reset to run */ + return ret; } -- cgit v1.2.3 From 70cd685d4b161c9137020ba7ec551cb343cd6fbf Mon Sep 17 00:00:00 2001 From: Marcelo Tosatti Date: Fri, 17 Aug 2007 01:03:22 -0300 Subject: V4L/DVB (6028): Turn an unnecessary mdelay() into msleep(). Signed-off-by: Jonathan Corbet Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cafe_ccic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index acf64b19730e..ef5361824f87 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -730,7 +730,7 @@ static void cafe_ctlr_init(struct cafe_camera *cam) * Here we must wait a bit for the controller to come around. */ spin_unlock_irqrestore(&cam->dev_lock, flags); - mdelay(5); /* FIXME revisit this */ + msleep(5); spin_lock_irqsave(&cam->dev_lock, flags); cafe_reg_write(cam, REG_GL_CSR, GCSR_CCIC_EN|GCSR_SRC|GCSR_MRC); -- cgit v1.2.3 From 82a0e70e795ee605e1a34a874dd3a3a43b745fb9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 20 Aug 2007 22:42:53 +0200 Subject: ide: make CONFIG_IDE_GENERIC default to N These days, CONFIG_IDE_GENERIC causes more confusion and misconfiguration than it helps. Especially so because libata is linked after the generic driver. Default to N. Signed-off-by: Tejun Heo Acked-by: Jeff Garzik Cc: "P.C.Chan" Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/Kconfig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e049f65bc3a2..e7fcdd2580fb 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,9 +304,8 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" - default y help - If unsure, say Y. + If unsure, say N. config BLK_DEV_CMD640 bool "CMD640 chipset bugfix/support" -- cgit v1.2.3 From 2195dadf853bb32262bd2e5a64f517ae45698c55 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: ide: fix hidden dependencies on CONFIG_IDE_GENERIC Some host drivers depend on CONFIG_IDE_GENERIC to do the probing but their config options lack explicit dependencies on IDE_GENERIC. In the long-term these host drivers should be fixed to do the probing themselves but for now fix them by making their config options select CONFIG_IDE_GENERIC. Signed-off-by: Bartlomiej Zolnierkiewicz --- arch/cris/arch-v10/drivers/Kconfig | 1 + arch/cris/arch-v32/drivers/Kconfig | 1 + drivers/ide/Kconfig | 9 +++++++++ 3 files changed, 11 insertions(+) (limited to 'drivers') diff --git a/arch/cris/arch-v10/drivers/Kconfig b/arch/cris/arch-v10/drivers/Kconfig index e7e724bc0ba6..03e2e68f947d 100644 --- a/arch/cris/arch-v10/drivers/Kconfig +++ b/arch/cris/arch-v10/drivers/Kconfig @@ -548,6 +548,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enable this to get support for ATA/IDE. You can't use parallel ports or SCSI ports diff --git a/arch/cris/arch-v32/drivers/Kconfig b/arch/cris/arch-v32/drivers/Kconfig index 1d859c16931e..cc6ba5423754 100644 --- a/arch/cris/arch-v32/drivers/Kconfig +++ b/arch/cris/arch-v32/drivers/Kconfig @@ -592,6 +592,7 @@ config ETRAX_IDE select BLK_DEV_IDEDISK select BLK_DEV_IDECD select BLK_DEV_IDEDMA + select IDE_GENERIC help Enables the ETRAX IDE driver. diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig index e7fcdd2580fb..7adb61bad6ad 100644 --- a/drivers/ide/Kconfig +++ b/drivers/ide/Kconfig @@ -304,6 +304,7 @@ comment "IDE chipset support/bugfixes" config IDE_GENERIC tristate "generic/default IDE chipset support" + default H8300 help If unsure, say N. @@ -344,6 +345,7 @@ config BLK_DEV_CMD640_ENHANCED config BLK_DEV_IDEPNP bool "PNP EIDE support" depends on PNP + select IDE_GENERIC help If you have a PnP (Plug and Play) compatible EIDE card and would like the kernel to automatically detect and activate @@ -833,6 +835,7 @@ config BLK_DEV_IDE_AU1XXX_SEQTS_PER_RQ config IDE_ARM def_bool ARM && (ARCH_CLPS7500 || ARCH_RPC || ARCH_SHARK) + select IDE_GENERIC config BLK_DEV_IDE_ICSIDE tristate "ICS IDE interface support" @@ -866,6 +869,7 @@ config BLK_DEV_IDE_BAST config BLK_DEV_GAYLE bool "Amiga Gayle IDE interface support" depends on AMIGA + select IDE_GENERIC help This is the IDE driver for the Amiga Gayle IDE interface. It supports both the `A1200 style' and `A4000 style' of the Gayle IDE interface, @@ -897,6 +901,7 @@ config BLK_DEV_IDEDOUBLER config BLK_DEV_BUDDHA bool "Buddha/Catweasel/X-Surf IDE interface support (EXPERIMENTAL)" depends on ZORRO && EXPERIMENTAL + select IDE_GENERIC help This is the IDE driver for the IDE interfaces on the Buddha, Catweasel and X-Surf expansion boards. It supports up to two interfaces @@ -909,6 +914,7 @@ config BLK_DEV_BUDDHA config BLK_DEV_FALCON_IDE bool "Falcon IDE interface support" depends on ATARI + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on the Atari Falcon. Say Y if you have a Falcon and want to use IDE devices (hard @@ -918,6 +924,7 @@ config BLK_DEV_FALCON_IDE config BLK_DEV_MAC_IDE bool "Macintosh Quadra/Powerbook IDE interface support" depends on MAC + select IDE_GENERIC help This is the IDE driver for the builtin IDE interface on some m68k Macintosh models. It supports both the `Quadra style' (used in @@ -931,6 +938,7 @@ config BLK_DEV_MAC_IDE config BLK_DEV_Q40IDE bool "Q40/Q60 IDE interface support" depends on Q40 + select IDE_GENERIC help Enable the on-board IDE controller in the Q40/Q60. This should normally be on; disable it only if you are running a custom hard @@ -939,6 +947,7 @@ config BLK_DEV_Q40IDE config BLK_DEV_MPC8xx_IDE bool "MPC8xx IDE support" depends on 8xx && IDE=y && BLK_DEV_IDE=y + select IDE_GENERIC help This option provides support for IDE on Motorola MPC8xx Systems. Please see 'Type of MPC8xx IDE interface' for details. -- cgit v1.2.3 From 8292e8c7e4c2b99f22120f677858487de43c484b Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:54 +0200 Subject: ide-cris: fix ->set_pio_mode method to set transfer mode on the device Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/cris/ide-cris.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c index fbfea46a34f2..04636f7eaae7 100644 --- a/drivers/ide/cris/ide-cris.c +++ b/drivers/ide/cris/ide-cris.c @@ -718,6 +718,8 @@ static void tune_cris_ide(ide_drive_t *drive, u8 pio) } cris_ide_set_speed(TYPE_PIO, setup, strobe, hold); + + (void)ide_config_drive_speed(drive, XFER_PIO_0 + pio); } static int speed_cris_ide(ide_drive_t *drive, u8 speed) -- cgit v1.2.3 From 1116fae5fdfa80c6744a9b5d75fb3ef687a69b19 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: ide: config_drive_for_dma() fixes * Add DMA blacklist checking (->ide_dma_on check probably can go now). * Add ->atapi_dma flag checking and remove no longer needed ns87415_ide_dma_check() from ns87415 host driver. * Remove now needless __ide_dma_check() wrapper and symbol export. * Check drive->autodma instead of hwif->autodma (there should be no changes in behavior as all users of config_drive_for_dma() set both ->autodma flags). Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 26 ++++++++++---------------- drivers/ide/pci/ns87415.c | 9 --------- include/linux/ide.h | 1 - 3 files changed, 10 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 5fe1d72ab451..865a2740a6e3 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -349,9 +349,17 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable); static int config_drive_for_dma (ide_drive_t *drive) { + ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; - if ((id->capability & 1) && drive->hwif->autodma) { + /* consult the list of known "bad" drives */ + if (__ide_dma_bad_drive(drive)) + return -1; + + if (drive->media != ide_disk && hwif->atapi_dma == 0) + return -1; + + if ((id->capability & 1) && drive->autodma) { /* * Enable DMA on any drive that has * UltraDMA (mode 0/1/2/3/4/5/6) enabled @@ -513,20 +521,6 @@ int __ide_dma_on (ide_drive_t *drive) EXPORT_SYMBOL(__ide_dma_on); -/** - * __ide_dma_check - check DMA setup - * @drive: drive to check - * - * Don't use - due for extermination - */ - -int __ide_dma_check (ide_drive_t *drive) -{ - return config_drive_for_dma(drive); -} - -EXPORT_SYMBOL(__ide_dma_check); - /** * ide_dma_setup - begin a DMA phase * @drive: target device @@ -1021,7 +1015,7 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p if (!hwif->dma_host_on) hwif->dma_host_on = &ide_dma_host_on; if (!hwif->ide_dma_check) - hwif->ide_dma_check = &__ide_dma_check; + hwif->ide_dma_check = &config_drive_for_dma; if (!hwif->dma_setup) hwif->dma_setup = &ide_dma_setup; if (!hwif->dma_exec_cmd) diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c index 09941f37d635..465c935fdf25 100644 --- a/drivers/ide/pci/ns87415.c +++ b/drivers/ide/pci/ns87415.c @@ -187,14 +187,6 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive) return 1; } -static int ns87415_ide_dma_check (ide_drive_t *drive) -{ - if (drive->media != ide_disk) - return -1; - - return __ide_dma_check(drive); -} - static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; @@ -266,7 +258,6 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif) outb(0x60, hwif->dma_status); hwif->dma_setup = &ns87415_ide_dma_setup; - hwif->ide_dma_check = &ns87415_ide_dma_check; hwif->ide_dma_end = &ns87415_ide_dma_end; if (!noautodma) diff --git a/include/linux/ide.h b/include/linux/ide.h index d71d0121b7f9..7e15e0870290 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1312,7 +1312,6 @@ void ide_dma_host_off(ide_drive_t *); void ide_dma_off_quietly(ide_drive_t *); void ide_dma_host_on(ide_drive_t *); extern int __ide_dma_on(ide_drive_t *); -extern int __ide_dma_check(ide_drive_t *); extern int ide_dma_setup(ide_drive_t *); extern void ide_dma_start(ide_drive_t *); extern int __ide_dma_end(ide_drive_t *); -- cgit v1.2.3 From 59785c8fe23ca2f432bc41ef473a8933ab435812 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:55 +0200 Subject: ide-pmac: fix drive->init_speed reporting pmac_ide_tune_chipset() don't set drive->init_speed. Fix it by setting drive->{current,init}_speed in pmac_ide_do_setfeature() and clean up pmac_ide_{tune_chipset,mdma_enable,udma_enable}(). Acked-by: Benjamin Herrenschmidt Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ppc/pmac.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c index 33630ad3e794..4b13cd9a027d 100644 --- a/drivers/ide/ppc/pmac.c +++ b/drivers/ide/ppc/pmac.c @@ -604,6 +604,9 @@ out: drive->id->dma_1word |= 0x0101; break; default: break; } + if (!drive->init_speed) + drive->init_speed = command; + drive->current_speed = command; } enable_irq(hwif->irq); return result; @@ -986,7 +989,6 @@ pmac_ide_tune_chipset (ide_drive_t *drive, byte speed) return ret; pmac_ide_do_update_timings(drive); - drive->current_speed = speed; return 0; } @@ -1737,11 +1739,6 @@ pmac_ide_mdma_enable(ide_drive_t *drive, u16 mode) /* Apply timings to controller */ *timings = timing_local[0]; *timings2 = timing_local[1]; - - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; return 1; } @@ -1793,11 +1790,6 @@ pmac_ide_udma_enable(ide_drive_t *drive, u16 mode) *timings = timing_local[0]; *timings2 = timing_local[1]; - /* Set speed info in drive */ - drive->current_speed = mode; - if (!drive->init_speed) - drive->init_speed = mode; - return 1; } -- cgit v1.2.3 From a5b7e70d787f528386eda025d3e38f545017f241 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: ide: add cable detection for early UDMA66 devices (take 3) * Move ide_in_drive_list() from ide-dma.c to ide-iops.c. * Add ivb_list[] table for listening early UDMA66 devices which don't conform to ATA4 standard wrt cable detection (bit14 is zero, only bit13 is valid) and use only device side cable detection for them since host side cable detection may be unreliable. * Add model "QUANTUM FIREBALLlct10 05" with firwmare "A03.0900" to the list (from Craig's bugreport). v2: * Improve kernel message basing on suggestion from Sergei. v3: * Don't print kernel message when no device side cable detection is done, plus some minor fixes. (Noticed by Sergei) Thanks to Craig for testing this patch. Cc: Craig Block Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-dma.c | 19 ------------------- drivers/ide/ide-iops.c | 39 ++++++++++++++++++++++++++++++++++++--- include/linux/ide.h | 3 ++- 3 files changed, 38 insertions(+), 23 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c index 865a2740a6e3..ff644a5e12cd 100644 --- a/drivers/ide/ide-dma.c +++ b/drivers/ide/ide-dma.c @@ -134,25 +134,6 @@ static const struct drive_list_entry drive_blacklist [] = { }; -/** - * ide_in_drive_list - look for drive in black/white list - * @id: drive identifier - * @drive_table: list to inspect - * - * Look for a drive in the blacklist and the whitelist tables - * Returns 1 if the drive is found in the table. - */ - -int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) -{ - for ( ; drive_table->id_model ; drive_table++) - if ((!strcmp(drive_table->id_model, id->model)) && - (!drive_table->id_firmware || - strstr(id->fw_rev, drive_table->id_firmware))) - return 1; - return 0; -} - /** * ide_dma_intr - IDE DMA interrupt handler * @drive: the drive the interrupt is for diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 92578b6832e9..fe2a69fed72b 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -565,6 +565,34 @@ int ide_wait_stat (ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 b EXPORT_SYMBOL(ide_wait_stat); +/** + * ide_in_drive_list - look for drive in black/white list + * @id: drive identifier + * @drive_table: list to inspect + * + * Look for a drive in the blacklist and the whitelist tables + * Returns 1 if the drive is found in the table. + */ + +int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table) +{ + for ( ; drive_table->id_model; drive_table++) + if ((!strcmp(drive_table->id_model, id->model)) && + (!drive_table->id_firmware || + strstr(id->fw_rev, drive_table->id_firmware))) + return 1; + return 0; +} + +/* + * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. + * We list them here and depend on the device side cable detection for them. + */ +static const struct drive_list_entry ivb_list[] = { + { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, + { NULL , NULL } +}; + /* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. @@ -573,11 +601,16 @@ u8 eighty_ninty_three (ide_drive_t *drive) { ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; + int ivb = ide_in_drive_list(id, ivb_list); if (hwif->cbl == ATA_CBL_PATA40_SHORT) return 1; - if (hwif->cbl != ATA_CBL_PATA80) + if (ivb) + printk(KERN_DEBUG "%s: skipping word 93 validity check\n", + drive->name); + + if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; /* Check for SATA but only if we are ATA5 or higher */ @@ -587,11 +620,11 @@ u8 eighty_ninty_three (ide_drive_t *drive) /* * FIXME: * - change master/slave IDENTIFY order - * - force bit13 (80c cable present) check + * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ #ifndef CONFIG_IDEDMA_IVB - if (id->hw_config & 0x4000) + if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) #else if (id->hw_config & 0x6000) #endif diff --git a/include/linux/ide.h b/include/linux/ide.h index 7e15e0870290..c792b4fd1588 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -1285,13 +1285,14 @@ void ide_init_sg_cmd(ide_drive_t *, struct request *); #define BAD_DMA_DRIVE 0 #define GOOD_DMA_DRIVE 1 -#ifdef CONFIG_BLK_DEV_IDEDMA struct drive_list_entry { const char *id_model; const char *id_firmware; }; int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *); + +#ifdef CONFIG_BLK_DEV_IDEDMA int __ide_dma_bad_drive(ide_drive_t *); int __ide_dma_good_drive(ide_drive_t *); u8 ide_max_dma_mode(ide_drive_t *); -- cgit v1.2.3 From adcd33d41bfea8fb6870cf1f7e7ed2e5f7323fc1 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: ide: ide_config_drive_speed() bugfixes * Use ->OUTBSYNC instead of ->OUTB when writing command register (needed for scc_pata and pmac host drivers). * Don't check DRDY bit of the status register on ATAPI devices (ATAPI devices are free to ignore DRDY bit). Cc: Benjamin Herrenschmidt Cc: Kou Ishizaki Cc: Akira Iguchi Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-iops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index fe2a69fed72b..18cf3a66a1a3 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -828,7 +828,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); - hwif->OUTB(WIN_SETFEATURES, IDE_COMMAND_REG); + hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); udelay(1); @@ -855,7 +855,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed) */ for (i = 0; i < 10; i++) { udelay(1); - if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), DRIVE_READY, BUSY_STAT|DRQ_STAT|ERR_STAT)) { + if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT)) { error = 0; break; } -- cgit v1.2.3 From f7b0d2df2f6fd9abdf47b4a1965dcaa2870e35df Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: cs5530: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/cs5530.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c index acaf71fd4c09..e5949b1d3fb0 100644 --- a/drivers/ide/pci/cs5530.c +++ b/drivers/ide/pci/cs5530.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/cs5530.c Version 0.73 Mar 10 2007 + * linux/drivers/ide/pci/cs5530.c Version 0.74 Jul 28 2007 * * Copyright (C) 2000 Andre Hedrick * Copyright (C) 2000 Mark Lord @@ -207,6 +207,9 @@ static unsigned int __devinit init_chipset_cs5530 (struct pci_dev *dev, const ch struct pci_dev *master_0 = NULL, *cs5530_0 = NULL; unsigned long flags; + if (pci_resource_start(dev, 4) == 0) + return -EFAULT; + dev = NULL; while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { switch (dev->device) { @@ -325,6 +328,9 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif) /* needs autotuning later */ } + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; -- cgit v1.2.3 From 01cc643ae3c7de35b63989b7b65e3ef3132e48e4 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: pdc202xx_new: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Also this host driver requires valid PCI BAR4 for normal operation so check it in ->init_chipset and fail initialization if not set. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_new.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c index 8a66a2871b3a..f6db2f37efad 100644 --- a/drivers/ide/pci/pdc202xx_new.c +++ b/drivers/ide/pci/pdc202xx_new.c @@ -378,6 +378,9 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha int f, r; u8 pll_ctl0, pll_ctl1; + if (dma_base == 0) + return -EFAULT; + #ifdef CONFIG_PPC_PMAC apple_kiwi_init(dev); #endif @@ -494,15 +497,18 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->speedproc = &pdcnew_tune_chipset; hwif->resetproc = &pdcnew_reset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; if (hwif->cbl != ATA_CBL_PATA40_SHORT) -- cgit v1.2.3 From e98d6e50be87c1ad2df81f73c7442cf631d6f931 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: pdc202xx_old: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/pdc202xx_old.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index fbcb0bb9c956..e19a891171cb 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c @@ -1,5 +1,5 @@ /* - * linux/drivers/ide/pci/pdc202xx_old.c Version 0.50 Mar 3, 2007 + * linux/drivers/ide/pci/pdc202xx_old.c Version 0.51 Jul 27, 2007 * * Copyright (C) 1998-2002 Andre Hedrick * Copyright (C) 2006-2007 MontaVista Software, Inc. @@ -337,15 +337,18 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->speedproc = &pdc202xx_tune_chipset; + hwif->err_stops_fifo = 1; + hwif->drives[0].autotune = hwif->drives[1].autotune = 1; + if (hwif->dma_base == 0) + return; + hwif->ultra_mask = hwif->cds->udma_mask; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; hwif->atapi_dma = 1; - hwif->err_stops_fifo = 1; - hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->dma_lost_irq = &pdc202xx_dma_lost_irq; hwif->dma_timeout = &pdc202xx_dma_timeout; -- cgit v1.2.3 From 88b47040f8365ad56ecfd4103e964ba9b695987e Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:56 +0200 Subject: triflex: add missing ->dma_base check If ->dma_base is not set (== PCI BAR4 cannot be reserved) then DMA hooks shouldn't be initialized or bad things will happen. Acked-by: Sergei Shtylyov Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/triflex.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c index 024bbfae0429..098692a6d615 100644 --- a/drivers/ide/pci/triflex.c +++ b/drivers/ide/pci/triflex.c @@ -115,6 +115,9 @@ static void __devinit init_hwif_triflex(ide_hwif_t *hwif) hwif->tuneproc = &triflex_tune_drive; hwif->speedproc = &triflex_tune_chipset; + if (hwif->dma_base == 0) + return; + hwif->atapi_dma = 1; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; -- cgit v1.2.3 From 76e1faa7cfd464fa06a9c2cafd633d643daafeae Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: hpt34x: fix CONFIG_HPT34X_AUTODMA=n handling Programming DMA mode may destroy current PIO mode setting so if CONFIG_HPT34X_AUTODMA=n (the default case) make ide_tune_dma() fail early by disabling all host DMA masks and re-tune PIO mode. This fix doesn't help with the driver being broken but is needed for some other changes. Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/pci/hpt34x.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c index 19778c5fe711..cb8fe5643d3b 100644 --- a/drivers/ide/pci/hpt34x.c +++ b/drivers/ide/pci/hpt34x.c @@ -89,11 +89,7 @@ static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) drive->init_speed = 0; if (ide_tune_dma(drive)) -#ifndef CONFIG_HPT34X_AUTODMA return -1; -#else - return 0; -#endif if (ide_use_fast_pio(drive)) hpt34x_tune_drive(drive, 255); @@ -160,9 +156,11 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif) if (!hwif->dma_base) return; +#ifdef CONFIG_HPT34X_AUTODMA hwif->ultra_mask = 0x07; hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; +#endif hwif->ide_dma_check = &hpt34x_config_drive_xfer_rate; if (!noautodma) -- cgit v1.2.3 From b0244a00451c1ad64bf0a51f50679f7146786780 Mon Sep 17 00:00:00 2001 From: Bartlomiej Zolnierkiewicz Date: Mon, 20 Aug 2007 22:42:57 +0200 Subject: ide-disk: workaround for buggy HPA support on ST340823A (take 3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This disk reports total number of sectors instead of maximum sector address in response to READ_NATIVE_MAX_ADDRESS command and also happily accepts SET_MAX_ADDRESS command with the bogus value. This results in +1 sector capacity being used and errors on attempts to use the last sector. ... hdd: Host Protected Area detected.         current capacity is 78165360 sectors (40020 MB)         native  capacity is 78165361 sectors (40020 MB) hdd: Host Protected Area disabled. ... hdd: reading: block=78165360, sectors=1, buffer=0xc1e63000 hdd: dma_intr: status=0x51 { DriveReady SeekComplete Error } hdd: dma_intr: error=0x10 { SectorIdNotFound }, LBAsect=78165360, sector=78165360 ... Add hpa_list[] table and workaround the issue in idedisk_check_hpa(). v2: * Add missing export and improve patch description a bit. v3: * Add list termination. (From Mikko) Fixes kernel bugzilla bug #8816. Thanks to Mikko for investigating the issue and helping with this patch. Cc: Mikko Rapeli Cc: Alan Cox Signed-off-by: Bartlomiej Zolnierkiewicz --- drivers/ide/ide-disk.c | 18 ++++++++++++++++++ drivers/ide/ide-iops.c | 2 ++ 2 files changed, 20 insertions(+) (limited to 'drivers') diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c index 5ce4216f72a2..eba1adbc1b6a 100644 --- a/drivers/ide/ide-disk.c +++ b/drivers/ide/ide-disk.c @@ -481,6 +481,15 @@ static inline int idedisk_supports_lba48(const struct hd_driveid *id) && id->lba_capacity_2; } +/* + * Some disks report total number of sectors instead of + * maximum sector address. We list them here. + */ +static const struct drive_list_entry hpa_list[] = { + { "ST340823A", NULL }, + { NULL, NULL } +}; + static void idedisk_check_hpa(ide_drive_t *drive) { unsigned long long capacity, set_max; @@ -492,6 +501,15 @@ static void idedisk_check_hpa(ide_drive_t *drive) else set_max = idedisk_read_native_max_address(drive); + if (ide_in_drive_list(drive->id, hpa_list)) { + /* + * Since we are inclusive wrt to firmware revisions do this + * extra check and apply the workaround only when needed. + */ + if (set_max == capacity + 1) + set_max--; + } + if (set_max <= capacity) return; diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c index 18cf3a66a1a3..f4cd2700cae5 100644 --- a/drivers/ide/ide-iops.c +++ b/drivers/ide/ide-iops.c @@ -584,6 +584,8 @@ int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *driv return 0; } +EXPORT_SYMBOL_GPL(ide_in_drive_list); + /* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. * We list them here and depend on the device side cable detection for them. -- cgit v1.2.3 From 8c99fdce30787b0d1fc00b907d4cd55a714e4cdd Mon Sep 17 00:00:00 2001 From: Len Brown Date: Mon, 20 Aug 2007 18:46:50 -0400 Subject: ACPI: thermal: set "thermal.nocrt" via DMI on Gigabyte GA-7ZX This system BIOS sets a critical temperature to 65C, which is too low. https://bugzilla.redhat.com/bugzilla/show_bug.cgi?id=155496 Signed-off-by: Len Brown --- drivers/acpi/thermal.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 4c420feba207..39479b0befa4 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -89,7 +89,7 @@ MODULE_PARM_DESC(tzp, "Thermal zone polling frequency, in 1/10 seconds."); static int nocrt; module_param(nocrt, int, 0); -MODULE_PARM_DESC(nocrt, "Set to disable action on ACPI thermal zone critical and hot trips."); +MODULE_PARM_DESC(nocrt, "Set to take no action upon ACPI thermal zone critical trips points."); static int off; module_param(off, int, 0); @@ -1357,6 +1357,13 @@ static int thermal_act(struct dmi_system_id *d) { } return 0; } +static int thermal_nocrt(struct dmi_system_id *d) { + + printk(KERN_NOTICE "ACPI: %s detected: " + "disabling all critical thermal trip point actions.\n", d->ident); + nocrt = 1; + return 0; +} static int thermal_tzp(struct dmi_system_id *d) { if (tzp == 0) { @@ -1405,6 +1412,14 @@ static struct dmi_system_id thermal_dmi_table[] __initdata = { DMI_MATCH(DMI_BOARD_NAME, "i915GMm-HFS"), }, }, + { + .callback = thermal_nocrt, + .ident = "Gigabyte GA-7ZX", + .matches = { + DMI_MATCH(DMI_BOARD_VENDOR, "Gigabyte Technology Co., Ltd."), + DMI_MATCH(DMI_BOARD_NAME, "7ZX"), + }, + }, {} }; #endif /* CONFIG_DMI */ -- cgit v1.2.3 From 8eb891fc809b2300137bcd247025628c06c95a63 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 20 Aug 2007 23:38:44 -0700 Subject: Revert "USB: EHCI cpufreq fix" This reverts commit 196705c9bbc03540429b0f7cf9ee35c2f928a534. It was reported to cause a regression by Daniel Exner, and Arjan van de Ven points out that we actually already have infrastructure in place for setting limits on acceptable DMA latency that would be the much more correct fix for the problem with some Broadcom EHCI controllers. Fixed up trivial conflicts due to the changes to support big-endian host controller descriptors in drivers/usb/host/{ehci-sched.c,ehci.h}. Signed-off-by: Linus Torvalds --- drivers/usb/host/ehci-hcd.c | 67 ---------------------- drivers/usb/host/ehci-mem.c | 3 - drivers/usb/host/ehci-q.c | 4 -- drivers/usb/host/ehci-sched.c | 127 ------------------------------------------ drivers/usb/host/ehci.h | 14 ----- 5 files changed, 215 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c4e15ed1405a..35cdba10411b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -275,58 +275,6 @@ static void ehci_work(struct ehci_hcd *ehci); /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -#include - -static void ehci_cpufreq_pause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!ehci->cpufreq_changing++) - qh_inactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) -{ - unsigned long flags; - - spin_lock_irqsave(&ehci->lock, flags); - if (!--ehci->cpufreq_changing) - qh_reactivate_split_intr_qhs(ehci); - spin_unlock_irqrestore(&ehci->lock, flags); -} - -/* - * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when - * EHCI controllers that don't cache many uframes get delayed trying to - * read main memory during CPU frequency transitions. This can cause - * split interrupt transactions to not be completed in the required uframe. - * This has been observed on the Broadcom/ServerWorks HT1000 controller. - */ -static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, - void *data) -{ - struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, - cpufreq_transition); - - switch (val) { - case CPUFREQ_PRECHANGE: - ehci_cpufreq_pause(ehci); - break; - case CPUFREQ_POSTCHANGE: - ehci_cpufreq_unpause(ehci); - break; - } - return 0; -} - -#endif - -/*-------------------------------------------------------------------------*/ - static void ehci_watchdog (unsigned long param) { struct ehci_hcd *ehci = (struct ehci_hcd *) param; @@ -460,10 +408,6 @@ static void ehci_stop (struct usb_hcd *hcd) ehci_writel(ehci, 0, &ehci->regs->intr_enable); spin_unlock_irq(&ehci->lock); -#ifdef CONFIG_CPU_FREQ - cpufreq_unregister_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif /* let companion controllers work when we aren't */ ehci_writel(ehci, 0, &ehci->regs->configured_flag); @@ -569,17 +513,6 @@ static int ehci_init(struct usb_hcd *hcd) } ehci->command = temp; -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD(&ehci->split_intr_qhs); - /* - * If the EHCI controller caches enough uframes, this probably - * isn't needed unless there are so many low/full speed devices - * that the controller's can't cache it all. - */ - ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; - cpufreq_register_notifier(&ehci->cpufreq_transition, - CPUFREQ_TRANSITION_NOTIFIER); -#endif return 0; } diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 8816d09903d0..0431397836f6 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c @@ -94,9 +94,6 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) qh->qh_dma = dma; // INIT_LIST_HEAD (&qh->qh_list); INIT_LIST_HEAD (&qh->qtd_list); -#ifdef CONFIG_CPU_FREQ - INIT_LIST_HEAD (&qh->split_intr_qhs); -#endif /* dummy td enables safe urb queuing */ qh->dummy = ehci_qtd_alloc (ehci, flags); diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2284028f8aa5..140bfa423e07 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -312,10 +312,6 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) struct urb *urb; u32 token = 0; - /* ignore QHs that are currently inactive */ - if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) - break; - qtd = list_entry (entry, struct ehci_qtd, qtd_list); urb = qtd->urb; diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d4a8ace49676..e682f2342ef8 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c @@ -479,109 +479,6 @@ static int disable_periodic (struct ehci_hcd *ehci) } /*-------------------------------------------------------------------------*/ -#ifdef CONFIG_CPU_FREQ - -static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh) -{ - int now; /* current (frame * 8) + uframe */ - int prev_start, next_start; /* uframes from/to split start */ - int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK); - int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8); - int split_duration = end_uframe - start_uframe; - - now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3); - - next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) - % (qh->period << 3); - prev_start = (qh->period << 3) - next_start; - - /* - * Make sure there will be at least one uframe when qh is safe. - */ - if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration)) - /* never safe */ - return -EINVAL; - - /* - * Wait 1 uframe after transaction should have started, to make - * sure controller has time to write back overlay, so we can - * check QTD_STS_STS to see if transaction is in progress. - */ - if ((next_start > ehci->i_thresh) && (prev_start > 1)) - /* safe to set "i" bit if split isn't in progress */ - return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1; - else - return 0; -} - -/* Set inactivate bit for all the split interrupt QHs. */ -static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, - split_intr_qhs) { - if (qh->hw_info1 & inactivate) - /* already off */ - continue; - /* - * To avoid setting "I" after the start split happens, - * don't set it if the QH might be cached in the - * controller. Some HCs (Broadcom/ServerWorks HT1000) - * will stop in the middle of a split transaction when - * the "I" bit is set. - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - qh->was_active = qh->hw_token & active; - qh->hw_info1 |= inactivate; - } - } - } while (not_done); - wmb(); -} - -static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci) -{ - struct ehci_qh *qh; - u32 token; - int not_done, safe; - u32 inactivate = INACTIVATE_BIT(ehci); - u32 active = ACTIVE_BIT(ehci); - u32 halt = HALT_BIT(ehci); - - do { - not_done = 0; - list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) { - if (!(qh->hw_info1 & inactivate)) /* already on */ - continue; - /* - * Don't reactivate if cached, or controller might - * overwrite overlay after we modify it! - */ - safe = safe_to_modify_i(ehci, qh); - if (safe == 0) { - not_done = 1; - } else if (safe > 0) { - /* See EHCI 1.0 section 4.15.2.4. */ - token = qh->hw_token; - qh->hw_token = (token | halt) & ~active; - wmb(); - qh->hw_info1 &= ~inactivate; - wmb(); - qh->hw_token = (token & ~halt) | qh->was_active; - } - } - } while (not_done); -} -#endif /* periodic schedule slots have iso tds (normal or split) first, then a * sparse tree for active interrupt transfers. @@ -599,17 +496,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), qh, qh->start, qh->usecs, qh->c_usecs); -#ifdef CONFIG_CPU_FREQ - /* - * If low/full speed interrupt QHs are inactive (because of - * cpufreq changing processor speeds), start QH with I flag set-- - * it will automatically be cleared when cpufreq is done. - */ - if (ehci->cpufreq_changing) - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) - qh->hw_info1 |= INACTIVATE_BIT(ehci); -#endif - /* high bandwidth, or otherwise every microframe */ if (period == 0) period = 1; @@ -658,12 +544,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) ? ((qh->usecs + qh->c_usecs) / qh->period) : (qh->usecs * 8); -#ifdef CONFIG_CPU_FREQ - /* add qh to list of low/full speed interrupt QHs, if applicable */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs); - } -#endif /* maybe enable periodic schedule processing */ if (!ehci->periodic_sched++) return enable_periodic (ehci); @@ -683,13 +563,6 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) // THEN // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); -#ifdef CONFIG_CPU_FREQ - /* remove qh from list of low/full speed interrupt QHs */ - if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { - list_del_init(&qh->split_intr_qhs); - } -#endif - /* high bandwidth, or otherwise part of every microframe */ if ((period = qh->period) == 0) period = 1; diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2c68a04230c1..951d69fec513 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -71,12 +71,6 @@ struct ehci_hcd { /* one per controller */ __u32 hcs_params; /* cached register copy */ spinlock_t lock; -#ifdef CONFIG_CPU_FREQ - struct notifier_block cpufreq_transition; - int cpufreq_changing; - struct list_head split_intr_qhs; -#endif - /* async schedule support */ struct ehci_qh *async; struct ehci_qh *reclaim; @@ -439,10 +433,6 @@ struct ehci_qh { __hc32 hw_next; /* see EHCI 3.6.1 */ __hc32 hw_info1; /* see EHCI 3.6.2 */ #define QH_HEAD 0x00008000 -#define QH_INACTIVATE 0x00000080 - -#define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE) - __hc32 hw_info2; /* see EHCI 3.6.2 */ #define QH_SMASK 0x000000ff #define QH_CMASK 0x0000ff00 @@ -492,10 +482,6 @@ struct ehci_qh { unsigned short start; /* where polling starts */ #define NO_FRAME ((unsigned short)~0) /* pick new start */ struct usb_device *dev; /* access to TT */ -#ifdef CONFIG_CPU_FREQ - struct list_head split_intr_qhs; /* list of split qhs */ - __le32 was_active; /* active bit before "i" set */ -#endif } __attribute__ ((aligned (32))); /*-------------------------------------------------------------------------*/ -- cgit v1.2.3 From d6c59c13c070cb9d043edf38b4639fdacdb0c18c Mon Sep 17 00:00:00 2001 From: Martin Bachem Date: Tue, 21 Aug 2007 14:26:21 +0200 Subject: hisax: update hfc_usb driver This fixes handling of USB ISO completion error -EXDEV and includes several other changes to current CVS version at isdn4linux.de (changes in debug flags, style of code remarks, etc) Signed-off-by: Martin Bachem Acked-by: Karsten Keil Signed-off-by: Linus Torvalds --- drivers/isdn/hisax/hfc_usb.c | 603 +++++++++++++++++-------------------------- drivers/isdn/hisax/hfc_usb.h | 130 ++++------ 2 files changed, 288 insertions(+), 445 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/hisax/hfc_usb.c b/drivers/isdn/hisax/hfc_usb.c index b1a26e02df02..60843b3f3b6f 100644 --- a/drivers/isdn/hisax/hfc_usb.c +++ b/drivers/isdn/hisax/hfc_usb.c @@ -1,12 +1,12 @@ /* * hfc_usb.c * - * $Id: hfc_usb.c,v 2.3.2.13 2006/02/17 17:17:22 mbachem Exp $ + * $Id: hfc_usb.c,v 2.3.2.20 2007/08/20 14:07:54 mbachem Exp $ * * modular HiSax ISDN driver for Colognechip HFC-S USB chip * - * Authors : Peter Sprenger (sprenger@moving-bytes.de) - * Martin Bachem (info@colognechip.com) + * Authors : Peter Sprenger (sprenger@moving-bytes.de) + * Martin Bachem (m.bachem@gmx.de, info@colognechip.com) * * based on the first hfc_usb driver of * Werner Cornelius (werner@isdn-development.de) @@ -37,24 +37,25 @@ #include #include #include +#include +#include +#include #include "hisax.h" #include "hisax_if.h" #include "hfc_usb.h" static const char *hfcusb_revision = - "$Revision: 2.3.2.13 $ $Date: 2006/02/17 17:17:22 $ "; + "$Revision: 2.3.2.20 $ $Date: 2007/08/20 14:07:54 $ "; /* Hisax debug support -* use "modprobe debug=x" where x is bitfield of USB_DBG & ISDN_DBG +* debug flags defined in hfc_usb.h as HFCUSB_DBG_[*] */ -#ifdef CONFIG_HISAX_DEBUG -#include #define __debug_variable hfc_debug #include "hisax_debug.h" static u_int debug; module_param(debug, uint, 0); static int hfc_debug; -#endif + /* private vendor specific data */ typedef struct { @@ -63,9 +64,7 @@ typedef struct { char *vend_name; // device name } hfcsusb_vdata; -/****************************************/ -/* data defining the devices to be used */ -/****************************************/ +/* VID/PID device list */ static struct usb_device_id hfcusb_idtab[] = { { USB_DEVICE(0x0959, 0x2bd0), @@ -90,49 +89,47 @@ static struct usb_device_id hfcusb_idtab[] = { .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Stollmann USB TA"}), - }, + }, { USB_DEVICE(0x0742, 0x2009), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "Aceex USB ISDN TA"}), - }, + }, { USB_DEVICE(0x0742, 0x200A), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {4, 0, 2, 1}, "OEM USB ISDN TA"}), - }, + }, { USB_DEVICE(0x08e3, 0x0301), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {2, 0, 1, 4}, "Olitec USB RNIS"}), - }, + }, { USB_DEVICE(0x07fa, 0x0846), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Bewan Modem RNIS USB"}), - }, + }, { USB_DEVICE(0x07fa, 0x0847), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Djinn Numeris USB"}), - }, + }, { USB_DEVICE(0x07b0, 0x0006), .driver_info = (unsigned long) &((hfcsusb_vdata) {LED_SCHEME1, {0x80, -64, -32, -16}, "Twister ISDN TA"}), - }, + }, { } }; -/***************************************************************/ /* structure defining input+output fifos (interrupt/bulk mode) */ -/***************************************************************/ struct usb_fifo; /* forward definition */ typedef struct iso_urb_struct { struct urb *purb; @@ -140,8 +137,8 @@ typedef struct iso_urb_struct { struct usb_fifo *owner_fifo; /* pointer to owner fifo */ } iso_urb_struct; - struct hfcusb_data; /* forward definition */ + typedef struct usb_fifo { int fifonum; /* fifo index attached to this structure */ int active; /* fifo is currently active */ @@ -160,15 +157,12 @@ typedef struct usb_fifo { struct hisax_if *hif; /* hisax interface */ int delete_flg; /* only delete skbuff once */ int last_urblen; /* remember length of last packet */ - } usb_fifo; -/*********************************************/ /* structure holding all data for one device */ -/*********************************************/ typedef struct hfcusb_data { /* HiSax Interface for loadable Layer1 drivers */ - struct hisax_d_if d_if; /* see hisax_if.h */ + struct hisax_d_if d_if; /* see hisax_if.h */ struct hisax_b_if b_if[2]; /* see hisax_if.h */ int protocol; @@ -176,12 +170,13 @@ typedef struct hfcusb_data { int if_used; /* used interface number */ int alt_used; /* used alternate config */ int ctrl_paksize; /* control pipe packet size */ - int ctrl_in_pipe, ctrl_out_pipe; /* handles for control pipe */ + int ctrl_in_pipe, /* handles for control pipe */ + ctrl_out_pipe; int cfg_used; /* configuration index used */ int vend_idx; /* vendor found */ int b_mode[2]; /* B-channel mode */ int l1_activated; /* layer 1 activated */ - int disc_flag; /* 'true' if device was disonnected to avoid some USB actions */ + int disc_flag; /* TRUE if device was disonnected to avoid some USB actions */ int packet_size, iso_packet_size; /* control pipe background handling */ @@ -208,7 +203,6 @@ typedef struct hfcusb_data { static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish); - static inline const char * symbolic(struct hfcusb_symbolic_list list[], const int num) { @@ -219,10 +213,6 @@ symbolic(struct hfcusb_symbolic_list list[], const int num) return ""; } - -/******************************************************/ -/* start next background transfer for control channel */ -/******************************************************/ static void ctrl_start_transfer(hfcusb_data * hfc) { @@ -240,10 +230,6 @@ ctrl_start_transfer(hfcusb_data * hfc) } } /* ctrl_start_transfer */ -/************************************/ -/* queue a control transfer request */ -/* return 0 on success. */ -/************************************/ static int queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) { @@ -260,19 +246,8 @@ queue_control_request(hfcusb_data * hfc, __u8 reg, __u8 val, int action) if (++hfc->ctrl_cnt == 1) ctrl_start_transfer(hfc); return (0); -} /* queue_control_request */ - -static int -control_action_handler(hfcusb_data * hfc, int reg, int val, int action) -{ - if (!action) - return (1); /* no action defined */ - return (0); } -/***************************************************************/ -/* control completion routine handling background control cmds */ -/***************************************************************/ static void ctrl_complete(struct urb *urb) { @@ -282,9 +257,6 @@ ctrl_complete(struct urb *urb) urb->dev = hfc->dev; if (hfc->ctrl_cnt) { buf = &hfc->ctrl_buff[hfc->ctrl_out_idx]; - control_action_handler(hfc, buf->hfc_reg, buf->reg_val, - buf->action); - hfc->ctrl_cnt--; /* decrement actual count */ if (++hfc->ctrl_out_idx >= HFC_CTRL_BUFSIZE) hfc->ctrl_out_idx = 0; /* pointer wrap */ @@ -293,9 +265,7 @@ ctrl_complete(struct urb *urb) } } /* ctrl_complete */ -/***************************************************/ /* write led data to auxport & invert if necessary */ -/***************************************************/ static void write_led(hfcusb_data * hfc, __u8 led_state) { @@ -305,9 +275,6 @@ write_led(hfcusb_data * hfc, __u8 led_state) } } -/**************************/ -/* handle LED bits */ -/**************************/ static void set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) { @@ -324,9 +291,7 @@ set_led_bit(hfcusb_data * hfc, signed short led_bits, int unset) } } -/**************************/ -/* handle LED requests */ -/**************************/ +/* handle LED requests */ static void handle_led(hfcusb_data * hfc, int event) { @@ -339,85 +304,73 @@ handle_led(hfcusb_data * hfc, int event) switch (event) { case LED_POWER_ON: - set_led_bit(hfc, driver_info->led_bits[0], - 0); - set_led_bit(hfc, driver_info->led_bits[1], - 1); - set_led_bit(hfc, driver_info->led_bits[2], - 1); - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[0], 0); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; - case LED_POWER_OFF: /* no Power off handling */ + case LED_POWER_OFF: + set_led_bit(hfc, driver_info->led_bits[0], 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; case LED_S0_ON: - set_led_bit(hfc, driver_info->led_bits[1], - 0); + set_led_bit(hfc, driver_info->led_bits[1], 0); break; case LED_S0_OFF: - set_led_bit(hfc, driver_info->led_bits[1], - 1); + set_led_bit(hfc, driver_info->led_bits[1], 1); break; case LED_B1_ON: - set_led_bit(hfc, driver_info->led_bits[2], - 0); + set_led_bit(hfc, driver_info->led_bits[2], 0); break; case LED_B1_OFF: - set_led_bit(hfc, driver_info->led_bits[2], - 1); + set_led_bit(hfc, driver_info->led_bits[2], 1); break; case LED_B2_ON: - set_led_bit(hfc, driver_info->led_bits[3], - 0); + set_led_bit(hfc, driver_info->led_bits[3], 0); break; case LED_B2_OFF: - set_led_bit(hfc, driver_info->led_bits[3], - 1); + set_led_bit(hfc, driver_info->led_bits[3], 1); break; } write_led(hfc, hfc->led_state); } -/********************************/ -/* called when timer t3 expires */ -/********************************/ +/* ISDN l1 timer T3 expires */ static void l1_timer_expire_t3(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T3 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); /* deactivate : */ queue_control_request(hfc, HFCUSB_STATES, 0x10, 1); queue_control_request(hfc, HFCUSB_STATES, 3, 1); } -/********************************/ -/* called when timer t4 expires */ -/********************************/ +/* ISDN l1 timer T4 expires */ static void l1_timer_expire_t4(hfcusb_data * hfc) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (T4 expire)"); -#endif - hfc->l1_activated = false; + + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } -/*****************************/ -/* handle S0 state changes */ -/*****************************/ +/* S0 state changed */ static void -state_handler(hfcusb_data * hfc, __u8 state) +s0_state_handler(hfcusb_data * hfc, __u8 state) { __u8 old_state; @@ -425,38 +378,29 @@ state_handler(hfcusb_data * hfc, __u8 state) if (state == old_state || state < 1 || state > 8) return; -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: new S0 state:%d old_state:%d", state, - old_state); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: S0 statechange(%d -> %d)", + old_state, state); + if (state < 4 || state == 7 || state == 8) { if (timer_pending(&hfc->t3_timer)) del_timer(&hfc->t3_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T3 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T3 deactivated"); } if (state >= 7) { if (timer_pending(&hfc->t4_timer)) del_timer(&hfc->t4_timer); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 deactivated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 deactivated"); } if (state == 7 && !hfc->l1_activated) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_ACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = true; + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent"); + hfc->l1_activated = 1; handle_led(hfc, LED_S0_ON); } else if (state <= 3 /* && activated */ ) { if (old_state == 7 || old_state == 8) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: T4 activated"); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: T4 activated"); if (!timer_pending(&hfc->t4_timer)) { hfc->t4_timer.expires = jiffies + (HFC_TIMER_T4 * HZ) / 1000; @@ -466,18 +410,15 @@ state_handler(hfcusb_data * hfc, __u8 state) hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent"); -#endif - hfc->l1_activated = false; + hfc->l1_activated = 0; handle_led(hfc, LED_S0_OFF); } } hfc->l1_state = state; } -/* prepare iso urb */ static void fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, void *buf, int num_packets, int packet_size, int interval, @@ -503,15 +444,16 @@ fill_isoc_urb(struct urb *urb, struct usb_device *dev, unsigned int pipe, } /* allocs urbs and start isoc transfer with two pending urbs to avoid - gaps in the transfer chain */ + * gaps in the transfer chain + */ static int start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, usb_complete_t complete, int packet_size) { int i, k, errcode; - printk(KERN_INFO "HFC-S USB: starting ISO-chain for Fifo %i\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting ISO-URBs for fifo:%d\n", + fifo->fifonum); /* allocate Memory for Iso out Urbs */ for (i = 0; i < 2; i++) { @@ -556,10 +498,9 @@ start_isoc_chain(usb_fifo * fifo, int num_packets_per_urb, errcode = usb_submit_urb(fifo->iso[i].purb, GFP_KERNEL); fifo->active = (errcode >= 0) ? 1 : 0; - if (errcode < 0) { - printk(KERN_INFO "HFC-S USB: %s URB nr:%d\n", - symbolic(urb_errlist, errcode), i); - }; + if (errcode < 0) + printk(KERN_INFO "HFC-S USB: usb_submit_urb URB nr:%d, error(%i): '%s'\n", + i, errcode, symbolic(urb_errlist, errcode)); } return (fifo->active); } @@ -572,16 +513,15 @@ stop_isoc_chain(usb_fifo * fifo) for (i = 0; i < 2; i++) { if (fifo->iso[i].purb) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, + DBG(HFCUSB_DBG_INIT, "HFC-S USB: Stopping iso chain for fifo %i.%i", fifo->fifonum, i); -#endif usb_kill_urb(fifo->iso[i].purb); usb_free_urb(fifo->iso[i].purb); fifo->iso[i].purb = NULL; } } + usb_kill_urb(fifo->urb); usb_free_urb(fifo->urb); fifo->urb = NULL; @@ -594,9 +534,6 @@ static int iso_packets[8] = ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D, ISOC_PACKETS_D }; -/*****************************************************/ -/* transmit completion routine for all ISO tx fifos */ -/*****************************************************/ static void tx_iso_complete(struct urb *urb) { @@ -607,20 +544,38 @@ tx_iso_complete(struct urb *urb) errcode; int frame_complete, transp_mode, fifon, status; __u8 threshbit; - __u8 threshtable[8] = { 1, 2, 4, 8, 0x10, 0x20, 0x40, 0x80 }; fifon = fifo->fifonum; status = urb->status; tx_offset = 0; + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete with -EXDEV" + ", urb->status %d, fifonum %d\n", + status, fifon); + + for (k = 0; k < iso_packets[fifon]; ++k) { + errcode = urb->iso_frame_desc[k].status; + if (errcode) + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: tx_iso_complete " + "packet %i, status: %i\n", + k, errcode); + } + + // clear status, so go on with ISO transfers + status = 0; + } + if (fifo->active && !status) { transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; /* is FifoFull-threshold set for our channel? */ - threshbit = threshtable[fifon] & hfc->threshold_mask; + threshbit = (hfc->threshold_mask & (1 << fifon)); num_isoc_packets = iso_packets[fifon]; /* predict dataflow to avoid fifo overflow */ @@ -635,8 +590,9 @@ tx_iso_complete(struct urb *urb) tx_iso_complete, urb->context); memset(context_iso_urb->buffer, 0, sizeof(context_iso_urb->buffer)); - frame_complete = false; - /* Generate next Iso Packets */ + frame_complete = 0; + + /* Generate next ISO Packets */ for (k = 0; k < num_isoc_packets; ++k) { if (fifo->skbuff) { len = fifo->skbuff->len; @@ -661,7 +617,7 @@ tx_iso_complete(struct urb *urb) /* add 2 byte flags and 16bit CRC at end of ISDN frame */ fifo->bit_line += 32; } - frame_complete = true; + frame_complete = 1; } memcpy(context_iso_urb->buffer + @@ -688,7 +644,7 @@ tx_iso_complete(struct urb *urb) } if (frame_complete) { - fifo->delete_flg = true; + fifo->delete_flg = 1; fifo->hif->l1l2(fifo->hif, PH_DATA | CONFIRM, (void *) (unsigned long) fifo->skbuff-> @@ -696,30 +652,26 @@ tx_iso_complete(struct urb *urb) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } - frame_complete = false; + frame_complete = 0; } } errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { printk(KERN_INFO - "HFC-S USB: tx_iso_complete : urb->status %s (%i), fifonum=%d\n", - symbolic(urb_errlist, status), status, - fifon); + "HFC-S USB: tx_iso_complete: error(%i): '%s', fifonum=%d\n", + status, symbolic(urb_errlist, status), fifon); } } -} /* tx_iso_complete */ +} -/*****************************************************/ -/* receive completion routine for all ISO tx fifos */ -/*****************************************************/ static void rx_iso_complete(struct urb *urb) { @@ -731,21 +683,25 @@ rx_iso_complete(struct urb *urb) unsigned int iso_status; __u8 *buf; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif fifon = fifo->fifonum; status = urb->status; if (urb->status == -EOVERFLOW) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: ignoring USB DATAOVERRUN for fifo %i \n", - fifon); -#endif + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-USB: ignoring USB DATAOVERRUN fifo(%i)", fifon); + status = 0; + } + + /* ISO transfer only partially completed, + look at individual frame status for details */ + if (status == -EXDEV) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: rx_iso_complete with -EXDEV " + "urb->status %d, fifonum %d\n", + status, fifon); status = 0; } + if (fifo->active && !status) { num_isoc_packets = iso_packets[fifon]; maxlen = fifo->usb_packet_maxlen; @@ -754,40 +710,38 @@ rx_iso_complete(struct urb *urb) offset = urb->iso_frame_desc[k].offset; buf = context_iso_urb->buffer + offset; iso_status = urb->iso_frame_desc[k].status; -#ifdef CONFIG_HISAX_DEBUG + if (iso_status && !hfc->disc_flag) - DBG(USB_DBG, - "HFC-S USB: ISO packet failure - status:%x", - iso_status); + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: rx_iso_complete " + "ISO packet %i, status: %i\n", + k, iso_status); - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, "HFC-S USB: ISO-D-RX lst_urblen:%2d " - "act_urblen:%2d max-urblen:%2d " - "EOF:0x%0x DATA: ", + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif + if (fifo->last_urblen != maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* care for L1 state only for D-Channel to avoid overlapped iso completions */ - if (fifon == 5) { + if (fifon == HFCUSB_D_RX) { /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); } eof[fifon] = buf[0] & 1; if (len > 2) collect_rx_frame(fifo, buf + 2, len - 2, - (len < - maxlen) ? + (len < maxlen) ? eof[fifon] : 0); } else { collect_rx_frame(fifo, buf, len, @@ -804,41 +758,37 @@ rx_iso_complete(struct urb *urb) rx_iso_complete, urb->context); errcode = usb_submit_urb(urb, GFP_ATOMIC); if (errcode < 0) { - printk(KERN_INFO - "HFC-S USB: error submitting ISO URB: %d \n", + printk(KERN_ERR + "HFC-S USB: error submitting ISO URB: %d\n", errcode); } } else { if (status && !hfc->disc_flag) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: rx_iso_complete : " "urb->status %d, fifonum %d\n", status, fifon); } } -} /* rx_iso_complete */ +} -/*****************************************************/ -/* collect data from interrupt or isochron in */ -/*****************************************************/ +/* collect rx data from INT- and ISO-URBs */ static void collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) { hfcusb_data *hfc = fifo->hfc; int transp_mode, fifon; -#ifdef CONFIG_HISAX_DEBUG - int i; -#endif + fifon = fifo->fifonum; transp_mode = 0; if (fifon < 4 && hfc->b_mode[fifon / 2] == L1_MODE_TRANS) - transp_mode = true; + transp_mode = 1; if (!fifo->skbuff) { fifo->skbuff = dev_alloc_skb(fifo->max_size + 3); if (!fifo->skbuff) { - printk(KERN_INFO - "HFC-S USB: cannot allocate buffer (dev_alloc_skb) fifo:%d\n", + printk(KERN_ERR + "HFC-S USB: cannot allocate buffer for fifo(%d)\n", fifon); return; } @@ -847,17 +797,11 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (fifo->skbuff->len + len < fifo->max_size) { memcpy(skb_put(fifo->skbuff, len), data, len); } else { -#ifdef CONFIG_HISAX_DEBUG - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff->data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); -#endif - printk(KERN_INFO - "HCF-USB: got frame exceeded fifo->max_size:%d on fifo:%d\n", + DBG(HFCUSB_DBG_FIFO_ERR, + "HCF-USB: got frame exceeded fifo->max_size(%d) fifo(%d)", fifo->max_size, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); + skb_trim(fifo->skbuff, 0); } } if (transp_mode && fifo->skbuff->len >= 128) { @@ -870,6 +814,13 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) if (finish) { if ((!fifo->skbuff->data[fifo->skbuff->len - 1]) && (fifo->skbuff->len > 3)) { + + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_DCHANNEL, + "HFC-S USB: D-RX len(%d)", fifo->skbuff->len); + DBG_SKB(HFCUSB_DBG_DCHANNEL, fifo->skbuff); + } + /* remove CRC & status */ skb_trim(fifo->skbuff, fifo->skbuff->len - 3); if (fifon == HFCUSB_PCM_RX) { @@ -882,39 +833,17 @@ collect_rx_frame(usb_fifo * fifo, __u8 * data, int len, int finish) fifo->skbuff); fifo->skbuff = NULL; /* buffer was freed from upper layer */ } else { - if (fifo->skbuff->len > 3) { - printk(KERN_INFO - "HFC-S USB: got frame %d bytes but CRC ERROR on fifo:%d!!!\n", - fifo->skbuff->len, fifon); -#ifdef CONFIG_HISAX_DEBUG - if (debug > 1) { - printk(KERN_INFO "HFC-S USB: "); - for (i = 0; i < 15; i++) - printk("%.2x ", - fifo->skbuff-> - data[fifo->skbuff-> - len - 15 + i]); - printk("\n"); - } -#endif - } -#ifdef CONFIG_HISAX_DEBUG - else { - printk(KERN_INFO - "HFC-S USB: frame to small (%d bytes)!!!\n", - fifo->skbuff->len); - } -#endif + DBG(HFCUSB_DBG_FIFO_ERR, + "HFC-S USB: ERROR frame len(%d) fifo(%d)", + fifo->skbuff->len, fifon); + DBG_SKB(HFCUSB_DBG_VERBOSE_USB, fifo->skbuff); skb_trim(fifo->skbuff, 0); } } } -/***********************************************/ -/* receive completion routine for all rx fifos */ -/***********************************************/ static void -rx_complete(struct urb *urb) +rx_int_complete(struct urb *urb) { int len; int status; @@ -922,18 +851,14 @@ rx_complete(struct urb *urb) usb_fifo *fifo = (usb_fifo *) urb->context; hfcusb_data *hfc = fifo->hfc; static __u8 eof[8]; -#ifdef CONFIG_HISAX_DEBUG - __u8 i; -#endif urb->dev = hfc->dev; /* security init */ fifon = fifo->fifonum; if ((!fifo->active) || (urb->status)) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: RX-Fifo %i is going down (%i)", + DBG(HFCUSB_DBG_INIT, "HFC-S USB: RX-Fifo %i is going down (%i)", fifon, urb->status); -#endif + fifo->urb->interval = 0; /* cancel automatic rescheduling */ if (fifo->skbuff) { dev_kfree_skb_any(fifo->skbuff); @@ -945,22 +870,20 @@ rx_complete(struct urb *urb) buf = fifo->buffer; maxlen = fifo->usb_packet_maxlen; -#ifdef CONFIG_HISAX_DEBUG - if ((fifon == 5) && (debug > 1)) { - printk(KERN_INFO - "HFC-S USB: INT-D-RX lst_urblen:%2d act_urblen:%2d max-urblen:%2d EOF:0x%0x DATA: ", - fifo->last_urblen, len, maxlen, eof[5]); - for (i = 0; i < len; i++) - printk("%.2x ", buf[i]); - printk("\n"); + if (fifon == HFCUSB_D_RX) { + DBG(HFCUSB_DBG_VERBOSE_USB, + "HFC-S USB: INT-D-RX lst_urblen:%2d " + "act_urblen:%2d max-urblen:%2d EOF:0x%0x", + fifo->last_urblen, len, maxlen, + eof[5]); + DBG_PACKET(HFCUSB_DBG_VERBOSE_USB, buf, len); } -#endif if (fifo->last_urblen != fifo->usb_packet_maxlen) { /* the threshold mask is in the 2nd status byte */ hfc->threshold_mask = buf[1]; /* the S0 state is in the upper half of the 1st status byte */ - state_handler(hfc, buf[0] >> 4); + s0_state_handler(hfc, buf[0] >> 4); eof[fifon] = buf[0] & 1; /* if we have more than the 2 status bytes -> collect data */ if (len > 2) @@ -975,20 +898,19 @@ rx_complete(struct urb *urb) status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { printk(KERN_INFO - "HFC-S USB: error resubmitting URN at rx_complete...\n"); + "HFC-S USB: %s error resubmitting URB fifo(%d)\n", + __FUNCTION__, fifon); } -} /* rx_complete */ +} -/***************************************************/ -/* start the interrupt transfer for the given fifo */ -/***************************************************/ +/* start initial INT-URB for certain fifo */ static void start_int_fifo(usb_fifo * fifo) { int errcode; - printk(KERN_INFO "HFC-S USB: starting intr IN fifo:%d\n", - fifo->fifonum); + DBG(HFCUSB_DBG_INIT, "HFC-S USB: starting RX INT-URB for fifo:%d\n", + fifo->fifonum); if (!fifo->urb) { fifo->urb = usb_alloc_urb(0, GFP_KERNEL); @@ -997,33 +919,28 @@ start_int_fifo(usb_fifo * fifo) } usb_fill_int_urb(fifo->urb, fifo->hfc->dev, fifo->pipe, fifo->buffer, fifo->usb_packet_maxlen, - rx_complete, fifo, fifo->intervall); + rx_int_complete, fifo, fifo->intervall); fifo->active = 1; /* must be marked active */ errcode = usb_submit_urb(fifo->urb, GFP_KERNEL); if (errcode) { - printk(KERN_INFO + printk(KERN_ERR "HFC-S USB: submit URB error(start_int_info): status:%i\n", errcode); fifo->active = 0; fifo->skbuff = NULL; } -} /* start_int_fifo */ +} -/*****************************/ -/* set the B-channel mode */ -/*****************************/ static void -set_hfcmode(hfcusb_data * hfc, int channel, int mode) +setup_bchannel(hfcusb_data * hfc, int channel, int mode) { __u8 val, idx_table[2] = { 0, 2 }; if (hfc->disc_flag) { return; } -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, "HFC-S USB: setting channel %d to mode %d", channel, - mode); -#endif + DBG(HFCUSB_DBG_STATES, "HFC-S USB: setting channel %d to mode %d", + channel, mode); hfc->b_mode[channel] = mode; /* setup CON_HDLC */ @@ -1080,20 +997,17 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) switch (pr) { case PH_ACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_ACTIVATE | REQUEST"); -#endif + if (hfc->l1_state != 3 && hfc->l1_state != 7) { hfc->d_if.ifc.l1l2(&hfc->d_if.ifc, PH_DEACTIVATE | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_DEACTIVATE | INDICATION sent (not state 3 or 7)"); -#endif } else { if (hfc->l1_state == 7) { /* l1 already active */ hfc->d_if.ifc.l1l2(&hfc-> @@ -1103,10 +1017,8 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) | INDICATION, NULL); -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC-S USB: PH_ACTIVATE | INDICATION sent again ;)"); -#endif } else { /* force sending sending INFO1 */ queue_control_request(hfc, @@ -1132,11 +1044,9 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) } } } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, - "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_ACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1 B-chan: PH_ACTIVATE | REQUEST"); + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (long) arg); @@ -1147,18 +1057,12 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) break; case PH_DEACTIVATE | REQUEST: if (fifo->fifonum == HFCUSB_D_TX) { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 D-chan: PH_DEACTIVATE | REQUEST"); -#endif - printk(KERN_INFO - "HFC-S USB: ISDN TE device should not deativate...\n"); } else { -#ifdef CONFIG_HISAX_DEBUG - DBG(ISDN_DBG, + DBG(HFCUSB_DBG_STATES, "HFC_USB: hfc_usb_d_l2l1 Bx-chan: PH_DEACTIVATE | REQUEST"); -#endif - set_hfcmode(hfc, + setup_bchannel(hfc, (fifo->fifonum == HFCUSB_B1_TX) ? 0 : 1, (int) L1_MODE_NULL); @@ -1171,25 +1075,20 @@ hfc_usb_l2l1(struct hisax_if *my_hisax_if, int pr, void *arg) if (fifo->skbuff && fifo->delete_flg) { dev_kfree_skb_any(fifo->skbuff); fifo->skbuff = NULL; - fifo->delete_flg = false; + fifo->delete_flg = 0; } fifo->skbuff = arg; /* we have a new buffer */ break; default: - printk(KERN_INFO - "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x\n", - pr); + DBG(HFCUSB_DBG_STATES, + "HFC_USB: hfc_usb_d_l2l1: unkown state : %#x", pr); break; } } -/***************************************************************************/ -/* usb_init is called once when a new matching device is detected to setup */ -/* main parameters. It registers the driver at the main hisax module. */ -/* on success 0 is returned. */ -/***************************************************************************/ +/* initial init HFC-S USB chip registers, HiSax interface, USB URBs */ static int -usb_init(hfcusb_data * hfc) +hfc_usb_init(hfcusb_data * hfc) { usb_fifo *fifo; int i, err; @@ -1214,11 +1113,11 @@ usb_init(hfcusb_data * hfc) /* aux = output, reset off */ write_usb(hfc, HFCUSB_CIRM, 0x10); - /* set USB_SIZE to match the wMaxPacketSize for INT or BULK transfers */ + /* set USB_SIZE to match wMaxPacketSize for INT or BULK transfers */ write_usb(hfc, HFCUSB_USB_SIZE, (hfc->packet_size / 8) | ((hfc->packet_size / 8) << 4)); - /* set USB_SIZE_I to match the wMaxPacketSize for ISO transfers */ + /* set USB_SIZE_I to match wMaxPacketSize for ISO transfers */ write_usb(hfc, HFCUSB_USB_SIZE_I, hfc->iso_packet_size); /* enable PCM/GCI master mode */ @@ -1257,8 +1156,8 @@ usb_init(hfcusb_data * hfc) hfc->b_mode[0] = L1_MODE_NULL; hfc->b_mode[1] = L1_MODE_NULL; - hfc->l1_activated = false; - hfc->disc_flag = false; + hfc->l1_activated = 0; + hfc->disc_flag = 0; hfc->led_state = 0; hfc->led_new_data = 0; hfc->old_led_state = 0; @@ -1349,11 +1248,9 @@ usb_init(hfcusb_data * hfc) handle_led(hfc, LED_POWER_ON); return (0); -} /* usb_init */ +} -/*************************************************/ -/* function called to probe a new plugged device */ -/*************************************************/ +/* initial callback for each plugged USB device */ static int hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -1378,11 +1275,6 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) } } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, - iface->desc.bAlternateSetting, intf->minor); -#endif printk(KERN_INFO "HFC-S USB: probing interface(%d) actalt(%d) minor(%d)\n", ifnum, iface->desc.bAlternateSetting, intf->minor); @@ -1403,15 +1295,11 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* check for config EOL element */ while (validconf[cfg_used][0]) { - cfg_found = true; + cfg_found = 1; vcf = validconf[cfg_used]; /* first endpoint descriptor */ ep = iface->endpoint; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: (if=%d alt=%d cfg_used=%d)\n", - ifnum, probe_alt_setting, cfg_used); -#endif + memcpy(cmptbl, vcf, 16 * sizeof(int)); /* check for all endpoints in this alternate setting */ @@ -1425,7 +1313,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) idx++; attr = ep->desc.bmAttributes; if (cmptbl[idx] == EP_NUL) { - cfg_found = false; + cfg_found = 0; } if (attr == USB_ENDPOINT_XFER_INT && cmptbl[idx] == EP_INT) @@ -1438,16 +1326,9 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) cmptbl[idx] = EP_NUL; /* check if all INT endpoints match minimum interval */ - if (attr == USB_ENDPOINT_XFER_INT - && ep->desc.bInterval < - vcf[17]) { -#ifdef CONFIG_HISAX_DEBUG - if (cfg_found) - DBG(USB_DBG, - "HFC-S USB: Interrupt Endpoint interval < %d found - skipping config", - vcf[17]); -#endif - cfg_found = false; + if ((attr == USB_ENDPOINT_XFER_INT) + && (ep->desc.bInterval < vcf[17])) { + cfg_found = 0; } ep++; } @@ -1455,7 +1336,7 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) /* all entries must be EP_NOP or EP_NUL for a valid config */ if (cmptbl[i] != EP_NOP && cmptbl[i] != EP_NUL) - cfg_found = false; + cfg_found = 0; } if (cfg_found) { if (cfg_used < small_match) { @@ -1464,23 +1345,16 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) probe_alt_setting; iface_used = iface; } -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-USB: small_match=%x %x\n", - small_match, alt_used); -#endif } cfg_used++; } alt_idx++; - } /* (alt_idx < intf->num_altsetting) */ + } /* (alt_idx < intf->num_altsetting) */ /* found a valid USB Ta Endpint config */ if (small_match != 0xffff) { iface = iface_used; - if (! - (context = - kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) + if (!(context = kzalloc(sizeof(hfcusb_data), GFP_KERNEL))) return (-ENOMEM); /* got no mem */ ep = iface->endpoint; @@ -1613,20 +1487,15 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) driver_info; printk(KERN_INFO "HFC-S USB: detected \"%s\"\n", driver_info->vend_name); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d)\n", + + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: Endpoint-Config: %s (if=%d alt=%d), E-Channel(%d)", conf_str[small_match], context->if_used, - context->alt_used); - printk(KERN_INFO - "HFC-S USB: E-channel (\"ECHO:\") logging "); - if (validconf[small_match][18]) - printk(" possible\n"); - else - printk("NOT possible\n"); -#endif + context->alt_used, + validconf[small_match][18]); + /* init the chip and register the driver */ - if (usb_init(context)) { + if (hfc_usb_init(context)) { usb_kill_urb(context->ctrl_urb); usb_free_urb(context->ctrl_urb); context->ctrl_urb = NULL; @@ -1643,17 +1512,19 @@ hfc_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) return (-EIO); } -/****************************************************/ -/* function called when an active device is removed */ -/****************************************************/ +/* callback for unplugged USB device */ static void hfc_usb_disconnect(struct usb_interface *intf) { hfcusb_data *context = usb_get_intfdata(intf); int i; + + handle_led(context, LED_POWER_OFF); + schedule_timeout((10 * HZ) / 1000); + printk(KERN_INFO "HFC-S USB: device disconnect\n"); - context->disc_flag = true; + context->disc_flag = 1; usb_set_intfdata(intf, NULL); if (!context) return; @@ -1661,25 +1532,22 @@ hfc_usb_disconnect(struct usb_interface del_timer(&context->t3_timer); if (timer_pending(&context->t4_timer)) del_timer(&context->t4_timer); + /* tell all fifos to terminate */ for (i = 0; i < HFCUSB_NUM_FIFOS; i++) { if (context->fifos[i].usb_transfer_mode == USB_ISOC) { if (context->fifos[i].active > 0) { stop_isoc_chain(&context->fifos[i]); -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: stopping ISOC chain Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s stopping ISOC chain Fifo(%i)", + __FUNCTION__, i); } } else { if (context->fifos[i].active > 0) { context->fifos[i].active = 0; -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, - "HFC-S USB: hfc_usb_disconnect: unlinking URB for Fifo no %i", - i); -#endif + DBG(HFCUSB_DBG_INIT, + "HFC-S USB: %s unlinking URB for Fifo(%i)", + __FUNCTION__, i); } usb_kill_urb(context->fifos[i].urb); usb_free_urb(context->fifos[i].urb); @@ -1692,34 +1560,29 @@ hfc_usb_disconnect(struct usb_interface context->ctrl_urb = NULL; hisax_unregister(&context->d_if); kfree(context); /* free our structure again */ -} /* hfc_usb_disconnect */ +} -/************************************/ -/* our driver information structure */ -/************************************/ static struct usb_driver hfc_drv = { .name = "hfc_usb", .id_table = hfcusb_idtab, .probe = hfc_usb_probe, .disconnect = hfc_usb_disconnect, }; + static void __exit -hfc_usb_exit(void) +hfc_usb_mod_exit(void) { -#ifdef CONFIG_HISAX_DEBUG - DBG(USB_DBG, "HFC-S USB: calling \"hfc_usb_exit\" ..."); -#endif - usb_deregister(&hfc_drv); /* release our driver */ + usb_deregister(&hfc_drv); /* release our driver */ printk(KERN_INFO "HFC-S USB: module removed\n"); } static int __init -hfc_usb_init(void) +hfc_usb_mod_init(void) { + char revstr[30], datestr[30], dummy[30]; #ifndef CONFIG_HISAX_DEBUG - unsigned int debug = -1; + hfc_debug = debug; #endif - char revstr[30], datestr[30], dummy[30]; sscanf(hfcusb_revision, "%s %s $ %s %s %s $ ", dummy, revstr, dummy, datestr, dummy); @@ -1734,8 +1597,8 @@ hfc_usb_init(void) return (0); } -module_init(hfc_usb_init); -module_exit(hfc_usb_exit); +module_init(hfc_usb_mod_init); +module_exit(hfc_usb_mod_exit); MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_DESCRIPTION(DRIVER_DESC); MODULE_LICENSE("GPL"); diff --git a/drivers/isdn/hisax/hfc_usb.h b/drivers/isdn/hisax/hfc_usb.h index 471f2354dfde..e79f56568d30 100644 --- a/drivers/isdn/hisax/hfc_usb.h +++ b/drivers/isdn/hisax/hfc_usb.h @@ -1,8 +1,8 @@ /* -* hfc_usb.h -* -* $Id: hfc_usb.h,v 4.2 2005/04/07 15:27:17 martinb1 Exp $ -*/ + * hfc_usb.h + * + * $Id: hfc_usb.h,v 1.1.2.5 2007/08/20 14:36:03 mbachem Exp $ + */ #ifndef __HFC_USB_H__ #define __HFC_USB_H__ @@ -10,25 +10,20 @@ #define DRIVER_AUTHOR "Peter Sprenger (sprenger@moving-byters.de)" #define DRIVER_DESC "HFC-S USB based HiSAX ISDN driver" -#define VERBOSE_USB_DEBUG +#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ +#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ +#define HFC_TIMER_T4 500 /* time for state change interval */ -/***********/ -/* defines */ -/***********/ -#define HFC_CTRL_TIMEOUT 20 /* 5ms timeout writing/reading regs */ -#define HFC_TIMER_T3 8000 /* timeout for l1 activation timer */ -#define HFC_TIMER_T4 500 /* time for state change interval */ +#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ +#define HFCUSB_L1_DRX 1 /* D-frame received */ +#define HFCUSB_L1_ERX 2 /* E-frame received */ +#define HFCUSB_L1_DTX 4 /* D-frames completed */ -#define HFCUSB_L1_STATECHANGE 0 /* L1 state changed */ -#define HFCUSB_L1_DRX 1 /* D-frame received */ -#define HFCUSB_L1_ERX 2 /* E-frame received */ -#define HFCUSB_L1_DTX 4 /* D-frames completed */ +#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ -#define MAX_BCH_SIZE 2048 /* allowed B-channel packet size */ - -#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ -#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ +#define HFCUSB_RX_THRESHOLD 64 /* threshold for fifo report bit rx */ +#define HFCUSB_TX_THRESHOLD 64 /* threshold for fifo report bit tx */ #define HFCUSB_CHIP_ID 0x16 /* Chip ID register index */ #define HFCUSB_CIRM 0x00 /* cirm register index */ @@ -52,9 +47,8 @@ #define HFCUSB_CHIPID 0x40 /* ID value of HFC-S USB */ -/******************/ + /* fifo registers */ -/******************/ #define HFCUSB_NUM_FIFOS 8 /* maximum number of fifos */ #define HFCUSB_B1_TX 0 /* index for B1 transmit bulk/int */ #define HFCUSB_B1_RX 1 /* index for B1 receive bulk/int */ @@ -66,9 +60,9 @@ #define HFCUSB_PCM_RX 7 /* -* used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just -* supports ISO out, while the Cologne Chip EVAL TA just supports BULK out -*/ + * used to switch snd_transfer_mode for different TA modes e.g. the Billion USB TA just + * supports ISO out, while the Cologne Chip EVAL TA just supports BULK out + */ #define USB_INT 0 #define USB_BULK 1 #define USB_ISOC 2 @@ -77,49 +71,36 @@ #define ISOC_PACKETS_B 8 #define ISO_BUFFER_SIZE 128 -// ISO send definitions +/* Fifo flow Control for TX ISO */ #define SINK_MAX 68 #define SINK_MIN 48 #define SINK_DMIN 12 #define SINK_DMAX 18 #define BITLINE_INF (-64*8) - -/**********/ -/* macros */ -/**********/ +/* HFC-S USB register access by Control-URSs */ #define write_usb(a,b,c)usb_control_msg((a)->dev,(a)->ctrl_out_pipe,0,0x40,(c),(b),NULL,0,HFC_CTRL_TIMEOUT) #define read_usb(a,b,c) usb_control_msg((a)->dev,(a)->ctrl_in_pipe,1,0xC0,0,(b),(c),1,HFC_CTRL_TIMEOUT) - - -/*******************/ -/* Debugging Flags */ -/*******************/ -#define USB_DBG 1 -#define ISDN_DBG 2 - - -/* *********************/ -/* USB related defines */ -/***********************/ #define HFC_CTRL_BUFSIZE 32 - - -/*************************************************/ /* entry and size of output/input control buffer */ -/*************************************************/ typedef struct { __u8 hfc_reg; /* register number */ __u8 reg_val; /* value to be written (or read) */ int action; /* data for action handler */ } ctrl_buft; +/* Debugging Flags */ +#define HFCUSB_DBG_INIT 0x0001 +#define HFCUSB_DBG_STATES 0x0002 +#define HFCUSB_DBG_DCHANNEL 0x0080 +#define HFCUSB_DBG_FIFO_ERR 0x4000 +#define HFCUSB_DBG_VERBOSE_USB 0x8000 -/********************/ -/* URB error codes: */ -/********************/ -/* Used to represent a list of values and their respective symbolic names */ +/* + * URB error codes: + * Used to represent a list of values and their respective symbolic names + */ struct hfcusb_symbolic_list { const int num; const char *name; @@ -134,20 +115,20 @@ static struct hfcusb_symbolic_list urb_errlist[] = { {-ENXIO, "URB already queued"}, {-EFBIG, "Too much ISO frames requested"}, {-ENOSR, "Buffer error (overrun)"}, - {-EPIPE, "Specified endpoint is stalled"}, + {-EPIPE, "Specified endpoint is stalled (device not responding)"}, {-EOVERFLOW, "Babble (bad cable?)"}, {-EPROTO, "Bit-stuff error (bad cable?)"}, - {-EILSEQ, "CRC or missing token"}, - {-ETIME, "Device did not respond"}, + {-EILSEQ, "CRC/Timeout"}, + {-ETIMEDOUT, "NAK (device does not respond)"}, {-ESHUTDOWN, "Device unplugged"}, {-1, NULL} }; -/*****************************************************/ -/* device dependant information to support different */ -/* ISDN Ta's using the HFC-S USB chip */ -/*****************************************************/ +/* + * device dependant information to support different + * ISDN Ta's using the HFC-S USB chip + */ /* USB descriptor need to contain one of the following EndPoint combination: */ #define CNF_4INT3ISO 1 // 4 INT IN, 3 ISO OUT @@ -155,16 +136,19 @@ static struct hfcusb_symbolic_list urb_errlist[] = { #define CNF_4ISO3ISO 3 // 4 ISO IN, 3 ISO OUT #define CNF_3ISO3ISO 4 // 3 ISO IN, 3 ISO OUT -#define EP_NUL 1 // Endpoint at this position not allowed -#define EP_NOP 2 // all type of endpoints allowed at this position -#define EP_ISO 3 // Isochron endpoint mandatory at this position -#define EP_BLK 4 // Bulk endpoint mandatory at this position -#define EP_INT 5 // Interrupt endpoint mandatory at this position +#define EP_NUL 1 // Endpoint at this position not allowed +#define EP_NOP 2 // all type of endpoints allowed at this position +#define EP_ISO 3 // Isochron endpoint mandatory at this position +#define EP_BLK 4 // Bulk endpoint mandatory at this position +#define EP_INT 5 // Interrupt endpoint mandatory at this position -/* this array represents all endpoints possible in the HCF-USB the last -* 3 entries are the configuration number, the minimum interval for -* Interrupt endpoints & boolean if E-channel logging possible -*/ +/* + * List of all supported endpoint configuration sets, used to find the + * best matching endpoint configuration within a devices' USB descriptor. + * We need at least 3 RX endpoints, and 3 TX endpoints, either + * INT-in and ISO-out, or ISO-in and ISO-out) + * with 4 RX endpoints even E-Channel logging is possible + */ static int validconf[][19] = { // INT in, ISO out config {EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NUL, EP_INT, EP_NOP, EP_INT, @@ -193,7 +177,6 @@ static char *conf_str[] = { }; #endif - typedef struct { int vendor; // vendor id int prod_id; // product id @@ -202,9 +185,9 @@ typedef struct { signed short led_bits[8]; // array of 8 possible LED bitmask settings } vendor_data; -#define LED_OFF 0 // no LED support -#define LED_SCHEME1 1 // LED standard scheme -#define LED_SCHEME2 2 // not used yet... +#define LED_OFF 0 // no LED support +#define LED_SCHEME1 1 // LED standard scheme +#define LED_SCHEME2 2 // not used yet... #define LED_POWER_ON 1 #define LED_POWER_OFF 2 @@ -217,11 +200,8 @@ typedef struct { #define LED_B2_OFF 9 #define LED_B2_DATA 10 -#define LED_NORMAL 0 // LEDs are normal -#define LED_INVERTED 1 // LEDs are inverted - -/* time in ms to perform a Flashing LED when B-Channel has traffic */ -#define LED_TIME 250 +#define LED_NORMAL 0 // LEDs are normal +#define LED_INVERTED 1 // LEDs are inverted -#endif // __HFC_USB_H__ +#endif // __HFC_USB_H__ -- cgit v1.2.3 From f350339cbd0e8ed7751f98f0ef60cb3a0d410eda Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 21 Aug 2007 11:10:22 -0700 Subject: sky2: don't clear phy power bits There are special PHY settings available on Yukon EC-U chip that should not get cleared. This should solve mysterious errors on some motherboards (like Gigabyte DS-3). Signed-off-by: Stephen Hemminger Signed-off-by: Linus Torvalds --- drivers/net/sky2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index e7a2eadcc3b0..757592436390 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -696,8 +696,8 @@ static void sky2_mac_init(struct sky2_hw *hw, unsigned port) int i; const u8 *addr = hw->dev[port]->dev_addr; - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); - sky2_write32(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET); + sky2_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_CLR); sky2_write8(hw, SK_REG(port, GMAC_CTRL), GMC_RST_CLR); -- cgit v1.2.3 From 06c7af563d925d04961ce70cd9154fad8e2750c8 Mon Sep 17 00:00:00 2001 From: Konstantin Sharlaimov Date: Tue, 21 Aug 2007 00:12:44 -0700 Subject: [PPP]: Fix output buffer size in ppp_decompress_frame(). This patch addresses the issue with "osize too small" errors in mppe encryption. The patch fixes the issue with wrong output buffer size being passed to ppp decompression routine. -------------------- As pointed out by Suresh Mahalingam, the issue addressed by ppp-fix-osize-too-small-errors-when-decoding patch is not fully resolved yet. The size of allocated output buffer is correct, however it size passed to ppp->rcomp->decompress in ppp_generic.c if wrong. The patch fixes that. -------------------- Signed-off-by: Konstantin Sharlaimov Signed-off-by: David S. Miller --- drivers/net/ppp_generic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c index ef3325b69233..9293c82ef2af 100644 --- a/drivers/net/ppp_generic.c +++ b/drivers/net/ppp_generic.c @@ -1726,7 +1726,7 @@ ppp_decompress_frame(struct ppp *ppp, struct sk_buff *skb) } /* the decompressor still expects the A/C bytes in the hdr */ len = ppp->rcomp->decompress(ppp->rc_state, skb->data - 2, - skb->len + 2, ns->data, ppp->mru + PPP_HDRLEN); + skb->len + 2, ns->data, obuff_size); if (len < 0) { /* Pass the compressed frame to pppd as an error indication. */ -- cgit v1.2.3 From 3520c92283bb7ddd59daf90cfc1eb107dc9ab76c Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Aug 2007 13:51:36 +0200 Subject: [S390] cio: dont forget to set last slot to NULL in ccw_uevent(). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/device.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c index 297659fa0e26..e44d92eac8e9 100644 --- a/drivers/s390/cio/device.c +++ b/drivers/s390/cio/device.c @@ -117,7 +117,10 @@ static int ccw_uevent(struct device *dev, char **envp, int num_envp, snprint_alias(modalias_buf, sizeof(modalias_buf), id, ""); ret = add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &len, "MODALIAS=%s", modalias_buf); - return ret; + if (ret) + return ret; + envp[i] = NULL; + return 0; } struct bus_type ccw_bus_type; -- cgit v1.2.3 From 23eb68c569cdbaad1a88015be1d69c565cd3926a Mon Sep 17 00:00:00 2001 From: Cornelia Huck Date: Wed, 22 Aug 2007 13:51:37 +0200 Subject: [S390] cio: change confusing message in cmf. cmf currently prints a message that more than 4096 channels are not allowed in basic mode - however, this can only be enforced if cmf was a module (which is no longer possible). It makes much more sense to not check the specified number of channels and just print a message if the block for basic mode could not be allocated (which may happen for any number of specified channels). Signed-off-by: Cornelia Huck Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/cmf.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/cio/cmf.c b/drivers/s390/cio/cmf.c index 02fd00b55e1b..34a796913b06 100644 --- a/drivers/s390/cio/cmf.c +++ b/drivers/s390/cio/cmf.c @@ -594,6 +594,9 @@ alloc_cmb (struct ccw_device *cdev) free_pages((unsigned long)mem, get_order(size)); } else if (!mem) { /* no luck */ + printk(KERN_WARNING "cio: failed to allocate area " + "for measuring %d subchannels\n", + cmb_area.num_channels); ret = -ENOMEM; goto out; } else { @@ -1279,13 +1282,6 @@ init_cmf(void) case CMF_BASIC: format_string = "basic"; cmbops = &cmbops_basic; - if (cmb_area.num_channels > 4096 || cmb_area.num_channels < 1) { - printk(KERN_ERR "cio: Basic channel measurement " - "facility can only use 1 to 4096 devices\n" - KERN_ERR "when the cmf driver is built" - " as a loadable module\n"); - return 1; - } break; case CMF_EXTENDED: format_string = "extended"; -- cgit v1.2.3 From f276730f8da0e8136d8491b6ef44fc719d450a1b Mon Sep 17 00:00:00 2001 From: "Klaus D. Wacker" Date: Wed, 22 Aug 2007 13:51:38 +0200 Subject: [S390] qdio: fix EQBS handling on CCQ96 QDIO returned from EQBS instruction in any case after return code CCQ=96 was issued regardless whether buffer states for at least one buffer were extracted or not. This caused FCP devices to hang when running under z/VM and having QIOASSASIST=ON and having high I/O rates. In order to fix this qdio return code processing of EQBS instruction after CCQ=96 is changed that buffers are returned and if no buffers where extracted the instruction is repeated at once. Signed-off-by: Klaus D. Wacker Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/cio/qdio.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index 03347aed2b3e..badfb5b21304 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -195,6 +195,8 @@ qdio_do_eqbs(struct qdio_q *q, unsigned char *state, again: ccq = do_eqbs(irq->sch_token, state, q_no, start, cnt); rc = qdio_check_ccq(q, ccq); + if ((ccq == 96) && (tmp_cnt != *cnt)) + rc = 0; if (rc == 1) { QDIO_DBF_TEXT5(1,trace,"eqAGAIN"); goto again; -- cgit v1.2.3 From 37cd0a007f88f1d6269035bdb02b50f536cca8de Mon Sep 17 00:00:00 2001 From: "Klaus D. Wacker" Date: Wed, 22 Aug 2007 13:51:39 +0200 Subject: [S390] qdio: Refresh buffer states for IQDIO Asynchronous output queue Hipersocket Multicast queue works asynchronously. When sending buffers, the buffer state change may happen delayed. The tasklet for checking changes in the outbound queue excluded IQDIO async queues from this process. This created either a hang situation when the queue ran full, or presented a hang situation a interface close time. The tasklet processing is changed to include IQDIO async queues when requesting buffer state refresh. Signed-off-by: Klaus D. Wacker Signed-off-by: Martin Schwidefsky --- drivers/s390/cio/qdio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c index badfb5b21304..d8d479876ec7 100644 --- a/drivers/s390/cio/qdio.c +++ b/drivers/s390/cio/qdio.c @@ -742,7 +742,8 @@ qdio_get_outbound_buffer_frontier(struct qdio_q *q) first_not_to_check=f+qdio_min(atomic_read(&q->number_of_buffers_used), (QDIO_MAX_BUFFERS_PER_Q-1)); - if ((!q->is_iqdio_q)&&(!q->hydra_gives_outbound_pcis)) + if (((!q->is_iqdio_q) && (!q->hydra_gives_outbound_pcis)) || + (q->queue_type == QDIO_IQDIO_QFMT_ASYNCH)) SYNC_MEMORY; check_next: -- cgit v1.2.3 From 0a87c5cfc0bb0c1bdcc1cc9fd82e4a1711fac512 Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 22 Aug 2007 13:51:40 +0200 Subject: [S390] vmur: fix diag14 exceptions with addresses > 2GB. There are several s390 diagnose calls, which must be executed below the 2GB memory boundary. In order to enforce this, those diagnoses must be compiled into the kernel. Currently diag 14 can be called within the vmur kernel module from addresses above 2GB. This leads to specification exceptions. This patch moves diag10, diag14 and diag210 into the new diag.c file. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- arch/s390/kernel/Makefile | 2 +- arch/s390/kernel/diag.c | 102 +++++++++++++++++++++++++++++++++++++++++ arch/s390/kernel/s390_ksyms.c | 1 - arch/s390/mm/cmm.c | 1 + arch/s390/mm/init.c | 17 ------- drivers/s390/block/dasd_diag.c | 1 + drivers/s390/char/raw3270.c | 1 + drivers/s390/char/vmur.c | 32 ++----------- drivers/s390/cio/device_id.c | 48 +------------------ include/asm-s390/cio.h | 15 ------ include/asm-s390/diag.h | 39 ++++++++++++++++ include/asm-s390/pgalloc.h | 2 - 12 files changed, 150 insertions(+), 111 deletions(-) create mode 100644 arch/s390/kernel/diag.c create mode 100644 include/asm-s390/diag.h (limited to 'drivers') diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 3195d375bd51..56cb71007cd9 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile @@ -6,7 +6,7 @@ EXTRA_AFLAGS := -traditional obj-y := bitmap.o traps.o time.o process.o base.o early.o \ setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ - semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o + semaphore.o s390_ext.o debug.o irq.o ipl.o dis.o diag.o obj-y += $(if $(CONFIG_64BIT),entry64.o,entry.o) obj-y += $(if $(CONFIG_64BIT),reipl64.o,reipl.o) diff --git a/arch/s390/kernel/diag.c b/arch/s390/kernel/diag.c new file mode 100644 index 000000000000..c032d11da8a1 --- /dev/null +++ b/arch/s390/kernel/diag.c @@ -0,0 +1,102 @@ +/* + * Implementation of s390 diagnose codes + * + * Copyright IBM Corp. 2007 + * Author(s): Michael Holzheu + */ + +#include +#include + +/* + * Diagnose 10: Release pages + */ +void diag10(unsigned long addr) +{ + if (addr >= 0x7ff00000) + return; + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %0,%0,0x10\n" + "0: sam64\n" +#else + " diag %0,%0,0x10\n" + "0:\n" +#endif + EX_TABLE(0b, 0b) + : : "a" (addr)); +} +EXPORT_SYMBOL(diag10); + +/* + * Diagnose 14: Input spool file manipulation + */ +int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode) +{ + register unsigned long _ry1 asm("2") = ry1; + register unsigned long _ry2 asm("3") = subcode; + int rc = 0; + + asm volatile( +#ifdef CONFIG_64BIT + " sam31\n" + " diag %2,2,0x14\n" + " sam64\n" +#else + " diag %2,2,0x14\n" +#endif + " ipm %0\n" + " srl %0,28\n" + : "=d" (rc), "+d" (_ry2) + : "d" (rx), "d" (_ry1) + : "cc"); + + return rc; +} +EXPORT_SYMBOL(diag14); + +/* + * Diagnose 210: Get information about a virtual device + */ +int diag210(struct diag210 *addr) +{ + /* + * diag 210 needs its data below the 2GB border, so we + * use a static data area to be sure + */ + static struct diag210 diag210_tmp; + static DEFINE_SPINLOCK(diag210_lock); + unsigned long flags; + int ccode; + + spin_lock_irqsave(&diag210_lock, flags); + diag210_tmp = *addr; + +#ifdef CONFIG_64BIT + asm volatile( + " lhi %0,-1\n" + " sam31\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1: sam64\n" + EX_TABLE(0b, 1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#else + asm volatile( + " lhi %0,-1\n" + " diag %1,0,0x210\n" + "0: ipm %0\n" + " srl %0,28\n" + "1:\n" + EX_TABLE(0b, 1b) + : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); +#endif + + *addr = diag210_tmp; + spin_unlock_irqrestore(&diag210_lock, flags); + + return ccode; +} +EXPORT_SYMBOL(diag210); diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 90b5ef529eb7..7234c737f825 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c @@ -25,7 +25,6 @@ EXPORT_SYMBOL(_oi_bitmap); EXPORT_SYMBOL(_ni_bitmap); EXPORT_SYMBOL(_zb_findmap); EXPORT_SYMBOL(_sb_findmap); -EXPORT_SYMBOL(diag10); /* * semaphore ops diff --git a/arch/s390/mm/cmm.c b/arch/s390/mm/cmm.c index c5b2f4f078bc..fabc50adc46a 100644 --- a/arch/s390/mm/cmm.c +++ b/arch/s390/mm/cmm.c @@ -20,6 +20,7 @@ #include #include +#include static char *sender = "VMRMSVM"; module_param(sender, charp, 0400); diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 9098531a2671..3a25bbf2eb0a 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -42,23 +42,6 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__((__aligned__(PAGE_SIZE))); char empty_zero_page[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); -void diag10(unsigned long addr) -{ - if (addr >= 0x7ff00000) - return; - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %0,%0,0x10\n" - "0: sam64\n" -#else - " diag %0,%0,0x10\n" - "0:\n" -#endif - EX_TABLE(0b,0b) - : : "a" (addr)); -} - void show_mem(void) { int i, total = 0, reserved = 0; diff --git a/drivers/s390/block/dasd_diag.c b/drivers/s390/block/dasd_diag.c index eccac1c3b71b..d32c60dbdd82 100644 --- a/drivers/s390/block/dasd_diag.c +++ b/drivers/s390/block/dasd_diag.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "dasd_int.h" #include "dasd_diag.h" diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c index 4f2f81b16cfa..2edd5fb6d3dc 100644 --- a/drivers/s390/char/raw3270.c +++ b/drivers/s390/char/raw3270.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "raw3270.h" diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 04b19bdc09da..2d96c958df64 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "vmur.h" @@ -379,31 +380,6 @@ static ssize_t ur_write(struct file *file, const char __user *udata, return do_write(urf->urd, udata, count, urf->dev_reclen, ppos); } -static int do_diag_14(unsigned long rx, unsigned long ry1, - unsigned long subcode) -{ - register unsigned long _ry1 asm("2") = ry1; - register unsigned long _ry2 asm("3") = subcode; - int rc = 0; - - asm volatile( -#ifdef CONFIG_64BIT - " sam31\n" - " diag %2,2,0x14\n" - " sam64\n" -#else - " diag %2,2,0x14\n" -#endif - " ipm %0\n" - " srl %0,28\n" - : "=d" (rc), "+d" (_ry2) - : "d" (rx), "d" (_ry1) - : "cc"); - - TRACE("diag 14: subcode=0x%lx, cc=%i\n", subcode, rc); - return rc; -} - /* * diagnose code 0x14 subcode 0x0028 - position spool file to designated * record @@ -415,7 +391,7 @@ static int diag_position_to_record(int devno, int record) { int cc; - cc = do_diag_14(record, devno, 0x28); + cc = diag14(record, devno, 0x28); switch (cc) { case 0: return 0; @@ -440,7 +416,7 @@ static int diag_read_file(int devno, char *buf) { int cc; - cc = do_diag_14((unsigned long) buf, devno, 0x00); + cc = diag14((unsigned long) buf, devno, 0x00); switch (cc) { case 0: return 0; @@ -533,7 +509,7 @@ static int diag_read_next_file_info(struct file_control_block *buf, int spid) { int cc; - cc = do_diag_14((unsigned long) buf, spid, 0xfff); + cc = diag14((unsigned long) buf, spid, 0xfff); switch (cc) { case 0: return 0; diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c index 60b9347f7c92..f232832f2b22 100644 --- a/drivers/s390/cio/device_id.c +++ b/drivers/s390/cio/device_id.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "cio.h" #include "cio_debug.h" @@ -24,51 +25,6 @@ #include "device.h" #include "ioasm.h" -/* - * diag210 is used under VM to get information about a virtual device - */ -int -diag210(struct diag210 * addr) -{ - /* - * diag 210 needs its data below the 2GB border, so we - * use a static data area to be sure - */ - static struct diag210 diag210_tmp; - static DEFINE_SPINLOCK(diag210_lock); - unsigned long flags; - int ccode; - - spin_lock_irqsave(&diag210_lock, flags); - diag210_tmp = *addr; - -#ifdef CONFIG_64BIT - asm volatile( - " lhi %0,-1\n" - " sam31\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1: sam64\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#else - asm volatile( - " lhi %0,-1\n" - " diag %1,0,0x210\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b,1b) - : "=&d" (ccode) : "a" (&diag210_tmp) : "cc", "memory"); -#endif - - *addr = diag210_tmp; - spin_unlock_irqrestore(&diag210_lock, flags); - - return ccode; -} - /* * Input : * devno - device number @@ -349,5 +305,3 @@ ccw_device_sense_id_irq(struct ccw_device *cdev, enum dev_event dev_event) break; } } - -EXPORT_SYMBOL(diag210); diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h index f738d2827582..1982fb344164 100644 --- a/include/asm-s390/cio.h +++ b/include/asm-s390/cio.h @@ -258,19 +258,6 @@ struct ciw { /* Sick revalidation of device. */ #define CIO_REVALIDATE 0x0008 -struct diag210 { - __u16 vrdcdvno : 16; /* device number (input) */ - __u16 vrdclen : 16; /* data block length (input) */ - __u32 vrdcvcla : 8; /* virtual device class (output) */ - __u32 vrdcvtyp : 8; /* virtual device type (output) */ - __u32 vrdcvsta : 8; /* virtual device status (output) */ - __u32 vrdcvfla : 8; /* virtual device flags (output) */ - __u32 vrdcrccl : 8; /* real device class (output) */ - __u32 vrdccrty : 8; /* real device type (output) */ - __u32 vrdccrmd : 8; /* real device model (output) */ - __u32 vrdccrft : 8; /* real device feature (output) */ -} __attribute__ ((packed,aligned(4))); - struct ccw_dev_id { u8 ssid; u16 devno; @@ -285,8 +272,6 @@ static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, return 0; } -extern int diag210(struct diag210 *addr); - extern void wait_cons_dev(void); extern void css_schedule_reprobe(void); diff --git a/include/asm-s390/diag.h b/include/asm-s390/diag.h new file mode 100644 index 000000000000..72b2e2f2d32d --- /dev/null +++ b/include/asm-s390/diag.h @@ -0,0 +1,39 @@ +/* + * s390 diagnose functions + * + * Copyright IBM Corp. 2007 + * Author(s): Michael Holzheu + */ + +#ifndef _ASM_S390_DIAG_H +#define _ASM_S390_DIAG_H + +/* + * Diagnose 10: Release pages + */ +extern void diag10(unsigned long addr); + +/* + * Diagnose 14: Input spool file manipulation + */ +extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); + +/* + * Diagnose 210: Get information about a virtual device + */ +struct diag210 { + u16 vrdcdvno; /* device number (input) */ + u16 vrdclen; /* data block length (input) */ + u8 vrdcvcla; /* virtual device class (output) */ + u8 vrdcvtyp; /* virtual device type (output) */ + u8 vrdcvsta; /* virtual device status (output) */ + u8 vrdcvfla; /* virtual device flags (output) */ + u8 vrdcrccl; /* real device class (output) */ + u8 vrdccrty; /* real device type (output) */ + u8 vrdccrmd; /* real device model (output) */ + u8 vrdccrft; /* real device feature (output) */ +} __attribute__((packed, aligned(4))); + +extern int diag210(struct diag210 *addr); + +#endif /* _ASM_S390_DIAG_H */ diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h index 56c8a6c80e2e..e45d3c9a4b7e 100644 --- a/include/asm-s390/pgalloc.h +++ b/include/asm-s390/pgalloc.h @@ -19,8 +19,6 @@ #define check_pgt_cache() do {} while (0) -extern void diag10(unsigned long addr); - /* * Page allocation orders. */ -- cgit v1.2.3 From 8127a1f80a002d02a30909ddf6187faedf89e00a Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Wed, 22 Aug 2007 13:51:41 +0200 Subject: [S390] vmur: fix reference counting for vmur device structure When a vmur device is removed due to a detach of the device, currently the ur device structure is freed. Unfortunately it can happen, that there is still a user of the device structure, when the character device is open during the detach process. To fix this, reference counting for the vmur structure is introduced. In addition to that, the online, offline, probe and remove functions are serialized now using a global mutex. Signed-off-by: Michael Holzheu Signed-off-by: Martin Schwidefsky Signed-off-by: Heiko Carstens --- drivers/s390/char/vmur.c | 218 ++++++++++++++++++++++++++++++++++------------- drivers/s390/char/vmur.h | 1 + 2 files changed, 161 insertions(+), 58 deletions(-) (limited to 'drivers') diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c index 2d96c958df64..d70a6e65bf14 100644 --- a/drivers/s390/char/vmur.c +++ b/drivers/s390/char/vmur.c @@ -69,8 +69,26 @@ static struct ccw_driver ur_driver = { .set_offline = ur_set_offline, }; +static DEFINE_MUTEX(vmur_mutex); + /* * Allocation, freeing, getting and putting of urdev structures + * + * Each ur device (urd) contains a reference to its corresponding ccw device + * (cdev) using the urd->cdev pointer. Each ccw device has a reference to the + * ur device using the cdev->dev.driver_data pointer. + * + * urd references: + * - ur_probe gets a urd reference, ur_remove drops the reference + * (cdev->dev.driver_data) + * - ur_open gets a urd reference, ur_relase drops the reference + * (urf->urd) + * + * cdev references: + * - urdev_alloc get a cdev reference (urd->cdev) + * - urdev_free drops the cdev reference (urd->cdev) + * + * Setting and clearing of cdev->dev.driver_data is protected by the ccwdev lock */ static struct urdev *urdev_alloc(struct ccw_device *cdev) { @@ -79,42 +97,61 @@ static struct urdev *urdev_alloc(struct ccw_device *cdev) urd = kzalloc(sizeof(struct urdev), GFP_KERNEL); if (!urd) return NULL; - urd->cdev = cdev; urd->reclen = cdev->id.driver_info; ccw_device_get_id(cdev, &urd->dev_id); mutex_init(&urd->io_mutex); mutex_init(&urd->open_mutex); + atomic_set(&urd->ref_count, 1); + urd->cdev = cdev; + get_device(&cdev->dev); return urd; } static void urdev_free(struct urdev *urd) { + TRACE("urdev_free: %p\n", urd); + if (urd->cdev) + put_device(&urd->cdev->dev); kfree(urd); } -/* - * This is how the character device driver gets a reference to a - * ur device. When this call returns successfully, a reference has - * been taken (by get_device) on the underlying kobject. The recipient - * of this urdev pointer must eventually drop it with urdev_put(urd) - * which does the corresponding put_device(). - */ +static void urdev_get(struct urdev *urd) +{ + atomic_inc(&urd->ref_count); +} + +static struct urdev *urdev_get_from_cdev(struct ccw_device *cdev) +{ + struct urdev *urd; + unsigned long flags; + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urd = cdev->dev.driver_data; + if (urd) + urdev_get(urd); + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + return urd; +} + static struct urdev *urdev_get_from_devno(u16 devno) { char bus_id[16]; struct ccw_device *cdev; + struct urdev *urd; sprintf(bus_id, "0.0.%04x", devno); cdev = get_ccwdev_by_busid(&ur_driver, bus_id); if (!cdev) return NULL; - - return cdev->dev.driver_data; + urd = urdev_get_from_cdev(cdev); + put_device(&cdev->dev); + return urd; } static void urdev_put(struct urdev *urd) { - put_device(&urd->cdev->dev); + if (atomic_dec_and_test(&urd->ref_count)) + urdev_free(urd); } /* @@ -246,6 +283,7 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, return; } urd = cdev->dev.driver_data; + BUG_ON(!urd); /* On special conditions irb is an error pointer */ if (IS_ERR(irb)) urd->io_request_rc = PTR_ERR(irb); @@ -263,9 +301,15 @@ static void ur_int_handler(struct ccw_device *cdev, unsigned long intparm, static ssize_t ur_attr_reclen_show(struct device *dev, struct device_attribute *attr, char *buf) { - struct urdev *urd = dev->driver_data; + struct urdev *urd; + int rc; - return sprintf(buf, "%zu\n", urd->reclen); + urd = urdev_get_from_cdev(to_ccwdev(dev)); + if (!urd) + return -ENODEV; + rc = sprintf(buf, "%zu\n", urd->reclen); + urdev_put(urd); + return rc; } static DEVICE_ATTR(reclen, 0444, ur_attr_reclen_show, NULL); @@ -726,64 +770,63 @@ static struct file_operations ur_fops = { /* * ccw_device infrastructure: - * ur_probe gets its own ref to the device (i.e. get_device), - * creates the struct urdev, the device attributes, sets up - * the interrupt handler and validates the virtual unit record device. - * ur_remove removes the device attributes, frees the struct urdev - * and drops (put_device) the ref to the device we got in ur_probe. + * ur_probe creates the struct urdev (with refcount = 1), the device + * attributes, sets up the interrupt handler and validates the virtual + * unit record device. + * ur_remove removes the device attributes and drops the reference to + * struct urdev. + * + * ur_probe, ur_remove, ur_set_online and ur_set_offline are serialized + * by the vmur_mutex lock. + * + * urd->char_device is used as indication that the online function has + * been completed successfully. */ static int ur_probe(struct ccw_device *cdev) { struct urdev *urd; int rc; - TRACE("ur_probe: cdev=%p state=%d\n", cdev, *(int *) cdev->private); - - if (!get_device(&cdev->dev)) - return -ENODEV; + TRACE("ur_probe: cdev=%p\n", cdev); + mutex_lock(&vmur_mutex); urd = urdev_alloc(cdev); if (!urd) { rc = -ENOMEM; - goto fail; + goto fail_unlock; } + rc = ur_create_attributes(&cdev->dev); if (rc) { rc = -ENOMEM; - goto fail; + goto fail_urdev_put; } - cdev->dev.driver_data = urd; cdev->handler = ur_int_handler; /* validate virtual unit record device */ urd->class = get_urd_class(urd); if (urd->class < 0) { rc = urd->class; - goto fail; + goto fail_remove_attr; } if ((urd->class != DEV_CLASS_UR_I) && (urd->class != DEV_CLASS_UR_O)) { rc = -ENOTSUPP; - goto fail; + goto fail_remove_attr; } + spin_lock_irq(get_ccwdev_lock(cdev)); + cdev->dev.driver_data = urd; + spin_unlock_irq(get_ccwdev_lock(cdev)); + mutex_unlock(&vmur_mutex); return 0; -fail: - urdev_free(urd); - put_device(&cdev->dev); - return rc; -} - -static void ur_remove(struct ccw_device *cdev) -{ - struct urdev *urd = cdev->dev.driver_data; - - TRACE("ur_remove\n"); - if (cdev->online) - ur_set_offline(cdev); +fail_remove_attr: ur_remove_attributes(&cdev->dev); - urdev_free(urd); - put_device(&cdev->dev); +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); + return rc; } static int ur_set_online(struct ccw_device *cdev) @@ -792,20 +835,29 @@ static int ur_set_online(struct ccw_device *cdev) int minor, major, rc; char node_id[16]; - TRACE("ur_set_online: cdev=%p state=%d\n", cdev, - *(int *) cdev->private); + TRACE("ur_set_online: cdev=%p\n", cdev); - if (!try_module_get(ur_driver.owner)) - return -EINVAL; + mutex_lock(&vmur_mutex); + urd = urdev_get_from_cdev(cdev); + if (!urd) { + /* ur_remove already deleted our urd */ + rc = -ENODEV; + goto fail_unlock; + } + + if (urd->char_device) { + /* Another ur_set_online was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } - urd = (struct urdev *) cdev->dev.driver_data; minor = urd->dev_id.devno; major = MAJOR(ur_first_dev_maj_min); urd->char_device = cdev_alloc(); if (!urd->char_device) { rc = -ENOMEM; - goto fail_module_put; + goto fail_urdev_put; } cdev_init(urd->char_device, &ur_fops); @@ -834,29 +886,79 @@ static int ur_set_online(struct ccw_device *cdev) TRACE("ur_set_online: device_create rc=%d\n", rc); goto fail_free_cdev; } - + urdev_put(urd); + mutex_unlock(&vmur_mutex); return 0; fail_free_cdev: cdev_del(urd->char_device); -fail_module_put: - module_put(ur_driver.owner); - + urd->char_device = NULL; +fail_urdev_put: + urdev_put(urd); +fail_unlock: + mutex_unlock(&vmur_mutex); return rc; } -static int ur_set_offline(struct ccw_device *cdev) +static int ur_set_offline_force(struct ccw_device *cdev, int force) { struct urdev *urd; + int rc; - TRACE("ur_set_offline: cdev=%p cdev->private=%p state=%d\n", - cdev, cdev->private, *(int *) cdev->private); - urd = (struct urdev *) cdev->dev.driver_data; + TRACE("ur_set_offline: cdev=%p\n", cdev); + urd = urdev_get_from_cdev(cdev); + if (!urd) + /* ur_remove already deleted our urd */ + return -ENODEV; + if (!urd->char_device) { + /* Another ur_set_offline was faster */ + rc = -EBUSY; + goto fail_urdev_put; + } + if (!force && (atomic_read(&urd->ref_count) > 2)) { + /* There is still a user of urd (e.g. ur_open) */ + TRACE("ur_set_offline: BUSY\n"); + rc = -EBUSY; + goto fail_urdev_put; + } device_destroy(vmur_class, urd->char_device->dev); cdev_del(urd->char_device); - module_put(ur_driver.owner); + urd->char_device = NULL; + rc = 0; - return 0; +fail_urdev_put: + urdev_put(urd); + return rc; +} + +static int ur_set_offline(struct ccw_device *cdev) +{ + int rc; + + mutex_lock(&vmur_mutex); + rc = ur_set_offline_force(cdev, 0); + mutex_unlock(&vmur_mutex); + return rc; +} + +static void ur_remove(struct ccw_device *cdev) +{ + unsigned long flags; + + TRACE("ur_remove\n"); + + mutex_lock(&vmur_mutex); + + if (cdev->online) + ur_set_offline_force(cdev, 1); + ur_remove_attributes(&cdev->dev); + + spin_lock_irqsave(get_ccwdev_lock(cdev), flags); + urdev_put(cdev->dev.driver_data); + cdev->dev.driver_data = NULL; + spin_unlock_irqrestore(get_ccwdev_lock(cdev), flags); + + mutex_unlock(&vmur_mutex); } /* diff --git a/drivers/s390/char/vmur.h b/drivers/s390/char/vmur.h index 2b3c564e0472..fa959644735a 100644 --- a/drivers/s390/char/vmur.h +++ b/drivers/s390/char/vmur.h @@ -70,6 +70,7 @@ struct urdev { size_t reclen; /* Record length for *write* CCWs */ int class; /* VM device class */ int io_request_rc; /* return code from I/O request */ + atomic_t ref_count; /* reference counter */ }; /* -- cgit v1.2.3 From 8c273033906f8e85d54cb6ae052050f109440171 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 1 Aug 2007 12:45:36 -0700 Subject: USB: px2xx_udc bugfix, missing check for gpio_pullup git commit b2bbb20b37d734443d1c279d0033a64f6095db54 added direct support for PXA GPIO D+ pullup as alternative to the older udc_command ops method. This was done by introduction of the pxa2xx_udc_mach_info member "gpio_pullup" which, if initialized, is now used in (almost) all places where udc_command used to be called. This patch fixes two places where checks for availability of D+ pullup control still only honor udc_command. Signed-off-by: Uli Luckas Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/pxa2xx_udc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 72b4ebbf132d..1407ad1c8128 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -967,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) udc = container_of(_gadget, struct pxa2xx_udc, gadget); /* not all boards support pullup control */ - if (!udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) return -EOPNOTSUPP; is_active = (is_active != 0); @@ -2309,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) { struct pxa2xx_udc *udc = platform_get_drvdata(dev); - if (!udc->mach->udc_command) + if (!udc->mach->gpio_pullup && !udc->mach->udc_command) WARN("USB host won't detect disconnect!\n"); pullup(udc, 0); -- cgit v1.2.3 From 74da5d68a54d66667664fbe233ededab2376a070 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 2 Aug 2007 13:29:10 -0400 Subject: USB: cdc-acm: fix sysfs attribute registration bug This patch (as950) fixes a bug in the cdc-acm driver. It doesn't keep track of which interface (control or data) the sysfs attributes get registered for, and as a result, during disconnect it will sometimes attempt to remove the attributes from the wrong interface. The left-over attributes can cause a crash later on, particularly if the driver module has been unloaded. Signed-off-by: Alan Stern Acked-by: Oliver Neukum Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/class/cdc-acm.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index fe940e0536e0..f51e22490edf 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -921,6 +921,10 @@ skip_normal_probe: return -EINVAL; } } + + /* Accept probe requests only for the control interface */ + if (intf != control_interface) + return -ENODEV; if (usb_interface_claimed(data_interface)) { /* valid in this context */ dev_dbg(&intf->dev,"The data interface isn't available"); @@ -1109,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf) return; } if (acm->country_codes){ - device_remove_file(&intf->dev, &dev_attr_wCountryCodes); - device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); + device_remove_file(&acm->control->dev, + &dev_attr_wCountryCodes); + device_remove_file(&acm->control->dev, + &dev_attr_iCountryCodeRelDate); } - device_remove_file(&intf->dev, &dev_attr_bmCapabilities); + device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); acm->dev = NULL; usb_set_intfdata(acm->control, NULL); usb_set_intfdata(acm->data, NULL); -- cgit v1.2.3 From c8ba84a0c682068a55a5892d6e12e3f196fd792c Mon Sep 17 00:00:00 2001 From: Maximilian Attems Date: Sat, 4 Aug 2007 10:19:41 +0200 Subject: USB: visor add ACER S10 palm device id modprobe visor vendor=0x502 product=0x1 is said to work, plus there are patch instructions for it. fixes http://bugs.debian.org/340547 see http://www.chinaitpower.com/A/2004-07-28/87909.html Signed-off-by: Maximilian Attems Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/visor.c | 2 ++ drivers/usb/serial/visor.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 7d84a7647e81..30e08c0bcdc2 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -104,6 +104,8 @@ static struct usb_device_id id_table [] = { .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 4ce6f62a6f39..57229cf66477 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h @@ -48,6 +48,9 @@ #define SONY_CLIE_UX50_ID 0x0144 #define SONY_CLIE_TJ25_ID 0x0169 +#define ACER_VENDOR_ID 0x0502 +#define ACER_S10_ID 0x0001 + #define SAMSUNG_VENDOR_ID 0x04E8 #define SAMSUNG_SCH_I330_ID 0x8001 #define SAMSUNG_SPH_I500_ID 0x6601 -- cgit v1.2.3 From 468d13623b6c8d048abab71ed465fa8ad3bf8875 Mon Sep 17 00:00:00 2001 From: Hermann Kneissel Date: Fri, 3 Aug 2007 20:20:33 +0200 Subject: USB: serial: garmin_gps: fixes package loss if used from gpsbabel This patch contains two fixes submitted by Ondrej Palkovsky: - the 'ACK' packet is sent after the transfer of the USB packet is completed, i.e. in the write_callback function. Because the close function sends the 'abort' command, a parameter is added that allows the caller of garmin_write_bulk to specify, if the 'ack' should be propagated to the serial link or dimissed. This fixes the problem with gpsbabel, it has sent several packets that were acknowledged before they were sent to the GPS and GpsBabel closed the device - thus effectively cancelled all outstanding requests in the queue. - removed the APP_RESP_SEEN and APP_REQ_SEEN flags and changed them into counters. It evades USB reset of the gps on every device close. Signed-off-by: Hermann Kneissel Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/garmin_gps.c | 93 +++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 04bd3b7a2985..f1c90cfe7251 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1,7 +1,7 @@ /* * Garmin GPS driver * - * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net + * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net * * The latest version of the driver can be found at * http://sourceforge.net/projects/garmin-gps/ @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ static int debug = 0; */ #define VERSION_MAJOR 0 -#define VERSION_MINOR 28 +#define VERSION_MINOR 31 #define _STR(s) #s #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) @@ -141,6 +142,8 @@ struct garmin_data { __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ __u8 privpkt[4*6]; + atomic_t req_count; + atomic_t resp_count; spinlock_t lock; struct list_head pktlist; }; @@ -171,8 +174,6 @@ struct garmin_data { #define CLEAR_HALT_REQUIRED 0x0001 #define FLAGS_QUEUING 0x0100 -#define FLAGS_APP_RESP_SEEN 0x0200 -#define FLAGS_APP_REQ_SEEN 0x0400 #define FLAGS_DROP_DATA 0x0800 #define FLAGS_GSP_SKIP 0x1000 @@ -186,7 +187,8 @@ struct garmin_data { /* function prototypes */ static void gsp_next_packet(struct garmin_data * garmin_data_p); static int garmin_write_bulk(struct usb_serial_port *port, - const unsigned char *buf, int count); + const unsigned char *buf, int count, + int dismiss_ack); /* some special packets to be send or received */ static unsigned char const GARMIN_START_SESSION_REQ[] @@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = { static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) { - return ((garmin_data_p->flags - & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN)) - == FLAGS_APP_REQ_SEEN); + return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count); } @@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) usbdata[2] = __cpu_to_le32(size); garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, - GARMIN_PKTHDR_LENGTH+size); + GARMIN_PKTHDR_LENGTH+size, 0); /* if this was an abort-transfer command, flush all queued data. */ @@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p, if (garmin_data_p->insize >= len) { garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, - len); + len, 0); garmin_data_p->insize = 0; /* if this was an abort-transfer command, @@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p) struct usb_serial_port *port = garmin_data_p->port; - if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) { + if (port != NULL && atomic_read(&garmin_data_p->resp_count)) { /* send a terminate command */ status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, - sizeof(GARMIN_STOP_TRANSFER_REQ)); + sizeof(GARMIN_STOP_TRANSFER_REQ), + 1); } /* flush all queued data */ @@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port) dbg("%s - starting session ...", __FUNCTION__); garmin_data_p->state = STATE_ACTIVE; status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, - sizeof(GARMIN_START_SESSION_REQ)); + sizeof(GARMIN_START_SESSION_REQ), + 0); if (status >= 0) { @@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port) /* not needed, but the win32 driver does it too ... */ status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ2, - sizeof(GARMIN_START_SESSION_REQ2)); + sizeof(GARMIN_START_SESSION_REQ2), + 0); if (status >= 0) { status = 0; spin_lock_irqsave(&garmin_data_p->lock, flags); @@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) garmin_data_p->mode = initial_mode; garmin_data_p->count = 0; garmin_data_p->flags = 0; + atomic_set(&garmin_data_p->req_count, 0); + atomic_set(&garmin_data_p->resp_count, 0); spin_unlock_irqrestore(&garmin_data_p->lock, flags); /* shutdown any bulk reads that might be going on */ @@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb) { unsigned long flags; struct usb_serial_port *port = (struct usb_serial_port *)urb->context; - struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); int status = urb->status; - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree (urb->transfer_buffer); + if (port) { + struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); - dbg("%s - port %d", __FUNCTION__, port->number); + dbg("%s - port %d", __FUNCTION__, port->number); - if (status) { - dbg("%s - nonzero write bulk status received: %d", - __FUNCTION__, status); - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= CLEAR_HALT_REQUIRED; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) + && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { + gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]); + } + + if (status) { + dbg("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); + spin_lock_irqsave(&garmin_data_p->lock, flags); + garmin_data_p->flags |= CLEAR_HALT_REQUIRED; + spin_unlock_irqrestore(&garmin_data_p->lock, flags); + } + + usb_serial_port_softint(port); } - usb_serial_port_softint(port); + /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */ + + /* free up the transfer buffer, as usb_free_urb() does not do this */ + kfree (urb->transfer_buffer); } static int garmin_write_bulk (struct usb_serial_port *port, - const unsigned char *buf, int count) + const unsigned char *buf, int count, + int dismiss_ack) { unsigned long flags; struct usb_serial *serial = port->serial; @@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port, usb_sndbulkpipe (serial->dev, port->bulk_out_endpointAddress), buffer, count, - garmin_write_bulk_callback, port); + garmin_write_bulk_callback, + dismiss_ack ? NULL : port); urb->transfer_flags |= URB_ZERO_PACKET; if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->req_count); if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { pkt_clear(garmin_data_p); garmin_data_p->state = STATE_GSP_WAIT_DATA; @@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, "failed with status = %d\n", __FUNCTION__, status); count = status; - } else { - - if (GARMIN_LAYERID_APPL == getLayerId(buffer) - && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { - - gsp_send_ack(garmin_data_p, buffer[4]); - } } /* we are done with this urb, so let the host driver @@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, static int garmin_write (struct usb_serial_port *port, const unsigned char *buf, int count) { - unsigned long flags; int pktid, pktsiz, len; struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; @@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port, break; case PRIV_PKTID_RESET_REQ: - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->req_count); break; case PRIV_PKTID_SET_DEF_MODE: @@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port) static void garmin_read_process(struct garmin_data * garmin_data_p, unsigned char *data, unsigned data_length) { - unsigned long flags; - if (garmin_data_p->flags & FLAGS_DROP_DATA) { /* abort-transfer cmd is actice */ dbg("%s - pkt dropped", __FUNCTION__); @@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, the device */ if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, sizeof(GARMIN_APP_LAYER_REPLY))) { - spin_lock_irqsave(&garmin_data_p->lock, flags); - garmin_data_p->flags |= FLAGS_APP_RESP_SEEN; - spin_unlock_irqrestore(&garmin_data_p->lock, flags); + atomic_inc(&garmin_data_p->resp_count); } /* if throttling is active or postprecessing is required -- cgit v1.2.3 From 88e45dbbababd29cd6c80a3e0b60a828676b3ba9 Mon Sep 17 00:00:00 2001 From: Luis Lloret Date: Thu, 26 Jul 2007 10:08:47 -0400 Subject: USB: Stall control endpoint when file storage class request wValue != 0 This patch makes the File Storage Gadget stall the control endpoint when a MSC class request is made with wValue != 0. This change makes some MSC compliance test warnings disappear. Signed-off-by: Luis Lloret Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index be7a1bd2823b..01ddb6d3e51b 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -1295,6 +1295,7 @@ static int class_setup_req(struct fsg_dev *fsg, struct usb_request *req = fsg->ep0req; int value = -EOPNOTSUPP; u16 w_index = le16_to_cpu(ctrl->wIndex); + u16 w_value = le16_to_cpu(ctrl->wValue); u16 w_length = le16_to_cpu(ctrl->wLength); if (!fsg->config) @@ -1308,7 +1309,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -1324,7 +1325,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } @@ -1343,7 +1344,7 @@ static int class_setup_req(struct fsg_dev *fsg, if (ctrl->bRequestType != (USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) break; - if (w_index != 0) { + if (w_index != 0 || w_value != 0) { value = -EDOM; break; } -- cgit v1.2.3 From 3aec6e26d7655eea07be8bbec4728447274ed43f Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Mon, 30 Jul 2007 06:38:31 -0400 Subject: USB: Typo: "USB_SAFE_PADDED" -> "USB_SERIAL_SAFE_PADDED". Fix typo in safe_serial.c to match the actual CONFIG variable. Signed-off-by: Robert P. J. Day Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/safe_serial.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 86899d55d8d8..51669b7622bb 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c @@ -74,13 +74,13 @@ #include -#ifndef CONFIG_USB_SAFE_PADDED -#define CONFIG_USB_SAFE_PADDED 0 +#ifndef CONFIG_USB_SERIAL_SAFE_PADDED +#define CONFIG_USB_SERIAL_SAFE_PADDED 0 #endif static int debug; static int safe = 1; -static int padded = CONFIG_USB_SAFE_PADDED; +static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; #define DRIVER_VERSION "v0.0b" #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" -- cgit v1.2.3 From 5b570d43cea0f5a6aa5bec2da2a0f68b96a37346 Mon Sep 17 00:00:00 2001 From: Gabriel C Date: Mon, 30 Jul 2007 12:57:03 +0200 Subject: USB: u132-hcd.c - Fix a warning when CONFIG_PM=n I noticed this warning with CONFING_PM=n ... drivers/usb/host/u132-hcd.c:1525: warning: 'port_power' defined but not used ... Signed-off-by: Gabriel Craciunescu Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/u132-hcd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index 7f765ec038cd..b88eb3c62c02 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c @@ -1520,12 +1520,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) } } } +#ifdef CONFIG_PM static void port_power(struct u132 *u132, int pn, int is_on) { u132->port[pn].power = is_on; } +#endif + static void u132_power(struct u132 *u132, int is_on) { struct usb_hcd *hcd = u132_to_hcd(u132) -- cgit v1.2.3 From 96443218be7f61027c23772d048a1bf549dfb2d7 Mon Sep 17 00:00:00 2001 From: Faidon Liambotis Date: Tue, 7 Aug 2007 05:46:05 +0300 Subject: USB: fix support for Dell Wireless Broadband (aka WWAN) Dell Wireless Broadband ExpressCards are rebrands of Novatel's cards. Add all of their known PCI IDs to date along with their mapping to the exact Novatel model to the Option driver which already claims to support them. Signed-off-by: Faidon Liambotis Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/airprime.c | 1 - drivers/usb/serial/option.c | 10 +++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index cff6fd190a28..77bb893bf2e9 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -18,7 +18,6 @@ static struct usb_device_id id_table [] = { { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ - { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 84c12b5f1271..4cb3c165742b 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -110,6 +110,7 @@ static int option_send_setup(struct usb_serial_port *port); #define HUAWEI_PRODUCT_E220 0x1003 #define NOVATELWIRELESS_VENDOR_ID 0x1410 +#define DELL_VENDOR_ID 0x413C #define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_PRODUCT_ADU_E100A 0x6501 @@ -119,8 +120,6 @@ static int option_send_setup(struct usb_serial_port *port); #define BANDRICH_PRODUCT_C100_1 0x1002 #define BANDRICH_PRODUCT_C100_2 0x1003 -#define DELL_VENDOR_ID 0x413C - static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -171,11 +170,16 @@ static struct usb_device_id option_ids[] = { { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ + { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, - { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ { } /* Terminating entry */ }; MODULE_DEVICE_TABLE(usb, option_ids); -- cgit v1.2.3 From a3b53514bd89c77c6aaf80b0ea37249d79c3f3bd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 7 Aug 2007 19:21:09 +0900 Subject: usb: Enable hcd support on SH unconditionally. Previous boards were likely seeing USB_ARCH_HAS_HCD selected by way of PCMCIA or PCI, though none of those are required for hcd support on SH. Enable support unconditionally. Signed-off-by: Paul Mundt Signed-off-by: Greg Kroah-Hartman --- drivers/usb/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 63436892688c..7580aa5da0f8 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig @@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD default y if USB_ARCH_HAS_EHCI default y if PCMCIA && !M32R # sl811_cs default y if ARM # SL-811 + default y if SUPERH # r8a66597-hcd default PCI # many non-PCI SOC chips embed OHCI -- cgit v1.2.3 From 71ee9a6c6c882c6293d7f2f96d2cd6d78beaf093 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 7 Aug 2007 19:21:42 +0900 Subject: usb: r8a66597-hcd: fix up error path. Currently when registration fails we're left with a stray reference to release_mem_region(), this leads to the following case: r8a66597_hcd r8a66597_hcd: irq 13, io base 0x18040000 drivers/usb/host/r8a66597-hcd.c: register access fail. r8a66597_hcd r8a66597_hcd: startup error -6 r8a66597_hcd r8a66597_hcd: USB bus 1 deregistered drivers/usb/host/r8a66597-hcd.c: Failed to add hcd Trying to free nonexistent resource <0000000018040000-0000000018040000> This fixes it up. Signed-off-by: Paul Mundt Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/r8a66597-hcd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index d60f1985320c..40a1de4c256e 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c @@ -2208,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) clean_up: if (reg) iounmap(reg); - if (res) - release_mem_region(res->start, 1); return ret; } -- cgit v1.2.3 From 8b2580e26565246cb196b5e9469b5aa5073d48ec Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 7 Aug 2007 21:16:05 -0700 Subject: USB: quirks: multicard reader doesn't like autosuspend It appears that one reason the "iConnect"-labeled multi-card reader was on sale for only $5 is that it doesn't handle suspend/resume correctly. Other than that, it was a good deal for a highspeed MMC/SD bridge. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index b7917c5a3c6f..dc81f46b8c94 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -70,6 +70,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Philips PSC805 audio device */ { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, + /* Alcor multi-card reader */ + { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* RIM Blackberry */ { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, -- cgit v1.2.3 From c1f8ea7d350d46c68f9d5293c4101816170301bc Mon Sep 17 00:00:00 2001 From: Søren Hauberg Date: Wed, 8 Aug 2007 10:50:17 +0200 Subject: USB: Support for the Evolution Scorpion robots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The attached (mostly trivial) patches adds support for the Evolution Scorpion Robots. Evolution Robotics supplies a patch against 2.6.8 with their software. My patch is based on their work, so I don't know if I can sign it off, or if you need some Evolution people to do this (which might be hard). The patch adds device ID's for some robots which is trivial. From: Søren Hauberg Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman Søren --- drivers/usb/serial/ftdi_sio.c | 2 ++ drivers/usb/serial/ftdi_sio.h | 3 +++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7b1673a44077..1370c423d7c2 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, + { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, + { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index d9e49716db13..c70e1de6389e 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -430,6 +430,9 @@ */ #define EVOLUTION_VID 0xDEEE /* Vendor ID */ #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ +#define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ +#define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ +#define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ /* Pyramid Computer GmbH */ #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ -- cgit v1.2.3 From e48eb085aca2971a1249efbb68f33e9ebca1395e Mon Sep 17 00:00:00 2001 From: Andy Green Date: Thu, 9 Aug 2007 12:19:38 -0700 Subject: USB: belkin_sa: avoid divide by zero error The belkin_sa module has a problem coping with a 0 return from tty_get_baud_rate() -- the subsequent BELKIN_SA_BAUD macro drivers/usb/serial/belkin_sa.h:#define BELKIN_SA_BAUD(b) (230400/b) performs a divide with it leading to the following divide error: usb 3-1: Belkin / Peracom / GoHubs USB Serial Adapter converter now attached to ttyUSB0 PM: Adding info for No Bus:usbdev3.3_ep81 PM: Adding info for No Bus:usbdev3.3_ep01 PM: Adding info for No Bus:usbdev3.3_ep82 divide error: 0000 [#1] SMP Modules linked in: vfat fat iwl3945 mac80211 cfg80211 belkin_sa usbserial usb_storage autofs4 vmnet(P) vmmon(P) aes nf_conntrack_netbios_ns ipt_REJECT nf_conntrack_ipv4 xt_state nf_conntrack nfnetlink xt_tcpudp iptable_filter ip_tables x_tables cpufreq_ondemand acpi_cpufreq video output sbs button dock battery ac arc4 snd_hda_intel ecb blkcipher snd_seq_dummy snd_seq_oss snd_seq_midi_event snd_seq snd_seq_device snd_pcm_oss sr_mod snd_mixer_oss rtc_cmos cdrom iTCO_wdt iTCO_vendor_support snd_pcm rtc_core snd_timer serio_raw b44 ssb rtc_lib parport ata_piix snd soundcore snd_page_alloc mii ata_generic sg ahci libata sd_mod scsi_mod ext3 jbd mbcache ehci_hcd ohci_hcd uhci_hcd CPU: 1 EIP: 0060:[] Tainted: P VLI EFLAGS: 00010246 (2.6.23-rc1 #1) EIP is at belkin_sa_set_termios+0x18e/0x5b9 [belkin_sa] eax: 00038400 ebx: 00000000 ecx: 00000000 edx: 00000000 esi: 00038400 edi: 00001cb2 ebp: de49adb0 esp: de49ad6c ds: 007b es: 007b fs: 00d8 gs: 0033 ss: 0068 Process minicom (pid: 7306, ti=de49a000 task=eed6c3b0 task.ti=de49a000) Stack: d85c74f0 00000046 00000002 00000001 d85c74f0 d85c74f0 00000246 c887c658 00000001 00000cb0 00000001 00000084 00000000 d01b58c0 f6ba10e0 de49ade8 de49ae40 de49add0 f8e2526b d85c74b8 ca6e6dbc de49ae40 d85c746c eded72e8 Call Trace: [] show_trace_log_lvl+0x1a/0x2f [] show_stack_log_lvl+0x9b/0xa3 [] show_registers+0x1b8/0x289 [] die+0x113/0x246 [] do_trap+0x8a/0xa3 [] do_divide_error+0x85/0x8f [] error_code+0x72/0x78 [] serial_set_termios+0x86/0x8d [usbserial] [] set_termios+0x309/0x34c [] n_tty_ioctl+0x158/0x4ba [] tty_ioctl+0xc78/0xcd6 [] do_ioctl+0x50/0x67 [] vfs_ioctl+0x249/0x25c [] sys_ioctl+0x49/0x61 [] sysenter_past_esp+0x5f/0x99 ======================= Code: 85 c0 79 14 c7 44 24 04 67 1c dd f8 c7 04 24 d4 1e dd f8 e8 96 99 65 c7 8b 46 04 be 00 84 03 00 e8 47 11 77 c7 31 d2 89 c1 89 f0 f1 66 85 c0 89 c1 b8 01 00 00 00 0f 44 c8 8b 45 d8 85 db 8b EIP: [] belkin_sa_set_termios+0x18e/0x5b9 [belkin_sa] SS:ESP 0068:de49ad6c The small patch below should take care of this situation. Note that my kernel was tainted (vmware) but the problem will occur if tty_get_baud_rate() ever returns zero and should be taken care of. Signed-off-by: Andy Green Cc: William Greathouse Cc: Alan Cox Cc: stable Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/belkin_sa.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index e67ce25f7512..86724e885704 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios } baud = tty_get_baud_rate(port->tty); + if (baud == 0) { + dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__); + return; + } urb_value = BELKIN_SA_BAUD(baud); /* Clip to maximum speed */ if (urb_value == 0) -- cgit v1.2.3 From 1207cf84f289694ba7ba8eeaa346a0195b3de606 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 9 Aug 2007 23:02:36 +0200 Subject: USB: Fix a memory leak in em28xx_usb_probe() If, in em28xx_usb_probe() the memory allocation dev->alt_max_pkt_size = kmalloc(32* dev->num_alt,GFP_KERNEL); fails, then we'll bail out and return -ENOMEM. The problem is that in that case we don't free the storage allocated to 'dev', thus causing a memory leak. This patch fixes the leak by freeing 'dev' before we return -ENOMEM. This fixes Coverity bug #647. Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/media/video/em28xx/em28xx-video.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/media/video/em28xx/em28xx-video.c b/drivers/media/video/em28xx/em28xx-video.c index 2c7b158ce7e1..40307f3f6fe3 100644 --- a/drivers/media/video/em28xx/em28xx-video.c +++ b/drivers/media/video/em28xx/em28xx-video.c @@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface, if (dev->alt_max_pkt_size == NULL) { em28xx_errdev("out of memory!\n"); em28xx_devused&=~(1< Date: Wed, 8 Aug 2007 17:16:12 -0400 Subject: USB: remove DEBUG definition from dummy_hcd This patch (as958) removes an unneeded and unwanted #define line from dummy_hcd. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/dummy_hcd.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f2fbdc7fe376..d008d1360a7a 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c @@ -34,8 +34,6 @@ * bypassing some hardware (and driver) issues. UML could help too. */ -#define DEBUG - #include #include #include -- cgit v1.2.3 From a66639ab286250fe66b960c34ac91d0b2ee58a79 Mon Sep 17 00:00:00 2001 From: Thomas Viehmann Date: Wed, 25 Jul 2007 10:21:21 +0200 Subject: usb-serial: fix oti6858.c segfault in termios handling The oti6858 usb serial driver should use kernel_termios_to_user_termios/ user_termios_to_kernel_termios to avoid segfaults because the kernel uses a structure differing from that of user space with a different size. Signed-off-by: Thomas Viehmann CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/oti6858.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d7db71eca520..833ada47fc54 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -818,19 +818,17 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, switch (cmd) { case TCGETS: - if (copy_to_user(user_arg, port->tty->termios, - sizeof(struct ktermios))) { + if (kernel_termios_to_user_termios((struct ktermios __user *)arg, + port->tty->termios)) return -EFAULT; - } return 0; case TCSETS: case TCSETSW: /* FIXME: this is not the same! */ case TCSETSF: /* FIXME: this is not the same! */ - if (copy_from_user(port->tty->termios, user_arg, - sizeof(struct ktermios))) { + if (user_termios_to_kernel_termios(port->tty->termios, + (struct ktermios __user *)arg)) return -EFAULT; - } oti6858_set_termios(port, NULL); return 0; -- cgit v1.2.3 From f095137e799ddb6a7c2bf0e4c73cda193ab9df41 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 14 Aug 2007 18:48:08 +0200 Subject: USB: blacklist Samsung ML-2010 printer Hi, this printer does not survive suspension. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index dc81f46b8c94..51d14032b27c 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -56,6 +56,8 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Seiko Epson Corp.*/ { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Samsung ML-2010 printer */ + { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Samsung ML-2510 Series printer */ { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Elsa MicroLink 56k (V.250) */ -- cgit v1.2.3 From 46dede4690bbb23a2c9d60561e2e4fdc3e6bee61 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Tue, 14 Aug 2007 10:56:10 -0400 Subject: USB: accept 1-byte Device Status replies, fixing some b0rken devices Some devices have a bug which causes them to send a 1-byte reply to Get-Device-Status requests instead of 2 bytes as required by the spec. This doesn't play well with autosuspend, since we look for a valid status reply to make sure the device is still present when it resumes. Without both bytes, we assume the device has been disconnected. Lack of the second byte shouldn't matter much, since the spec requires it always to be equal to 0. Hence this patch (as959) causes finish_port_resume() to accept a 1-byte reply as valid. Signed-off-by: Alan Stern Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index e341a1da517f..f7b337feb3ea 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev) * and device drivers will know about any resume quirks. */ if (status == 0) { + devstatus = 0; status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); if (status >= 0) - status = (status == 2 ? 0 : -ENODEV); + status = (status > 0 ? 0 : -ENODEV); } if (status) { -- cgit v1.2.3 From fa0de2b614ca89d14d046e6756ba020fd386ff71 Mon Sep 17 00:00:00 2001 From: M4rkusXXL Date: Fri, 10 Aug 2007 14:53:32 -0700 Subject: usb: typo in usb R8A66597 HCD config Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2f529828c74d..565d6ef4c4cf 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -237,7 +237,7 @@ config USB_SL811_CS module will be called "sl811_cs". config USB_R8A66597_HCD - tristate "R8A66597 HCD suppoort" + tristate "R8A66597 HCD support" depends on USB help The R8A66597 is a USB 2.0 host and peripheral controller. -- cgit v1.2.3 From 2f67cd5b1d5066d11761aebb0bf4b76bc253cc99 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 16 Aug 2007 16:16:00 -0400 Subject: usb-storage: fix bugs in the disconnect pathway This patch (as961) fixes a couple of bugs in the disconnect pathway of usb-storage. The first problem, which apparently has been around for a while although nobody noticed it, shows up when an aborted command is still pending when a disconnect occurs. The SCSI error-handler will continue to wait in command_abort() until the us->notify completion is signalled. Thus quiesce_and_remove_host() needs to signal it. The second problem was introduced recently along with autosuspend support. Since usb_stor_scan_thread() now calls usb_autopm_put_interface() before exiting, we can't simply leave the scanning thread running after a disconnect; we must wait until the thread exits. This is solved by adding a new struct completion to the private data structure. Fortuitously, it allows the removal of the rather clunky mechanism used in the past to insure that all threads have finished before the module is unloaded. Signed-off-by: Alan Stern CC: Matthew Dharm Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/usb.c | 33 ++++++--------------------------- drivers/usb/storage/usb.h | 1 + 2 files changed, 7 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 28842d208bb0..25e557d4fe6b 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR); MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); -/* These are used to make sure the module doesn't unload before all the - * threads have exited. - */ -static atomic_t total_threads = ATOMIC_INIT(0); -static DECLARE_COMPLETION(threads_gone); - - /* * The entries in this table correspond, line for line, * with the entries of us_unusual_dev_list[]. @@ -879,9 +872,6 @@ static void quiesce_and_remove_host(struct us_data *us) usb_stor_stop_transport(us); wake_up(&us->delay_wait); - /* It doesn't matter if the SCSI-scanning thread is still running. - * The thread will exit when it sees the DISCONNECTING flag. */ - /* queuecommand won't accept any new commands and the control * thread won't execute a previously-queued command. If there * is such a command pending, complete it with an error. */ @@ -891,12 +881,16 @@ static void quiesce_and_remove_host(struct us_data *us) scsi_lock(host); us->srb->scsi_done(us->srb); us->srb = NULL; + complete(&us->notify); /* in case of an abort */ scsi_unlock(host); } mutex_unlock(&us->dev_mutex); /* Now we own no commands so it's safe to remove the SCSI host */ scsi_remove_host(host); + + /* Wait for the SCSI-scanning thread to stop */ + wait_for_completion(&us->scanning_done); } /* Second stage of disconnect processing: deallocate all resources */ @@ -947,9 +941,8 @@ retry: /* Should we unbind if no devices were detected? */ } - scsi_host_put(us_to_host(us)); usb_autopm_put_interface(us->pusb_intf); - complete_and_exit(&threads_gone, 0); + complete_and_exit(&us->scanning_done, 0); } @@ -984,6 +977,7 @@ static int storage_probe(struct usb_interface *intf, init_MUTEX_LOCKED(&(us->sema)); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); + init_completion(&us->scanning_done); /* Associate the us_data structure with the USB device */ result = associate_dev(us, intf); @@ -1033,11 +1027,6 @@ static int storage_probe(struct usb_interface *intf, goto BadDevice; } - /* Take a reference to the host for the scanning thread and - * count it among all the threads we have launched. Then - * start it up. */ - scsi_host_get(us_to_host(us)); - atomic_inc(&total_threads); usb_autopm_get_interface(intf); /* dropped in the scanning thread */ wake_up_process(th); @@ -1104,16 +1093,6 @@ static void __exit usb_stor_exit(void) US_DEBUGP("-- calling usb_deregister()\n"); usb_deregister(&usb_storage_driver) ; - /* Don't return until all of our control and scanning threads - * have exited. Since each thread signals threads_gone as its - * last act, we have to call wait_for_completion the right number - * of times. - */ - while (atomic_read(&total_threads) > 0) { - wait_for_completion(&threads_gone); - atomic_dec(&total_threads); - } - usb_usual_clear_present(USB_US_TYPE_STOR); } diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 6445665b1577..8d87503e2560 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -150,6 +150,7 @@ struct us_data { struct semaphore sema; /* to sleep thread on */ struct completion notify; /* thread begin/end */ wait_queue_head_t delay_wait; /* wait during scan, reset */ + struct completion scanning_done; /* wait for scan thread */ /* subdriver information */ void *extra; /* Any extra data */ -- cgit v1.2.3 From bdd203a002681d7b2e133e485573f43d41e4cf69 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 17 Aug 2007 22:19:59 -0700 Subject: USB: ohci, fix oddball gcc warning Some versions of GCC recently grew annoying warnings about constants. This gets rid of that warning from the OHCI driver. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ohci-dbg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 6f9e43e9a6ca..f61c6cdd06f2 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small) #define ohci_dbg_sw(ohci, next, size, format, arg...) \ do { \ - if (next) { \ + if (next != NULL) { \ unsigned s_len; \ s_len = scnprintf (*next, *size, format, ## arg ); \ *size -= s_len; *next += s_len; \ -- cgit v1.2.3 From 5f546c5835fc301694da6c8ae1467b19f4cfec24 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 16 Aug 2007 10:55:18 +0200 Subject: USB: quirky mass storage device this device has been reported to break with autosuspend. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 51d14032b27c..78a98ffae3bd 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -30,6 +30,8 @@ static const struct usb_device_id usb_quirk_list[] = { /* HP 5300/5370C scanner */ { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, + /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */ + { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */ { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Benq S2W 3300U */ -- cgit v1.2.3 From 53059f4d19eb2cd6cde1bbcb1b7201bec340a47b Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Sun, 19 Aug 2007 17:14:34 +0200 Subject: USB: another quirky device for the drive Jean reported. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 78a98ffae3bd..655c15d60393 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -68,6 +68,8 @@ static const struct usb_device_id usb_quirk_list[] = { { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Agfa Snapscan1212u */ { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Seagate RSS LLC */ + { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, /* Umax [hex] Astra 3400U */ { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, -- cgit v1.2.3 From 04cab1329336d4577d6638360c905e360934b425 Mon Sep 17 00:00:00 2001 From: Christian Heim Date: Sun, 19 Aug 2007 13:29:15 +0200 Subject: USB: Adding support for HTC Smartphones to ipaq This patch enables support for HTC Smartphones. The original patch is at https://bugs.gentoo.org/show_bug.cgi?id=187522. Original author is Mike Doty . Signed-off-by: Christian Heim Signed-off-by: Greg Kroah-Hartman --- drivers/usb/serial/ipaq.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 0455c1552ae9..6a3a704b5849 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -545,6 +545,7 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ + { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ { } /* Terminating entry */ }; -- cgit v1.2.3 From 3b79cc26708bcc476d4e4bf3846032fa3a1eeb85 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Thu, 16 Aug 2007 16:06:06 +0200 Subject: USB: unkill cxacru atm driver it seems like you overdid it a bit in your quest to clean up the use of urb->status. In this driver you read it the first thing, which means that you are in a race against URB completion you'll usually lose, returning -EINPROGRESS. This kills the driver. Signed-off-by: Oliver Neukum Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/cxacru.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 02c52f8d5dbf..a73e714288e5 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c @@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, int* actual_length) { struct timer_list timer; - int status = urb->status; init_timer(&timer); timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); @@ -468,7 +467,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, if (actual_length) *actual_length = urb->actual_length; - return status; + return urb->status; /* must read status after completion */ } static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, -- cgit v1.2.3 From c39772d82ad453647ea4bf9d793010d86ef5e597 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 20 Aug 2007 10:45:28 -0400 Subject: USB: allow retry on descriptor fetch errors This patch (as964) was suggested by Steffen Koepf. It makes usb_get_descriptor() retry on all errors other than ETIMEDOUT, instead of only on EPIPE. This helps with some devices. Signed-off-by: Alan Stern CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index b6bd05e3d439..5498506e9c5e 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char memset(buf,0,size); // Make sure we parse really received data for (i = 0; i < 3; ++i) { - /* retry on length 0 or stall; some devices are flakey */ + /* retry on length 0 or error; some devices are flakey */ result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, (type << 8) + index, 0, buf, size, USB_CTRL_GET_TIMEOUT); - if (result == 0 || result == -EPIPE) + if (result <= 0 && result != -ETIMEDOUT) continue; if (result > 1 && ((u8 *)buf)[1] != type) { result = -EPROTO; -- cgit v1.2.3 From 85237f202d46d55c1bffe0c5b1aa3ddc0f1dce4d Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Tue, 21 Aug 2007 07:10:42 +0200 Subject: USB: fix DoS in pwc USB video driver the pwc driver has a disconnect method that waits for user space to close the device. This opens up an opportunity for a DoS attack, blocking the USB subsystem and making khubd's task busy wait in kernel space. This patch shifts freeing resources to close if an opened device is disconnected. Signed-off-by: Oliver Neukum CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/media/video/pwc/pwc-if.c | 52 +++++++++++++++++++++++++++------------- drivers/media/video/pwc/pwc.h | 1 + 2 files changed, 36 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/media/video/pwc/pwc-if.c b/drivers/media/video/pwc/pwc-if.c index 9c0e8d18c2f6..3d81966d8c42 100644 --- a/drivers/media/video/pwc/pwc-if.c +++ b/drivers/media/video/pwc/pwc-if.c @@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file) return 0; } + +static void pwc_cleanup(struct pwc_device *pdev) +{ + pwc_remove_sysfs_files(pdev->vdev); + video_unregister_device(pdev->vdev); +} + /* Note that all cleanup is done in the reverse order as in _open */ static int pwc_video_close(struct inode *inode, struct file *file) { struct video_device *vdev = file->private_data; struct pwc_device *pdev; - int i; + int i, hint; PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev); @@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file) pwc_isoc_cleanup(pdev); pwc_free_buffers(pdev); + lock_kernel(); /* Turn off LEDS and power down camera, but only when not unplugged */ - if (pdev->error_status != EPIPE) { + if (!pdev->unplugged) { /* Turn LEDs off */ if (pwc_set_leds(pdev, 0, 0) < 0) PWC_DEBUG_MODULE("Failed to set LED on/off time.\n"); @@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file) if (i < 0) PWC_ERROR("Failed to power down camera (%d)\n", i); } + pdev->vopen--; + PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i); + } else { + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; } - pdev->vopen--; - PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen); + unlock_kernel(); + return 0; } @@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf) /* Alert waiting processes */ wake_up_interruptible(&pdev->frameq); /* Wait until device is closed */ - while (pdev->vopen) - schedule(); - /* Device is now closed, so we can safely unregister it */ - PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); - pwc_remove_sysfs_files(pdev->vdev); - video_unregister_device(pdev->vdev); - - /* Free memory (don't set pdev to 0 just yet) */ - kfree(pdev); + if(pdev->vopen) { + pdev->unplugged = 1; + } else { + /* Device is closed, so we can safely unregister it */ + PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n"); + pwc_cleanup(pdev); + /* Free memory (don't set pdev to 0 just yet) */ + kfree(pdev); disconnect_out: - /* search device_hint[] table if we occupy a slot, by any chance */ - for (hint = 0; hint < MAX_DEV_HINTS; hint++) - if (device_hint[hint].pdev == pdev) - device_hint[hint].pdev = NULL; + /* search device_hint[] table if we occupy a slot, by any chance */ + for (hint = 0; hint < MAX_DEV_HINTS; hint++) + if (device_hint[hint].pdev == pdev) + device_hint[hint].pdev = NULL; + } unlock_kernel(); } diff --git a/drivers/media/video/pwc/pwc.h b/drivers/media/video/pwc/pwc.h index 910a04f53920..8e8e5b27e77e 100644 --- a/drivers/media/video/pwc/pwc.h +++ b/drivers/media/video/pwc/pwc.h @@ -193,6 +193,7 @@ struct pwc_device char vsnapshot; /* snapshot mode */ char vsync; /* used by isoc handler */ char vmirror; /* for ToUCaM series */ + char unplugged; int cmd_len; unsigned char cmd_buf[13]; -- cgit v1.2.3 From 013d27f265de6934ad7fb48fb29ab0172a20ab40 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 20 Aug 2007 12:18:39 -0400 Subject: USB: update last_busy field correctly This patch (as966) fixes a bug in the autosuspend code. The last_busy field should be updated whenever any event occurs, not just events that cause an autosuspend or an autoresume. This partially fixes Bugzilla #8892. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/driver.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 654857493a82..a1ad11d0c47c 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) udev->auto_pm = 1; udev->pm_usage_cnt += inc_usage_cnt; WARN_ON(udev->pm_usage_cnt < 0); + if (inc_usage_cnt) + udev->last_busy = jiffies; if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { if (udev->state == USB_STATE_SUSPENDED) status = usb_resume_both(udev); @@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) else if (inc_usage_cnt) udev->last_busy = jiffies; } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { - if (inc_usage_cnt) - udev->last_busy = jiffies; status = usb_suspend_both(udev, PMSG_SUSPEND); } usb_pm_unlock(udev); @@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf, else { udev->auto_pm = 1; intf->pm_usage_cnt += inc_usage_cnt; + udev->last_busy = jiffies; if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { if (udev->state == USB_STATE_SUSPENDED) status = usb_resume_both(udev); if (status != 0) intf->pm_usage_cnt -= inc_usage_cnt; - else if (inc_usage_cnt) + else udev->last_busy = jiffies; } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { - if (inc_usage_cnt) - udev->last_busy = jiffies; status = usb_suspend_both(udev, PMSG_SUSPEND); } } -- cgit v1.2.3 From d1a94f080f5bdfe46c9fb4954ffe8ae9ec29e44a Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 17 Aug 2007 10:58:16 -0400 Subject: USB: g_file_storage: fix bug in DMA buffer handling This patch (as963) fixes a recently-introduced bug. The gadget conversion removing DMA-mapped buffer allocation did not remove quite enough code from the g_file_storage driver; DMA pointers were being set to 0. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/file_storage.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 01ddb6d3e51b..965ad7bec7b7 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c @@ -599,7 +599,6 @@ enum fsg_buffer_state { struct fsg_buffhd { void *buf; - dma_addr_t dma; enum fsg_buffer_state state; struct fsg_buffhd *next; @@ -2612,7 +2611,6 @@ static int send_status(struct fsg_dev *fsg) fsg->intr_buffhd = bh; // Point to the right buffhd fsg->intreq->buf = bh->inreq->buf; - fsg->intreq->dma = bh->inreq->dma; fsg->intreq->context = bh; start_transfer(fsg, fsg->intr_in, fsg->intreq, &fsg->intreq_busy, &bh->state); @@ -3201,7 +3199,6 @@ reset: if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) goto reset; bh->inreq->buf = bh->outreq->buf = bh->buf; - bh->inreq->dma = bh->outreq->dma = bh->dma; bh->inreq->context = bh->outreq->context = bh; bh->inreq->complete = bulk_in_complete; bh->outreq->complete = bulk_out_complete; -- cgit v1.2.3 From 39d1f8c9fcb241c526efa5fff5869cad7beba98e Mon Sep 17 00:00:00 2001 From: Li Yang Date: Fri, 17 Aug 2007 08:36:44 -0700 Subject: USB: fsl_usb2_udc: fix bug in processing setup requests Kim Liu found that in the original code certain class setup requests are wrongly recognized and processed as standard setup requests. For that reason gadget ether can't work in RNDIS mode with Windows host. The patch fixes the setup request processing code, and makes class requests correctly passed to gadget layer. Signed-off-by: Li Yang Signed-off-by: Kim Liu Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/gadget/fsl_usb2_udc.c | 77 +++++++++++++++++++++------------------ 1 file changed, 41 insertions(+), 36 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 10b2b33b8698..d57bcfbc08a5 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c @@ -1277,31 +1277,32 @@ static void setup_received_irq(struct fsl_udc *udc, udc_reset_ep_queue(udc, 0); + /* We process some stardard setup requests here */ switch (setup->bRequest) { - /* Request that need Data+Status phase from udc */ case USB_REQ_GET_STATUS: - if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD)) + /* Data+Status phase from udc */ + if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) != (USB_DIR_IN | USB_TYPE_STANDARD)) break; ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); - break; + return; - /* Requests that need Status phase from udc */ case USB_REQ_SET_ADDRESS: + /* Status phase from udc */ if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE)) break; ch9setaddress(udc, wValue, wIndex, wLength); - break; + return; - /* Handled by udc, no data, status by udc */ case USB_REQ_CLEAR_FEATURE: case USB_REQ_SET_FEATURE: - { /* status transaction */ + /* Status phase from udc */ + { int rc = -EOPNOTSUPP; - if ((setup->bRequestType & USB_RECIP_MASK) - == USB_RECIP_ENDPOINT) { + if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) + == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { int pipe = get_pipe_by_windex(wIndex); struct fsl_ep *ep; @@ -1315,8 +1316,9 @@ static void setup_received_irq(struct fsl_udc *udc, ? 1 : 0); spin_lock(&udc->lock); - } else if ((setup->bRequestType & USB_RECIP_MASK) - == USB_RECIP_DEVICE) { + } else if ((setup->bRequestType & (USB_RECIP_MASK + | USB_TYPE_MASK)) == (USB_RECIP_DEVICE + | USB_TYPE_STANDARD)) { /* Note: The driver has not include OTG support yet. * This will be set when OTG support is added */ if (!udc->gadget.is_otg) @@ -1329,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc, USB_DEVICE_A_ALT_HNP_SUPPORT) udc->gadget.a_alt_hnp_support = 1; rc = 0; - } + } else + break; + if (rc == 0) { if (ep0_prime_status(udc, EP_DIR_IN)) ep0stall(udc); } - break; + return; } - /* Requests handled by gadget */ - default: - if (wLength) { - /* Data phase from gadget, status phase from udc */ - udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) - ? USB_DIR_IN : USB_DIR_OUT; - spin_unlock(&udc->lock); - if (udc->driver->setup(&udc->gadget, - &udc->local_setup_buff) < 0) - ep0stall(udc); - spin_lock(&udc->lock); - udc->ep0_state = (setup->bRequestType & USB_DIR_IN) - ? DATA_STATE_XMIT : DATA_STATE_RECV; - } else { - /* No data phase, IN status from gadget */ - udc->ep0_dir = USB_DIR_IN; - spin_unlock(&udc->lock); - if (udc->driver->setup(&udc->gadget, - &udc->local_setup_buff) < 0) - ep0stall(udc); - spin_lock(&udc->lock); - udc->ep0_state = WAIT_FOR_OUT_STATUS; - } + default: break; } + + /* Requests handled by gadget */ + if (wLength) { + /* Data phase from gadget, status phase from udc */ + udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) + ? USB_DIR_IN : USB_DIR_OUT; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + ep0stall(udc); + spin_lock(&udc->lock); + udc->ep0_state = (setup->bRequestType & USB_DIR_IN) + ? DATA_STATE_XMIT : DATA_STATE_RECV; + } else { + /* No data phase, IN status from gadget */ + udc->ep0_dir = USB_DIR_IN; + spin_unlock(&udc->lock); + if (udc->driver->setup(&udc->gadget, + &udc->local_setup_buff) < 0) + ep0stall(udc); + spin_lock(&udc->lock); + udc->ep0_state = WAIT_FOR_OUT_STATUS; + } } /* Process request for Data or Status phase of ep0 -- cgit v1.2.3 From 4c132e77242c130aea81c8fc64d59f573a26bf8d Mon Sep 17 00:00:00 2001 From: Stanislaw Gruszka Date: Mon, 20 Aug 2007 23:20:49 +0200 Subject: UEAGLE: Remove sysfs files on error case Bugfix, remove sysfs files when modem fails to boot. Signed-off-by: Stanislaw Gruszka Signed-off-by: Greg Kroah-Hartman --- drivers/usb/atm/ueagle-atm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index a1a1c9d467e0..29807d048b04 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -1721,9 +1721,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, ret = uea_boot(sc); if (ret < 0) - goto error; + goto error_rm_grp; return 0; + +error_rm_grp: + sysfs_remove_group(&intf->dev.kobj, &attr_grp); error: kfree(sc); return ret; -- cgit v1.2.3 From c907d3b09f7a50023b61ba6ec4e01ccaa543a7ae Mon Sep 17 00:00:00 2001 From: Mike Nuss Date: Mon, 20 Aug 2007 18:21:15 -0700 Subject: USB: make EHCI initialize properly on PPC SOCs Correctly initialize the on-chip EHCI controller on the AMCC PPC440EPx. Fix "USB 0.0" initialization message, and properly put the controller into a known state before starting it. Add "FIXME" comment to the au1xxx bus glue which is doing the same wrong thing here. (Who maintains that, now that AMD sold off Alchemy?) Remove some false copyright attributions which were somehow placed in the au1xxx bus glue then copied into ppc-soc. Signed-off-by: Mike Nuss Signed-off-by: David Brownell Cc: K.Boge Cc: Jordan Crouse Signed-off-by: Stefan Roese Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-au1xxx.c | 5 +++-- drivers/usb/host/ehci-ppc-soc.c | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 5d1b12aad776..b1d19268cb23 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c @@ -1,8 +1,6 @@ /* * EHCI HCD (Host Controller Driver) for USB. * - * (C) Copyright 2000-2004 David Brownell - * * Bus Glue for AMD Alchemy Au1xxx * * Based on "ohci-au1xxx.c" by Matt Porter @@ -196,6 +194,9 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { /* * basic lifecycle operations + * + * FIXME -- ehci_init() doesn't do enough here. + * See ehci-ppc-soc for a complete implementation. */ .reset = ehci_init, .start = ehci_run, diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index c2cedb09ed8b..4f99b0eb27bc 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c @@ -6,7 +6,7 @@ * Bus Glue for PPC On-Chip EHCI driver * Tested on AMCC 440EPx * - * Based on "ehci-au12xx.c" by David Brownell + * Based on "ehci-au1xxx.c" by K.Boge * * This file is licenced under the GPL. */ @@ -15,6 +15,24 @@ extern int usb_disabled(void); +/* called during probe() after chip reset completes */ +static int ehci_ppc_soc_setup(struct usb_hcd *hcd) +{ + struct ehci_hcd *ehci = hcd_to_ehci(hcd); + int retval; + + retval = ehci_halt(ehci); + if (retval) + return retval; + + retval = ehci_init(hcd); + if (retval) + return retval; + + ehci->sbrn = 0x20; + return ehci_reset(ehci); +} + /** * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs * Context: !in_interrupt() @@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { /* * basic lifecycle operations */ - .reset = ehci_init, + .reset = ehci_ppc_soc_setup, .start = ehci_run, .stop = ehci_stop, .shutdown = ehci_shutdown, -- cgit v1.2.3 From a78d702beed61956b26c1b6288da868946642317 Mon Sep 17 00:00:00 2001 From: Paul Walmsley Date: Thu, 16 Aug 2007 16:21:35 -0700 Subject: usb quirks: Add Canon EOS 5D (PC Connection mode) to the autosuspend blacklist Recent versions of the Linux kernel auto-suspend attached USB devices. After this happens to the Canon EOS 5D camera, the camera's interrupt endpoints don't seem to wake back up correctly, causing further use with libgphoto2 to fail with a -114 "OS error in camera communication" error. A similar fix is probably necessary for this camera in PTP mode, which identifies as USB product id 0x3102, but we haven't tested this. As part of our testing process, we tried the USB_QUIRK_RESET_RESUME quirk also, it's not helpful in this case. Signed-off-by: Raj Kumar Signed-off-by: Paul Walmsley Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/quirks.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index 655c15d60393..9e467118dc94 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c @@ -79,6 +79,9 @@ static const struct usb_device_id usb_quirk_list[] = { /* Alcor multi-card reader */ { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* Canon EOS 5D in PC Connection mode */ + { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, + /* RIM Blackberry */ { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, -- cgit v1.2.3 From 83fc8a151beda2d63e196a7ab2e12316c37a1e91 Mon Sep 17 00:00:00 2001 From: Mike Pagano Date: Wed, 15 Aug 2007 10:13:28 -0400 Subject: USB: resubmission unusual_devs modification for Nikon D80 Upgrade the unusual_devs.h file to support the new 1.01 firmware for the Nikon D80. Signed-off-by: Mike Pagano Signed-off-by: Phil Dibowitz Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/unusual_devs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d8d008d42946..2d92ce31018f 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -342,7 +342,7 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, US_FL_FIX_CAPACITY), /* Reported by Emil Larsson */ -UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100, +UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, "NIKON", "NIKON DSC D80", US_SC_DEVICE, US_PR_DEVICE, NULL, -- cgit v1.2.3 From d65cc1b45e7d3a24c25fd3d730042e407d6d64ce Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 21 Aug 2007 13:41:08 +0200 Subject: usb: add PRODUCT, TYPE to usb-interface events This fixes a regression for userspace programs that were relying on these events. Signed-off-by: Kay Sievers Cc: Andreas Jellinghaus Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/message.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'drivers') diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 5498506e9c5e..d8f7b089a8f0 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, usb_dev = interface_to_usbdev(intf); alt = intf->cur_altsetting; +#ifdef CONFIG_USB_DEVICEFS + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "DEVICE=/proc/bus/usb/%03d/%03d", + usb_dev->bus->busnum, usb_dev->devnum)) + return -ENOMEM; +#endif + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "PRODUCT=%x/%x/%x", + le16_to_cpu(usb_dev->descriptor.idVendor), + le16_to_cpu(usb_dev->descriptor.idProduct), + le16_to_cpu(usb_dev->descriptor.bcdDevice))) + return -ENOMEM; + + if (add_uevent_var(envp, num_envp, &i, + buffer, buffer_size, &length, + "TYPE=%d/%d/%d", + usb_dev->descriptor.bDeviceClass, + usb_dev->descriptor.bDeviceSubClass, + usb_dev->descriptor.bDeviceProtocol)) + return -ENOMEM; + if (add_uevent_var(envp, num_envp, &i, buffer, buffer_size, &length, "INTERFACE=%d/%d/%d", -- cgit v1.2.3 From ce5ccdef1090367f3024b4d5e7908bf6bd2929ae Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 16 Jul 2007 23:27:10 -0500 Subject: PCI: Move prototypes for pci_bus_find_capability to include/linux/pci.h We need pci_bus_find_capability() in some arch/powerpc code so move the prototype into a header accessible to it. Also kill the duplicate prototype for pci_bus_alloc_resource(). Signed-off-by: Kumar Gala Signed-off-by: Greg Kroah-Hartman --- drivers/pci/pci.h | 8 +------- include/linux/pci.h | 3 +++ 2 files changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index c6e132d7c0f7..4c36e80f6d26 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -5,12 +5,7 @@ extern int pci_uevent(struct device *dev, char **envp, int num_envp, extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); -extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - resource_size_t size, resource_size_t align, - resource_size_t min, unsigned int type_mask, - void (*alignf)(void *, struct resource *, - resource_size_t, resource_size_t), - void *alignf_data); + /* Firmware callbacks */ extern pci_power_t (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); extern int (*platform_pci_set_power_state)(struct pci_dev *dev, pci_power_t state); @@ -35,7 +30,6 @@ static inline int pci_proc_detach_bus(struct pci_bus *bus) { return 0; } /* Functions for PCI Hotplug drivers to use */ extern unsigned int pci_do_scan_bus(struct pci_bus *bus); -extern int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); extern void pci_remove_legacy_files(struct pci_bus *bus); diff --git a/include/linux/pci.h b/include/linux/pci.h index e7d8d4e19a53..325225c48458 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -578,6 +578,9 @@ int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); +/* Functions for PCI Hotplug drivers to use */ +int pci_bus_find_capability (struct pci_bus *bus, unsigned int devfn, int cap); + /* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ void pci_bus_assign_resources(struct pci_bus *bus); void pci_bus_size_bridges(struct pci_bus *bus); -- cgit v1.2.3 From 4e68fc97b17470365a65bc569523dd9012730e44 Mon Sep 17 00:00:00 2001 From: Marian Balakowicz Date: Tue, 3 Jul 2007 11:03:18 +0200 Subject: PCI: quirk_e100_interrupt() called too early quirk_e100_interrupts() is called after PCI controller is initialized and before PCI bus enumeration is performed. On some powerpc platforms which modify PCI controller configuration and set different MEM and IO windows than those set by firmware quirk_e100_interrupt() is causing kernel panic as it tries to read from device BAR0 offets which at this time points to a invalid PCI window (set by firmware). This patch delays the quirk_100_interrupt() to pci_fixup_final phase, which happens after bus enumeration and before PCI enable and device driver initialization. Signed-off-by: Marian Balakowicz Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index c559085c89a5..ab1c5c5d03f8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1485,7 +1485,7 @@ static void __devinit quirk_e100_interrupt(struct pci_dev *dev) iounmap(csr); } -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { -- cgit v1.2.3 From 60ac8f20feb0bba8caee63be3e7ca5801fe16d4c Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Tue, 24 Jul 2007 11:16:37 +0200 Subject: pci/hotplug/cpqphp_ctrl.c: remove stale BKL use remove stale BKL use from drivers/pci/hotplug/cpqphp_ctrl.c. Signed-off-by: Ingo Molnar Signed-off-by: Greg Kroah-Hartman --- drivers/pci/hotplug/cpqphp_ctrl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index 79ff6b4de3a6..37d72f123a80 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c @@ -1746,10 +1746,8 @@ static void pushbutton_helper_thread(unsigned long data) static int event_thread(void* data) { struct controller *ctrl; - lock_kernel(); + daemonize("phpd_event"); - - unlock_kernel(); while (1) { dbg("!!!!event_thread sleeping\n"); -- cgit v1.2.3 From d55bef515a01c85aa65c03c285ea8d285fcbab3b Mon Sep 17 00:00:00 2001 From: Bernhard Kaindl Date: Mon, 30 Jul 2007 20:35:13 +0200 Subject: PCI: lets kill the 'PCI hidden behind bridge' message MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adrian Bunk wrote: > Alois Nešpor wrote >> PCI: Bus #0b (-#0e) is hidden behind transparent bridge #0a (-#0b) (try 'pci=assign-busses') >> Please report the result to linux-kernel to fix this permanently" >> >> dmesg: >> "Yenta: Raising subordinate bus# of parent bus (#0a) from #0b to #0e" >> without pci=assign-busses and nothing with pci=assign-busses. > > Bernhard? Ok, lets kill the message. As Alois Nešpor also saw, that's fixed up by Yenta, so PCI does not have to warn about it. PCI could still warn about it if is_cardbus is 0 in that instance of pci_scan_bridge(), but so far I have not seen a report where this would have been the case so I think we can spare the kernel of that check (removes ~300 lines of asm) unless debugging is done. History: The whole check was added in the days before we had the fixup for this in Yenta and pci=assign-busses was the only way to get CardBus cards detected on many (not all) of the machines which give this warning. In theory, there could be cases when this warning would be triggered and it's not cardbus, then the warning should still apply, but I think this should only be the case when working on a completely broken PCI setup, but one may have already enabled the debug code in drivers/pci and the patched check would then trigger. I do not sign this off yet because it's completely untested so far, but everyone is free to test it (with the #ifdef DEBUG replaced by #if 1 and pr_debug( changed to printk(. We may also dump the whole check (remove everything within the #ifdef from the source) if that's perferred. On Alois Nešpor's machine this would then (only when debugging) this message: "PCI: Bus #0b (-#0e) is partially hidden behind transparent bridge #0a (-#0b)" "partially" should be in the message on his machine because #0b of #0b-#0e is reachable behind #0a-#0b, but not #0c-#0e. But that differentiation is now moot anyway because the fixup in Yenta takes care of it as far as I could see so far, which means that unless somebody is debugging a totally broken PCI setup, this message is not needed anymore, not even for debugging PCI. Ok, here the patch with the following changes: * Refined to say that the bus is only partially hidden when the parent bus numbers are not totally way off (outside of) the child bus range * remove the reference to pci=assign-busses and the plea to report it We could add a pure source code-only comment to keep a reference to pci=assign-busses the in case when this is triggered by someone who is debugging the cause of this message and looking the way to solve it. From: Bernhard Kaindl Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/probe.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 34b8dae0d90f..27e00b2d7b5b 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -653,20 +653,20 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass sprintf(child->name, (is_cardbus ? "PCI CardBus #%02x" : "PCI Bus #%02x"), child->number); + /* Has only triggered on CardBus, fixup is in yenta_socket */ while (bus->parent) { if ((child->subordinate > bus->subordinate) || (child->number > bus->subordinate) || (child->number < bus->number) || (child->subordinate < bus->number)) { - printk(KERN_WARNING "PCI: Bus #%02x (-#%02x) is " - "hidden behind%s bridge #%02x (-#%02x)%s\n", - child->number, child->subordinate, - bus->self->transparent ? " transparent" : " ", - bus->number, bus->subordinate, - pcibios_assign_all_busses() ? " " : - " (try 'pci=assign-busses')"); - printk(KERN_WARNING "Please report the result to " - " to fix this permanently\n"); + pr_debug("PCI: Bus #%02x (-#%02x) is %s" + "hidden behind%s bridge #%02x (-#%02x)\n", + child->number, child->subordinate, + (bus->number > child->subordinate && + bus->subordinate < child->number) ? + "wholly " : " partially", + bus->self->transparent ? " transparent" : " ", + bus->number, bus->subordinate); } bus = bus->parent; } -- cgit v1.2.3 From 4be8f906435a6af241821ab5b94b2b12cb7d57d8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Aug 2007 14:34:42 +0900 Subject: PCI: disable MSI on RS690 RS690 can't do MSI like its predecessors. Disable MSI on RS690. Signed-off-by: Tejun Heo Cc: Henry Su Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ab1c5c5d03f8..ca89ed92cd04 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1650,6 +1650,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); /* Disable MSI on chipsets that are known to not support it */ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8938d59013c6..0d6279c60b32 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -360,6 +360,7 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +#define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 #define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 -- cgit v1.2.3 From aea6a433f50cd89b9cbd10850fd0b32f961f9883 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 18 Aug 2007 03:03:10 +0900 Subject: PCI: disable MSI on RD580 RD580 can't do MSI like its predecessors. Disable MSI on RD580. Signed-off-by: Tejun Heo CC: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ca89ed92cd04..ebfc1de7579e 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1650,6 +1650,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_GCN DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000_PCIX, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 0d6279c60b32..80c27d7bf021 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -360,6 +360,7 @@ #define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 +#define PCI_DEVICE_ID_ATI_RD580 0x5952 #define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 -- cgit v1.2.3 From f122392f679ebed39db08074f935d770504623eb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 21 Aug 2007 14:33:01 +0900 Subject: PCI: disable MSI on RX790 RX790 can't do MSI like its predecessors. Disable MSI on RX790. Signed-off-by: Tejun Heo Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ebfc1de7579e..31f680f238c8 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1651,6 +1651,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1 DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RD580, quirk_disable_all_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RX790, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS690, quirk_disable_all_msi); DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_VT3351, quirk_disable_all_msi); diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 80c27d7bf021..f77944e432f2 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -361,6 +361,7 @@ #define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 #define PCI_DEVICE_ID_ATI_RS480 0x5950 #define PCI_DEVICE_ID_ATI_RD580 0x5952 +#define PCI_DEVICE_ID_ATI_RX790 0x5957 #define PCI_DEVICE_ID_ATI_RS690 0x7910 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 -- cgit v1.2.3 From 18166c1a50dc4f5b121ab2bd4fdf178404db9d99 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sun, 19 Aug 2007 12:03:07 +0200 Subject: PCI: Run k8t_sound_hostbridge quirk only when needed The k8t_sound_hostbridge PCI quick fires on my motherboard (Jetway K8M8MS) while it shouldn't: the on-board sound chip is not disabled and is working just fine. Looking at the code, I see that we are running the quirk for two distinct register values (0x88 and 0xc8) and then clear bit 6 (0x40). However value 0x88 already has bit 6 cleared so this is a no-op. This is what happens on my board. Thus I believe that the quirk should only be run for register value 0xc8. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- drivers/pci/quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 31f680f238c8..2d40f437b9fc 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -947,7 +947,7 @@ static void k8t_sound_hostbridge(struct pci_dev *dev) unsigned char val; pci_read_config_byte(dev, 0x50, &val); - if (val == 0x88 || val == 0xc8) { + if (val == 0xc8) { /* Assume it's probably a MSI-K8T-Neo2Fir */ printk(KERN_INFO "PCI: MSI-K8T-Neo2Fir, attempting to turn soundcard ON\n"); pci_write_config_byte(dev, 0x50, val & (~0x40)); -- cgit v1.2.3 From 8e81cc13a88ce486a6b0a6ca56aba6985824917a Mon Sep 17 00:00:00 2001 From: Kent Yoder Date: Wed, 22 Aug 2007 14:01:04 -0700 Subject: tpmdd maintainers Fix up the maintainers info in the tpm drivers. Kylene will be out for some time, so copying the sourceforge list is the best way to get some attention. Cc: Marcel Selhorst Cc: Kylene Jo Hall Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- MAINTAINERS | 2 +- drivers/char/tpm/tpm.c | 2 +- drivers/char/tpm/tpm.h | 2 +- drivers/char/tpm/tpm_atmel.c | 2 +- drivers/char/tpm/tpm_atmel.h | 2 +- drivers/char/tpm/tpm_bios.c | 2 ++ drivers/char/tpm/tpm_nsc.c | 2 +- drivers/char/tpm/tpm_tis.c | 2 ++ 8 files changed, 10 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/MAINTAINERS b/MAINTAINERS index 371fe67a4eef..abe5fa7f9c33 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3452,7 +3452,7 @@ S: Maintained TPM DEVICE DRIVER P: Kylene Hall -M: kjhall@us.ibm.com +M: tpmdd-devel@lists.sourceforge.net W: http://tpmdd.sourceforge.net P: Marcel Selhorst M: tpm@selhorst.net diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 9bb542913b86..39564b76d4a3 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index b2e2b002a1bb..d15ccddc92eb 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index 1ab0896070be..d0e7926eb486 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h index 9363bcf0a402..6c831f9466b7 100644 --- a/drivers/char/tpm/tpm_atmel.h +++ b/drivers/char/tpm/tpm_atmel.h @@ -4,7 +4,7 @@ * Authors: * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 8677fc6a545e..60a2d2630e36 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c @@ -7,6 +7,8 @@ * Reiner Sailer * Kylene Hall * + * Maintained by: + * * Access to the eventlog extended by the TCG BIOS of PC platform * * This program is free software; you can redistribute it and/or diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 608f73071bef..6313326bc41f 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c @@ -7,7 +7,7 @@ * Reiner Sailer * Kylene Hall * - * Maintained by: + * Maintained by: * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 483f3f60013c..23fa18a6654c 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -5,6 +5,8 @@ * Leendert van Doorn * Kylene Hall * + * Maintained by: + * * Device driver for TCG/TCPA TPM (trusted platform module). * Specifications at www.trustedcomputinggroup.org * -- cgit v1.2.3 From 20620d688ac6ff8ea01a873e46febf5a6a7909f1 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Wed, 22 Aug 2007 14:01:11 -0700 Subject: serial: don't optimise away baud rate changes when BOTHER is used The uart_set_termios() function will bail out early without bothering to touch the hardware, if it decides that nothing "relevant" has changed. Unfortunately, its idea of "relevant" doesn't include c_[io]speed. So if the baud rate bits are BOTHER and you just change the speed, the change gets optimised away. This patch makes it ignore the old Bfoo bits in c_cflag and just check whether c_ispeed and c_ospeed have changed. Those integers are always set appropriately for us by set_termios(). Signed-off-by: David Woodhouse Acked-by: Alan Cox Cc: Russell King Cc: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/serial_core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c index 030a6063541d..a055f58f342f 100644 --- a/drivers/serial/serial_core.c +++ b/drivers/serial/serial_core.c @@ -1146,11 +1146,14 @@ static void uart_set_termios(struct tty_struct *tty, struct ktermios *old_termio /* * These are the bits that are used to setup various - * flags in the low level driver. + * flags in the low level driver. We can ignore the Bfoo + * bits in c_cflag; c_[io]speed will always be set + * appropriately by set_termios() in tty_ioctl.c */ #define RELEVANT_IFLAG(iflag) ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) - if ((cflag ^ old_termios->c_cflag) == 0 && + tty->termios->c_ospeed == old_termios->c_ospeed && + tty->termios->c_ispeed == old_termios->c_ispeed && RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) return; -- cgit v1.2.3 From 84f8c6fc0e3b6e48fd22c28fc3bb666a130b3994 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Wed, 22 Aug 2007 14:01:14 -0700 Subject: serial: add support for ITE 887x chips Add support for the it887x-chips (PCI) manufactured by ITE. Signed-off-by: Niels de Vos Cc: Russell King Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 159 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index 5e485876f54c..fd76542c5977 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -580,6 +580,138 @@ static int pci_netmos_init(struct pci_dev *dev) return num_serial; } +/* + * ITE support by Niels de Vos + * + * These chips are available with optionally one parallel port and up to + * two serial ports. Unfortunately they all have the same product id. + * + * Basic configuration is done over a region of 32 I/O ports. The base + * ioport is called INTA or INTC, depending on docs/other drivers. + * + * The region of the 32 I/O ports is configured in POSIO0R... + */ + +/* registers */ +#define ITE_887x_MISCR 0x9c +#define ITE_887x_INTCBAR 0x78 +#define ITE_887x_UARTBAR 0x7c +#define ITE_887x_PS0BAR 0x10 +#define ITE_887x_POSIO0 0x60 + +/* I/O space size */ +#define ITE_887x_IOSIZE 32 +/* I/O space size (bits 26-24; 8 bytes = 011b) */ +#define ITE_887x_POSIO_IOSIZE_8 (3 << 24) +/* I/O space size (bits 26-24; 32 bytes = 101b) */ +#define ITE_887x_POSIO_IOSIZE_32 (5 << 24) +/* Decoding speed (1 = slow, 2 = medium, 3 = fast) */ +#define ITE_887x_POSIO_SPEED (3 << 29) +/* enable IO_Space bit */ +#define ITE_887x_POSIO_ENABLE (1 << 31) + +static int __devinit pci_ite887x_init(struct pci_dev *dev) +{ + /* inta_addr are the configuration addresses of the ITE */ + static const short inta_addr[] = { 0x2a0, 0x2c0, 0x220, 0x240, 0x1e0, + 0x200, 0x280, 0 }; + int ret, i, type; + struct resource *iobase = NULL; + u32 miscr, uartbar, ioport; + + /* search for the base-ioport */ + i = 0; + while (inta_addr[i] && iobase == NULL) { + iobase = request_region(inta_addr[i], ITE_887x_IOSIZE, + "ite887x"); + if (iobase != NULL) { + /* write POSIO0R - speed | size | ioport */ + pci_write_config_dword(dev, ITE_887x_POSIO0, + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_32 | inta_addr[i]); + /* write INTCBAR - ioport */ + pci_write_config_dword(dev, ITE_887x_INTCBAR, inta_addr[i]); + ret = inb(inta_addr[i]); + if (ret != 0xff) { + /* ioport connected */ + break; + } + release_region(iobase->start, ITE_887x_IOSIZE); + iobase = NULL; + } + i++; + } + + if (!inta_addr[i]) { + printk(KERN_ERR "ite887x: could not find iobase\n"); + return -ENODEV; + } + + /* start of undocumented type checking (see parport_pc.c) */ + type = inb(iobase->start + 0x18) & 0x0f; + + switch (type) { + case 0x2: /* ITE8871 (1P) */ + case 0xa: /* ITE8875 (1P) */ + ret = 0; + break; + case 0xe: /* ITE8872 (2S1P) */ + ret = 2; + break; + case 0x6: /* ITE8873 (1S) */ + ret = 1; + break; + case 0x8: /* ITE8874 (2S) */ + ret = 2; + break; + default: + moan_device("Unknown ITE887x", dev); + ret = -ENODEV; + } + + /* configure all serial ports */ + for (i = 0; i < ret; i++) { + /* read the I/O port from the device */ + pci_read_config_dword(dev, ITE_887x_PS0BAR + (0x4 * (i + 1)), + &ioport); + ioport &= 0x0000FF00; /* the actual base address */ + pci_write_config_dword(dev, ITE_887x_POSIO0 + (0x4 * (i + 1)), + ITE_887x_POSIO_ENABLE | ITE_887x_POSIO_SPEED | + ITE_887x_POSIO_IOSIZE_8 | ioport); + + /* write the ioport to the UARTBAR */ + pci_read_config_dword(dev, ITE_887x_UARTBAR, &uartbar); + uartbar &= ~(0xffff << (16 * i)); /* clear half the reg */ + uartbar |= (ioport << (16 * i)); /* set the ioport */ + pci_write_config_dword(dev, ITE_887x_UARTBAR, uartbar); + + /* get current config */ + pci_read_config_dword(dev, ITE_887x_MISCR, &miscr); + /* disable interrupts (UARTx_Routing[3:0]) */ + miscr &= ~(0xf << (12 - 4 * i)); + /* activate the UART (UARTx_En) */ + miscr |= 1 << (23 - i); + /* write new config with activated UART */ + pci_write_config_dword(dev, ITE_887x_MISCR, miscr); + } + + if (ret <= 0) { + /* the device has no UARTs if we get here */ + release_region(iobase->start, ITE_887x_IOSIZE); + } + + return ret; +} + +static void __devexit pci_ite887x_exit(struct pci_dev *dev) +{ + u32 ioport; + /* the ioport is bit 0-15 in POSIO0R */ + pci_read_config_dword(dev, ITE_887x_POSIO0, &ioport); + ioport &= 0xffff; + release_region(ioport, ITE_887x_IOSIZE); +} + static int pci_default_setup(struct serial_private *priv, struct pciserial_board *board, struct uart_port *port, int idx) @@ -652,6 +784,18 @@ static struct pci_serial_quirk pci_serial_quirks[] = { .init = pci_inteli960ni_init, .setup = pci_default_setup, }, + /* + * ITE + */ + { + .vendor = PCI_VENDOR_ID_ITE, + .device = PCI_DEVICE_ID_ITE_8872, + .subvendor = PCI_ANY_ID, + .subdevice = PCI_ANY_ID, + .init = pci_ite887x_init, + .setup = pci_default_setup, + .exit = __devexit_p(pci_ite887x_exit), + }, /* * Panacom */ @@ -933,6 +1077,7 @@ enum pci_board_num_t { pbn_b1_2_1250000, + pbn_b1_bt_1_115200, pbn_b1_bt_2_921600, pbn_b1_1_1382400, @@ -1211,6 +1356,13 @@ static struct pciserial_board pci_boards[] __devinitdata = { .uart_offset = 8, }, + [pbn_b1_bt_1_115200] = { + .flags = FL_BASE1|FL_BASE_BARS, + .num_ports = 1, + .base_baud = 115200, + .uart_offset = 8, + }, + [pbn_b1_bt_2_921600] = { .flags = FL_BASE1|FL_BASE_BARS, .num_ports = 2, @@ -2364,6 +2516,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_TOPIC, PCI_DEVICE_ID_TOPIC_TP560, PCI_ANY_ID, PCI_ANY_ID, 0, 0, pbn_b0_1_115200 }, + /* + * ITE + */ + { PCI_VENDOR_ID_ITE, PCI_DEVICE_ID_ITE_8872, + PCI_ANY_ID, PCI_ANY_ID, + 0, 0, + pbn_b1_bt_1_115200 }, /* * IntaShield IS-200 -- cgit v1.2.3 From 999999616e45c603da45ee2667741fb7348629a5 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Wed, 22 Aug 2007 14:01:15 -0700 Subject: serial_txx9: Fix modem control line handling This chip does not have modem control lines. Return TIOCM_CAR and TIOCM_DSR always on get_mctrl() and ajust some bits in termios cflag. Signed-off-by: Atsushi Nemoto Cc: Ralf Baechle Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/serial_txx9.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c index b8f91e018b21..0930e2a85514 100644 --- a/drivers/serial/serial_txx9.c +++ b/drivers/serial/serial_txx9.c @@ -37,7 +37,7 @@ #include -static char *serial_version = "1.09"; +static char *serial_version = "1.10"; static char *serial_name = "TX39/49 Serial driver"; #define PASS_LIMIT 256 @@ -436,8 +436,10 @@ static unsigned int serial_txx9_get_mctrl(struct uart_port *port) struct uart_txx9_port *up = (struct uart_txx9_port *)port; unsigned int ret; - ret = ((sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS) - | ((sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS); + /* no modem control lines */ + ret = TIOCM_CAR | TIOCM_DSR; + ret |= (sio_in(up, TXX9_SIFLCR) & TXX9_SIFLCR_RTSSC) ? 0 : TIOCM_RTS; + ret |= (sio_in(up, TXX9_SICISR) & TXX9_SICISR_CTSS) ? 0 : TIOCM_CTS; return ret; } @@ -557,6 +559,12 @@ serial_txx9_set_termios(struct uart_port *port, struct ktermios *termios, unsigned long flags; unsigned int baud, quot; + /* + * We don't support modem control lines. + */ + termios->c_cflag &= ~(HUPCL | CMSPAR); + termios->c_cflag |= CLOCAL; + cval = sio_in(up, TXX9_SILCR); /* byte size and parity */ cval &= ~TXX9_SILCR_UMODE_MASK; -- cgit v1.2.3 From ad4c2aa6354fad5316565b1cff57f80db0e04db8 Mon Sep 17 00:00:00 2001 From: Corey Minyard Date: Wed, 22 Aug 2007 14:01:18 -0700 Subject: Serial 8250: handle saving the clear-on-read bits from the LSR and MSR Reading the LSR clears the break, parity, frame error, and overrun bits in the 8250 chip, but these are not being saved in all places that read the LSR. Same goes for the MSR delta bits. Save the LSR bits off whenever the lsr is read so they can be handled later in the receive routine. Save the MSR bits to be handled in the modem status routine. Also, clear the stored bits and clear the interrupt registers before enabling interrupts, to avoid handling old values of the stored bits in the interrupt routines. [akpm@linux-foundation.org: clean up pre-existing code] Signed-off-by: Corey Minyard Cc: Russell King Cc: Yinghai Lu Cc: Bjorn Helgaas Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250.c | 85 ++++++++++++++++++++++++++++++---------------- include/linux/serial_reg.h | 1 + 2 files changed, 57 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c index 301313002f6b..f94109cbb46e 100644 --- a/drivers/serial/8250.c +++ b/drivers/serial/8250.c @@ -129,7 +129,16 @@ struct uart_8250_port { unsigned char mcr; unsigned char mcr_mask; /* mask of user bits */ unsigned char mcr_force; /* mask of forced bits */ - unsigned char lsr_break_flag; + + /* + * Some bits in registers are cleared on a read, so they must + * be saved whenever the register is read but the bits will not + * be immediately processed. + */ +#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS + unsigned char lsr_saved_flags; +#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA + unsigned char msr_saved_flags; /* * We provide a per-port pm hook. @@ -1238,6 +1247,7 @@ static void serial8250_start_tx(struct uart_port *port) if (up->bugs & UART_BUG_TXEN) { unsigned char lsr, iir; lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; iir = serial_in(up, UART_IIR) & 0x0f; if ((up->port.type == PORT_RM9000) ? (lsr & UART_LSR_THRE && @@ -1290,18 +1300,10 @@ receive_chars(struct uart_8250_port *up, unsigned int *status) flag = TTY_NORMAL; up->port.icount.rx++; -#ifdef CONFIG_SERIAL_8250_CONSOLE - /* - * Recover the break flag from console xmit - */ - if (up->port.line == up->port.cons->index) { - lsr |= up->lsr_break_flag; - up->lsr_break_flag = 0; - } -#endif + lsr |= up->lsr_saved_flags; + up->lsr_saved_flags = 0; - if (unlikely(lsr & (UART_LSR_BI | UART_LSR_PE | - UART_LSR_FE | UART_LSR_OE))) { + if (unlikely(lsr & UART_LSR_BRK_ERROR_BITS)) { /* * For statistics only */ @@ -1392,6 +1394,8 @@ static unsigned int check_modem_status(struct uart_8250_port *up) { unsigned int status = serial_in(up, UART_MSR); + status |= up->msr_saved_flags; + up->msr_saved_flags = 0; if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI && up->port.info != NULL) { if (status & UART_MSR_TERI) @@ -1591,7 +1595,8 @@ static void serial8250_timeout(unsigned long data) static void serial8250_backup_timeout(unsigned long data) { struct uart_8250_port *up = (struct uart_8250_port *)data; - unsigned int iir, ier = 0; + unsigned int iir, ier = 0, lsr; + unsigned long flags; /* * Must disable interrupts or else we risk racing with the interrupt @@ -1610,9 +1615,13 @@ static void serial8250_backup_timeout(unsigned long data) * the "Diva" UART used on the management processor on many HP * ia64 and parisc boxes. */ + spin_lock_irqsave(&up->port.lock, flags); + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; + spin_unlock_irqrestore(&up->port.lock, flags); if ((iir & UART_IIR_NO_INT) && (up->ier & UART_IER_THRI) && (!uart_circ_empty(&up->port.info->xmit) || up->port.x_char) && - (serial_in(up, UART_LSR) & UART_LSR_THRE)) { + (lsr & UART_LSR_THRE)) { iir &= ~(UART_IIR_ID | UART_IIR_NO_INT); iir |= UART_IIR_THRI; } @@ -1631,13 +1640,14 @@ static unsigned int serial8250_tx_empty(struct uart_port *port) { struct uart_8250_port *up = (struct uart_8250_port *)port; unsigned long flags; - unsigned int ret; + unsigned int lsr; spin_lock_irqsave(&up->port.lock, flags); - ret = serial_in(up, UART_LSR) & UART_LSR_TEMT ? TIOCSER_TEMT : 0; + lsr = serial_in(up, UART_LSR); + up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS; spin_unlock_irqrestore(&up->port.lock, flags); - return ret; + return lsr & UART_LSR_TEMT ? TIOCSER_TEMT : 0; } static unsigned int serial8250_get_mctrl(struct uart_port *port) @@ -1708,8 +1718,7 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) do { status = serial_in(up, UART_LSR); - if (status & UART_LSR_BI) - up->lsr_break_flag = UART_LSR_BI; + up->lsr_saved_flags |= status & LSR_SAVE_FLAGS; if (--tmout == 0) break; @@ -1718,8 +1727,12 @@ static inline void wait_for_xmitr(struct uart_8250_port *up, int bits) /* Wait up to 1s for flow control if necessary */ if (up->port.flags & UPF_CONS_FLOW) { - tmout = 1000000; - while (!(serial_in(up, UART_MSR) & UART_MSR_CTS) && --tmout) { + unsigned int tmout; + for (tmout = 1000000; tmout; tmout--) { + unsigned int msr = serial_in(up, UART_MSR); + up->msr_saved_flags |= msr & MSR_SAVE_FLAGS; + if (msr & UART_MSR_CTS) + break; udelay(1); touch_nmi_watchdog(); } @@ -1888,6 +1901,18 @@ static int serial8250_startup(struct uart_port *port) spin_unlock_irqrestore(&up->port.lock, flags); + /* + * Clear the interrupt registers again for luck, and clear the + * saved flags to avoid getting false values from polling + * routines or the previous session. + */ + serial_inp(up, UART_LSR); + serial_inp(up, UART_RX); + serial_inp(up, UART_IIR); + serial_inp(up, UART_MSR); + up->lsr_saved_flags = 0; + up->msr_saved_flags = 0; + /* * Finally, enable interrupts. Note: Modem status interrupts * are set via set_termios(), which will be occurring imminently @@ -1906,14 +1931,6 @@ static int serial8250_startup(struct uart_port *port) (void) inb_p(icp); } - /* - * And clear the interrupt registers again for luck. - */ - (void) serial_inp(up, UART_LSR); - (void) serial_inp(up, UART_RX); - (void) serial_inp(up, UART_IIR); - (void) serial_inp(up, UART_MSR); - return 0; } @@ -2484,6 +2501,16 @@ serial8250_console_write(struct console *co, const char *s, unsigned int count) wait_for_xmitr(up, BOTH_EMPTY); serial_out(up, UART_IER, ier); + /* + * The receive handling will happen properly because the + * receive ready bit will still be set; it is not cleared + * on read. However, modem control will not, we must + * call it if we have saved something in the saved flags + * while processing with interrupts off. + */ + if (up->msr_saved_flags) + check_modem_status(up); + if (locked) spin_unlock(&up->port.lock); local_irq_restore(flags); diff --git a/include/linux/serial_reg.h b/include/linux/serial_reg.h index 1c5ed7d92b0f..96c0d93fc2ca 100644 --- a/include/linux/serial_reg.h +++ b/include/linux/serial_reg.h @@ -118,6 +118,7 @@ #define UART_LSR_PE 0x04 /* Parity error indicator */ #define UART_LSR_OE 0x02 /* Overrun error indicator */ #define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ #define UART_MSR 6 /* In: Modem Status Register */ #define UART_MSR_DCD 0x80 /* Data Carrier Detect */ -- cgit v1.2.3 From 436bbd431d41e0fd3bfedb0312ab764b291ddf82 Mon Sep 17 00:00:00 2001 From: Christian Schmidt Date: Wed, 22 Aug 2007 14:01:19 -0700 Subject: Add blacklisting capability to serial_pci to avoid misdetection of serial ports The serial_pci driver tries to guess serial ports on unknown devices based on the PCI class (modem or serial). On certain softmodems (AC'97 modems) this can lead to the recognition of non-existing serial ports. This patch adds a blacklist of PCI IDs that are to be ignored by the driver. [akpm@linux-foundation.org: cleanups] Signed-off-by: Christian Schmidt Cc: Bjorn Helgaas Cc: Russell King Cc: Yinghai Lu Acked-by: Alan Cox Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index fd76542c5977..e3140e5b16cc 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1652,6 +1652,10 @@ static struct pciserial_board pci_boards[] __devinitdata = { }, }; +static const struct pci_device_id softmodem_blacklist[] = { + { PCI_VDEVICE ( AL, 0x5457 ), }, /* ALi Corporation M5457 AC'97 Modem */ +}; + /* * Given a complete unknown PCI device, try to use some heuristics to * guess what the configuration might be, based on the pitiful PCI @@ -1660,6 +1664,7 @@ static struct pciserial_board pci_boards[] __devinitdata = { static int __devinit serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) { + const struct pci_device_id *blacklist; int num_iomem, num_port, first_port = -1, i; /* @@ -1674,6 +1679,18 @@ serial_pci_guess_board(struct pci_dev *dev, struct pciserial_board *board) (dev->class & 0xff) > 6) return -ENODEV; + /* + * Do not access blacklisted devices that are known not to + * feature serial ports. + */ + for (blacklist = softmodem_blacklist; + blacklist < softmodem_blacklist + ARRAY_SIZE(softmodem_blacklist); + blacklist++) { + if (dev->vendor == blacklist->vendor && + dev->device == blacklist->device) + return -ENODEV; + } + num_iomem = num_port = 0; for (i = 0; i < PCI_NUM_BAR_RESOURCES; i++) { if (pci_resource_flags(dev, i) & IORESOURCE_IO) { -- cgit v1.2.3 From afe1ab4d577892822de2c8e803fbfaed6ec44ba3 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 22 Aug 2007 14:01:27 -0700 Subject: correct name for rtc-m41t80 The new rtc-m41t80 driver name doesn't match its module name, which prevents it from properly hotplugging. Since it's new, no platforms yet depend on that name ... so this patch fixes the driver name to match its module name, rather than going the other way around with a MODULE_ALIAS(). NOTE: This sort of bug is a new thing to watch out for with new-style I2C drivers; previously I2C couldn't hotplug. Signed-off-by: David Brownell Acked-by: Atsushi Nemoto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-m41t80.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-m41t80.c b/drivers/rtc/rtc-m41t80.c index 80c4a8463065..1cb33cac1237 100644 --- a/drivers/rtc/rtc-m41t80.c +++ b/drivers/rtc/rtc-m41t80.c @@ -892,7 +892,7 @@ static int m41t80_remove(struct i2c_client *client) static struct i2c_driver m41t80_driver = { .driver = { - .name = "m41t80", + .name = "rtc-m41t80", }, .probe = m41t80_probe, .remove = m41t80_remove, -- cgit v1.2.3 From 0d5e74fc7f44b1cdcd793496877c67a2a7a32a1e Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 22 Aug 2007 14:01:31 -0700 Subject: remove dead code in via-pmu68k When suspend is ever implemented for pmu68k it really should follow the generic pm_ops concept and not mirror the platform-specific /dev/pmu device with ioctls on it. Hence, this patch removes the unused code there; should the implementers need it they can look at via-pmu.c and/or the history of the file. Signed-off-by: Johannes Berg Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/macintosh/via-pmu68k.c | 240 ----------------------------------------- 1 file changed, 240 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/via-pmu68k.c b/drivers/macintosh/via-pmu68k.c index dfdf11c1eec4..e2f84da09e7c 100644 --- a/drivers/macintosh/via-pmu68k.c +++ b/drivers/macintosh/via-pmu68k.c @@ -818,243 +818,3 @@ pmu_present(void) { return (pmu_kind != PMU_UNKNOWN); } - -#if 0 /* needs some work for 68K */ - -/* - * This struct is used to store config register values for - * PCI devices which may get powered off when we sleep. - */ -static struct pci_save { - u16 command; - u16 cache_lat; - u16 intr; -} *pbook_pci_saves; -static int n_pbook_pci_saves; - -static inline void -pbook_pci_save(void) -{ - int npci; - struct pci_dev *pd = NULL; - struct pci_save *ps; - - npci = 0; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) - ++npci; - n_pbook_pci_saves = npci; - if (npci == 0) - return; - ps = kmalloc(npci * sizeof(*ps), GFP_KERNEL); - pbook_pci_saves = ps; - if (ps == NULL) - return; - - pd = NULL; - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - pci_read_config_word(pd, PCI_COMMAND, &ps->command); - pci_read_config_word(pd, PCI_CACHE_LINE_SIZE, &ps->cache_lat); - pci_read_config_word(pd, PCI_INTERRUPT_LINE, &ps->intr); - ++ps; - --npci; - } -} - -static inline void -pbook_pci_restore(void) -{ - u16 cmd; - struct pci_save *ps = pbook_pci_saves; - struct pci_dev *pd = NULL; - int j; - - while ((pd = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pd)) != NULL) { - if (ps->command == 0) - continue; - pci_read_config_word(pd, PCI_COMMAND, &cmd); - if ((ps->command & ~cmd) == 0) - continue; - switch (pd->hdr_type) { - case PCI_HEADER_TYPE_NORMAL: - for (j = 0; j < 6; ++j) - pci_write_config_dword(pd, - PCI_BASE_ADDRESS_0 + j*4, - pd->resource[j].start); - pci_write_config_dword(pd, PCI_ROM_ADDRESS, - pd->resource[PCI_ROM_RESOURCE].start); - pci_write_config_word(pd, PCI_CACHE_LINE_SIZE, - ps->cache_lat); - pci_write_config_word(pd, PCI_INTERRUPT_LINE, - ps->intr); - pci_write_config_word(pd, PCI_COMMAND, ps->command); - break; - /* other header types not restored at present */ - } - } -} - -/* - * Put the powerbook to sleep. - */ -#define IRQ_ENABLE ((unsigned int *)0xf3000024) -#define MEM_CTRL ((unsigned int *)0xf8000070) - -int powerbook_sleep(void) -{ - int ret, i, x; - static int save_backlight; - static unsigned int save_irqen; - unsigned long msr; - unsigned int hid0; - unsigned long p, wait; - struct adb_request sleep_req; - - /* Notify device drivers */ - ret = blocking_notifier_call_chain(&sleep_notifier_list, - PBOOK_SLEEP, NULL); - if (ret & NOTIFY_STOP_MASK) - return -EBUSY; - - /* Sync the disks. */ - /* XXX It would be nice to have some way to ensure that - * nobody is dirtying any new buffers while we wait. */ - sys_sync(); - - /* Turn off the display backlight */ - save_backlight = backlight_enabled; - if (save_backlight) - pmu_enable_backlight(0); - - /* Give the disks a little time to actually finish writing */ - for (wait = jiffies + (HZ/4); time_before(jiffies, wait); ) - mb(); - - /* Disable all interrupts except pmu */ - save_irqen = in_le32(IRQ_ENABLE); - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - disable_irq(i); - asm volatile("mtdec %0" : : "r" (0x7fffffff)); - - /* Save the state of PCI config space for some slots */ - pbook_pci_save(); - - /* Set the memory controller to keep the memory refreshed - while we're asleep */ - for (i = 0x403f; i >= 0x4000; --i) { - out_be32(MEM_CTRL, i); - do { - x = (in_be32(MEM_CTRL) >> 16) & 0x3ff; - } while (x == 0); - if (x >= 0x100) - break; - } - - /* Ask the PMU to put us to sleep */ - pmu_request(&sleep_req, NULL, 5, PMU_SLEEP, 'M', 'A', 'T', 'T'); - while (!sleep_req.complete) - mb(); - /* displacement-flush the L2 cache - necessary? */ - for (p = KERNELBASE; p < KERNELBASE + 0x100000; p += 0x1000) - i = *(volatile int *)p; - asleep = 1; - - /* Put the CPU into sleep mode */ - asm volatile("mfspr %0,1008" : "=r" (hid0) :); - hid0 = (hid0 & ~(HID0_NAP | HID0_DOZE)) | HID0_SLEEP; - asm volatile("mtspr 1008,%0" : : "r" (hid0)); - local_save_flags(msr); - msr |= MSR_POW | MSR_EE; - local_irq_restore(msr); - udelay(10); - - /* OK, we're awake again, start restoring things */ - out_be32(MEM_CTRL, 0x3f); - pbook_pci_restore(); - - /* wait for the PMU interrupt sequence to complete */ - while (asleep) - mb(); - - /* reenable interrupts */ - for (i = 0; i < 32; ++i) - if (i != vias->intrs[0].line && (save_irqen & (1 << i))) - enable_irq(i); - - /* Notify drivers */ - blocking_notifier_call_chain(&sleep_notifier_list, PBOOK_WAKE, NULL); - - /* reenable ADB autopoll */ - pmu_adb_autopoll(adb_dev_map); - - /* Turn on the screen backlight, if it was on before */ - if (save_backlight) - pmu_enable_backlight(1); - - /* Wait for the hard disk to spin up */ - - return 0; -} - -/* - * Support for /dev/pmu device - */ -static int pmu_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t pmu_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static ssize_t pmu_write(struct file *file, const char *buf, - size_t count, loff_t *ppos) -{ - return 0; -} - -static int pmu_ioctl(struct inode * inode, struct file *filp, - u_int cmd, u_long arg) -{ - int error; - __u32 value; - - switch (cmd) { - case PMU_IOC_SLEEP: - return -ENOSYS; - case PMU_IOC_GET_BACKLIGHT: - return put_user(backlight_level, (__u32 *)arg); - case PMU_IOC_SET_BACKLIGHT: - error = get_user(value, (__u32 *)arg); - if (!error) - pmu_set_brightness(value); - return error; - case PMU_IOC_GET_MODEL: - return put_user(pmu_kind, (__u32 *)arg); - } - return -EINVAL; -} - -static const struct file_operations pmu_device_fops = { - .read = pmu_read, - .write = pmu_write, - .ioctl = pmu_ioctl, - .open = pmu_open, -}; - -static struct miscdevice pmu_device = { - PMU_MINOR, "pmu", &pmu_device_fops -}; - -void pmu_device_init(void) -{ - if (!via) - return; - if (misc_register(&pmu_device) < 0) - printk(KERN_ERR "via-pmu68k: cannot register misc device.\n"); -} -#endif /* CONFIG_PMAC_PBOOK */ - -- cgit v1.2.3 From 90638f9975e34aef82e97146012ad9d16ac9e4c2 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:34 -0700 Subject: m68k: Fix a few hickups in drivers/scsi/Kconfig m68k: Fix a few hickups in drivers/scsi/Kconfig Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/scsi/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index d2b3898b750a..a50b9553d5b1 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -1561,7 +1561,7 @@ config A3000_SCSI built-in SCSI controller, say Y. Otherwise, say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a3000. config A2091_SCSI tristate "A2091/A590 WD33C93A support" @@ -1571,7 +1571,7 @@ config A2091_SCSI say N. To compile this driver as a module, choose M here: the - module will be called wd33c93. + module will be called a2091. config GVP11_SCSI tristate "GVP Series II WD33C93A support" -- cgit v1.2.3 From a01086687c5f795a9c2b85d757e3af3cb7bb4f2d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:34 -0700 Subject: zorro: Make sysfs config attribute read-only zorro: Make the sysfs `config' attribute read-only, as you cannot write to it (there's no .write function neither). Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/zorro/zorro-sysfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c index 9130f1c12c26..808b4f8675c5 100644 --- a/drivers/zorro/zorro-sysfs.c +++ b/drivers/zorro/zorro-sysfs.c @@ -78,7 +78,7 @@ static ssize_t zorro_read_config(struct kobject *kobj, static struct bin_attribute zorro_config_attr = { .attr = { .name = "config", - .mode = S_IRUGO | S_IWUSR, + .mode = S_IRUGO, }, .size = sizeof(struct ConfigDev), .read = zorro_read_config, -- cgit v1.2.3 From 2301060e2b19aa4830060524ef66abdf32b26a26 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:35 -0700 Subject: m68k/mac: Make mac_hid_mouse_emulate_buttons() declaration visible m68k/mac: Make mac_hid_mouse_emulate_buttons() declaration visible drivers/char/keyboard.c: In function 'kbd_keycode': drivers/char/keyboard.c:1142: error: implicit declaration of function 'mac_hid_mouse_emulate_buttons' The forward declaration of mac_hid_mouse_emulate_buttons() is not visible on m68k because it's hidden in the middle of a big #ifdef block. Move it to , correct the type of the second parameter, and include where needed. Signed-off-by: Geert Uytterhoeven Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/keyboard.c | 4 ---- drivers/macintosh/mac_hid.c | 1 + include/linux/kbd_kern.h | 3 +++ 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 2ce0af1bd588..d95f316afb5a 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -1022,10 +1022,6 @@ static const unsigned short x86_keycodes[256] = 308,310,313,314,315,317,318,319,320,357,322,323,324,325,276,330, 332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 }; -#ifdef CONFIG_MAC_EMUMOUSEBTN -extern int mac_hid_mouse_emulate_buttons(int, int, int); -#endif /* CONFIG_MAC_EMUMOUSEBTN */ - #ifdef CONFIG_SPARC static int sparc_l1_a_state = 0; extern void sun_do_break(void); diff --git a/drivers/macintosh/mac_hid.c b/drivers/macintosh/mac_hid.c index 76c1e8e4a487..33dee3a773ed 100644 --- a/drivers/macintosh/mac_hid.c +++ b/drivers/macintosh/mac_hid.c @@ -13,6 +13,7 @@ #include #include #include +#include static struct input_dev *emumousebtn; diff --git a/include/linux/kbd_kern.h b/include/linux/kbd_kern.h index 506ad20c18f8..8bdb16bfe5fb 100644 --- a/include/linux/kbd_kern.h +++ b/include/linux/kbd_kern.h @@ -161,4 +161,7 @@ static inline void con_schedule_flip(struct tty_struct *t) schedule_delayed_work(&t->buf.work, 0); } +/* mac_hid.c */ +extern int mac_hid_mouse_emulate_buttons(int, unsigned int, int); + #endif -- cgit v1.2.3 From 928923c76b393e38e5ba1d47e843e208ceef6cf9 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 22 Aug 2007 14:01:36 -0700 Subject: Introduce CONFIG_CHECK_SIGNATURE Introduce CONFIG_CHECK_SIGNATURE to control inclusion of check_signature() and avoid problems on platforms that don't have readb(). Let the few legacy (ISA || PCI || X86) drivers that need check_signature() select CONFIG_CHECK_SIGNATURE. Signed-off-by: Geert Uytterhoeven Cc: Jeff Dike Cc: Heiko Carstens Cc: Roman Zippel Cc: Alan Cox Cc: Martin Schwidefsky Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/block/Kconfig | 1 + drivers/input/misc/Kconfig | 1 + drivers/scsi/Kconfig | 6 ++++++ lib/Kconfig | 3 +++ lib/Makefile | 3 ++- 5 files changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index ef32e977d307..4245b7f80a49 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -68,6 +68,7 @@ config AMIGA_Z2RAM config BLK_DEV_XD tristate "XT hard disk support" depends on ISA && ISA_DMA_API + select CHECK_SIGNATURE help Very old 8 bit hard disk controllers used in the IBM XT computer will be supported if you say Y here. diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 9b26574f1466..d602b8fa7d46 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig @@ -68,6 +68,7 @@ config INPUT_WISTRON_BTNS select INPUT_POLLDEV select NEW_LEDS select LEDS_CLASS + select CHECK_SIGNATURE help Say Y here for support of Winstron laptop button interface, used on laptops of various brands, including Acer and Fujitsu-Siemens. If diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index a50b9553d5b1..6f2c71ef47ee 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -367,6 +367,7 @@ config SCSI_3W_9XXX config SCSI_7000FASST tristate "7000FASST SCSI support" depends on ISA && SCSI && ISA_DMA_API + select CHECK_SIGNATURE help This driver supports the Western Digital 7000 SCSI host adapter family. Some information is in the source: @@ -388,6 +389,7 @@ config SCSI_AHA152X tristate "Adaptec AHA152X/2825 support" depends on ISA && SCSI && !64BIT select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is a driver for the AHA-1510, AHA-1520, AHA-1522, and AHA-2825 SCSI host adapters. It also works for the AVA-1505, but the IRQ etc. @@ -583,6 +585,7 @@ config SCSI_DTC3280 tristate "DTC3180/3280 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE help This is support for DTC 3180/3280 SCSI Host Adapters. Please read the SCSI-HOWTO, available from @@ -657,6 +660,7 @@ config SCSI_EATA_PIO config SCSI_FUTURE_DOMAIN tristate "Future Domain 16xx SCSI/AHA-2920A support" depends on (ISA || PCI) && SCSI + select CHECK_SIGNATURE ---help--- This is support for Future Domain's 16-bit SCSI host adapters (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and @@ -1324,6 +1328,7 @@ config SCSI_LPFC config SCSI_SEAGATE tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support" depends on X86 && ISA && SCSI + select CHECK_SIGNATURE ---help--- These are 8-bit SCSI controllers; the ST-01 is also supported by this driver. It is explained in section 3.9 of the SCSI-HOWTO, @@ -1397,6 +1402,7 @@ config SCSI_T128 tristate "Trantor T128/T128F/T228 SCSI support" depends on ISA && SCSI select SCSI_SPI_ATTRS + select CHECK_SIGNATURE ---help--- This is support for a SCSI host adapter. It is explained in section 3.11 of the SCSI-HOWTO, available from diff --git a/lib/Kconfig b/lib/Kconfig index e5c2c514174a..ba3d104994d9 100644 --- a/lib/Kconfig +++ b/lib/Kconfig @@ -138,4 +138,7 @@ config HAS_DMA depends on !NO_DMA default y +config CHECK_SIGNATURE + bool + endmenu diff --git a/lib/Makefile b/lib/Makefile index d9e5f1cd0bfb..6b0ba8cf4e5f 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -21,7 +21,8 @@ CFLAGS_kobject_uevent.o += -DDEBUG endif obj-$(CONFIG_GENERIC_IOMAP) += iomap.o -obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o check_signature.o +obj-$(CONFIG_HAS_IOMEM) += iomap_copy.o devres.o +obj-$(CONFIG_CHECK_SIGNATURE) += check_signature.o obj-$(CONFIG_DEBUG_LOCKING_API_SELFTESTS) += locking-selftest.o obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock_debug.o lib-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o -- cgit v1.2.3 From 32d219854d31daba3407389ada1d454a4cd86fda Mon Sep 17 00:00:00 2001 From: Mijo Safradin Date: Wed, 22 Aug 2007 14:01:48 -0700 Subject: IPMI: fix warning in ipmi_si_intf.c trivial change: fix warning Signed-off-by: Mijo Safradin Acked-by: Christian Krafft Signed-off-by: Corey Minyard Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/ipmi/ipmi_si_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 96d2f9ee42d6..9b07f7851061 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -2292,7 +2292,7 @@ static int __devinit ipmi_of_probe(struct of_device *dev, info->irq = irq_of_parse_and_map(dev->node, 0); info->dev = &dev->dev; - dev_dbg(&dev->dev, "addr 0x%lx regsize %ld spacing %ld irq %x\n", + dev_dbg(&dev->dev, "addr 0x%lx regsize %d spacing %d irq %x\n", info->io.addr_data, info->io.regsize, info->io.regspacing, info->irq); -- cgit v1.2.3 From d4c63b7c74507c424afcc9c80ba77a55bfb0d07e Mon Sep 17 00:00:00 2001 From: Paul Fulghum Date: Wed, 22 Aug 2007 14:01:50 -0700 Subject: synclink_gt fix module reference Get module reference on open() by generic HDLC to prevent module from unloading while interface is active. Signed-off-by: Paul Fulghum Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/char/synclink_gt.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c index bbb7f1292665..2f97d2f8f916 100644 --- a/drivers/char/synclink_gt.c +++ b/drivers/char/synclink_gt.c @@ -1565,6 +1565,9 @@ static int hdlcdev_open(struct net_device *dev) int rc; unsigned long flags; + if (!try_module_get(THIS_MODULE)) + return -EBUSY; + DBGINFO(("%s hdlcdev_open\n", dev->name)); /* generic HDLC layer open processing */ @@ -1634,6 +1637,7 @@ static int hdlcdev_close(struct net_device *dev) info->netcount=0; spin_unlock_irqrestore(&info->netlock, flags); + module_put(THIS_MODULE); return 0; } -- cgit v1.2.3 From 59d9445e851976d973a5a4009f80a3d55959d231 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Wed, 22 Aug 2007 14:01:51 -0700 Subject: w1: fix w1_remove_master_device() searching In case bus master driver provided bogus value as its private data, search can be incorrect. Problem found by Adrian Bunk. Signed-off-by: Evgeniy Polyakov Cc: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/w1/w1_int.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c index 2fbd8dd16df5..6840dfebe4d4 100644 --- a/drivers/w1/w1_int.c +++ b/drivers/w1/w1_int.c @@ -170,22 +170,24 @@ void __w1_remove_master_device(struct w1_master *dev) void w1_remove_master_device(struct w1_bus_master *bm) { - struct w1_master *dev = NULL; + struct w1_master *dev, *found = NULL; list_for_each_entry(dev, &w1_masters, w1_master_entry) { if (!dev->initialized) continue; - if (dev->bus_master->data == bm->data) + if (dev->bus_master->data == bm->data) { + found = dev; break; + } } - if (!dev) { + if (!found) { printk(KERN_ERR "Device doesn't exist.\n"); return; } - __w1_remove_master_device(dev); + __w1_remove_master_device(found); } EXPORT_SYMBOL(w1_add_master_device); -- cgit v1.2.3 From 918f02383fb9ff5dba29709f3199189eeac55021 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 22 Aug 2007 14:01:52 -0700 Subject: md: make sure a re-add after a restart honours bitmap when resyncing Commit 1757128438d41670ded8bc3bc735325cc07dc8f9 was slightly bad. If an array has a write-intent bitmap, and you remove a drive, then readd it, only the changed parts should be resynced. However after the above commit, this only works if the array has not been shut down and restarted. This is because it sets 'fullsync' at little more often than it should. This patch is more careful. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 650991bddd8e..ea2a58d28871 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -1972,7 +1972,8 @@ static int run(mddev_t *mddev) !test_bit(In_sync, &disk->rdev->flags)) { disk->head_position = 0; mddev->degraded++; - conf->fullsync = 1; + if (disk->rdev) + conf->fullsync = 1; } } if (mddev->degraded == conf->raid_disks) { -- cgit v1.2.3 From a88aa7865bc1d1d451af2d585ac0119164ce8e00 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Wed, 22 Aug 2007 14:01:53 -0700 Subject: md: correctly update sysfs when a raid1 is reshaped When a raid1 array is reshaped (number of drives changed), the list of devices is compacted, so that slots for missing devices are filled with working devices from later slots. This requires the "rd%d" symlinks in sysfs to be updated. Signed-off-by: Neil Brown Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/md/raid1.c | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index ea2a58d28871..f33a729960ca 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c @@ -2154,11 +2154,25 @@ static int raid1_reshape(mddev_t *mddev) oldpool = conf->r1bio_pool; conf->r1bio_pool = newpool; - for (d=d2=0; d < conf->raid_disks; d++) - if (conf->mirrors[d].rdev) { - conf->mirrors[d].rdev->raid_disk = d2; - newmirrors[d2++].rdev = conf->mirrors[d].rdev; + for (d = d2 = 0; d < conf->raid_disks; d++) { + mdk_rdev_t *rdev = conf->mirrors[d].rdev; + if (rdev && rdev->raid_disk != d2) { + char nm[20]; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + rdev->raid_disk = d2; + sprintf(nm, "rd%d", rdev->raid_disk); + sysfs_remove_link(&mddev->kobj, nm); + if (sysfs_create_link(&mddev->kobj, + &rdev->kobj, nm)) + printk(KERN_WARNING + "md/raid1: cannot register " + "%s for %s\n", + nm, mdname(mddev)); } + if (rdev) + newmirrors[d2++].rdev = rdev; + } kfree(conf->mirrors); conf->mirrors = newmirrors; kfree(conf->poolinfo); -- cgit v1.2.3 From aa7985056286f5f912af7bb03f883230cc527701 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Wed, 22 Aug 2007 14:01:55 -0700 Subject: serial: add pci ids for PA Semi PWRficient onchip uarts Add PCI IDs for the onchip UARTs on PA Semi PWRficient. Signed-off-by: Olof Johansson Cc: Russell King Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/serial/8250_pci.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c index e3140e5b16cc..bd66339f7a3f 100644 --- a/drivers/serial/8250_pci.c +++ b/drivers/serial/8250_pci.c @@ -1128,6 +1128,7 @@ enum pci_board_num_t { pbn_exar_XR17C152, pbn_exar_XR17C154, pbn_exar_XR17C158, + pbn_pasemi_1682M, }; /* @@ -1650,6 +1651,14 @@ static struct pciserial_board pci_boards[] __devinitdata = { .base_baud = 921600, .uart_offset = 0x200, }, + /* + * PA Semi PWRficient PA6T-1682M on-chip UART + */ + [pbn_pasemi_1682M] = { + .flags = FL_BASE0, + .num_ports = 1, + .base_baud = 8333333, + }, }; static const struct pci_device_id softmodem_blacklist[] = { @@ -2557,6 +2566,13 @@ static struct pci_device_id serial_pci_tbl[] = { { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 0, 0, pbn_b2_8_921600 }, + /* + * PA Semi PA6T-1682M on-chip UART + */ + { PCI_VENDOR_ID_PASEMI, 0xa004, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, + pbn_pasemi_1682M }, + /* * These entries match devices with class COMMUNICATION_SERIAL, * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL -- cgit v1.2.3 From fe58103a56f05613cb1f0ef228354d4d5f6c2b08 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Wed, 22 Aug 2007 14:01:56 -0700 Subject: cfag12864b fix This one-liner patch fixes a bug in drivers/auxdisplay/cfag12864b.c At cfag12864b_init(), the driver tries to kalloc some memory in the variable cfag12864b_cache. Then, as usual, it checks if the call failed. However, it checks cfag12864b_buffer instead. This patch changes the "cfag12864b_buffer" to "cfag12864b_cache" so the correct variable is checked. Signed-off-by: Miguel Ojeda Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/auxdisplay/cfag12864b.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/auxdisplay/cfag12864b.c b/drivers/auxdisplay/cfag12864b.c index cb44cb4f6a47..80bb06105387 100644 --- a/drivers/auxdisplay/cfag12864b.c +++ b/drivers/auxdisplay/cfag12864b.c @@ -355,7 +355,7 @@ static int __init cfag12864b_init(void) cfag12864b_cache = kmalloc(sizeof(unsigned char) * CFAG12864B_SIZE, GFP_KERNEL); - if (cfag12864b_buffer == NULL) { + if (cfag12864b_cache == NULL) { printk(KERN_ERR CFAG12864B_NAME ": ERROR: " "can't alloc cache buffer (%i bytes)\n", CFAG12864B_SIZE); -- cgit v1.2.3 From 5c076fce2e217240b44bc753a5ec8ecd379c6eb9 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Wed, 22 Aug 2007 14:01:57 -0700 Subject: rtc-max6902 minor fixes Minor tweaks to rtc-max6902: make it hotplug correctly, and fix a few space-before-tab whitespace botches. This driver has no current in-tree users, so the hotplug fix changes the driver name. Signed-off-by: David Brownell Cc: Atsushi Nemoto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/rtc/rtc-max6902.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-max6902.c b/drivers/rtc/rtc-max6902.c index d94170728075..3e183cfee10f 100644 --- a/drivers/rtc/rtc-max6902.c +++ b/drivers/rtc/rtc-max6902.c @@ -13,7 +13,7 @@ * * 24-May-2006: Raphael Assenat * - Major rework - * Converted to rtc_device and uses the SPI layer. + * Converted to rtc_device and uses the SPI layer. * * ??-???-2005: Someone at Compulab * - Initial driver creation. @@ -259,11 +259,11 @@ static int __devexit max6902_remove(struct spi_device *spi) static struct spi_driver max6902_driver = { .driver = { - .name = "max6902", + .name = "rtc-max6902", .bus = &spi_bus_type, .owner = THIS_MODULE, }, - .probe = max6902_probe, + .probe = max6902_probe, .remove = __devexit_p(max6902_remove), }; -- cgit v1.2.3 From de5986dd3a102b8ae34bf08fe6f45b62b57ab2eb Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Wed, 22 Aug 2007 14:02:00 -0700 Subject: Check for PPC32 in imsttfb This is the correct fix according to Paul Mackerras and allows an allyesconfig on PPC64 to build. Signed-off-by: Stephen Rothwell Cc: Paul Mackerras Cc: "Antonino A. Daplas" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/imsttfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c index 5715b8ad0ddc..94f4511023d8 100644 --- a/drivers/video/imsttfb.c +++ b/drivers/video/imsttfb.c @@ -1391,7 +1391,7 @@ init_imstt(struct fb_info *info) } } -#if USE_NV_MODES && defined(CONFIG_PPC) +#if USE_NV_MODES && defined(CONFIG_PPC32) { int vmode = init_vmode, cmode = init_cmode; -- cgit v1.2.3 From 4ae8aeae47e0f014ec453c4b75c9de00bd29e9e6 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Wed, 22 Aug 2007 14:02:01 -0700 Subject: newport_con warning fix drivers/video/console/newport_con.c: In function `newport_console_init': drivers/video/console/newport_con.c:743: warning: return makes integer from pointer without a cast Although one wonders whether that should have been -ENODEV... Cc: "Antonino A. Daplas" Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/console/newport_con.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c index 7fa1afeae8dc..dda0586ab3f3 100644 --- a/drivers/video/console/newport_con.c +++ b/drivers/video/console/newport_con.c @@ -738,9 +738,8 @@ const struct consw newport_con = { #ifdef MODULE static int __init newport_console_init(void) { - if (!sgi_gfxaddr) - return NULL; + return 0; if (!npregs) npregs = (struct newport_regs *)/* ioremap cannot fail */ -- cgit v1.2.3 From 8e92f21ba3ea3f54e4be062b87ef9fc4af2d33e2 Mon Sep 17 00:00:00 2001 From: Yoichi Yuasa Date: Wed, 22 Aug 2007 14:02:03 -0700 Subject: au1100fb: move au1100fb_fb_blank() beforce au1100fb_setmode() au1100fb_fb_blank() should come before au1100fb_setmode(). drivers/video/au1100fb.c: In function 'au1100fb_setmode': drivers/video/au1100fb.c:211: error: implicit declaration of function 'au1100fb_fb_blank' Signed-off-by: Yoichi Yuasa Cc: "Antonino A. Daplas" Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/video/au1100fb.c | 92 ++++++++++++++++++++++++------------------------ 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'drivers') diff --git a/drivers/video/au1100fb.c b/drivers/video/au1100fb.c index 80a81eccad36..832e4613673a 100644 --- a/drivers/video/au1100fb.c +++ b/drivers/video/au1100fb.c @@ -115,6 +115,52 @@ static int nocursor = 0; module_param(nocursor, int, 0644); MODULE_PARM_DESC(nocursor, "cursor enable/disable"); +/* fb_blank + * Blank the screen. Depending on the mode, the screen will be + * activated with the backlight color, or desactivated + */ +static int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) +{ + struct au1100fb_device *fbdev = to_au1100fb_device(fbi); + + print_dbg("fb_blank %d %p", blank_mode, fbi); + + switch (blank_mode) { + + case VESA_NO_BLANKING: + /* Turn on panel */ + fbdev->regs->lcd_control |= LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + + case VESA_VSYNC_SUSPEND: + case VESA_HSYNC_SUSPEND: + case VESA_POWERDOWN: + /* Turn off panel */ + fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; +#ifdef CONFIG_MIPS_PB1100 + if (drv_info.panel_idx == 1) { + au_writew(au_readw(PB1100_G_CONTROL) + & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), + PB1100_G_CONTROL); + } +#endif + au_sync(); + break; + default: + break; + + } + return 0; +} + /* * Set hardware with var settings. This will enable the controller with a specific * mode, normally validated with the fb_check_var method @@ -272,52 +318,6 @@ int au1100fb_fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned return 0; } -/* fb_blank - * Blank the screen. Depending on the mode, the screen will be - * activated with the backlight color, or desactivated - */ -int au1100fb_fb_blank(int blank_mode, struct fb_info *fbi) -{ - struct au1100fb_device *fbdev = to_au1100fb_device(fbi); - - print_dbg("fb_blank %d %p", blank_mode, fbi); - - switch (blank_mode) { - - case VESA_NO_BLANKING: - /* Turn on panel */ - fbdev->regs->lcd_control |= LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - | (PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - - case VESA_VSYNC_SUSPEND: - case VESA_HSYNC_SUSPEND: - case VESA_POWERDOWN: - /* Turn off panel */ - fbdev->regs->lcd_control &= ~LCD_CONTROL_GO; -#ifdef CONFIG_MIPS_PB1100 - if (drv_info.panel_idx == 1) { - au_writew(au_readw(PB1100_G_CONTROL) - & ~(PB1100_G_CONTROL_BL | PB1100_G_CONTROL_VDD), - PB1100_G_CONTROL); - } -#endif - au_sync(); - break; - default: - break; - - } - return 0; -} - /* fb_pan_display * Pan display in x and/or y as specified */ -- cgit v1.2.3 From 733cb1e44047ed88f97754fbfd5173741b6dca1a Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 14:00:47 -0700 Subject: drivers/mmc/core/bus.c: kmalloc + memset conversion to kzalloc drivers/mmc/core/bus.c | 5663 -> 5619 (-44 bytes) drivers/mmc/core/bus.o | 70899 -> 70731 (-168 bytes) Signed-off-by: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: Pierre Ossman --- drivers/mmc/core/bus.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c index fe0e785ed7d2..817a79462b3d 100644 --- a/drivers/mmc/core/bus.c +++ b/drivers/mmc/core/bus.c @@ -186,12 +186,10 @@ struct mmc_card *mmc_alloc_card(struct mmc_host *host) { struct mmc_card *card; - card = kmalloc(sizeof(struct mmc_card), GFP_KERNEL); + card = kzalloc(sizeof(struct mmc_card), GFP_KERNEL); if (!card) return ERR_PTR(-ENOMEM); - memset(card, 0, sizeof(struct mmc_card)); - card->host = host; device_initialize(&card->dev); -- cgit v1.2.3 From be760a9de881d84994403bb93177bcb95319c4cb Mon Sep 17 00:00:00 2001 From: Mariusz Kozlowski Date: Fri, 10 Aug 2007 14:00:50 -0700 Subject: drivers/mmc/core/host.c: kmalloc + memset conversion to kzalloc drivers/mmc/core/host.c | 3509 -> 3457 (-52 bytes) drivers/mmc/core/host.o | 92400 -> 92136 (-264 bytes) Signed-off-by: Mariusz Kozlowski Signed-off-by: Andrew Morton Signed-off-by: Pierre Ossman --- drivers/mmc/core/host.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 6a7e29849603..2c7ce8f43a9a 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c @@ -58,12 +58,10 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) { struct mmc_host *host; - host = kmalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); + host = kzalloc(sizeof(struct mmc_host) + extra, GFP_KERNEL); if (!host) return NULL; - memset(host, 0, sizeof(struct mmc_host) + extra); - host->parent = dev; host->class_dev.parent = dev; host->class_dev.class = &mmc_host_class; -- cgit v1.2.3 From 2b061973404802fb87db93175b856ee0dfbe38e4 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 12 Aug 2007 13:13:24 +0200 Subject: sdhci: be more cautious about block count register The block count register shouldn't be trusted for single block transfers, so avoid using it completely when calculating transferred bytes. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f2bc87ac24f7..7181e867863e 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -477,8 +477,8 @@ static void sdhci_finish_data(struct sdhci_host *host) /* * Controller doesn't count down when in single block mode. */ - if ((data->blocks == 1) && (data->error == MMC_ERR_NONE)) - blocks = 0; + if (data->blocks == 1) + blocks = (data->error == MMC_ERR_NONE) ? 0 : 1; else blocks = readw(host->ioaddr + SDHCI_BLOCK_COUNT); data->bytes_xfered = data->blksz * (data->blocks - blocks); -- cgit v1.2.3 From 03f8590d90844f04d20488a80e75eaf4c4e0b35c Mon Sep 17 00:00:00 2001 From: David Vrabel Date: Fri, 10 Aug 2007 13:25:03 +0100 Subject: mmc: ignore bad max block size in sdhci Some SDHC cards report an invalid maximum block size, in these cases assume they support block sizes up to 512 bytes instead of returning an error. Signed-off-by: David Vrabel Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7181e867863e..2b327b40fa81 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -1347,12 +1347,11 @@ static int __devinit sdhci_probe_slot(struct pci_dev *pdev, int slot) */ mmc->max_blk_size = (caps & SDHCI_MAX_BLOCK_MASK) >> SDHCI_MAX_BLOCK_SHIFT; if (mmc->max_blk_size >= 3) { - printk(KERN_ERR "%s: Invalid maximum block size.\n", + printk(KERN_WARNING "%s: Invalid maximum block size, assuming 512\n", host->slot_descr); - ret = -ENODEV; - goto unmap; - } - mmc->max_blk_size = 512 << mmc->max_blk_size; + mmc->max_blk_size = 512; + } else + mmc->max_blk_size = 512 << mmc->max_blk_size; /* * Maximum block count. -- cgit v1.2.3 From e538fbe83e374a3521128c1f4642aca037661c9d Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 12 Aug 2007 16:46:32 +0200 Subject: sdhci: handle data interrupts during command It is fully legal for a controller to start issuing data related interrupts before it has signalled that the command has completed. Make sure the driver actually can handle this. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 28 +++++++++++++++++++++------- drivers/mmc/host/sdhci.h | 1 + 2 files changed, 22 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 2b327b40fa81..f8fc0a98b8c4 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -385,6 +385,9 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_data *data) BUG_ON(data->blksz > host->mmc->max_blk_size); BUG_ON(data->blocks > 65535); + host->data = data; + host->data_early = 0; + /* timeout in us */ target_timeout = data->timeout_ns / 1000 + data->timeout_clks / host->clock; @@ -443,11 +446,11 @@ static void sdhci_set_transfer_mode(struct sdhci_host *host, { u16 mode; - WARN_ON(host->data); - if (data == NULL) return; + WARN_ON(!host->data); + mode = SDHCI_TRNS_BLK_CNT_EN; if (data->blocks > 1) mode |= SDHCI_TRNS_MULTI; @@ -600,9 +603,10 @@ static void sdhci_finish_command(struct sdhci_host *host) host->cmd->error = MMC_ERR_NONE; - if (host->cmd->data) - host->data = host->cmd->data; - else + if (host->data && host->data_early) + sdhci_finish_data(host); + + if (!host->cmd->data) tasklet_schedule(&host->finish_tasklet); host->cmd = NULL; @@ -991,8 +995,18 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) writel(readl(host->ioaddr + SDHCI_DMA_ADDRESS), host->ioaddr + SDHCI_DMA_ADDRESS); - if (intmask & SDHCI_INT_DATA_END) - sdhci_finish_data(host); + if (intmask & SDHCI_INT_DATA_END) { + if (host->cmd) { + /* + * Data managed to finish before the + * command completed. Make sure we do + * things in the proper order. + */ + host->data_early = 1; + } else { + sdhci_finish_data(host); + } + } } } diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index d157776c1149..e28987d6d2eb 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h @@ -182,6 +182,7 @@ struct sdhci_host { struct mmc_request *mrq; /* Current request */ struct mmc_command *cmd; /* Current command */ struct mmc_data *data; /* Current data request */ + int data_early:1; /* Data finished before cmd */ struct scatterlist *cur_sg; /* We're working on this */ int num_sg; /* Entries left */ -- cgit v1.2.3 From b67ac3f339c76dfea3cc75fc0285b6d13edc35fa Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Sun, 12 Aug 2007 17:29:47 +0200 Subject: sdhci: tell which spurious interrupt we got When we get unexpected interrupts, also print which interrupt it was. Signed-off-by: Pierre Ossman --- drivers/mmc/host/sdhci.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index f8fc0a98b8c4..20a7d89e01ba 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -933,9 +933,9 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask) BUG_ON(intmask == 0); if (!host->cmd) { - printk(KERN_ERR "%s: Got command interrupt even though no " - "command operation was in progress.\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Got command interrupt 0x%08x even " + "though no command operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); sdhci_dumpregs(host); return; } @@ -965,9 +965,9 @@ static void sdhci_data_irq(struct sdhci_host *host, u32 intmask) if (intmask & SDHCI_INT_DATA_END) return; - printk(KERN_ERR "%s: Got data interrupt even though no " - "data operation was in progress.\n", - mmc_hostname(host->mmc)); + printk(KERN_ERR "%s: Got data interrupt 0x%08x even " + "though no data operation was in progress.\n", + mmc_hostname(host->mmc), (unsigned)intmask); sdhci_dumpregs(host); return; -- cgit v1.2.3 From 8270bec40075eec9df8778c1d5da36ef0e535176 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Aug 2007 03:02:22 +0900 Subject: libata: fix n_sectors failure handling during revalidation If revalidation fails because device has different n_sectors after configuration the original n_sectors should be restored before failing revalidation. Without this fix, n_sectors difference will incorrectly and silently pass revalidation when revalidation is retried. Signed-off-by: Tejun Heo Acked-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 99d4fbffb0df..9bfe329fb579 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3705,6 +3705,10 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) "%llu != %llu\n", (unsigned long long)n_sectors, (unsigned long long)dev->n_sectors); + + /* restore original n_sectors */ + dev->n_sectors = n_sectors; + rc = -ENODEV; goto fail; } -- cgit v1.2.3 From 78c4af0b43e152c40d232137f8cb637f2c58826a Mon Sep 17 00:00:00 2001 From: Mikael Pettersson Date: Sat, 18 Aug 2007 22:58:53 +0200 Subject: pata_pdc2027x: PLL detection fixes Previously I reported that the pata_pdc2027x PLL detection changes in kernel 2.6.22 broke the driver on my PowerMac: >pata_pdc2027x: Invalid PLL input clock 1691742kHz, give up! This is followed by a number of errors and speed reduction steps on the affected ports. There are two bugs in pata_pdc2027x's PLL detection code: 1. The PLL counter's start value is read before the chip is put in "test mode". Outside of test mode the counter is halted, and on the PowerMac the counter is zero because the chip hasn't been initialised by its BIOS. The fix is to move the read of the start value to after test mode is started, but before the mdelay() in test mode. This also improves the precision of the PLL detection. 2. The code to compute the number of PLL decrements during the mdelay() in test mode fails to consider that the PLL counter only is 30 bits wide. If there is a wraparound, it will compute an incorrect and much too large value. On the PowerMac, the start count is zero, the end count is a large 30-bit value, so wraparound occurs and an out of bounds PLL clock is detected. The fix is to mask the (start - end) computation to 30 bits. While debugging this I also noticed that pdc_read_counter() reads the two halves of the 30-bit PLL counter as 16-bit values, and then combines them as if the halves only are 15 bits wide. To avoid confusion, the halves should be read as 15-bit values. This patch implements all three changes. It fixes the PLL detection failure on my PowerMac, and doesn't cause any regressions on an x86 with an identical card. Signed-off-by: Mikael Pettersson Signed-off-by: Jeff Garzik --- drivers/ata/pata_pdc2027x.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c index 69a5aa4949f5..e3245b36269a 100644 --- a/drivers/ata/pata_pdc2027x.c +++ b/drivers/ata/pata_pdc2027x.c @@ -563,13 +563,13 @@ static long pdc_read_counter(struct ata_host *host) u32 bccrl, bccrh, bccrlv, bccrhv; retry: - bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff; - bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; + bccrl = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff; + bccrh = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff; rmb(); /* Read the counter values again for verification */ - bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0xffff; - bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0xffff; + bccrlv = readl(mmio_base + PDC_BYTE_COUNT) & 0x7fff; + bccrhv = readl(mmio_base + PDC_BYTE_COUNT + 0x100) & 0x7fff; rmb(); counter = (bccrh << 15) | bccrl; @@ -692,16 +692,16 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) struct timeval start_time, end_time; long pll_clock, usec_elapsed; - /* Read current counter value */ - start_count = pdc_read_counter(host); - do_gettimeofday(&start_time); - /* Start the test mode */ scr = readl(mmio_base + PDC_SYS_CTL); PDPRINTK("scr[%X]\n", scr); writel(scr | (0x01 << 14), mmio_base + PDC_SYS_CTL); readl(mmio_base + PDC_SYS_CTL); /* flush */ + /* Read current counter value */ + start_count = pdc_read_counter(host); + do_gettimeofday(&start_time); + /* Let the counter run for 100 ms. */ mdelay(100); @@ -719,7 +719,7 @@ static long pdc_detect_pll_input_clock(struct ata_host *host) usec_elapsed = (end_time.tv_sec - start_time.tv_sec) * 1000000 + (end_time.tv_usec - start_time.tv_usec); - pll_clock = (start_count - end_count) / 100 * + pll_clock = ((start_count - end_count) & 0x3fffffff) / 100 * (100000000 / usec_elapsed); PDPRINTK("start[%ld] end[%ld] \n", start_count, end_count); -- cgit v1.2.3 From 4f2d47cfddc84969b6934893fc40132750ae3b5e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 22 Aug 2007 22:56:43 +0100 Subject: pata_sis: Add the FSC Amilo and friends More short cables Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- drivers/ata/pata_sis.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c index 66bd0e83ac07..2bd7645f1a88 100644 --- a/drivers/ata/pata_sis.c +++ b/drivers/ata/pata_sis.c @@ -54,6 +54,7 @@ struct sis_laptop { static const struct sis_laptop sis_laptop[] = { /* devid, subvendor, subdev */ { 0x5513, 0x1043, 0x1107 }, /* ASUS A6K */ + { 0x5513, 0x1734, 0x105F }, /* FSC Amilo A1630 */ /* end marker */ { 0, } }; -- cgit v1.2.3 From 9edbdbea003b8be96e2f5d70515227d5fb32ad72 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 22 Aug 2007 22:57:48 +0100 Subject: pata_via: Add Arima W730-K8 and other rebadgings More cable funnies Signed-off-by: Alan Cox Tested-by: Mikael Pettersson Signed-off-by: Jeff Garzik --- drivers/ata/pata_via.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c index f645fe22cd1e..ea18e33f50ef 100644 --- a/drivers/ata/pata_via.c +++ b/drivers/ata/pata_via.c @@ -63,7 +63,7 @@ #include #define DRV_NAME "pata_via" -#define DRV_VERSION "0.3.1" +#define DRV_VERSION "0.3.2" /* * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx @@ -144,6 +144,9 @@ static int via_cable_override(struct pci_dev *pdev) /* Systems by DMI */ if (dmi_check_system(cable_dmi_table)) return 1; + /* Arima W730-K8/Targa Visionary 811/... */ + if (pdev->subsystem_vendor == 0x161F && pdev->subsystem_device == 0x2032) + return 1; return 0; } -- cgit v1.2.3 From b54eebd673861136291b97e409a0f248b96e74ae Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 17 Aug 2007 18:46:51 +0900 Subject: libata: don't check n_sectors during revalidation if zero If the initial configuration fails early, n_sectors is left at zero. Checking against it during revalidation makes retried configuration fail due to n_sectors mismatch. Ignore zero n_sectors during revalidation. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- drivers/ata/libata-core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 9bfe329fb579..2ad4dda6d4a7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -3700,7 +3700,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags) goto fail; /* verify n_sectors hasn't changed */ - if (dev->class == ATA_DEV_ATA && dev->n_sectors != n_sectors) { + if (dev->class == ATA_DEV_ATA && n_sectors && + dev->n_sectors != n_sectors) { ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch " "%llu != %llu\n", (unsigned long long)n_sectors, -- cgit v1.2.3 From 2aa44d0567ed21b47b87d68819415d48194cb923 Mon Sep 17 00:00:00 2001 From: Ingo Molnar Date: Thu, 23 Aug 2007 15:18:02 +0200 Subject: sched: sched_clock_idle_[sleep|wakeup]_event() construct a more or less wall-clock time out of sched_clock(), by using ACPI-idle's existing knowledge about how much time we spent idling. This allows the rq clock to work around TSC-stops-in-C2, TSC-gets-corrupted-in-C3 type of problems. ( Besides the scheduler's statistics this also benefits blktrace and printk-timestamps as well. ) Furthermore, the precise before-C2/C3-sleep and after-C2/C3-wakeup callbacks allow the scheduler to get out the most of the period where the CPU has a reliable TSC. This results in slightly more precise task statistics. the ACPI bits were acked by Len. Signed-off-by: Ingo Molnar Acked-by: Len Brown --- arch/i386/kernel/tsc.c | 1 - drivers/acpi/processor_idle.c | 32 +++++++++++++++++++++++++------- include/linux/sched.h | 3 ++- kernel/sched.c | 41 ++++++++++++++++++++++++++++++++--------- kernel/sched_debug.c | 3 ++- 5 files changed, 61 insertions(+), 19 deletions(-) (limited to 'drivers') diff --git a/arch/i386/kernel/tsc.c b/arch/i386/kernel/tsc.c index debd7dbb4158..a39280b4dd3a 100644 --- a/arch/i386/kernel/tsc.c +++ b/arch/i386/kernel/tsc.c @@ -292,7 +292,6 @@ static struct clocksource clocksource_tsc = { void mark_tsc_unstable(char *reason) { - sched_clock_unstable_event(); if (!tsc_unstable) { tsc_unstable = 1; tsc_enabled = 0; diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index a8634a0655fc..d9b8af763e1e 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -63,6 +63,7 @@ ACPI_MODULE_NAME("processor_idle"); #define ACPI_PROCESSOR_FILE_POWER "power" #define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) +#define PM_TIMER_TICK_NS (1000000000ULL/PM_TIMER_FREQUENCY) #define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ #define C3_OVERHEAD 4 /* 1us (3.579 ticks per us) */ static void (*pm_idle_save) (void) __read_mostly; @@ -462,6 +463,9 @@ static void acpi_processor_idle(void) * TBD: Can't get time duration while in C1, as resumes * go to an ISR rather than here. Need to instrument * base interrupt handler. + * + * Note: the TSC better not stop in C1, sched_clock() will + * skew otherwise. */ sleep_ticks = 0xFFFFFFFF; break; @@ -469,6 +473,8 @@ static void acpi_processor_idle(void) case ACPI_STATE_C2: /* Get start time (ticks) */ t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); /* Invoke C2 */ acpi_state_timer_broadcast(pr, cx, 1); acpi_cstate_enter(cx); @@ -479,17 +485,22 @@ static void acpi_processor_idle(void) /* TSC halts in C2, so notify users */ mark_tsc_unstable("possible TSC halt in C2"); #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + /* Re-enable interrupts */ local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C2_OVERHEAD; + current_thread_info()->status |= TS_POLLING; - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = - ticks_elapsed(t1, t2) - cx->latency_ticks - C2_OVERHEAD; acpi_state_timer_broadcast(pr, cx, 0); break; case ACPI_STATE_C3: - /* * disable bus master * bm_check implies we need ARB_DIS @@ -518,6 +529,8 @@ static void acpi_processor_idle(void) t1 = inl(acpi_gbl_FADT.xpm_timer_block.address); /* Invoke C3 */ acpi_state_timer_broadcast(pr, cx, 1); + /* Tell the scheduler that we are going deep-idle: */ + sched_clock_idle_sleep_event(); acpi_cstate_enter(cx); /* Get end time (ticks) */ t2 = inl(acpi_gbl_FADT.xpm_timer_block.address); @@ -531,12 +544,17 @@ static void acpi_processor_idle(void) /* TSC halts in C3, so notify users */ mark_tsc_unstable("TSC halts in C3"); #endif + /* Compute time (ticks) that we were actually asleep */ + sleep_ticks = ticks_elapsed(t1, t2); + /* Tell the scheduler how much we idled: */ + sched_clock_idle_wakeup_event(sleep_ticks*PM_TIMER_TICK_NS); + /* Re-enable interrupts */ local_irq_enable(); + /* Do not account our idle-switching overhead: */ + sleep_ticks -= cx->latency_ticks + C3_OVERHEAD; + current_thread_info()->status |= TS_POLLING; - /* Compute time (ticks) that we were actually asleep */ - sleep_ticks = - ticks_elapsed(t1, t2) - cx->latency_ticks - C3_OVERHEAD; acpi_state_timer_broadcast(pr, cx, 0); break; diff --git a/include/linux/sched.h b/include/linux/sched.h index 682ef87da6eb..1845b2e99a87 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1388,7 +1388,8 @@ extern void sched_exec(void); #define sched_exec() {} #endif -extern void sched_clock_unstable_event(void); +extern void sched_clock_idle_sleep_event(void); +extern void sched_clock_idle_wakeup_event(u64 delta_ns); #ifdef CONFIG_HOTPLUG_CPU extern void idle_task_exit(void); diff --git a/kernel/sched.c b/kernel/sched.c index 45e17b83b7f1..48e7586168ef 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -262,7 +262,8 @@ struct rq { s64 clock_max_delta; unsigned int clock_warps, clock_overflows; - unsigned int clock_unstable_events; + u64 idle_clock; + unsigned int clock_deep_idle_events; u64 tick_timestamp; atomic_t nr_iowait; @@ -556,18 +557,40 @@ static inline struct rq *this_rq_lock(void) } /* - * CPU frequency is/was unstable - start new by setting prev_clock_raw: + * We are going deep-idle (irqs are disabled): */ -void sched_clock_unstable_event(void) +void sched_clock_idle_sleep_event(void) { - unsigned long flags; - struct rq *rq; + struct rq *rq = cpu_rq(smp_processor_id()); - rq = task_rq_lock(current, &flags); - rq->prev_clock_raw = sched_clock(); - rq->clock_unstable_events++; - task_rq_unlock(rq, &flags); + spin_lock(&rq->lock); + __update_rq_clock(rq); + spin_unlock(&rq->lock); + rq->clock_deep_idle_events++; +} +EXPORT_SYMBOL_GPL(sched_clock_idle_sleep_event); + +/* + * We just idled delta nanoseconds (called with irqs disabled): + */ +void sched_clock_idle_wakeup_event(u64 delta_ns) +{ + struct rq *rq = cpu_rq(smp_processor_id()); + u64 now = sched_clock(); + + rq->idle_clock += delta_ns; + /* + * Override the previous timestamp and ignore all + * sched_clock() deltas that occured while we idled, + * and use the PM-provided delta_ns to advance the + * rq clock: + */ + spin_lock(&rq->lock); + rq->prev_clock_raw = now; + rq->clock += delta_ns; + spin_unlock(&rq->lock); } +EXPORT_SYMBOL_GPL(sched_clock_idle_wakeup_event); /* * resched_task - mark a task 'to be rescheduled now'. diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c index 87e524762b85..ab18f45f2ab2 100644 --- a/kernel/sched_debug.c +++ b/kernel/sched_debug.c @@ -154,10 +154,11 @@ static void print_cpu(struct seq_file *m, int cpu) P(next_balance); P(curr->pid); P(clock); + P(idle_clock); P(prev_clock_raw); P(clock_warps); P(clock_overflows); - P(clock_unstable_events); + P(clock_deep_idle_events); P(clock_max_delta); P(cpu_load[0]); P(cpu_load[1]); -- cgit v1.2.3 From 6175e487e314385e37f06448847e4c46c20edb44 Mon Sep 17 00:00:00 2001 From: Trent Piepho Date: Sun, 19 Aug 2007 05:05:54 -0300 Subject: V4L/DVB (6042): b2c2-flexcop: fix Airstar HD5000 tuning regression Git changeset 6bdcc6e6dbab8daffd05e5026486f34ba41a6c72 dropped the stand-alone lgh06xf module, whose functionality was absorbed into the dvb-pll module. However, there was a minor difference between the code in lgh06xf and dvb-pll, which caused a regression in b2c2-flexcop devices using the LG-H06xF NIM. dvb-pll will probe for the presence of an i2c pll chip by performing a single byte read, the lgh06xf driver did not do this. Unfortunately, the code in flexcop-i2c.c does not currently support 1 byte or 0 byte reads as a probe. Such probes with the current code will always fail. In order to work around this problem, and restore proper functionality of the Airstar HD5000 device, this hack was created to make the probe appear to succeed. The single byte read in dvb_pll_attach is the only place where such a probe would ever occur, so this change is safe, and will not affect any other devices. Of course, if one knew how to actually perform the read operation, it would be better to go that route. In the meantime, however, we must apply this workaround, in order to prevent the regression that causes tuning to fail on the Airstar HD5000 ATSC device. Thanks to Jarod Wilson, who had originally reported this regression, and to Geoffrey Hausheer, whose original workaround patch led us to find the actual cause of the problem. Signed-off-by: Trent Piepho Cc: Geoffrey Hausheer Acked-by: Jarod Wilson Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/b2c2/flexcop-i2c.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'drivers') diff --git a/drivers/media/dvb/b2c2/flexcop-i2c.c b/drivers/media/dvb/b2c2/flexcop-i2c.c index 02a0ea6e1c17..6bf858a436c9 100644 --- a/drivers/media/dvb/b2c2/flexcop-i2c.c +++ b/drivers/media/dvb/b2c2/flexcop-i2c.c @@ -135,6 +135,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs struct flexcop_device *fc = i2c_get_adapdata(i2c_adap); int i, ret = 0; + /* Some drivers use 1 byte or 0 byte reads as probes, which this + * driver doesn't support. These probes will always fail, so this + * hack makes them always succeed. If one knew how, it would of + * course be better to actually do the read. */ + if (num == 1 && msgs[0].flags == I2C_M_RD && msgs[0].len <= 1) + return 1; + if (mutex_lock_interruptible(&fc->i2c_mutex)) return -ERESTARTSYS; -- cgit v1.2.3 From 04b35abef779f5ed1ff5c039dffbbcc5d2c060b6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 20 Aug 2007 16:45:35 -0300 Subject: V4L/DVB (6070): Fix a warning at dvb_net static function dvb_net_sec declares input arg "pkt" as u8. However, the same argument at dvb_net_sec_callback is defined as "const u8". When calling dvb_net_sec, this is casted as just "u8". gcc 4.2.1 generates a warning about that: CC [M] drivers/media/dvb/dvb-core/dvb_net.o drivers/media/dvb/dvb-core/dvb_net.c: In function "dvb_net_sec_callback": drivers/media/dvb/dvb-core/dvb_net.c:905: warning: passing argument 2 of "dvb_net_sec" discards qualifiers from pointer target type Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/dvb-core/dvb_net.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/media/dvb/dvb-core/dvb_net.c b/drivers/media/dvb/dvb-core/dvb_net.c index acf026342ec5..bdd797071cb0 100644 --- a/drivers/media/dvb/dvb-core/dvb_net.c +++ b/drivers/media/dvb/dvb-core/dvb_net.c @@ -800,7 +800,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len, } -static void dvb_net_sec(struct net_device *dev, u8 *pkt, int pkt_len) +static void dvb_net_sec(struct net_device *dev, const u8 *pkt, int +pkt_len) { u8 *eth; struct sk_buff *skb; @@ -902,7 +903,7 @@ static int dvb_net_sec_callback(const u8 *buffer1, size_t buffer1_len, * we rely on the DVB API definition where exactly one complete * section is delivered in buffer1 */ - dvb_net_sec (dev, (u8*) buffer1, buffer1_len); + dvb_net_sec (dev, buffer1, buffer1_len); return 0; } -- cgit v1.2.3 From 962ce8ca0604af0c3c5609f7613d4ec5fcfac623 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Thu, 23 Aug 2007 01:24:31 +0800 Subject: ACPI: don't duplicate input events on netlink The previous events patch added a netlink event for every user of the legacy /proc/acpi/event interface. However, some users of /proc/acpi/event are really input events, and they already report their events via the input layer. Introduce a new interface, acpi_bus_generate_netlink_event(), which is explicitly called by devices that want to repoprt events via netlink. This allows the input-like events to opt-out of generating netlink events. In summary: events that are sent via netlink: ac/battery/sbs thermal processor thinkpad_acpi dock/bay events that are sent via input layer: button video hotkey thinkpad_acpi hotkey asus_acpi/asus-laptop hotkey sonypi/sonylaptop Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/ac.c | 3 +++ drivers/acpi/battery.c | 3 +++ drivers/acpi/bus.c | 4 ---- drivers/acpi/event.c | 13 +++++++++---- drivers/acpi/processor_core.c | 7 +++++++ drivers/acpi/sbs.c | 1 + drivers/acpi/thermal.c | 12 ++++++++++++ drivers/misc/thinkpad_acpi.c | 20 ++++++++++++++------ drivers/pci/hotplug/acpiphp_ibm.c | 3 +++ include/acpi/acpi_bus.h | 3 +-- 10 files changed, 53 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d8b35093527a..b53c2cfcafd3 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -205,6 +205,9 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) case ACPI_NOTIFY_DEVICE_CHECK: acpi_ac_get_state(ac); acpi_bus_generate_event(device, event, (u32) ac->state); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + (u32) ac->state); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index d7b499fe0cd9..9f0bf90afdab 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -869,6 +869,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) acpi_battery_notify_update(battery); acpi_bus_generate_event(device, event, acpi_battery_present(battery)); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + acpi_battery_present(battery)); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index 6b2658c96242..e5084ececb6f 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -292,10 +292,6 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) if (!device) return -EINVAL; - if (acpi_bus_generate_genetlink_event(device, type, data)) - printk(KERN_WARNING PREFIX - "Failed to generate an ACPI event via genetlink!\n"); - /* drop event on the floor if no one's listening */ if (!event_is_open) return 0; diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index 95637a4ff782..b7b143288c22 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -147,7 +147,8 @@ static struct genl_multicast_group acpi_event_mcgrp = { .name = ACPI_GENL_MCAST_GROUP_NAME, }; -int acpi_bus_generate_genetlink_event(struct acpi_device *device, +int acpi_bus_generate_netlink_event(const char *device_class, + const char *bus_id, u8 type, int data) { struct sk_buff *skb; @@ -191,8 +192,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device, memset(event, 0, sizeof(struct acpi_genl_event)); - strcpy(event->device_class, device->pnp.device_class); - strcpy(event->bus_id, device->dev.bus_id); + strcpy(event->device_class, device_class); + strcpy(event->bus_id, bus_id); event->type = type; event->data = data; @@ -211,6 +212,8 @@ int acpi_bus_generate_genetlink_event(struct acpi_device *device, return 0; } +EXPORT_SYMBOL(acpi_bus_generate_netlink_event); + static int acpi_event_genetlink_init(void) { int result; @@ -228,12 +231,14 @@ static int acpi_event_genetlink_init(void) } #else -int acpi_bus_generate_genetlink_event(struct acpi_device *device, u8 type, +int acpi_bus_generate_netlink_event(struct acpi_device *device, u8 type, int data) { return 0; } +EXPORT_SYMBOL(acpi_generate_netlink_event); + static int acpi_event_genetlink_init(void) { return -ENODEV; diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index 498422343f38..dbc2e5d9d6a7 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -700,14 +700,21 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) acpi_processor_ppc_has_changed(pr); acpi_bus_generate_event(device, event, pr->performance_platform_limit); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, + pr->performance_platform_limit); break; case ACPI_PROCESSOR_NOTIFY_POWER: acpi_processor_cst_has_changed(pr); acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; case ACPI_PROCESSOR_NOTIFY_THROTTLING: acpi_processor_tstate_has_changed(pr); acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 82c3a550016d..2d67e92c8ff7 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -445,6 +445,7 @@ static int acpi_sbs_generate_event(struct acpi_device *device, strcpy(acpi_device_bid(device), bid_saved); strcpy(acpi_device_class(device), class_saved); + acpi_bus_generate_netlink_event(class, bid, event, state); return result; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 1e06159fd9c4..291758c9a4d6 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -487,6 +487,10 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) KELVIN_TO_CELSIUS(tz->temperature)); acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); + acpi_bus_generate_netlink_event(tz->device->pnp.device_class, + tz->device->dev.bus_id, + ACPI_THERMAL_NOTIFY_CRITICAL, + tz->trips.critical.flags.enabled); orderly_poweroff(true); @@ -506,6 +510,10 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); + acpi_bus_generate_netlink_event(tz->device->pnp.device_class, + tz->device->dev.bus_id, + ACPI_THERMAL_NOTIFY_HOT, + tz->trips.hot.flags.enabled); /* TBD: Call user-mode "sleep(S4)" function */ @@ -1150,11 +1158,15 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) acpi_thermal_get_trip_points(tz); acpi_thermal_check(tz); acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: if (tz->flags.devices) acpi_thermal_get_devices(tz); acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_netlink_event(device->pnp.device_class, + device->dev.bus_id, event, 0); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index f6cd34a3dbac..d0825a34a7b0 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -2162,22 +2162,27 @@ static void dock_notify(struct ibm_struct *ibm, u32 event) int docked = dock_docked(); int pci = ibm->acpi->hid && ibm->acpi->device && acpi_match_device_ids(ibm->acpi->device, ibm_pci_device_ids); + int data; if (event == 1 && !pci) /* 570 */ - acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ + data = 1; /* button */ else if (event == 1 && pci) /* 570 */ - acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */ + data = 3; /* dock */ else if (event == 3 && docked) - acpi_bus_generate_event(ibm->acpi->device, event, 1); /* button */ + data = 1; /* button */ else if (event == 3 && !docked) - acpi_bus_generate_event(ibm->acpi->device, event, 2); /* undock */ + data = 2; /* undock */ else if (event == 0 && docked) - acpi_bus_generate_event(ibm->acpi->device, event, 3); /* dock */ + data = 3; /* dock */ else { printk(IBM_ERR "unknown dock event %d, status %d\n", event, _sta(dock_handle)); - acpi_bus_generate_event(ibm->acpi->device, event, 0); /* unknown */ + data = 0; /* unknown */ } + acpi_bus_generate_event(ibm->acpi->device, event, data); + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, data); } static int dock_read(char *p) @@ -2276,6 +2281,9 @@ static int __init bay_init(struct ibm_init_struct *iibm) static void bay_notify(struct ibm_struct *ibm, u32 event) { acpi_bus_generate_event(ibm->acpi->device, event, 0); + acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, 0); } #define bay_occupied(b) (_sta(b##_handle) & 1) diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 70db38c0ced9..360902476bad 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -268,6 +268,9 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) if (subevent == 0x80) { dbg("%s: generationg bus event\n", __FUNCTION__); acpi_bus_generate_event(note->device, note->event, detail); + acpi_bus_generate_netlink_event(note->device->pnp.device_class, + note->device->dev.bus_id, + note->event, detail); } else note->event = event; } diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 3d0fea235bf3..8203cddeb4cb 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -321,8 +321,7 @@ struct acpi_bus_event { }; extern struct kset acpi_subsys; -extern int acpi_bus_generate_genetlink_event(struct acpi_device *device, - u8 type, int data); +extern int acpi_bus_generate_netlink_event(const char*, const char*, u8, int); /* * External Functions */ -- cgit v1.2.3 From 14e04fb34ffa82ee61ae69f98d8fca12d2e8e31c Mon Sep 17 00:00:00 2001 From: Len Brown Date: Thu, 23 Aug 2007 15:20:26 -0400 Subject: ACPI: Schedule /proc/acpi/event for removal Schedule /proc/acpi/event for removal in 6 months. Re-name acpi_bus_generate_event() to acpi_bus_generate_proc_event() to make sure there is no confusion that it is for /proc/acpi/event only. Add CONFIG_ACPI_PROC_EVENT to allow removal of /proc/acpi/event. There is no functional change if CONFIG_ACPI_PROC_EVENT=y Signed-off-by: Len Brown --- Documentation/feature-removal-schedule.txt | 8 ++++++++ drivers/acpi/Kconfig | 14 ++++++++++++++ drivers/acpi/ac.c | 2 +- drivers/acpi/asus_acpi.c | 2 +- drivers/acpi/battery.c | 2 +- drivers/acpi/bus.c | 6 ++++-- drivers/acpi/button.c | 2 +- drivers/acpi/event.c | 6 ++++++ drivers/acpi/processor_core.c | 6 +++--- drivers/acpi/sbs.c | 2 +- drivers/acpi/thermal.c | 8 ++++---- drivers/acpi/video.c | 10 +++++----- drivers/char/sonypi.c | 2 +- drivers/misc/asus-laptop.c | 2 +- drivers/misc/sony-laptop.c | 4 ++-- drivers/misc/thinkpad_acpi.c | 8 ++++---- drivers/pci/hotplug/acpiphp_ibm.c | 2 +- include/acpi/acpi_bus.h | 7 ++++++- 18 files changed, 64 insertions(+), 29 deletions(-) (limited to 'drivers') diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index a43d2878a4ef..b9a3fdc1cc5a 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -197,6 +197,14 @@ Who: Len Brown --------------------------- +What: /proc/acpi/event +When: February 2008 +Why: /proc/acpi/event has been replaced by events via the input layer + and netlink since 2.6.23. +Who: Len Brown + +--------------------------- + What: Compaq touchscreen device emulation When: Oct 2007 Files: drivers/input/tsdev.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index f1372de4ce79..574259476fbf 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -68,6 +68,20 @@ config ACPI_PROCFS Say N to delete /proc/acpi/ files that have moved to /sys/ +config ACPI_PROC_EVENT + bool "Deprecated /proc/acpi/event support" + depends on PROC_FS + ---help--- + A user-space daemon, acpi, typically read /proc/acpi/event + and handled all ACPI sub-system generated events. + + These events are now delivered to user-space via + either the input layer, or as netlink events. + + This build option enables the old code for for legacy + user-space implementation. After some time, this will + be moved under CONFIG_ACPI_PROCFS, and then deleted. + config ACPI_AC tristate "AC Adapter" depends on X86 diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index b53c2cfcafd3..26d70702b313 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c @@ -204,7 +204,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data) case ACPI_NOTIFY_BUS_CHECK: case ACPI_NOTIFY_DEVICE_CHECK: acpi_ac_get_state(ac); - acpi_bus_generate_event(device, event, (u32) ac->state); + acpi_bus_generate_proc_event(device, event, (u32) ac->state); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, (u32) ac->state); diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c index 86fd142f4bf3..d915fec9bf63 100644 --- a/drivers/acpi/asus_acpi.c +++ b/drivers/acpi/asus_acpi.c @@ -1069,7 +1069,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) hotk->brightness = (event & ~((u32) BR_DOWN)); } - acpi_bus_generate_event(hotk->device, event, + acpi_bus_generate_proc_event(hotk->device, event, hotk->event_count[event % 128]++); return; diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 9f0bf90afdab..91dc4b316a08 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c @@ -867,7 +867,7 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data) case ACPI_NOTIFY_DEVICE_CHECK: device = battery->device; acpi_battery_notify_update(battery); - acpi_bus_generate_event(device, event, + acpi_bus_generate_proc_event(device, event, acpi_battery_present(battery)); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c index e5084ececb6f..9ba778a2b484 100644 --- a/drivers/acpi/bus.c +++ b/drivers/acpi/bus.c @@ -276,6 +276,7 @@ EXPORT_SYMBOL(acpi_bus_set_power); Event Management -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROC_EVENT static DEFINE_SPINLOCK(acpi_bus_event_lock); LIST_HEAD(acpi_bus_event_list); @@ -283,7 +284,7 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue); extern int event_is_open; -int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) +int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) { struct acpi_bus_event *event = NULL; unsigned long flags = 0; @@ -314,7 +315,7 @@ int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data) return 0; } -EXPORT_SYMBOL(acpi_bus_generate_event); +EXPORT_SYMBOL(acpi_bus_generate_proc_event); int acpi_bus_receive_event(struct acpi_bus_event *event) { @@ -360,6 +361,7 @@ int acpi_bus_receive_event(struct acpi_bus_event *event) } EXPORT_SYMBOL(acpi_bus_receive_event); +#endif /* CONFIG_ACPI_PROC_EVENT */ /* -------------------------------------------------------------------------- Notification Handling diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 540581338ef5..2e79a3395ecf 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -284,7 +284,7 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data) } input_sync(input); - acpi_bus_generate_event(button->device, event, + acpi_bus_generate_proc_event(button->device, event, ++button->pushed); break; default: diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index b7b143288c22..cf6d5161cf31 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -17,6 +17,7 @@ #define _COMPONENT ACPI_SYSTEM_COMPONENT ACPI_MODULE_NAME("event"); +#ifdef CONFIG_ACPI_PROC_EVENT /* Global vars for handling event proc entry */ static DEFINE_SPINLOCK(acpi_system_event_lock); int event_is_open = 0; @@ -106,6 +107,7 @@ static const struct file_operations acpi_system_event_ops = { .release = acpi_system_close_event, .poll = acpi_system_poll_event, }; +#endif /* CONFIG_ACPI_PROC_EVENT */ #ifdef CONFIG_NET static unsigned int acpi_event_seqnum; @@ -247,7 +249,9 @@ static int acpi_event_genetlink_init(void) static int __init acpi_event_init(void) { +#ifdef CONFIG_ACPI_PROC_EVENT struct proc_dir_entry *entry; +#endif int error = 0; if (acpi_disabled) @@ -259,12 +263,14 @@ static int __init acpi_event_init(void) printk(KERN_WARNING PREFIX "Failed to create genetlink family for ACPI event\n"); +#ifdef CONFIG_ACPI_PROC_EVENT /* 'event' [R] */ entry = create_proc_entry("event", S_IRUSR, acpi_root_dir); if (entry) entry->proc_fops = &acpi_system_event_ops; else return -ENODEV; +#endif return 0; } diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c index dbc2e5d9d6a7..e944aaee4e06 100644 --- a/drivers/acpi/processor_core.c +++ b/drivers/acpi/processor_core.c @@ -698,7 +698,7 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_PROCESSOR_NOTIFY_PERFORMANCE: acpi_processor_ppc_has_changed(pr); - acpi_bus_generate_event(device, event, + acpi_bus_generate_proc_event(device, event, pr->performance_platform_limit); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, @@ -706,13 +706,13 @@ static void acpi_processor_notify(acpi_handle handle, u32 event, void *data) break; case ACPI_PROCESSOR_NOTIFY_POWER: acpi_processor_cst_has_changed(pr); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, 0); break; case ACPI_PROCESSOR_NOTIFY_THROTTLING: acpi_processor_tstate_has_changed(pr); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, 0); default: diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index 2d67e92c8ff7..a578986e3214 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c @@ -440,7 +440,7 @@ static int acpi_sbs_generate_event(struct acpi_device *device, strcpy(acpi_device_bid(device), bid); strcpy(acpi_device_class(device), class); - result = acpi_bus_generate_event(device, event, state); + result = acpi_bus_generate_proc_event(device, event, state); strcpy(acpi_device_bid(device), bid_saved); strcpy(acpi_device_class(device), class_saved); diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 291758c9a4d6..2c9cfe297f73 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -485,7 +485,7 @@ static int acpi_thermal_critical(struct acpi_thermal *tz) printk(KERN_EMERG "Critical temperature reached (%ld C), shutting down.\n", KELVIN_TO_CELSIUS(tz->temperature)); - acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, + acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_CRITICAL, tz->trips.critical.flags.enabled); acpi_bus_generate_netlink_event(tz->device->pnp.device_class, tz->device->dev.bus_id, @@ -508,7 +508,7 @@ static int acpi_thermal_hot(struct acpi_thermal *tz) } else if (tz->trips.hot.flags.enabled) tz->trips.hot.flags.enabled = 0; - acpi_bus_generate_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, + acpi_bus_generate_proc_event(tz->device, ACPI_THERMAL_NOTIFY_HOT, tz->trips.hot.flags.enabled); acpi_bus_generate_netlink_event(tz->device->pnp.device_class, tz->device->dev.bus_id, @@ -1157,14 +1157,14 @@ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) case ACPI_THERMAL_NOTIFY_THRESHOLDS: acpi_thermal_get_trip_points(tz); acpi_thermal_check(tz); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, 0); break; case ACPI_THERMAL_NOTIFY_DEVICES: if (tz->flags.devices) acpi_thermal_get_devices(tz); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); acpi_bus_generate_netlink_event(device->pnp.device_class, device->dev.bus_id, event, 0); break; diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d98701941981..9a5cfcfd8da5 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1775,7 +1775,7 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, * most likely via hotkey. */ - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); break; case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video @@ -1783,14 +1783,14 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) acpi_video_device_enumerate(video); acpi_video_device_rebind(video); acpi_video_switch_output(video, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); break; case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ acpi_video_switch_output(video, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); break; default: @@ -1815,7 +1815,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); break; case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ @@ -1823,7 +1823,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ acpi_video_switch_brightness(video_device, event); - acpi_bus_generate_event(device, event, 0); + acpi_bus_generate_proc_event(device, event, 0); break; default: ACPI_DEBUG_PRINT((ACPI_DB_INFO, diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index aeec67e27264..859858561ab6 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -875,7 +875,7 @@ found: #ifdef CONFIG_ACPI if (sonypi_acpi_device) - acpi_bus_generate_event(sonypi_acpi_device, 1, event); + acpi_bus_generate_proc_event(sonypi_acpi_device, 1, event); #endif kfifo_put(sonypi_device.fifo, (unsigned char *)&event, sizeof(event)); diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index d0fc4fd212e6..f8ae58f01637 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c @@ -732,7 +732,7 @@ static void asus_hotk_notify(acpi_handle handle, u32 event, void *data) lcd_blank(FB_BLANK_POWERDOWN); } - acpi_bus_generate_event(hotk->device, event, + acpi_bus_generate_proc_event(hotk->device, event, hotk->event_count[event % 128]++); return; diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 91da6880ae93..743bd49ae6f5 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -904,7 +904,7 @@ static void sony_acpi_notify(acpi_handle handle, u32 event, void *data) dprintk("sony_acpi_notify, event: 0x%.2x\n", ev); sony_laptop_report_input_event(ev); - acpi_bus_generate_event(sony_nc_acpi_device, 1, ev); + acpi_bus_generate_proc_event(sony_nc_acpi_device, 1, ev); } static acpi_status sony_walk_callback(acpi_handle handle, u32 level, @@ -2292,7 +2292,7 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id) found: sony_laptop_report_input_event(device_event); - acpi_bus_generate_event(spic_dev.acpi_dev, 1, device_event); + acpi_bus_generate_proc_event(spic_dev.acpi_dev, 1, device_event); sonypi_compat_report_event(device_event); return IRQ_HANDLED; diff --git a/drivers/misc/thinkpad_acpi.c b/drivers/misc/thinkpad_acpi.c index d0825a34a7b0..bb8956d0c104 100644 --- a/drivers/misc/thinkpad_acpi.c +++ b/drivers/misc/thinkpad_acpi.c @@ -1190,10 +1190,10 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } if (sendacpi) - acpi_bus_generate_event(ibm->acpi->device, event, hkey); + acpi_bus_generate_proc_event(ibm->acpi->device, event, hkey); } else { printk(IBM_ERR "unknown hotkey notification event %d\n", event); - acpi_bus_generate_event(ibm->acpi->device, event, 0); + acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); } } @@ -2179,7 +2179,7 @@ static void dock_notify(struct ibm_struct *ibm, u32 event) event, _sta(dock_handle)); data = 0; /* unknown */ } - acpi_bus_generate_event(ibm->acpi->device, event, data); + acpi_bus_generate_proc_event(ibm->acpi->device, event, data); acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, ibm->acpi->device->dev.bus_id, event, data); @@ -2280,7 +2280,7 @@ static int __init bay_init(struct ibm_init_struct *iibm) static void bay_notify(struct ibm_struct *ibm, u32 event) { - acpi_bus_generate_event(ibm->acpi->device, event, 0); + acpi_bus_generate_proc_event(ibm->acpi->device, event, 0); acpi_bus_generate_netlink_event(ibm->acpi->device->pnp.device_class, ibm->acpi->device->dev.bus_id, event, 0); diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 360902476bad..d2c410cd3c45 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -267,7 +267,7 @@ static void ibm_handle_events(acpi_handle handle, u32 event, void *context) if (subevent == 0x80) { dbg("%s: generationg bus event\n", __FUNCTION__); - acpi_bus_generate_event(note->device, note->event, detail); + acpi_bus_generate_proc_event(note->device, note->event, detail); acpi_bus_generate_netlink_event(note->device->pnp.device_class, note->device->dev.bus_id, note->event, detail); diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 8203cddeb4cb..86aea44ce6d4 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h @@ -331,8 +331,13 @@ void acpi_bus_data_handler(acpi_handle handle, u32 function, void *context); int acpi_bus_get_status(struct acpi_device *device); int acpi_bus_get_power(acpi_handle handle, int *state); int acpi_bus_set_power(acpi_handle handle, int state); -int acpi_bus_generate_event(struct acpi_device *device, u8 type, int data); +#ifdef CONFIG_ACPI_PROC_EVENT +int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data); int acpi_bus_receive_event(struct acpi_bus_event *event); +#else +static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) + { return 0; } +#endif int acpi_bus_register_driver(struct acpi_driver *driver); void acpi_bus_unregister_driver(struct acpi_driver *driver); int acpi_bus_add(struct acpi_device **child, struct acpi_device *parent, -- cgit v1.2.3 From a1eb96a2f635cdb8f626f4074dae2ba5a6fce1e8 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 20 Aug 2007 18:23:51 +0800 Subject: ACPI video hotkey: remove invalid events handler for video output devices Both ACPI_VIDEO_NOTIFY_SWITCH and ACPI_VIDEO_NOTIFY_PROBE are valid for video bus devices only. Actually ACPI video output device should never be notified for a output device switch/probe. ACPI bus devices notify handler already has the code to handle these kinds of events. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d98701941981..8efdea587ae3 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1813,10 +1813,6 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) device = video_device->dev; switch (event) { - case ACPI_VIDEO_NOTIFY_SWITCH: /* change in status (cycle output device) */ - case ACPI_VIDEO_NOTIFY_PROBE: /* change in status (output device status) */ - acpi_bus_generate_event(device, event, 0); - break; case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ -- cgit v1.2.3 From deec5950479b72eff3130dc6f956a87466ed41c6 Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Fri, 24 Aug 2007 00:03:47 +0400 Subject: lguest should depend on CONFIG_FUTEX It uses get_futex_key(). Signed-off-by: Alexey Dobriyan Signed-off-by: Rusty Russell Signed-off-by: Linus Torvalds --- drivers/lguest/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/lguest/Kconfig b/drivers/lguest/Kconfig index fd6925f41647..41e2250613a1 100644 --- a/drivers/lguest/Kconfig +++ b/drivers/lguest/Kconfig @@ -1,6 +1,6 @@ config LGUEST tristate "Linux hypervisor example code" - depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE + depends on X86 && PARAVIRT && EXPERIMENTAL && !X86_PAE && FUTEX select LGUEST_GUEST select HVC_DRIVER ---help--- -- cgit v1.2.3 From f9319f903f898dd4b15dbc386499725ce6c59776 Mon Sep 17 00:00:00 2001 From: Alexey Starikovskiy Date: Fri, 24 Aug 2007 08:10:11 +0400 Subject: ACPI: EC: revert fix for bugzilla 8709 This is a manual revert of 7c010de7506954e973abfab5c5999c5a97f7a73e, a fix that broke another ASUS in 8909 and 8919. Signed-off-by: Alexey Starikovskiy Signed-off-by: Len Brown --- drivers/acpi/ec.c | 47 +++++++++++++++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 56bee9e065cf..43749c86861f 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c @@ -696,14 +696,6 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) return AE_CTRL_TERMINATE; } -static void ec_remove_handlers(struct acpi_ec *ec) -{ - acpi_remove_address_space_handler(ec->handle, - ACPI_ADR_SPACE_EC, - &acpi_ec_space_handler); - acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); -} - static int acpi_ec_add(struct acpi_device *device) { struct acpi_ec *ec = NULL; @@ -727,13 +719,16 @@ static int acpi_ec_add(struct acpi_device *device) /* Check if we found the boot EC */ if (boot_ec) { if (boot_ec->gpe == ec->gpe) { - ec_remove_handlers(boot_ec); - mutex_destroy(&boot_ec->lock); - kfree(boot_ec); - first_ec = boot_ec = NULL; + /* We might have incorrect info for GL at boot time */ + mutex_lock(&boot_ec->lock); + boot_ec->global_lock = ec->global_lock; + /* Copy handlers from new ec into boot ec */ + list_splice(&ec->list, &boot_ec->list); + mutex_unlock(&boot_ec->lock); + kfree(ec); + ec = boot_ec; } - } - if (!first_ec) + } else first_ec = ec; ec->handle = device->handle; acpi_driver_data(device) = ec; @@ -762,6 +757,9 @@ static int acpi_ec_remove(struct acpi_device *device, int type) if (ec == first_ec) first_ec = NULL; + /* Don't touch boot EC */ + if (boot_ec != ec) + kfree(ec); return 0; } @@ -825,7 +823,9 @@ static int acpi_ec_start(struct acpi_device *device) if (!ec) return -EINVAL; - ret = ec_install_handlers(ec); + /* Boot EC is already working */ + if (ec != boot_ec) + ret = ec_install_handlers(ec); /* EC is fully operational, allow queries */ atomic_set(&ec->query_pending, 0); @@ -835,6 +835,7 @@ static int acpi_ec_start(struct acpi_device *device) static int acpi_ec_stop(struct acpi_device *device, int type) { + acpi_status status; struct acpi_ec *ec; if (!device) @@ -843,7 +844,21 @@ static int acpi_ec_stop(struct acpi_device *device, int type) ec = acpi_driver_data(device); if (!ec) return -EINVAL; - ec_remove_handlers(ec); + + /* Don't touch boot EC */ + if (ec == boot_ec) + return 0; + + status = acpi_remove_address_space_handler(ec->handle, + ACPI_ADR_SPACE_EC, + &acpi_ec_space_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + + status = acpi_remove_gpe_handler(NULL, ec->gpe, &acpi_ec_gpe_handler); + if (ACPI_FAILURE(status)) + return -ENODEV; + return 0; } -- cgit v1.2.3 From 604de6e0ee3517d7f66427c8fc782761e057f025 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 23 Aug 2007 20:18:55 +0100 Subject: pata_it821x: Fix regression/corruptor Whoever did the PCI revision patch slipped up on the it821x, and I didn't spot this at the time either. They moved the check for the errata from the 0x10 revision to 0x11. Put it back This one is important for 2.6.23 final as in some cases bad things will occur if 0x10 revision boards don't get the fixups. Signed-off-by: Alan Cox Signed-off-by: Linus Torvalds --- drivers/ata/pata_it821x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index 430673be1df7..7225124d96c2 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c @@ -587,7 +587,7 @@ static int it821x_port_start(struct ata_port *ap) itdev->want[1][1] = ATA_ANY; itdev->last_device = -1; - if (pdev->revision == 0x11) { + if (pdev->revision == 0x10) { itdev->timing10 = 1; /* Need to disable ATAPI DMA for this case */ if (!itdev->smart) -- cgit v1.2.3 From abcb1ff326bfe74f3611d7de653276540ea060dd Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Aug 2007 02:28:42 +0200 Subject: tty: dont needlessly cast kmalloc() return value kmalloc() hands us a void pointer, we don't need to cast it. Signed-off-by: Jesper Juhl Signed-off-by: Linus Torvalds --- drivers/char/tty_io.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 51ea93cab6c4..9c867cf6de64 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c @@ -2063,8 +2063,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*tp_loc) { - tp = (struct ktermios *) kmalloc(sizeof(struct ktermios), - GFP_KERNEL); + tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!tp) goto free_mem_out; *tp = driver->init_termios; @@ -2094,8 +2093,7 @@ static int init_dev(struct tty_driver *driver, int idx, } if (!*o_tp_loc) { - o_tp = (struct ktermios *) - kmalloc(sizeof(struct ktermios), GFP_KERNEL); + o_tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL); if (!o_tp) goto free_mem_out; *o_tp = driver->other->init_termios; -- cgit v1.2.3 From f46d1604ed84e5a4107bae1db7283e3a76d72ace Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sun, 12 Aug 2007 16:20:26 +0900 Subject: sony-laptop: enable Vaio FZ events Signed-off-by: Mattia Dongili Signed-off-by: Len Brown --- drivers/misc/sony-laptop.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 91da6880ae93..7707cc25f3a2 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -855,6 +855,15 @@ static struct dmi_system_id sony_nc_ids[] = { DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FE"), }, }, + { + .ident = "Sony Vaio FZ Series", + .callback = sony_nc_C_enable, + .driver_data = sony_C_events, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), + DMI_MATCH(DMI_PRODUCT_NAME, "VGN-FZ"), + }, + }, { .ident = "Sony Vaio C Series", .callback = sony_nc_C_enable, -- cgit v1.2.3 From 015a916fbbf105bb15f4bbfd80c3b9b2f2e0d7db Mon Sep 17 00:00:00 2001 From: Mattia Dongili Date: Sun, 12 Aug 2007 16:20:27 +0900 Subject: sony-laptop: call sonypi_compat_init earlier sonypi_compat uses a kfifo that needs to be present before _SRS is called to be able to cope with the IRQs triggered when setting resources. Signed-off-by: Mattia Dongili Signed-off-by: Len Brown --- drivers/misc/sony-laptop.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c index 7707cc25f3a2..7d8bebec2961 100644 --- a/drivers/misc/sony-laptop.c +++ b/drivers/misc/sony-laptop.c @@ -2317,8 +2317,6 @@ static int sony_pic_remove(struct acpi_device *device, int type) struct sony_pic_ioport *io, *tmp_io; struct sony_pic_irq *irq, *tmp_irq; - sonypi_compat_exit(); - if (sony_pic_disable(device)) { printk(KERN_ERR DRV_PFX "Couldn't disable device.\n"); return -ENXIO; @@ -2328,6 +2326,8 @@ static int sony_pic_remove(struct acpi_device *device, int type) release_region(spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); + sonypi_compat_exit(); + sony_laptop_remove_input(); /* pf attrs */ @@ -2393,6 +2393,9 @@ static int sony_pic_add(struct acpi_device *device) goto err_free_resources; } + if (sonypi_compat_init()) + goto err_remove_input; + /* request io port */ list_for_each_entry(io, &spic_dev.ioports, list) { if (request_region(io->io.minimum, io->io.address_length, @@ -2407,7 +2410,7 @@ static int sony_pic_add(struct acpi_device *device) if (!spic_dev.cur_ioport) { printk(KERN_ERR DRV_PFX "Failed to request_region.\n"); result = -ENODEV; - goto err_remove_input; + goto err_remove_compat; } /* request IRQ */ @@ -2447,9 +2450,6 @@ static int sony_pic_add(struct acpi_device *device) if (result) goto err_remove_pf; - if (sonypi_compat_init()) - goto err_remove_pf; - return 0; err_remove_pf: @@ -2465,6 +2465,9 @@ err_release_region: release_region(spic_dev.cur_ioport->io.minimum, spic_dev.cur_ioport->io.address_length); +err_remove_compat: + sonypi_compat_exit(); + err_remove_input: sony_laptop_remove_input(); -- cgit v1.2.3 From e1996a69e162b1c99c3d3802684d1c388b54f47d Mon Sep 17 00:00:00 2001 From: Guillaume Chazarain Date: Thu, 16 Aug 2007 18:18:53 +0200 Subject: asus-laptop: Fix rmmod of asus_laptop The asus laptop driver conditionnaly registers leds in asus_led_register() depending on their availability, but unconditionnaly unregisters them all at exit time or when the module fails to load. Unregistering not registered leds result in the following Oops. So we should check before unregistering. [] do_page_fault+0x511/0x5e9 [] error_code+0x6a/0x70 [] device_unregister+0x26/0x32 [] led_classdev_unregister+0x58/0x94 [led_class] [] asus_led_exit+0x17/0x41 [asus_laptop] [] asus_laptop_exit+0xd/0x3f [asus_laptop] [] sys_delete_module+0x17b/0x1a2 [] sysenter_past_esp+0x6b/0xa1 EIP: [] device_del+0xb/0x23a SS:ESP 0068:f594ef0c Signed-off-by: Guillaume Chazarain Signed-off-by: Len Brown --- drivers/misc/asus-laptop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c index d0fc4fd212e6..40db9f70148f 100644 --- a/drivers/misc/asus-laptop.c +++ b/drivers/misc/asus-laptop.c @@ -1072,7 +1072,8 @@ static void asus_backlight_exit(void) } #define ASUS_LED_UNREGISTER(object) \ - led_classdev_unregister(&object##_led) + if (object##_led.dev) \ + led_classdev_unregister(&object##_led) static void asus_led_exit(void) { -- cgit v1.2.3 From 79d2dfaa4e787f94b7f65f4611bc7d1c8d85fabc Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 24 Aug 2007 01:24:47 -0400 Subject: ACPI: enable GPEs before calling _WAK on resume It seems it's required to enable GPEs before _WAK. E.g. X60 triggers a LID related GPE instead of doing a Notify in WAK. Now the GPE reaches the kernel and the Notify for LID status change gets thrown from there. Signed-off-by: Thomas Renninger Acked-by: Rafael J. Wysocki Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/hardware/hwsleep.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c index 76c525dc590b..cf69c0040a39 100644 --- a/drivers/acpi/hardware/hwsleep.c +++ b/drivers/acpi/hardware/hwsleep.c @@ -576,13 +576,10 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) ACPI_EXCEPTION((AE_INFO, status, "During Method _BFS")); } - status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); - if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { - ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); - } - /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ - /* + * GPEs must be enabled before _WAK is called as GPEs + * might get fired there + * * Restore the GPEs: * 1) Disable/Clear all GPEs * 2) Enable all runtime GPEs @@ -591,13 +588,19 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } - acpi_gbl_system_awake_and_running = TRUE; - status = acpi_hw_enable_all_runtime_gpes(); if (ACPI_FAILURE(status)) { return_ACPI_STATUS(status); } + status = acpi_evaluate_object(NULL, METHOD_NAME__WAK, &arg_list, NULL); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + ACPI_EXCEPTION((AE_INFO, status, "During Method _WAK")); + } + /* TBD: _WAK "sometimes" returns stuff - do we want to look at it? */ + + acpi_gbl_system_awake_and_running = TRUE; + /* Enable power button */ (void) -- cgit v1.2.3 From 1e0aa9ad721349781b728ec4226876247e3fd431 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:08 -0600 Subject: PNP: fix up after Lindent More manual fixups after Lindent. No functional change. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/card.c | 16 ++++++++-------- drivers/pnp/driver.c | 2 +- drivers/pnp/interface.c | 9 +++++---- drivers/pnp/isapnp/core.c | 15 ++++++--------- drivers/pnp/manager.c | 4 ++-- drivers/pnp/pnpacpi/core.c | 4 ++-- drivers/pnp/pnpacpi/rsparser.c | 1 + drivers/pnp/pnpbios/core.c | 1 + drivers/pnp/pnpbios/proc.c | 2 +- drivers/pnp/pnpbios/rsparser.c | 9 +++++---- 10 files changed, 32 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/card.c b/drivers/pnp/card.c index b6a4f02b01d1..6c0440c20e31 100644 --- a/drivers/pnp/card.c +++ b/drivers/pnp/card.c @@ -25,13 +25,13 @@ static const struct pnp_card_device_id *match_card(struct pnp_card_driver *drv, int found; struct pnp_dev *dev; - if (i == PNP_MAX_DEVICES - || !*drv_id->devs[i].id) + if (i == PNP_MAX_DEVICES || + !*drv_id->devs[i].id) return drv_id; found = 0; card_for_each_dev(card, dev) { - if (compare_pnp_id - (dev->id, drv_id->devs[i].id)) { + if (compare_pnp_id(dev->id, + drv_id->devs[i].id)) { found = 1; break; } @@ -183,7 +183,7 @@ static int pnp_interface_attach_card(struct pnp_card *card) return 0; - err_name: +err_name: device_remove_file(&card->dev, &dev_attr_name); return rc; } @@ -321,10 +321,10 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, pos = pos->next; } - done: +done: return NULL; - found: +found: dev->card_link = clink; dev->dev.driver = &drv->link.driver; if (pnp_bus_type.probe(&dev->dev)) @@ -334,7 +334,7 @@ struct pnp_dev *pnp_request_card_device(struct pnp_card_link *clink, return dev; - err_out: +err_out: dev->dev.driver = NULL; dev->card_link = NULL; return NULL; diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 30b8f6f3258a..9be01b0433b9 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -118,7 +118,7 @@ static int pnp_device_probe(struct device *dev) goto fail; return error; - fail: +fail: pnp_device_detach(pnp_dev); return error; } diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c index fe6684e13e82..a0cfb75bbb8d 100644 --- a/drivers/pnp/interface.c +++ b/drivers/pnp/interface.c @@ -459,7 +459,8 @@ pnp_set_current_resources(struct device *dmdev, struct device_attribute *attr, up(&pnp_res_mutex); goto done; } - done: + +done: if (retval < 0) return retval; return count; @@ -499,10 +500,10 @@ int pnp_interface_attach_device(struct pnp_dev *dev) return 0; - err_res: +err_res: device_remove_file(&dev->dev, &dev_attr_resources); - err_opt: +err_opt: device_remove_file(&dev->dev, &dev_attr_options); - err: +err: return rc; } diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index b4e2aa995b53..32386ce60478 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -335,7 +335,7 @@ static int __init isapnp_isolate(void) } else if (iteration > 1) { break; } - __next: +__next: if (csn == 255) break; checksum = 0x6a; @@ -733,7 +733,7 @@ static int __init isapnp_create_device(struct pnp_card *card, "isapnp: unexpected or unknown tag type 0x%x for logical device %i (device %i), ignored\n", type, dev->number, card->number); } - __skip: +__skip: if (size > 0) isapnp_skip_bytes(size); } @@ -788,7 +788,7 @@ static void __init isapnp_parse_resource_map(struct pnp_card *card) "isapnp: unexpected or unknown tag type 0x%x for device %i, ignored\n", type, card->number); } - __skip: +__skip: if (size > 0) isapnp_skip_bytes(size); } @@ -940,9 +940,6 @@ EXPORT_SYMBOL(isapnp_protocol); EXPORT_SYMBOL(isapnp_present); EXPORT_SYMBOL(isapnp_cfg_begin); EXPORT_SYMBOL(isapnp_cfg_end); -#if 0 -EXPORT_SYMBOL(isapnp_read_byte); -#endif EXPORT_SYMBOL(isapnp_write_byte); static int isapnp_read_resources(struct pnp_dev *dev, @@ -993,6 +990,7 @@ static int isapnp_get_resources(struct pnp_dev *dev, struct pnp_resource_table *res) { int ret; + pnp_init_resource_table(res); isapnp_cfg_begin(dev->card->number, dev->number); ret = isapnp_read_resources(dev, res); @@ -1148,13 +1146,12 @@ static int __init isapnp_init(void) } } } - if (cards) { + if (cards) printk(KERN_INFO "isapnp: %i Plug & Play card%s detected total\n", cards, cards > 1 ? "s" : ""); - } else { + else printk(KERN_INFO "isapnp: No Plug & Play card found\n"); - } isapnp_proc_init(); return 0; diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 3bda513a6bd3..329dc6c18384 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -390,7 +390,7 @@ static int pnp_assign_resources(struct pnp_dev *dev, int depnum) up(&pnp_res_mutex); return 1; - fail: +fail: pnp_clean_resource_table(&dev->res); up(&pnp_res_mutex); return 0; @@ -444,7 +444,7 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, kfree(bak); return 0; - fail: +fail: dev->res = *bak; up(&pnp_res_mutex); kfree(bak); diff --git a/drivers/pnp/pnpacpi/core.c b/drivers/pnp/pnpacpi/core.c index 616fc72190bf..a5a372222d69 100644 --- a/drivers/pnp/pnpacpi/core.c +++ b/drivers/pnp/pnpacpi/core.c @@ -248,9 +248,9 @@ static int __init pnpacpi_add_device(struct acpi_device *device) num++; return AE_OK; - err1: +err1: kfree(dev_id); - err: +err: kfree(dev); return -EINVAL; } diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index ce5027feb3da..51478c084220 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -35,6 +35,7 @@ static int irq_flags(int triggering, int polarity) { int flag; + if (triggering == ACPI_LEVEL_SENSITIVE) { if (polarity == ACPI_ACTIVE_LOW) flag = IORESOURCE_IRQ_LOWLEVEL; diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 3692a099b45f..9892a6afe46c 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -591,6 +591,7 @@ subsys_initcall(pnpbios_init); static int __init pnpbios_thread_init(void) { struct task_struct *task; + #if defined(CONFIG_PPC_MERGE) if (check_legacy_ioport(PNPBIOS_BASE)) return 0; diff --git a/drivers/pnp/pnpbios/proc.c b/drivers/pnp/pnpbios/proc.c index 9c8c07701b65..9d9841f24a85 100644 --- a/drivers/pnp/pnpbios/proc.c +++ b/drivers/pnp/pnpbios/proc.c @@ -212,7 +212,7 @@ static int proc_write_node(struct file *file, const char __user * buf, goto out; } ret = count; - out: +out: kfree(node); return ret; } diff --git a/drivers/pnp/pnpbios/rsparser.c b/drivers/pnp/pnpbios/rsparser.c index 04ecd7b67230..3fabf11b0027 100644 --- a/drivers/pnp/pnpbios/rsparser.c +++ b/drivers/pnp/pnpbios/rsparser.c @@ -238,7 +238,7 @@ static unsigned char *pnpbios_parse_allocated_resource_data(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -298,6 +298,7 @@ static void pnpbios_parse_fixed_mem32_option(unsigned char *p, int size, struct pnp_option *option) { struct pnp_mem *mem; + mem = kzalloc(sizeof(struct pnp_mem), GFP_KERNEL); if (!mem) return; @@ -468,7 +469,7 @@ static unsigned char *pnpbios_parse_resource_option_data(unsigned char *p, return p + 2; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -562,7 +563,7 @@ static unsigned char *pnpbios_parse_compatible_ids(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); @@ -756,7 +757,7 @@ static unsigned char *pnpbios_encode_allocated_resource_data(unsigned char *p, break; default: /* an unkown tag */ - len_err: +len_err: printk(KERN_ERR "PnPBIOS: Unknown tag '0x%x', length '%d'.\n", tag, len); -- cgit v1.2.3 From 4cec086b219224167c22dd020d3dd2d9220e1d98 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:09 -0600 Subject: PNPACPI: simplify irq_flags() No need for a temporary variable; just return the flags once we know them. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/rsparser.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index 51478c084220..a0784fe5bcd8 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -34,20 +34,17 @@ */ static int irq_flags(int triggering, int polarity) { - int flag; - if (triggering == ACPI_LEVEL_SENSITIVE) { if (polarity == ACPI_ACTIVE_LOW) - flag = IORESOURCE_IRQ_LOWLEVEL; + return IORESOURCE_IRQ_LOWLEVEL; else - flag = IORESOURCE_IRQ_HIGHLEVEL; + return IORESOURCE_IRQ_HIGHLEVEL; } else { if (polarity == ACPI_ACTIVE_LOW) - flag = IORESOURCE_IRQ_LOWEDGE; + return IORESOURCE_IRQ_LOWEDGE; else - flag = IORESOURCE_IRQ_HIGHEDGE; + return IORESOURCE_IRQ_HIGHEDGE; } - return flag; } static void decode_irq_flags(int flag, int *triggering, int *polarity) -- cgit v1.2.3 From 4721a4cc8864f0eb92958c3e0479e7994e8b0072 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:10 -0600 Subject: PNPACPI: remove unnecessary casts of "void *" Remove unnecessary casts of void pointers. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/pnpacpi/rsparser.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/pnpacpi/rsparser.c b/drivers/pnp/pnpacpi/rsparser.c index a0784fe5bcd8..0e3b8d0ff06b 100644 --- a/drivers/pnp/pnpacpi/rsparser.c +++ b/drivers/pnp/pnpacpi/rsparser.c @@ -240,8 +240,7 @@ static void pnpacpi_parse_allocated_address_space(struct pnp_resource_table *res static acpi_status pnpacpi_allocated_resource(struct acpi_resource *res, void *data) { - struct pnp_resource_table *res_table = - (struct pnp_resource_table *)data; + struct pnp_resource_table *res_table = data; int i; switch (res->type) { @@ -564,8 +563,7 @@ static acpi_status pnpacpi_option_resource(struct acpi_resource *res, void *data) { int priority = 0; - struct acpipnp_parse_option_s *parse_data = - (struct acpipnp_parse_option_s *)data; + struct acpipnp_parse_option_s *parse_data = data; struct pnp_dev *dev = parse_data->dev; struct pnp_option *option = parse_data->option; @@ -703,7 +701,7 @@ static int pnpacpi_supported_resource(struct acpi_resource *res) static acpi_status pnpacpi_count_resources(struct acpi_resource *res, void *data) { - int *res_cnt = (int *)data; + int *res_cnt = data; if (pnpacpi_supported_resource(res)) (*res_cnt)++; @@ -712,7 +710,7 @@ static acpi_status pnpacpi_count_resources(struct acpi_resource *res, static acpi_status pnpacpi_type_resources(struct acpi_resource *res, void *data) { - struct acpi_resource **resource = (struct acpi_resource **)data; + struct acpi_resource **resource = data; if (pnpacpi_supported_resource(res)) { (*resource)->type = res->type; @@ -884,8 +882,7 @@ int pnpacpi_encode_resources(struct pnp_resource_table *res_table, int i = 0; /* pnpacpi_build_resource_template allocates extra mem */ int res_cnt = (buffer->length - 1) / sizeof(struct acpi_resource) - 1; - struct acpi_resource *resource = - (struct acpi_resource *)buffer->pointer; + struct acpi_resource *resource = buffer->pointer; int port = 0, irq = 0, dma = 0, mem = 0; pnp_dbg("res cnt %d", res_cnt); -- cgit v1.2.3 From 6c504d30a48157b7c05a0dfb6a799c72095e957d Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:11 -0600 Subject: ISAPNP: removed unused isapnp_detected and ISAPNP_DEBUG ISAPNP_DEBUG isn't used at all. isapnp_detected is set but never read. So remove them both. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/isapnp/core.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 32386ce60478..1a0d33a12862 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -47,9 +47,6 @@ #if 0 #define ISAPNP_REGION_OK #endif -#if 0 -#define ISAPNP_DEBUG -#endif int isapnp_disable; /* Disable ISA PnP */ static int isapnp_rdp; /* Read Data Port */ @@ -93,7 +90,6 @@ MODULE_LICENSE("GPL"); static unsigned char isapnp_checksum_value; static DEFINE_MUTEX(isapnp_cfg_mutex); -static int isapnp_detected; static int isapnp_csn_count; /* some prototypes */ @@ -1067,7 +1063,6 @@ static int __init isapnp_init(void) struct pnp_dev *dev; if (isapnp_disable) { - isapnp_detected = 0; printk(KERN_INFO "isapnp: ISA Plug & Play support disabled\n"); return 0; } @@ -1115,7 +1110,6 @@ static int __init isapnp_init(void) } isapnp_set_rdp(); } - isapnp_detected = 1; if (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff) { cards = isapnp_isolate(); if (cards < 0 || (isapnp_rdp < 0x203 || isapnp_rdp > 0x3ff)) { @@ -1123,7 +1117,6 @@ static int __init isapnp_init(void) release_region(_PIDXR, 1); #endif release_region(_PNPWRP, 1); - isapnp_detected = 0; printk(KERN_INFO "isapnp: No Plug & Play device found\n"); return 0; -- cgit v1.2.3 From 4f0217e30249ac0eb13b65ef64f2aee627465da2 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:12 -0600 Subject: PNP: remove MODULE infrastructure We don't support building any part of PNP as a module (*drivers* can be modules, of course, but the PNP infrastructure itself can not). Since MODULE will never be defined, remove the ifdefs and dead code. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/isapnp/proc.c | 45 --------------------------------------------- drivers/pnp/pnpbios/core.c | 43 ------------------------------------------- 2 files changed, 88 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/isapnp/proc.c b/drivers/pnp/isapnp/proc.c index 3fbc0f9ffc26..560ccb640816 100644 --- a/drivers/pnp/isapnp/proc.c +++ b/drivers/pnp/isapnp/proc.c @@ -112,33 +112,6 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev) return 0; } -#ifdef MODULE -static int __exit isapnp_proc_detach_device(struct pnp_dev *dev) -{ - struct pnp_card *bus = dev->card; - struct proc_dir_entry *de; - char name[16]; - - if (!(de = bus->procdir)) - return -EINVAL; - sprintf(name, "%02x", dev->number); - remove_proc_entry(name, de); - return 0; -} - -static int __exit isapnp_proc_detach_bus(struct pnp_card *bus) -{ - struct proc_dir_entry *de; - char name[16]; - - if (!(de = bus->procdir)) - return -EINVAL; - sprintf(name, "%02x", bus->number); - remove_proc_entry(name, isapnp_proc_bus_dir); - return 0; -} -#endif /* MODULE */ - int __init isapnp_proc_init(void) { struct pnp_dev *dev; @@ -149,21 +122,3 @@ int __init isapnp_proc_init(void) } return 0; } - -#ifdef MODULE -int __exit isapnp_proc_done(void) -{ - struct pnp_dev *dev; - struct pnp_bus *card; - - isapnp_for_each_dev(dev) { - isapnp_proc_detach_device(dev); - } - isapnp_for_each_card(card) { - isapnp_proc_detach_bus(card); - } - if (isapnp_proc_bus_dir) - remove_proc_entry("isapnp", proc_bus); - return 0; -} -#endif /* MODULE */ diff --git a/drivers/pnp/pnpbios/core.c b/drivers/pnp/pnpbios/core.c index 9892a6afe46c..0691f473e9d4 100644 --- a/drivers/pnp/pnpbios/core.c +++ b/drivers/pnp/pnpbios/core.c @@ -419,7 +419,6 @@ static void __init build_devlist(void) static int pnpbios_disabled; int pnpbios_dont_use_current_config; -#ifndef MODULE static int __init pnpbios_setup(char *str) { int invert; @@ -443,7 +442,6 @@ static int __init pnpbios_setup(char *str) } __setup("pnpbios=", pnpbios_setup); -#endif /* PnP BIOS signature: "$PnP" */ #define PNP_SIGNATURE (('$' << 0) + ('P' << 8) + ('n' << 16) + ('P' << 24)) @@ -607,48 +605,7 @@ static int __init pnpbios_thread_init(void) return 0; } -#ifndef MODULE - -/* init/main.c calls pnpbios_init early */ - /* Start the kernel thread later: */ module_init(pnpbios_thread_init); -#else - -/* - * N.B.: Building pnpbios as a module hasn't been fully implemented - */ - -MODULE_LICENSE("GPL"); - -static int __init pnpbios_init_all(void) -{ - int r; - - r = pnpbios_init(); - if (r) - return r; - r = pnpbios_thread_init(); - if (r) - return r; - return 0; -} - -static void __exit pnpbios_exit(void) -{ -#ifdef CONFIG_HOTPLUG - unloading = 1; - wait_for_completion(&unload_sem); -#endif - pnpbios_proc_exit(); - /* We ought to free resources here */ - return; -} - -module_init(pnpbios_init_all); -module_exit(pnpbios_exit); - -#endif - EXPORT_SYMBOL(pnpbios_protocol); -- cgit v1.2.3 From b173491339b9ae7f1322241ce6228c1268513a39 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Wed, 15 Aug 2007 10:32:13 -0600 Subject: PNP: remove null pointer checks Remove some null pointer checks. Null pointers in these areas indicate programming errors, and I think it's better to oops immediately rather than return an error that is easily ignored. Signed-off-by: Bjorn Helgaas Acked-by: Adam Belay Signed-off-by: Len Brown --- drivers/pnp/core.c | 7 +------ drivers/pnp/driver.c | 4 ---- drivers/pnp/isapnp/core.c | 2 +- drivers/pnp/manager.c | 23 ----------------------- drivers/pnp/resource.c | 26 -------------------------- 5 files changed, 2 insertions(+), 60 deletions(-) (limited to 'drivers') diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 61066fdb9e6d..d5964feb14de 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -52,9 +52,6 @@ int pnp_register_protocol(struct pnp_protocol *protocol) int nodenum; struct list_head *pos; - if (!protocol) - return -EINVAL; - INIT_LIST_HEAD(&protocol->devices); INIT_LIST_HEAD(&protocol->cards); nodenum = 0; @@ -94,8 +91,6 @@ static void pnp_free_ids(struct pnp_dev *dev) struct pnp_id *id; struct pnp_id *next; - if (!dev) - return; id = dev->id; while (id) { next = id->next; @@ -143,7 +138,7 @@ int __pnp_add_device(struct pnp_dev *dev) */ int pnp_add_device(struct pnp_dev *dev) { - if (!dev || !dev->protocol || dev->card) + if (dev->card) return -EINVAL; dev->dev.parent = &dev->protocol->dev; sprintf(dev->dev.bus_id, "%02x:%02x", dev->protocol->number, diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c index 9be01b0433b9..2fa64a6b25c8 100644 --- a/drivers/pnp/driver.c +++ b/drivers/pnp/driver.c @@ -232,10 +232,6 @@ int pnp_add_id(struct pnp_id *id, struct pnp_dev *dev) { struct pnp_id *ptr; - if (!id) - return -EINVAL; - if (!dev) - return -EINVAL; id->next = NULL; ptr = dev->id; while (ptr && ptr->next) diff --git a/drivers/pnp/isapnp/core.c b/drivers/pnp/isapnp/core.c index 1a0d33a12862..b035d60a1dcc 100644 --- a/drivers/pnp/isapnp/core.c +++ b/drivers/pnp/isapnp/core.c @@ -1040,7 +1040,7 @@ static int isapnp_set_resources(struct pnp_dev *dev, static int isapnp_disable_resources(struct pnp_dev *dev) { - if (!dev || !dev->active) + if (!dev->active) return -EINVAL; isapnp_cfg_begin(dev->card->number, dev->number); isapnp_deactivate(dev->number); diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index 329dc6c18384..0826287eef53 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c @@ -21,9 +21,6 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) resource_size_t *start, *end; unsigned long *flags; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_PORT) { pnp_err ("More than 4 ports is incompatible with pnp specifications."); @@ -66,9 +63,6 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) resource_size_t *start, *end; unsigned long *flags; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_MEM) { pnp_err ("More than 8 mems is incompatible with pnp specifications."); @@ -127,9 +121,6 @@ static int pnp_assign_irq(struct pnp_dev *dev, struct pnp_irq *rule, int idx) 5, 10, 11, 12, 9, 14, 15, 7, 3, 4, 13, 0, 1, 6, 8, 2 }; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_IRQ) { pnp_err ("More than 2 irqs is incompatible with pnp specifications."); @@ -181,9 +172,6 @@ static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) 1, 3, 5, 6, 7, 0, 2, 4 }; - if (!dev || !rule) - return -EINVAL; - if (idx >= PNP_MAX_DMA) { pnp_err ("More than 2 dmas is incompatible with pnp specifications."); @@ -410,8 +398,6 @@ int pnp_manual_config_dev(struct pnp_dev *dev, struct pnp_resource_table *res, int i; struct pnp_resource_table *bak; - if (!dev || !res) - return -EINVAL; if (!pnp_can_configure(dev)) return -ENODEV; bak = pnp_alloc(sizeof(struct pnp_resource_table)); @@ -460,9 +446,6 @@ int pnp_auto_config_dev(struct pnp_dev *dev) struct pnp_option *dep; int i = 1; - if (!dev) - return -EINVAL; - if (!pnp_can_configure(dev)) { pnp_dbg("Device %s does not support resource configuration.", dev->dev.bus_id); @@ -541,8 +524,6 @@ int pnp_activate_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (dev->active) return 0; /* the device is already active */ @@ -568,8 +549,6 @@ int pnp_disable_dev(struct pnp_dev *dev) { int error; - if (!dev) - return -EINVAL; if (!dev->active) return 0; /* the device is already disabled */ @@ -596,8 +575,6 @@ int pnp_disable_dev(struct pnp_dev *dev) void pnp_resource_change(struct resource *resource, resource_size_t start, resource_size_t size) { - if (resource == NULL) - return; resource->flags &= ~(IORESOURCE_AUTO | IORESOURCE_UNSET); resource->start = start; resource->end = start + size - 1; diff --git a/drivers/pnp/resource.c b/drivers/pnp/resource.c index ea6ec14a0559..ef1286900db3 100644 --- a/drivers/pnp/resource.c +++ b/drivers/pnp/resource.c @@ -47,9 +47,6 @@ struct pnp_option *pnp_register_independent_option(struct pnp_dev *dev) { struct pnp_option *option; - if (!dev) - return NULL; - option = pnp_build_option(PNP_RES_PRIORITY_PREFERRED); /* this should never happen but if it does we'll try to continue */ @@ -64,9 +61,6 @@ struct pnp_option *pnp_register_dependent_option(struct pnp_dev *dev, { struct pnp_option *option; - if (!dev) - return NULL; - option = pnp_build_option(priority); if (dev->dependent) { @@ -83,11 +77,6 @@ int pnp_register_irq_resource(struct pnp_option *option, struct pnp_irq *data) { struct pnp_irq *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->irq; while (ptr && ptr->next) ptr = ptr->next; @@ -112,11 +101,6 @@ int pnp_register_dma_resource(struct pnp_option *option, struct pnp_dma *data) { struct pnp_dma *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->dma; while (ptr && ptr->next) ptr = ptr->next; @@ -132,11 +116,6 @@ int pnp_register_port_resource(struct pnp_option *option, struct pnp_port *data) { struct pnp_port *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->port; while (ptr && ptr->next) ptr = ptr->next; @@ -152,11 +131,6 @@ int pnp_register_mem_resource(struct pnp_option *option, struct pnp_mem *data) { struct pnp_mem *ptr; - if (!option) - return -EINVAL; - if (!data) - return -EINVAL; - ptr = option->mem; while (ptr && ptr->next) ptr = ptr->next; -- cgit v1.2.3 From 3e069ee0c30d6f28b79e409ef2df1ffa427897ae Mon Sep 17 00:00:00 2001 From: Len Brown Date: Fri, 24 Aug 2007 03:06:33 -0400 Subject: ACPI: fix ia64 allnoconfig build MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit drivers/acpi/event.c:238: error: conflicting types for ‘acpi_bus_generate_netlink_event’ include/acpi/acpi_bus.h:324: error: previous declaration of ‘acpi_bus_generate_netlink_event’ was here Signed-off-by: Len Brown --- drivers/acpi/event.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c index cf6d5161cf31..a2b9304596ce 100644 --- a/drivers/acpi/event.c +++ b/drivers/acpi/event.c @@ -233,8 +233,9 @@ static int acpi_event_genetlink_init(void) } #else -int acpi_bus_generate_netlink_event(struct acpi_device *device, u8 type, - int data) +int acpi_bus_generate_netlink_event(const char *device_class, + const char *bus_id, + u8 type, int data) { return 0; } -- cgit v1.2.3 From 2db9ccba8d4bb8e3aa6d0cd8e7544c5736963bbc Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Fri, 24 Aug 2007 11:45:50 +0200 Subject: ACPI: /proc/acpi/thermal_zone trip points are now read-only, mark them as such Signed-off-by: Pavel Machek Signed-off-by: Len Brown --- drivers/acpi/thermal.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 39479b0befa4..7e8f48b7f9af 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -1085,9 +1085,9 @@ static int acpi_thermal_add_fs(struct acpi_device *device) entry->owner = THIS_MODULE; } - /* 'trip_points' [R/W] */ + /* 'trip_points' [R] */ entry = create_proc_entry(ACPI_THERMAL_FILE_TRIP_POINTS, - S_IFREG | S_IRUGO | S_IWUSR, + S_IRUGO, acpi_device_dir(device)); if (!entry) return -ENODEV; -- cgit v1.2.3 From 9f3119b70cf189530f1b46a006a052e171a1622f Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Fri, 24 Aug 2007 16:18:16 +0800 Subject: ACPI: Validate XSDT, use RSDT if XSDT fails ACPI 1.0 used an RSDT with 32-bit physical addresses. ACPI 2.0 adds an XSDT with 32-bit physical addresses. An ACPI 2.0 aware OS is supposed to use the XSDT (when present) instead of the RSDT. However, several systems have failed because the XSDT contains NULL entries -- while it is missing pointers to needed tables, such as SSDTs. When we find an XSDT with NULL entries, discard it and use the ACPI 1.0 RSDT instead. http://bugzilla.kernel.org/show_bug.cgi?id=8630 Signed-off-by: Zhao Yakui Signed-off-by: Len Brown --- drivers/acpi/tables/tbutils.c | 71 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/tables/tbutils.c b/drivers/acpi/tables/tbutils.c index 1da64b4518c0..8cc9492ffbf2 100644 --- a/drivers/acpi/tables/tbutils.c +++ b/drivers/acpi/tables/tbutils.c @@ -51,6 +51,65 @@ ACPI_MODULE_NAME("tbutils") static acpi_physical_address acpi_tb_get_root_table_entry(u8 * table_entry, acpi_native_uint table_entry_size); +/******************************************************************************* + * + * FUNCTION: acpi_tb_check_xsdt + * + * PARAMETERS: address - Pointer to the XSDT + * + * RETURN: status + * AE_OK - XSDT is okay + * AE_NO_MEMORY - can't map XSDT + * AE_INVALID_TABLE_LENGTH - invalid table length + * AE_NULL_ENTRY - XSDT has NULL entry + * + * DESCRIPTION: validate XSDT +******************************************************************************/ + +static acpi_status +acpi_tb_check_xsdt(acpi_physical_address address) +{ + struct acpi_table_header *table; + u32 length; + u64 xsdt_entry_address; + u8 *table_entry; + u32 table_count; + int i; + + table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); + if (!table) + return AE_NO_MEMORY; + + length = table->length; + acpi_os_unmap_memory(table, sizeof(struct acpi_table_header)); + if (length < sizeof(struct acpi_table_header)) + return AE_INVALID_TABLE_LENGTH; + + table = acpi_os_map_memory(address, length); + if (!table) + return AE_NO_MEMORY; + + /* Calculate the number of tables described in XSDT */ + table_count = + (u32) ((table->length - + sizeof(struct acpi_table_header)) / sizeof(u64)); + table_entry = + ACPI_CAST_PTR(u8, table) + sizeof(struct acpi_table_header); + for (i = 0; i < table_count; i++) { + ACPI_MOVE_64_TO_64(&xsdt_entry_address, table_entry); + if (!xsdt_entry_address) { + /* XSDT has NULL entry */ + break; + } + table_entry += sizeof(u64); + } + acpi_os_unmap_memory(table, length); + + if (i < table_count) + return AE_NULL_ENTRY; + else + return AE_OK; +} /******************************************************************************* * @@ -341,6 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) u32 table_count; struct acpi_table_header *table; acpi_physical_address address; + acpi_physical_address rsdt_address; u32 length; u8 *table_entry; acpi_status status; @@ -369,6 +429,8 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ address = (acpi_physical_address) rsdp->xsdt_physical_address; table_entry_size = sizeof(u64); + rsdt_address = (acpi_physical_address) + rsdp->rsdt_physical_address; } else { /* Root table is an RSDT (32-bit physical addresses) */ @@ -382,6 +444,15 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags) */ acpi_os_unmap_memory(rsdp, sizeof(struct acpi_table_rsdp)); + if (table_entry_size == sizeof(u64)) { + if (acpi_tb_check_xsdt(address) == AE_NULL_ENTRY) { + /* XSDT has NULL entry, RSDT is used */ + address = rsdt_address; + table_entry_size = sizeof(u32); + ACPI_WARNING((AE_INFO, "BIOS XSDT has NULL entry," + "using RSDT")); + } + } /* Map the RSDT/XSDT table header to get the full table length */ table = acpi_os_map_memory(address, sizeof(struct acpi_table_header)); -- cgit v1.2.3 From 6e106b0d97e79f1abb60cc49a53af760950c3384 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 24 Aug 2007 15:35:15 -0700 Subject: DM_MULTIPATH_RDAC: "scsi_normalize_sense" undefined DM_MULTIPATH_RDAC uses SCSI API(s) and is for a SCSI device, so add SCSI to its depends on to prevent build errors. Signed-off-by: Randy Dunlap [ Tested and Verified by Chandra Seetharaman ] Acked-by: Chandra Seetharaman Signed-off-by: Linus Torvalds --- drivers/md/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 531d4d17d011..34a8c60a254a 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig @@ -263,7 +263,7 @@ config DM_MULTIPATH_EMC config DM_MULTIPATH_RDAC tristate "LSI/Engenio RDAC multipath support (EXPERIMENTAL)" - depends on DM_MULTIPATH && BLK_DEV_DM && EXPERIMENTAL + depends on DM_MULTIPATH && BLK_DEV_DM && SCSI && EXPERIMENTAL ---help--- Multipath support for LSI/Engenio RDAC. -- cgit v1.2.3 From e9dab1960ac9746fa34eff726b81635147615a79 Mon Sep 17 00:00:00 2001 From: Luming Yu Date: Mon, 20 Aug 2007 18:23:53 +0800 Subject: ACPI video hotkey: export missing ACPI video hotkey events via input layer Signed-off-by: Yu Luming Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 88 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 8efdea587ae3..d727d2c715df 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -31,7 +31,7 @@ #include #include #include - +#include #include #include #include @@ -138,6 +138,8 @@ struct acpi_video_bus { struct semaphore sem; struct list_head video_device_list; struct proc_dir_entry *dir; + struct input_dev *input; + char phys[32]; /* for input device */ }; struct acpi_video_device_flags { @@ -1764,6 +1766,9 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_bus *video = data; struct acpi_device *device = NULL; + struct input_dev *input; + int keycode; + printk("video bus notify\n"); @@ -1771,11 +1776,13 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) return; device = video->device; + input = video->input; switch (event) { case ACPI_VIDEO_NOTIFY_SWITCH: /* User requested a switch, * most likely via hotkey. */ acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_PROBE: /* User plugged in or removed a video @@ -1784,21 +1791,37 @@ static void acpi_video_bus_notify(acpi_handle handle, u32 event, void *data) acpi_video_device_rebind(video); acpi_video_switch_output(video, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; break; case ACPI_VIDEO_NOTIFY_CYCLE: /* Cycle Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_SWITCHVIDEOMODE; + break; case ACPI_VIDEO_NOTIFY_NEXT_OUTPUT: /* Next Display output hotkey pressed. */ + acpi_video_switch_output(video, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_VIDEO_NEXT; + break; case ACPI_VIDEO_NOTIFY_PREV_OUTPUT: /* previous Display output hotkey pressed. */ acpi_video_switch_output(video, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_VIDEO_PREV; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } @@ -1806,26 +1829,55 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) { struct acpi_video_device *video_device = data; struct acpi_device *device = NULL; + struct acpi_video_bus *bus; + struct input_dev *input; + int keycode; if (!video_device) return; device = video_device->dev; + bus = video_device->video; + input = bus->input; switch (event) { case ACPI_VIDEO_NOTIFY_CYCLE_BRIGHTNESS: /* Cycle brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESS_CYCLE; + break; case ACPI_VIDEO_NOTIFY_INC_BRIGHTNESS: /* Increase brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESSUP; + break; case ACPI_VIDEO_NOTIFY_DEC_BRIGHTNESS: /* Decrease brightness */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESSDOWN; + break; case ACPI_VIDEO_NOTIFY_ZERO_BRIGHTNESS: /* zero brightnesss */ + acpi_video_switch_brightness(video_device, event); + acpi_bus_generate_event(device, event, 0); + keycode = KEY_BRIGHTNESS_ZERO; + break; case ACPI_VIDEO_NOTIFY_DISPLAY_OFF: /* display device off */ acpi_video_switch_brightness(video_device, event); acpi_bus_generate_event(device, event, 0); + keycode = KEY_DISPLAY_OFF; break; default: + keycode = KEY_UNKNOWN; ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Unsupported event [0x%x]\n", event)); break; } + + input_report_key(input, keycode, 1); + input_sync(input); + input_report_key(input, keycode, 0); + input_sync(input); + return; } @@ -1834,6 +1886,7 @@ static int acpi_video_bus_add(struct acpi_device *device) int result = 0; acpi_status status = 0; struct acpi_video_bus *video = NULL; + struct input_dev *input; if (!device) @@ -1877,6 +1930,39 @@ static int acpi_video_bus_add(struct acpi_device *device) goto end; } + + video->input = input = input_allocate_device(); + + snprintf(video->phys, sizeof(video->phys), + "%s/video/input0", acpi_device_hid(video->device)); + + input->name = acpi_device_name(video->device); + input->phys = video->phys; + input->id.bustype = BUS_HOST; + input->id.product = 0x06; + input->evbit[0] = BIT(EV_KEY); + set_bit(KEY_SWITCHVIDEOMODE, input->keybit); + set_bit(KEY_VIDEO_NEXT, input->keybit); + set_bit(KEY_VIDEO_PREV, input->keybit); + set_bit(KEY_BRIGHTNESS_CYCLE, input->keybit); + set_bit(KEY_BRIGHTNESSUP, input->keybit); + set_bit(KEY_BRIGHTNESSDOWN, input->keybit); + set_bit(KEY_BRIGHTNESS_ZERO, input->keybit); + set_bit(KEY_DISPLAY_OFF, input->keybit); + set_bit(KEY_UNKNOWN, input->keybit); + result = input_register_device(input); + if (result) { + acpi_remove_notify_handler(video->device->handle, + ACPI_DEVICE_NOTIFY, + acpi_video_bus_notify); + acpi_video_bus_stop_devices(video); + acpi_video_bus_put_devices(video); + kfree(video->attached_array); + acpi_video_bus_remove_fs(device); + goto end; + } + + printk(KERN_INFO PREFIX "%s [%s] (multi-head: %s rom: %s post: %s)\n", ACPI_VIDEO_DEVICE_NAME, acpi_device_bid(device), video->flags.multihead ? "yes" : "no", @@ -1910,6 +1996,7 @@ static int acpi_video_bus_remove(struct acpi_device *device, int type) acpi_video_bus_put_devices(video); acpi_video_bus_remove_fs(device); + input_unregister_device(video->input); kfree(video->attached_array); kfree(video); -- cgit v1.2.3 From ead77594af3a49e48ceec61a1824362be4b5cafa Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Thu, 23 Aug 2007 15:01:13 +0800 Subject: ACPI: "ACPI handle has no context!" should be KERN_DEBUG Signed-off-by: Shaohua Li Signed-off-by: Len Brown --- drivers/acpi/sleep/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c index e8cff5dd4cbc..c52ade816fb4 100644 --- a/drivers/acpi/sleep/main.c +++ b/drivers/acpi/sleep/main.c @@ -305,7 +305,7 @@ int acpi_pm_device_sleep_state(struct device *dev, int wake, int *d_min_p) unsigned long d_min, d_max; if (!handle || ACPI_FAILURE(acpi_bus_get_device(handle, &adev))) { - printk(KERN_ERR "ACPI handle has no context!\n"); + printk(KERN_DEBUG "ACPI handle has no context!\n"); return -ENODEV; } -- cgit v1.2.3 From 70b30fb13bf46d7874537f5e2089bcc772559fc4 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Tue, 21 Aug 2007 16:18:20 +0100 Subject: ACPI: Fix a warning of discarding qualifiers from pointer target type drivers/acpi/ec.c: In function `acpi_ec_ecdt_probe': drivers/acpi/ec.c:873: warning: passing arg 1 of `acpi_get_devices' discards qualifiers from pointer target type Signed-off-by: Al Viro Signed-off-by: Len Brown --- drivers/acpi/namespace/nsxfeval.c | 2 +- include/acpi/acpixf.h | 2 +- include/acpi/acstruct.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/namespace/nsxfeval.c b/drivers/acpi/namespace/nsxfeval.c index ab65b2c2560e..f39fbc6b9237 100644 --- a/drivers/acpi/namespace/nsxfeval.c +++ b/drivers/acpi/namespace/nsxfeval.c @@ -540,7 +540,7 @@ acpi_ns_get_device_callback(acpi_handle obj_handle, ******************************************************************************/ acpi_status -acpi_get_devices(char *HID, +acpi_get_devices(const char *HID, acpi_walk_callback user_function, void *context, void **return_value) { diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index b5cca5daa348..3d7ab9e0c9fe 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h @@ -130,7 +130,7 @@ acpi_walk_namespace(acpi_object_type type, void *context, void **return_value); acpi_status -acpi_get_devices(char *HID, +acpi_get_devices(const char *HID, acpi_walk_callback user_function, void *context, void **return_value); diff --git a/include/acpi/acstruct.h b/include/acpi/acstruct.h index aeb4498e5e06..88482655407f 100644 --- a/include/acpi/acstruct.h +++ b/include/acpi/acstruct.h @@ -146,7 +146,7 @@ struct acpi_init_walk_info { struct acpi_get_devices_info { acpi_walk_callback user_function; void *context; - char *hid; + const char *hid; }; union acpi_aml_operands { -- cgit v1.2.3 From b3e572d2eb7cdbda6f212ad177acd0c9381903b9 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 14 Aug 2007 23:22:35 +0200 Subject: make drivers/acpi/scan.c:create_modalias() static This patch makes the needlessly global create_modalias() static. Signed-off-by: Adrian Bunk Signed-off-by: Len Brown --- drivers/acpi/scan.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index be74347d1354..64620d668742 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -35,8 +35,9 @@ struct acpi_device_bus_id{ * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: * char *modalias: "acpi:IBM0001:ACPI0001" */ -int create_modalias(struct acpi_device *acpi_dev, char *modalias, int size){ - +static int create_modalias(struct acpi_device *acpi_dev, char *modalias, + int size) +{ int len; if (!acpi_dev->flags.hardware_id) -- cgit v1.2.3 From 3e0d69ecf04d25f1e9c4ad658683d6d92641bb08 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Sat, 25 Aug 2007 01:28:20 -0400 Subject: ACPI: add dump_stack() to trace acpi_format_exception programming errors Dump the stack so we can find the secretive caller to acpi_format_exception(). Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/acpi/utilities/utglobal.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/acpi/utilities/utglobal.c b/drivers/acpi/utilities/utglobal.c index 1621655d6e2b..93ea8290b4f7 100644 --- a/drivers/acpi/utilities/utglobal.c +++ b/drivers/acpi/utilities/utglobal.c @@ -126,6 +126,7 @@ const char *acpi_format_exception(acpi_status status) "Unknown exception code: 0x%8.8X", status)); exception = "UNKNOWN_STATUS_CODE"; + dump_stack(); } return (ACPI_CAST_PTR(const char, exception)); -- cgit v1.2.3 From 5e1f198bbfcffa1e3b9091b4ca7032c2d07fde81 Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Sat, 25 Aug 2007 01:31:45 -0400 Subject: acpiphp_ibm: add missing '\n' to error message Add missing \n to error in ibm_find_acpi_device. Signed-off-by: Jeremy Fitzhardinge Cc: Kristen Carlson Accardi Cc: Greg Kroah-Hartman Cc: Adrian Bunk Signed-off-by: Andrew Morton Signed-off-by: Len Brown --- drivers/pci/hotplug/acpiphp_ibm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pci/hotplug/acpiphp_ibm.c b/drivers/pci/hotplug/acpiphp_ibm.c index 70db38c0ced9..80544d87437b 100644 --- a/drivers/pci/hotplug/acpiphp_ibm.c +++ b/drivers/pci/hotplug/acpiphp_ibm.c @@ -399,7 +399,7 @@ static acpi_status __init ibm_find_acpi_device(acpi_handle handle, status = acpi_get_object_info(handle, &info_buffer); if (ACPI_FAILURE(status)) { - err("%s: Failed to get device information", __FUNCTION__); + err("%s: Failed to get device information\n", __FUNCTION__); return 0; } info.hardware_id.value[sizeof(info.hardware_id.value) - 1] = '\0'; -- cgit v1.2.3 From e6d9da1de0f31c57cfe3837b1b4e51c6d96fcd3c Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Sat, 25 Aug 2007 02:23:31 -0400 Subject: ACPI: work around duplicate name "VID" problem on T61 This can only fix the problem that more than one video bus device have the same AML name "VID". ie. the proc I/F for the second "VID" video bus device is located under /proc/acpi/video/VID1/... As this is really rare and the ACPI proc I/F is a legacy feature that we are planning to remove. We won't provide a generic solution for this problem. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'drivers') diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index d98701941981..ac63be4e8197 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1833,6 +1833,7 @@ static void acpi_video_device_notify(acpi_handle handle, u32 event, void *data) return; } +static int instance; static int acpi_video_bus_add(struct acpi_device *device) { int result = 0; @@ -1847,6 +1848,13 @@ static int acpi_video_bus_add(struct acpi_device *device) if (!video) return -ENOMEM; + /* a hack to fix the duplicate name "VID" problem on T61 */ + if (!strcmp(device->pnp.bus_id, "VID")) { + if (instance) + device->pnp.bus_id[3] = '0' + instance; + instance ++; + } + video->device = device; strcpy(acpi_device_name(device), ACPI_VIDEO_BUS_NAME); strcpy(acpi_device_class(device), ACPI_VIDEO_CLASS); -- cgit v1.2.3 From ba685fb2abd71162bea6895a99449c1071b01402 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Thu, 23 Aug 2007 21:35:41 +0200 Subject: fix realtek phy id in forcedeth As noticed by Chuck Ebbert, commit c5e3ae8823693b260ce1f217adca8add1bc0b3de introduced a copy-paste typo, as realtek phy is 0x732 and not 0x1c1. Obvious fix below suggested by Ayaz Abdulla. Signed-off-by: Willy Tarreau Cc: Ayaz Abdulla Cc: Chuck Ebbert Signed-off-by: Jeff Garzik --- drivers/net/forcedeth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 10f4e3b55168..1938d6dfc863 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c @@ -552,7 +552,7 @@ union ring_type { #define PHY_OUI_MARVELL 0x5043 #define PHY_OUI_CICADA 0x03f1 #define PHY_OUI_VITESSE 0x01c1 -#define PHY_OUI_REALTEK 0x01c1 +#define PHY_OUI_REALTEK 0x0732 #define PHYID1_OUI_MASK 0x03ff #define PHYID1_OUI_SHFT 6 #define PHYID2_OUI_MASK 0xfc00 -- cgit v1.2.3 From 09e06f652d86d358583df0b601c0c4d11923dd88 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 15 Aug 2007 12:53:16 +0100 Subject: Don't use GFP_DMA for zone allocation. IP32 doesn't even have a ZONE_DMA so no point in using GFP_DMA in any IP32-specific device driver. Signed-off-by: Ralf Baechle Signed-off-by: Jeff Garzik --- drivers/net/meth.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/meth.c b/drivers/net/meth.c index 92b403bf38b0..32bed6bc6c06 100644 --- a/drivers/net/meth.c +++ b/drivers/net/meth.c @@ -405,7 +405,7 @@ static void meth_rx(struct net_device* dev, unsigned long int_status) priv->stats.rx_length_errors++; skb = priv->rx_skbs[priv->rx_write]; } else { - skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC | GFP_DMA); + skb = alloc_skb(METH_RX_BUFF_SIZE, GFP_ATOMIC); if (!skb) { /* Ouch! No memory! Drop packet on the floor */ DPRINTK("No mem: dropping packet\n"); -- cgit v1.2.3 From bc1e0a095e9b8c4df4a2eedd7dc6a9d470a0e6b7 Mon Sep 17 00:00:00 2001 From: Domen Puncer Date: Fri, 17 Aug 2007 08:54:45 +0200 Subject: phy layer: fix genphy_setup_forced (don't reset) Writing BMCR_RESET bit will reset MII_BMCR to default values. This is clearly not what we want. Signed-off-by: Domen Puncer Signed-off-by: Jeff Garzik --- drivers/net/phy/phy_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c index a8b74cdab1ea..e275df8c55bc 100644 --- a/drivers/net/phy/phy_device.c +++ b/drivers/net/phy/phy_device.c @@ -364,7 +364,7 @@ EXPORT_SYMBOL(genphy_config_advert); */ int genphy_setup_forced(struct phy_device *phydev) { - int ctl = BMCR_RESET; + int ctl = 0; phydev->pause = phydev->asym_pause = 0; -- cgit v1.2.3 From c46ac9463fbdee41723dd9fd108b2c1ffd30615f Mon Sep 17 00:00:00 2001 From: Florian Westphal Date: Tue, 21 Aug 2007 01:33:42 +0200 Subject: DM9000: fix interface hang under load When transferring data at full speed, the DM9000 network interface sometimes stops sending/receiving data. Worse, ksoftirqd consumes 100% cpu and the net tx watchdog never triggers. Fix by spin_lock_irqsave() in dm9000_start_xmit() to prevent the interrupt handler from interfering. Signed-off-by: Florian Westphal Signed-off-by: Jeff Garzik --- drivers/net/dm9000.c | 25 +++++++------------------ 1 file changed, 7 insertions(+), 18 deletions(-) (limited to 'drivers') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index c3de81bf090a..738aa5906514 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -700,6 +700,7 @@ dm9000_init_dm9000(struct net_device *dev) static int dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) { + unsigned long flags; board_info_t *db = (board_info_t *) dev->priv; PRINTK3("dm9000_start_xmit\n"); @@ -707,10 +708,7 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) if (db->tx_pkt_cnt > 1) return 1; - netif_stop_queue(dev); - - /* Disable all interrupts */ - iow(db, DM9000_IMR, IMR_PAR); + spin_lock_irqsave(&db->lock, flags); /* Move data to DM9000 TX RAM */ writeb(DM9000_MWCMD, db->io_addr); @@ -718,12 +716,9 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) (db->outblk)(db->io_data, skb->data, skb->len); db->stats.tx_bytes += skb->len; + db->tx_pkt_cnt++; /* TX control: First packet immediately send, second packet queue */ - if (db->tx_pkt_cnt == 0) { - - /* First Packet */ - db->tx_pkt_cnt++; - + if (db->tx_pkt_cnt == 1) { /* Set TX length to DM9000 */ iow(db, DM9000_TXPLL, skb->len & 0xff); iow(db, DM9000_TXPLH, (skb->len >> 8) & 0xff); @@ -732,23 +727,17 @@ dm9000_start_xmit(struct sk_buff *skb, struct net_device *dev) iow(db, DM9000_TCR, TCR_TXREQ); /* Cleared after TX complete */ dev->trans_start = jiffies; /* save the time stamp */ - } else { /* Second packet */ - db->tx_pkt_cnt++; db->queue_pkt_len = skb->len; + netif_stop_queue(dev); } + spin_unlock_irqrestore(&db->lock, flags); + /* free this SKB */ dev_kfree_skb(skb); - /* Re-enable resource check */ - if (db->tx_pkt_cnt == 1) - netif_wake_queue(dev); - - /* Re-enable interrupt */ - iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM); - return 0; } -- cgit v1.2.3 From b23457737f073eaf5a7b797c2a195f83633e003d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 21 Aug 2007 14:34:02 -0700 Subject: sky2: clear PCI power control reg at startup Make sure PCI register for PHY power gets cleared on boot, and make sure to avoid any PCI posting problems. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 757592436390..33ba3486389e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -219,9 +219,12 @@ static void sky2_power_on(struct sky2_hw *hw) else sky2_write8(hw, B2_Y2_CLK_GATE, 0); - if (hw->chip_id == CHIP_ID_YUKON_EC_U || hw->chip_id == CHIP_ID_YUKON_EX) { + if (hw->chip_id == CHIP_ID_YUKON_EC_U || + hw->chip_id == CHIP_ID_YUKON_EX) { u32 reg; + sky2_pci_write32(hw, PCI_DEV_REG3, 0); + reg = sky2_pci_read32(hw, PCI_DEV_REG4); /* set all bits to 0 except bits 15..12 and 8 */ reg &= P_ASPM_CONTROL_MSK; @@ -238,6 +241,8 @@ static void sky2_power_on(struct sky2_hw *hw) reg = sky2_read32(hw, B2_GP_IO); reg |= GLB_GPIO_STAT_RACE_DIS; sky2_write32(hw, B2_GP_IO, reg); + + sky2_read32(hw, B2_GP_IO); } } -- cgit v1.2.3 From 32c2c30085324aef9699934295281cca0161ef7e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 21 Aug 2007 14:34:03 -0700 Subject: sky2: only bring up watchdog if link is active This fixes the extra timer overhead that people were whining about as a 2.6.23 regression. Running the watchdog timer all the time is unneeded. Change it to run only if link is up, and reduce frequency to save power. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 55 +++++++++++++++++++++++++----------------------------- drivers/net/sky2.h | 3 ++- 2 files changed, 27 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 33ba3486389e..00c5f056ef7e 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -99,10 +99,6 @@ static int disable_msi = 0; module_param(disable_msi, int, 0); MODULE_PARM_DESC(disable_msi, "Disable Message Signaled Interrupt (MSI)"); -static int idle_timeout = 100; -module_param(idle_timeout, int, 0); -MODULE_PARM_DESC(idle_timeout, "Watchdog timer for lost interrupts (ms)"); - static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) }, /* SK-9Sxx */ { PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) }, /* SK-9Exx */ @@ -1624,6 +1620,9 @@ static int sky2_down(struct net_device *dev) if (netif_msg_ifdown(sky2)) printk(KERN_INFO PFX "%s: disabling interface\n", dev->name); + if (netif_carrier_ok(dev) && --hw->active == 0) + del_timer(&hw->watchdog_timer); + /* Stop more packets from being queued */ netif_stop_queue(dev); @@ -1744,6 +1743,10 @@ static void sky2_link_up(struct sky2_port *sky2) netif_carrier_on(sky2->netdev); + if (hw->active++ == 0) + mod_timer(&hw->watchdog_timer, jiffies + 1); + + /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_ON | LINKLED_BLINK_OFF | LINKLED_LINKSYNC_OFF); @@ -1795,6 +1798,11 @@ static void sky2_link_down(struct sky2_port *sky2) netif_carrier_off(sky2->netdev); + /* Stop watchdog if both ports are not active */ + if (--hw->active == 0) + del_timer(&hw->watchdog_timer); + + /* Turn on link LED */ sky2_write8(hw, SK_REG(port, LNK_LED_REG), LINKLED_OFF); @@ -2426,25 +2434,20 @@ static void sky2_le_error(struct sky2_hw *hw, unsigned port, sky2_write32(hw, Q_ADDR(q, Q_CSR), BMU_CLR_IRQ_CHK); } -/* If idle then force a fake soft NAPI poll once a second - * to work around cases where sharing an edge triggered interrupt. - */ -static inline void sky2_idle_start(struct sky2_hw *hw) -{ - if (idle_timeout > 0) - mod_timer(&hw->idle_timer, - jiffies + msecs_to_jiffies(idle_timeout)); -} - -static void sky2_idle(unsigned long arg) +/* Check for lost IRQ once a second */ +static void sky2_watchdog(unsigned long arg) { struct sky2_hw *hw = (struct sky2_hw *) arg; - struct net_device *dev = hw->dev[0]; - if (__netif_rx_schedule_prep(dev)) - __netif_rx_schedule(dev); + if (sky2_read32(hw, B0_ISRC)) { + struct net_device *dev = hw->dev[0]; + + if (__netif_rx_schedule_prep(dev)) + __netif_rx_schedule(dev); + } - mod_timer(&hw->idle_timer, jiffies + msecs_to_jiffies(idle_timeout)); + if (hw->active > 0) + mod_timer(&hw->watchdog_timer, round_jiffies(jiffies + HZ)); } /* Hardware/software error handling */ @@ -2732,8 +2735,6 @@ static void sky2_restart(struct work_struct *work) struct net_device *dev; int i, err; - del_timer_sync(&hw->idle_timer); - rtnl_lock(); sky2_write32(hw, B0_IMSK, 0); sky2_read32(hw, B0_IMSK); @@ -2762,8 +2763,6 @@ static void sky2_restart(struct work_struct *work) } } - sky2_idle_start(hw); - rtnl_unlock(); } @@ -4030,11 +4029,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, sky2_show_addr(dev1); } - setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) hw); + setup_timer(&hw->watchdog_timer, sky2_watchdog, (unsigned long) hw); INIT_WORK(&hw->restart_work, sky2_restart); - sky2_idle_start(hw); - pci_set_drvdata(pdev, hw); return 0; @@ -4069,7 +4066,7 @@ static void __devexit sky2_remove(struct pci_dev *pdev) if (!hw) return; - del_timer_sync(&hw->idle_timer); + del_timer_sync(&hw->watchdog_timer); flush_scheduled_work(); @@ -4113,7 +4110,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) if (!hw) return 0; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { @@ -4179,7 +4175,7 @@ static int sky2_resume(struct pci_dev *pdev) } netif_poll_enable(hw->dev[0]); - sky2_idle_start(hw); + return 0; out: dev_err(&pdev->dev, "resume failed (%d)\n", err); @@ -4196,7 +4192,6 @@ static void sky2_shutdown(struct pci_dev *pdev) if (!hw) return; - del_timer_sync(&hw->idle_timer); netif_poll_disable(hw->dev[0]); for (i = 0; i < hw->ports; i++) { diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index dce4d276d443..72e12b7cfa40 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h @@ -2045,12 +2045,13 @@ struct sky2_hw { u8 chip_rev; u8 pmd_type; u8 ports; + u8 active; struct sky2_status_le *st_le; u32 st_idx; dma_addr_t st_dma; - struct timer_list idle_timer; + struct timer_list watchdog_timer; struct work_struct restart_work; int msi; wait_queue_head_t msi_wait; -- cgit v1.2.3 From c2cb71fafb4d514fbb8c9a8d663486a8f0400afa Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Tue, 21 Aug 2007 14:34:04 -0700 Subject: sky2 1.17 Mark new version to track if current driver is in use. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 00c5f056ef7e..e6d937ec6886 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -51,7 +51,7 @@ #include "sky2.h" #define DRV_NAME "sky2" -#define DRV_VERSION "1.16" +#define DRV_VERSION "1.17" #define PFX DRV_NAME " " /* -- cgit v1.2.3 From e3efb05468128e834cf17d492822333c6e189ae4 Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 22 Aug 2007 16:03:52 +0100 Subject: sgiseeq: Fix return type of sgiseeq_remove The driver remove method needs to return an int not void. This was just never noticed because usually this driver is not being built as a module. Signed-off-by: Ralf Baechle Signed-off-by: Jeff Garzik --- drivers/net/sgiseeq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c index 384b4685e977..0fb74cb51c4b 100644 --- a/drivers/net/sgiseeq.c +++ b/drivers/net/sgiseeq.c @@ -726,7 +726,7 @@ err_out: return err; } -static void __exit sgiseeq_remove(struct platform_device *pdev) +static int __exit sgiseeq_remove(struct platform_device *pdev) { struct net_device *dev = platform_get_drvdata(pdev); struct sgiseeq_private *sp = netdev_priv(dev); @@ -735,6 +735,8 @@ static void __exit sgiseeq_remove(struct platform_device *pdev) free_page((unsigned long) sp->srings); free_netdev(dev); platform_set_drvdata(pdev, NULL); + + return 0; } static struct platform_driver sgiseeq_driver = { -- cgit v1.2.3 From a8e34fda798861d0f3f12c2739c1bec258be8bed Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Wed, 22 Aug 2007 16:20:58 +0200 Subject: ehea: fix interface to DLPAR tools Userspace DLPAR tool expects decimal numbers to be written to and read from sysfs entries. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 9756211e83ce..22d000f50efa 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -2490,7 +2490,7 @@ static ssize_t ehea_show_port_id(struct device *dev, struct device_attribute *attr, char *buf) { struct ehea_port *port = container_of(dev, struct ehea_port, ofdev.dev); - return sprintf(buf, "0x%X", port->logical_port_id); + return sprintf(buf, "%d", port->logical_port_id); } static DEVICE_ATTR(log_port_id, S_IRUSR | S_IRGRP | S_IROTH, ehea_show_port_id, @@ -2781,7 +2781,7 @@ static ssize_t ehea_probe_port(struct device *dev, u32 logical_port_id; - sscanf(buf, "%X", &logical_port_id); + sscanf(buf, "%d", &logical_port_id); port = ehea_get_port(adapter, logical_port_id); @@ -2834,7 +2834,7 @@ static ssize_t ehea_remove_port(struct device *dev, int i; u32 logical_port_id; - sscanf(buf, "%X", &logical_port_id); + sscanf(buf, "%d", &logical_port_id); port = ehea_get_port(adapter, logical_port_id); -- cgit v1.2.3 From 18072a5bf7211d6899a2edc90c291c5c6fbc83d2 Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Wed, 22 Aug 2007 16:21:24 +0200 Subject: ehea: fix module parameter description Update the module parameter description of "use_mcs" to show correct default value Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index 22d000f50efa..db5747490a07 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -76,7 +76,7 @@ MODULE_PARM_DESC(rq1_entries, "Number of entries for Receive Queue 1 " MODULE_PARM_DESC(sq_entries, " Number of entries for the Send Queue " "[2^x - 1], x = [6..14]. Default = " __MODULE_STRING(EHEA_DEF_ENTRIES_SQ) ")"); -MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 1 "); +MODULE_PARM_DESC(use_mcs, " 0:NAPI, 1:Multiple receive queues, Default = 0 "); static int port_name_cnt = 0; static LIST_HEAD(adapter_list); -- cgit v1.2.3 From 28721c890c9b71cfee45e835bda4639777862e2f Mon Sep 17 00:00:00 2001 From: Jan-Bernd Themann Date: Wed, 22 Aug 2007 16:21:28 +0200 Subject: ehea: fix queue destructor Includes hcp_epas_dtor in eq/cq/qp destructors to unmap HW register. Signed-off-by: Jan-Bernd Themann Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_qmr.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c index a36fa6c23fdf..c82e24596074 100644 --- a/drivers/net/ehea/ehea_qmr.c +++ b/drivers/net/ehea/ehea_qmr.c @@ -235,6 +235,8 @@ int ehea_destroy_cq(struct ehea_cq *cq) if (!cq) return 0; + hcp_epas_dtor(&cq->epas); + if ((hret = ehea_destroy_cq_res(cq, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(cq->adapter, cq->fw_handle); hret = ehea_destroy_cq_res(cq, FORCE_FREE); @@ -361,6 +363,8 @@ int ehea_destroy_eq(struct ehea_eq *eq) if (!eq) return 0; + hcp_epas_dtor(&eq->epas); + if ((hret = ehea_destroy_eq_res(eq, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(eq->adapter, eq->fw_handle); hret = ehea_destroy_eq_res(eq, FORCE_FREE); @@ -541,6 +545,8 @@ int ehea_destroy_qp(struct ehea_qp *qp) if (!qp) return 0; + hcp_epas_dtor(&qp->epas); + if ((hret = ehea_destroy_qp_res(qp, NORMAL_FREE)) == H_R_STATE) { ehea_error_data(qp->adapter, qp->fw_handle); hret = ehea_destroy_qp_res(qp, FORCE_FREE); -- cgit v1.2.3 From 302d242cfb64eb53fb6d2aa2ae68ddd1ab47079f Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Fri, 24 Aug 2007 08:57:17 +0200 Subject: myri10ge: use pcie_get/set_readrq Based on a patch from Peter Oruba, convert myri10ge to use pcie_get_readrq() and pcie_set_readrq() instead of our own PCI calls and arithmetics. These driver changes incorporate the proposed PCI-X / PCI-Express read byte count interface. Reading and setting those values doesn't take place "manually", instead wrapping functions are called to allow quirks for some PCI bridges. Signed-off-by: Brice Goglin Signed-off by: Peter Oruba Based on work by Stephen Hemminger Signed-off-by: Andrew Morton Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 32 ++++++-------------------------- 1 file changed, 6 insertions(+), 26 deletions(-) (limited to 'drivers') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index ae9bb7b7fd67..3f9fb3405ac7 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -2514,26 +2514,20 @@ static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) { struct pci_dev *pdev = mgp->pdev; struct device *dev = &pdev->dev; - int cap, status; - u16 val; + int status; mgp->tx.boundary = 4096; /* * Verify the max read request size was set to 4KB * before trying the test with 4KB. */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { + status = pcie_get_readrq(pdev); + if (status < 0) { dev_err(dev, "Couldn't read max read req size: %d\n", status); goto abort; } - if ((val & (5 << 12)) != (5 << 12)) { - dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val); + if (status != 4096) { + dev_warn(dev, "Max Read Request size != 4096 (%d)\n", status); mgp->tx.boundary = 2048; } /* @@ -2850,9 +2844,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) size_t bytes; int i; int status = -ENXIO; - int cap; int dac_enabled; - u16 val; netdev = alloc_etherdev(sizeof(*mgp)); if (netdev == NULL) { @@ -2884,19 +2876,7 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) = pci_find_capability(pdev, PCI_CAP_ID_VNDR); /* Set our max read request to 4KB */ - cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); - if (cap < 64) { - dev_err(&pdev->dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); - goto abort_with_netdev; - } - status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); - if (status != 0) { - dev_err(&pdev->dev, "Error %d reading PCI_EXP_DEVCTL\n", - status); - goto abort_with_netdev; - } - val = (val & ~PCI_EXP_DEVCTL_READRQ) | (5 << 12); - status = pci_write_config_word(pdev, cap + PCI_EXP_DEVCTL, val); + status = pcie_set_readrq(pdev, 4096); if (status != 0) { dev_err(&pdev->dev, "Error %d writing PCI_EXP_DEVCTL\n", status); -- cgit v1.2.3 From 2972863768cc2ef94734abb22dec6a46b0891307 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Fri, 24 Aug 2007 08:57:54 +0200 Subject: myri10ge: update driver version to 1.3.2-1.269 Update myri10ge driver version to 1.3.2-1.269. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3f9fb3405ac7..1c42266bf889 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -72,7 +72,7 @@ #include "myri10ge_mcp.h" #include "myri10ge_mcp_gen_header.h" -#define MYRI10GE_VERSION_STR "1.3.1-1.248" +#define MYRI10GE_VERSION_STR "1.3.2-1.269" MODULE_DESCRIPTION("Myricom 10G driver (10GbE)"); MODULE_AUTHOR("Maintainer: help@myri.com"); -- cgit v1.2.3 From e120e8d03a263cf75f2abc0f8b3a03a65cfd3b88 Mon Sep 17 00:00:00 2001 From: Olaf Hering Date: Sat, 25 Aug 2007 05:42:01 +1000 Subject: [POWERPC] Fix undefined reference to device_power_up/resume Current Linus tree fails to link on pmac32: drivers/built-in.o: In function `pmac_wakeup_devices': via-pmu.c:(.text+0x5bab4): undefined reference to `device_power_up' via-pmu.c:(.text+0x5bb08): undefined reference to `device_resume' drivers/built-in.o: In function `pmac_suspend_devices': via-pmu.c:(.text+0x5c260): undefined reference to `device_power_down' via-pmu.c:(.text+0x5c27c): undefined reference to `device_resume' make[1]: *** [.tmp_vmlinux1] Error 1 changing CONFIG_PM > CONFIG_PM_SLEEP leads to: drivers/built-in.o: In function `pmu_led_set': via-pmu-led.c:(.text+0x5cdca): undefined reference to `pmu_sys_suspended' via-pmu-led.c:(.text+0x5cdce): undefined reference to `pmu_sys_suspended' drivers/built-in.o: In function `pmu_req_done': via-pmu-led.c:(.text+0x5ce3e): undefined reference to `pmu_sys_suspended' via-pmu-led.c:(.text+0x5ce42): undefined reference to `pmu_sys_suspended' drivers/built-in.o: In function `adb_init': (.init.text+0x4c5c): undefined reference to `pmu_register_sleep_notifier' make[1]: *** [.tmp_vmlinux1] Error 1 So change even more places from PM to PM_SLEEP to allow linking. Signed-off-by: Olaf Hering Signed-off-by: Paul Mackerras --- drivers/macintosh/adb.c | 4 ++-- drivers/macintosh/via-pmu.c | 34 +++++++++++++++++----------------- include/linux/pmu.h | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index bc77c5e2ca9f..5c742a526082 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -89,7 +89,7 @@ static int sleepy_trackpad; static int autopoll_devs; int __adb_probe_sync; -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static void adb_notify_sleep(struct pmu_sleep_notifier *self, int when); static struct pmu_sleep_notifier adb_sleep_notifier = { adb_notify_sleep, @@ -313,7 +313,7 @@ int __init adb_init(void) printk(KERN_WARNING "Warning: no ADB interface detected\n"); adb_controller = NULL; } else { -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP pmu_register_sleep_notifier(&adb_sleep_notifier); #endif /* CONFIG_PM */ #ifdef CONFIG_PPC diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index 157080b3b468..04f3973e3874 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -152,10 +152,10 @@ static spinlock_t pmu_lock; static u8 pmu_intr_mask; static int pmu_version; static int drop_interrupts; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) static int option_lid_wakeup = 1; -#endif /* CONFIG_PM && CONFIG_PPC32 */ -#if (defined(CONFIG_PM)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ +#if (defined(CONFIG_PM_SLEEP)&&defined(CONFIG_PPC32))||defined(CONFIG_PMAC_BACKLIGHT_LEGACY) static int sleep_in_progress; #endif static unsigned long async_req_locks; @@ -875,7 +875,7 @@ proc_read_options(char *page, char **start, off_t off, { char *p = page; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) if (pmu_kind == PMU_KEYLARGO_BASED && pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) p += sprintf(p, "lid_wakeup=%d\n", option_lid_wakeup); @@ -916,7 +916,7 @@ proc_write_options(struct file *file, const char __user *buffer, *(val++) = 0; while(*val == ' ') val++; -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) if (pmu_kind == PMU_KEYLARGO_BASED && pmac_call_feature(PMAC_FTR_SLEEP_STATE,NULL,0,-1) >= 0) if (!strcmp(label, "lid_wakeup")) @@ -1738,7 +1738,7 @@ pmu_present(void) return via != 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static LIST_HEAD(sleep_notifiers); @@ -1769,9 +1769,9 @@ pmu_unregister_sleep_notifier(struct pmu_sleep_notifier* n) return 0; } EXPORT_SYMBOL(pmu_unregister_sleep_notifier); -#endif /* CONFIG_PM */ +#endif /* CONFIG_PM_SLEEP */ -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) /* Sleep is broadcast last-to-first */ static void broadcast_sleep(int when) @@ -2390,7 +2390,7 @@ powerbook_sleep_3400(void) return 0; } -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ /* * Support for /dev/pmu device @@ -2573,7 +2573,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, int error = -EINVAL; switch (cmd) { -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) case PMU_IOC_SLEEP: if (!capable(CAP_SYS_ADMIN)) return -EACCES; @@ -2601,7 +2601,7 @@ pmu_ioctl(struct inode * inode, struct file *filp, return put_user(0, argp); else return put_user(1, argp); -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ #ifdef CONFIG_PMAC_BACKLIGHT_LEGACY /* Compatibility ioctl's for backlight */ @@ -2757,7 +2757,7 @@ pmu_polled_request(struct adb_request *req) * to do suspend-to-disk. */ -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) int pmu_sys_suspended; @@ -2792,7 +2792,7 @@ static int pmu_sys_resume(struct sys_device *sysdev) return 0; } -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ static struct sysdev_class pmu_sysclass = { set_kset_name("pmu"), @@ -2803,10 +2803,10 @@ static struct sys_device device_pmu = { }; static struct sysdev_driver driver_pmu = { -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) .suspend = &pmu_sys_suspend, .resume = &pmu_sys_resume, -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ }; static int __init init_pmu_sysfs(void) @@ -2841,10 +2841,10 @@ EXPORT_SYMBOL(pmu_wait_complete); EXPORT_SYMBOL(pmu_suspend); EXPORT_SYMBOL(pmu_resume); EXPORT_SYMBOL(pmu_unlock); -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) EXPORT_SYMBOL(pmu_enable_irled); EXPORT_SYMBOL(pmu_battery_count); EXPORT_SYMBOL(pmu_batteries); EXPORT_SYMBOL(pmu_power_flags); -#endif /* CONFIG_PM && CONFIG_PPC32 */ +#endif /* CONFIG_PM_SLEEP && CONFIG_PPC32 */ diff --git a/include/linux/pmu.h b/include/linux/pmu.h index 5ad913ff02b2..b7824c215354 100644 --- a/include/linux/pmu.h +++ b/include/linux/pmu.h @@ -226,7 +226,7 @@ extern unsigned int pmu_power_flags; extern void pmu_backlight_init(void); /* some code needs to know if the PMU was suspended for hibernation */ -#if defined(CONFIG_PM) && defined(CONFIG_PPC32) +#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PPC32) extern int pmu_sys_suspended; #else /* if power management is not configured it can't be suspended */ -- cgit v1.2.3 From 32ddef98f232585f20bc8bdb891029a6a5f633d0 Mon Sep 17 00:00:00 2001 From: Xavier Bachelot Date: Sat, 25 Aug 2007 18:10:52 +1000 Subject: agp: Add device id for P4M900 to via-agp module Signed-off-by: Dave Airlie --- drivers/char/agp/via-agp.c | 5 +++++ include/linux/pci_ids.h | 1 + 2 files changed, 6 insertions(+) (limited to 'drivers') diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 9aaf401a8975..0ecc54d327bc 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -399,6 +399,11 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata = .device_id = PCI_DEVICE_ID_VIA_P4M890, .chipset_name = "P4M890", }, + /* P4M900 */ + { + .device_id = PCI_DEVICE_ID_VIA_VT3364, + .chipset_name = "P4M900", + }, { }, /* dummy final entry, always present */ }; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 07fc57429b58..0d58a39017de 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1287,6 +1287,7 @@ #define PCI_DEVICE_ID_VIA_VT3324 0x0324 #define PCI_DEVICE_ID_VIA_VT3336 0x0336 #define PCI_DEVICE_ID_VIA_VT3351 0x0351 +#define PCI_DEVICE_ID_VIA_VT3364 0x0364 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 #define PCI_DEVICE_ID_VIA_8501_0 0x0501 #define PCI_DEVICE_ID_VIA_82C561 0x0561 -- cgit v1.2.3 From 5bdbc7dc2c07d507b41bffdadc2c8cc13b2d4326 Mon Sep 17 00:00:00 2001 From: Scott Thompson Date: Sat, 25 Aug 2007 18:14:00 +1000 Subject: agp: balance ioremap checks patchset against 2.6.23-rc3. corrects missing ioremap return checks and balancing on iounmap calls, integrated changes per list recommendations on the original set of patches.. Signed-off-by: Scott Thompson hushmail.com> Signed-off-by: Dave Airlie --- drivers/char/agp/amd-k7-agp.c | 2 ++ drivers/char/agp/ati-agp.c | 3 +++ drivers/char/agp/hp-agp.c | 1 + drivers/char/agp/i460-agp.c | 4 ++++ drivers/char/agp/intel-agp.c | 14 +++++++++----- drivers/char/agp/nvidia-agp.c | 3 +++ 6 files changed, 22 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index df0ddf14b85c..f60bca70d1fb 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -223,6 +223,8 @@ static int amd_irongate_configure(void) pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp); temp = (temp & PCI_BASE_ADDRESS_MEM_MASK); amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!amd_irongate_private.registers) + return -ENOMEM; /* Write out the address of the gatt table */ writel(agp_bridge->gatt_bus_addr, amd_irongate_private.registers+AMD_ATTBASE); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index da7513d7b4e7..2d46b713c8f2 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -213,6 +213,9 @@ static int ati_configure(void) temp = (temp & 0xfffff000); ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096); + if (!ati_generic_private.registers) + return -ENOMEM; + if (is_r200()) pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000); else diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c index bcdb149c8179..313a133a1172 100644 --- a/drivers/char/agp/hp-agp.c +++ b/drivers/char/agp/hp-agp.c @@ -221,6 +221,7 @@ hp_zx1_lba_init (u64 hpa) if (cap != PCI_CAP_ID_AGP) { printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n", cap, hp->lba_cap_offset); + iounmap(hp->lba_regs); return -ENODEV; } diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 53354bf83af7..75d2aca6353d 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -249,6 +249,10 @@ static int i460_create_gatt_table (struct agp_bridge_data *bridge) num_entries = A_SIZE_8(temp)->num_entries; i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order); + if (!i460.gatt) { + printk(KERN_ERR PFX "ioremap failed\n"); + return -ENOMEM; + } /* These are no good, the should be removed from the agp_bridge strucure... */ agp_bridge->gatt_table_real = NULL; diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index 294cdbf4d44d..2c9ca2c64628 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -930,8 +930,10 @@ static int intel_i915_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff80000; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) + if (!intel_private.registers) { + iounmap(intel_private.gtt); return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ @@ -985,13 +987,15 @@ static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) temp &= 0xfff00000; intel_private.gtt = ioremap((temp + (512 * 1024)) , 512 * 1024); - if (!intel_private.gtt) - return -ENOMEM; + if (!intel_private.gtt) + return -ENOMEM; intel_private.registers = ioremap(temp,128 * 4096); - if (!intel_private.registers) - return -ENOMEM; + if (!intel_private.registers) { + iounmap(intel_private.gtt); + return -ENOMEM; + } temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; global_cache_flush(); /* FIXME: ? */ diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index 6cd7373dcdf4..225ed2a53d45 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -157,6 +157,9 @@ static int nvidia_configure(void) nvidia_private.aperture = (volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE); + if (!nvidia_private.aperture) + return -ENOMEM; + return 0; } -- cgit v1.2.3 From 0769d39c993145754852b517ddd9c11586f0a014 Mon Sep 17 00:00:00 2001 From: Scott Thompson Date: Sat, 25 Aug 2007 18:17:49 +1000 Subject: drm: ioremap return value checks Signed-off-by: Scott Thompson hushmail.com> Signed-off-by: Dave Airlie --- drivers/char/drm/drm_bufs.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 3d1ec8234b8b..c115b39b8517 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c @@ -177,8 +177,14 @@ static int drm_addmap_core(struct drm_device * dev, unsigned int offset, MTRR_TYPE_WRCOMB, 1); } } - if (map->type == _DRM_REGISTERS) + if (map->type == _DRM_REGISTERS) { map->handle = ioremap(map->offset, map->size); + if (!map->handle) { + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + return -ENOMEM; + } + } + break; case _DRM_SHM: list = drm_find_matching_map(dev, map); -- cgit v1.2.3 From a2ee3f9bbb0ce57102dad8928d54f59acdc4b8f7 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 11 Aug 2007 11:51:16 +0200 Subject: ieee1394: sbp2: fix sbp2_remove_device for error cases Bug found by Olaf Hering : sbp2util_remove_command_orb_pool requires a valid lu->hi pointer. Signed-off-by: Stefan Richter --- drivers/ieee1394/sbp2.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c index 47dbe8f17e82..a81ba8fca0db 100644 --- a/drivers/ieee1394/sbp2.c +++ b/drivers/ieee1394/sbp2.c @@ -513,9 +513,9 @@ static int sbp2util_create_command_orb_pool(struct sbp2_lu *lu) return 0; } -static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu) +static void sbp2util_remove_command_orb_pool(struct sbp2_lu *lu, + struct hpsb_host *host) { - struct hpsb_host *host = lu->hi->host; struct list_head *lh, *next; struct sbp2_command_info *cmd; unsigned long flags; @@ -922,15 +922,16 @@ static void sbp2_remove_device(struct sbp2_lu *lu) if (!lu) return; - hi = lu->hi; + if (!hi) + goto no_hi; if (lu->shost) { scsi_remove_host(lu->shost); scsi_host_put(lu->shost); } flush_scheduled_work(); - sbp2util_remove_command_orb_pool(lu); + sbp2util_remove_command_orb_pool(lu, hi->host); list_del(&lu->lu_list); @@ -971,9 +972,8 @@ static void sbp2_remove_device(struct sbp2_lu *lu) lu->ud->device.driver_data = NULL; - if (hi) - module_put(hi->host->driver->owner); - + module_put(hi->host->driver->owner); +no_hi: kfree(lu); } -- cgit v1.2.3 From 8a2d9ed3210464d22fccb9834970629c1c36fa36 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Tue, 21 Aug 2007 01:05:14 +0200 Subject: firewire: fix unloading of fw-ohci while devices are attached Fix panic in run_timer_softirq right after "modprobe -r firewire-ohci" if a FireWire disk was attached and firewire-sbp2 loaded. Signed-off-by: Stefan Richter --- drivers/firewire/fw-card.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-card.c b/drivers/firewire/fw-card.c index 0aeab3218bb6..3e9719948a8e 100644 --- a/drivers/firewire/fw-card.c +++ b/drivers/firewire/fw-card.c @@ -510,9 +510,11 @@ fw_core_remove_card(struct fw_card *card) /* Set up the dummy driver. */ card->driver = &dummy_driver; - fw_flush_transactions(card); - fw_destroy_nodes(card); + flush_scheduled_work(); + + fw_flush_transactions(card); + del_timer_sync(&card->flush_timer); fw_card_put(card); } -- cgit v1.2.3 From e57d2011a6276d55a87f26653a0395f302ce0d51 Mon Sep 17 00:00:00 2001 From: Kristian Høgsberg Date: Fri, 24 Aug 2007 18:59:58 -0400 Subject: firewire: Add ref-counting for sbp2 orbs (fix command abortion) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This handles the case where we get the status write before getting the complete_transaction callback ("status write for unknown orb"). In this case, we just assume that the initial orb pointer transaction succeeded and finish the orb. To prevent the transaction callback from touching freed memory, we ref-count the orb structures. Signed-off-by: Kristian Høgsberg Signed-off-by: Stefan Richter --- drivers/firewire/fw-sbp2.c | 49 +++++++++++++++++++++++++++++++++++++--------- 1 file changed, 40 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/firewire/fw-sbp2.c b/drivers/firewire/fw-sbp2.c index ba816ef6def1..238730f75db1 100644 --- a/drivers/firewire/fw-sbp2.c +++ b/drivers/firewire/fw-sbp2.c @@ -159,6 +159,7 @@ struct sbp2_pointer { struct sbp2_orb { struct fw_transaction t; + struct kref kref; dma_addr_t request_bus; int rcode; struct sbp2_pointer pointer; @@ -279,6 +280,14 @@ static const struct { } }; +static void +free_orb(struct kref *kref) +{ + struct sbp2_orb *orb = container_of(kref, struct sbp2_orb, kref); + + kfree(orb); +} + static void sbp2_status_write(struct fw_card *card, struct fw_request *request, int tcode, int destination, int source, @@ -312,8 +321,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request, spin_lock_irqsave(&card->lock, flags); list_for_each_entry(orb, &sd->orb_list, link) { if (STATUS_GET_ORB_HIGH(status) == 0 && - STATUS_GET_ORB_LOW(status) == orb->request_bus && - orb->rcode == RCODE_COMPLETE) { + STATUS_GET_ORB_LOW(status) == orb->request_bus) { + orb->rcode = RCODE_COMPLETE; list_del(&orb->link); break; } @@ -325,6 +334,8 @@ sbp2_status_write(struct fw_card *card, struct fw_request *request, else fw_error("status write for unknown orb\n"); + kref_put(&orb->kref, free_orb); + fw_send_response(card, request, RCODE_COMPLETE); } @@ -335,13 +346,27 @@ complete_transaction(struct fw_card *card, int rcode, struct sbp2_orb *orb = data; unsigned long flags; - orb->rcode = rcode; - if (rcode != RCODE_COMPLETE) { - spin_lock_irqsave(&card->lock, flags); + /* + * This is a little tricky. We can get the status write for + * the orb before we get this callback. The status write + * handler above will assume the orb pointer transaction was + * successful and set the rcode to RCODE_COMPLETE for the orb. + * So this callback only sets the rcode if it hasn't already + * been set and only does the cleanup if the transaction + * failed and we didn't already get a status write. + */ + spin_lock_irqsave(&card->lock, flags); + + if (orb->rcode == -1) + orb->rcode = rcode; + if (orb->rcode != RCODE_COMPLETE) { list_del(&orb->link); - spin_unlock_irqrestore(&card->lock, flags); orb->callback(orb, NULL); } + + spin_unlock_irqrestore(&card->lock, flags); + + kref_put(&orb->kref, free_orb); } static void @@ -360,6 +385,10 @@ sbp2_send_orb(struct sbp2_orb *orb, struct fw_unit *unit, list_add_tail(&orb->link, &sd->orb_list); spin_unlock_irqrestore(&device->card->lock, flags); + /* Take a ref for the orb list and for the transaction callback. */ + kref_get(&orb->kref); + kref_get(&orb->kref); + fw_send_request(device->card, &orb->t, TCODE_WRITE_BLOCK_REQUEST, node_id, generation, device->max_speed, offset, &orb->pointer, sizeof(orb->pointer), @@ -416,6 +445,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (orb == NULL) return -ENOMEM; + kref_init(&orb->base.kref); orb->response_bus = dma_map_single(device->card->device, &orb->response, sizeof(orb->response), DMA_FROM_DEVICE); @@ -490,7 +520,7 @@ sbp2_send_management_orb(struct fw_unit *unit, int node_id, int generation, if (response) fw_memcpy_from_be32(response, orb->response, sizeof(orb->response)); - kfree(orb); + kref_put(&orb->base.kref, free_orb); return retval; } @@ -886,7 +916,6 @@ complete_command_orb(struct sbp2_orb *base_orb, struct sbp2_status *status) orb->cmd->result = result; orb->done(orb->cmd); - kfree(orb); } static int sbp2_command_orb_map_scatterlist(struct sbp2_command_orb *orb) @@ -1005,6 +1034,7 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) /* Initialize rcode to something not RCODE_COMPLETE. */ orb->base.rcode = -1; + kref_init(&orb->base.kref); orb->unit = unit; orb->done = done; @@ -1051,10 +1081,11 @@ static int sbp2_scsi_queuecommand(struct scsi_cmnd *cmd, scsi_done_fn_t done) sbp2_send_orb(&orb->base, unit, sd->node_id, sd->generation, sd->command_block_agent_address + SBP2_ORB_POINTER); + kref_put(&orb->base.kref, free_orb); return 0; fail_mapping: - kfree(orb); + kref_put(&orb->base.kref, free_orb); fail_alloc: return SCSI_MLQUEUE_HOST_BUSY; } -- cgit v1.2.3 From 9f90a03a7f93be7f247aa902a7d962a56a6f600e Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Sun, 19 Aug 2007 22:32:10 +0900 Subject: [PATCH] rtc: Make rtc-rs5c348 driver hotplug-aware The rtc-rs5c348 SPI driver name doesn't match its module name, which prevents it from properly hotplugging. There is only one in-tree user of its driver, which is fixed by this patch too. Signed-off-by: Atsushi Nemoto Acked-by: David Brownell Signed-off-by: Ralf Baechle --- arch/mips/tx4938/toshiba_rbtx4938/setup.c | 2 +- drivers/rtc/rtc-rs5c348.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 57f3c705d082..84ebff711e6e 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -1115,7 +1115,7 @@ static void __init txx9_spi_init(unsigned long base, int irq) static int __init rbtx4938_spi_init(void) { struct spi_board_info srtc_info = { - .modalias = "rs5c348", + .modalias = "rtc-rs5c348", .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ .bus_num = 0, .chip_select = 16 + SRTC_CS, diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index f50f3fc353cd..839462659afa 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c @@ -226,7 +226,7 @@ static int __devexit rs5c348_remove(struct spi_device *spi) static struct spi_driver rs5c348_driver = { .driver = { - .name = "rs5c348", + .name = "rtc-rs5c348", .bus = &spi_bus_type, .owner = THIS_MODULE, }, -- cgit v1.2.3 From db15f3626df80cebd69b69494c90528aae483caf Mon Sep 17 00:00:00 2001 From: Ralf Baechle Date: Wed, 22 Aug 2007 22:48:08 +0100 Subject: [MIPS] Delete duplicate inclusion of . Signed-off-by: Ralf Baechle --- drivers/char/lcd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers') diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c index 1f0962616ee5..4fe9206f84de 100644 --- a/drivers/char/lcd.c +++ b/drivers/char/lcd.c @@ -25,7 +25,6 @@ #include #include #include -#include #include "lcd.h" -- cgit v1.2.3 From 37d2e7316007b4583e5783c608efdd3b2284b74d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 24 Aug 2007 22:37:49 -0700 Subject: [EQL]: sparse warning fix More noodlin on long flights, patch bin. Sparse warning fix for eql. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/eql.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/eql.c b/drivers/net/eql.c index a93700e5661a..102218c4a907 100644 --- a/drivers/net/eql.c +++ b/drivers/net/eql.c @@ -391,7 +391,7 @@ static int __eql_insert_slave(slave_queue_t *queue, slave_t *slave) slave_t *duplicate_slave = NULL; duplicate_slave = __eql_find_slave_dev(queue, slave->dev); - if (duplicate_slave != 0) + if (duplicate_slave) eql_kill_one_slave(queue, duplicate_slave); list_add(&slave->list, &queue->all_slaves); -- cgit v1.2.3 From 97a1ad431b89765755d2b5aa8c0777ed637d5c4a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 24 Aug 2007 22:38:26 -0700 Subject: [SLIP]: trivial sparse warning fix Function declared static in forward declaration, but not in actual code. Signed-off-by: Stephen Hemminger Signed-off-by: David S. Miller --- drivers/net/slip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/slip.c b/drivers/net/slip.c index 65bd20fac820..3fd4735006f5 100644 --- a/drivers/net/slip.c +++ b/drivers/net/slip.c @@ -957,7 +957,7 @@ slip_close(struct tty_struct *tty) * STANDARD SLIP ENCAPSULATION * ************************************************************************/ -int +static int slip_esc(unsigned char *s, unsigned char *d, int len) { unsigned char *ptr = d; -- cgit v1.2.3 From e4223976341ffb22fabe5b3a69873966808c83aa Mon Sep 17 00:00:00 2001 From: Shannon Nelson Date: Fri, 24 Aug 2007 23:02:53 -0700 Subject: [IOAT]: ioatdma needs to to play nice in a multi-dma-client world Now that the DMA engine has a multi-client interface, fix the ioatdma driver to play along. At the same time, remove a couple of unnecessary reads and writes. Signed-off-by: Shannon Nelson Signed-off-by: David S. Miller --- drivers/dma/ioatdma.c | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioatdma.c index 2d1f17865b64..41b18c5a3141 100644 --- a/drivers/dma/ioatdma.c +++ b/drivers/dma/ioatdma.c @@ -191,17 +191,12 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) int i; LIST_HEAD(tmp_list); - /* - * In-use bit automatically set by reading chanctrl - * If 0, we got it, if 1, someone else did - */ - chanctrl = readw(ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); - if (chanctrl & IOAT_CHANCTRL_CHANNEL_IN_USE) - return -EBUSY; + /* have we already been set up? */ + if (!list_empty(&ioat_chan->free_desc)) + return INITIAL_IOAT_DESC_COUNT; /* Setup register to interrupt and write completion status on error */ - chanctrl = IOAT_CHANCTRL_CHANNEL_IN_USE | - IOAT_CHANCTRL_ERR_INT_EN | + chanctrl = IOAT_CHANCTRL_ERR_INT_EN | IOAT_CHANCTRL_ANY_ERR_ABORT_EN | IOAT_CHANCTRL_ERR_COMPLETION_EN; writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); @@ -282,11 +277,6 @@ static void ioat_dma_free_chan_resources(struct dma_chan *chan) in_use_descs - 1); ioat_chan->last_completion = ioat_chan->completion_addr = 0; - - /* Tell hw the chan is free */ - chanctrl = readw(ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); - chanctrl &= ~IOAT_CHANCTRL_CHANNEL_IN_USE; - writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); } static struct dma_async_tx_descriptor * -- cgit v1.2.3 From 901ded25fb98d76e55a8920834b173e7efc026b6 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Aug 2007 23:23:41 -0700 Subject: [IRDA]: Do not do pointless kmalloc return value cast in KingSun driver kmalloc() returns a void pointer, so there is no need to cast it in drivers/net/irda/kingsun-sir.c::kingsun_probe(). Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/irda/kingsun-sir.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/irda/kingsun-sir.c b/drivers/net/irda/kingsun-sir.c index bdd5c979bead..4e5101a45c3c 100644 --- a/drivers/net/irda/kingsun-sir.c +++ b/drivers/net/irda/kingsun-sir.c @@ -509,12 +509,12 @@ static int kingsun_probe(struct usb_interface *intf, spin_lock_init(&kingsun->lock); /* Allocate input buffer */ - kingsun->in_buf = (__u8 *)kmalloc(kingsun->max_rx, GFP_KERNEL); + kingsun->in_buf = kmalloc(kingsun->max_rx, GFP_KERNEL); if (!kingsun->in_buf) goto free_mem; /* Allocate output buffer */ - kingsun->out_buf = (__u8 *)kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); + kingsun->out_buf = kmalloc(KINGSUN_FIFO_SIZE, GFP_KERNEL); if (!kingsun->out_buf) goto free_mem; -- cgit v1.2.3 From c573f73ce95d7e421cb4b9928dd41ac9518fcccf Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Aug 2007 23:24:43 -0700 Subject: [NET]: Avoid pointless allocation casts in BSD compression module The general kernel memory allocation functions return void pointers and there is no need to cast their return values. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/net/bsd_comp.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bsd_comp.c b/drivers/net/bsd_comp.c index 202d4a4ef751..88edb986691a 100644 --- a/drivers/net/bsd_comp.c +++ b/drivers/net/bsd_comp.c @@ -406,8 +406,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = (struct bsd_dict *) vmalloc (hsize * - sizeof (struct bsd_dict)); + db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); if (!db->dict) { bsd_free (db); @@ -426,8 +425,7 @@ static void *bsd_alloc (unsigned char *options, int opt_len, int decomp) */ else { - db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) * - sizeof (db->lens[0])); + db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); if (!db->lens) { bsd_free (db); -- cgit v1.2.3 From 7c8347a91dbbb723d8ed106ec817dabac97f2bbc Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Aug 2007 23:25:33 -0700 Subject: [ISDN]: Get rid of some pointless allocation casts in common and bsd comp. vmalloc() returns a void pointer - no need to cast the return value. Signed-off-by: Jesper Juhl Signed-off-by: David S. Miller --- drivers/isdn/i4l/isdn_bsdcomp.c | 5 ++--- drivers/isdn/i4l/isdn_common.c | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/isdn/i4l/isdn_bsdcomp.c b/drivers/isdn/i4l/isdn_bsdcomp.c index 90a23795db7e..02d9918705dd 100644 --- a/drivers/isdn/i4l/isdn_bsdcomp.c +++ b/drivers/isdn/i4l/isdn_bsdcomp.c @@ -341,7 +341,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data) * Allocate space for the dictionary. This may be more than one page in * length. */ - db->dict = (struct bsd_dict *) vmalloc (hsize * sizeof (struct bsd_dict)); + db->dict = vmalloc(hsize * sizeof(struct bsd_dict)); if (!db->dict) { bsd_free (db); return NULL; @@ -354,8 +354,7 @@ static void *bsd_alloc (struct isdn_ppp_comp_data *data) if (!decomp) db->lens = NULL; else { - db->lens = (unsigned short *) vmalloc ((maxmaxcode + 1) * - sizeof (db->lens[0])); + db->lens = vmalloc((maxmaxcode + 1) * sizeof(db->lens[0])); if (!db->lens) { bsd_free (db); return (NULL); diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c index c97330b19877..ec5f4046412f 100644 --- a/drivers/isdn/i4l/isdn_common.c +++ b/drivers/isdn/i4l/isdn_common.c @@ -2291,7 +2291,7 @@ static int __init isdn_init(void) int i; char tmprev[50]; - if (!(dev = (isdn_dev *) vmalloc(sizeof(isdn_dev)))) { + if (!(dev = vmalloc(sizeof(isdn_dev)))) { printk(KERN_WARNING "isdn: Could not allocate device-struct.\n"); return -EIO; } -- cgit v1.2.3 From 1bd4b280394cdd14f82efc00808c6d77b097285a Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 24 Aug 2007 22:05:44 -0700 Subject: [SUNVDC]: Use slice 0xff on VD_DISK_TYPE_DISK. While debugging issues with the VDS server I made the driver use partition 2 to get at the whole disk since this is the "whole disk" partition in the Sun disk label. We really should use slice 0xff which really means the whole physical disk in the VIO disk protocol. Otherwise things won't work well on a disk image that doesn't have a proper disk label on it. Signed-off-by: David S. Miller --- drivers/block/sunvdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c index 4dff49256ac2..317a790c153b 100644 --- a/drivers/block/sunvdc.c +++ b/drivers/block/sunvdc.c @@ -417,7 +417,7 @@ static int __send_request(struct request *req) desc->req_id = port->req_id; desc->operation = op; if (port->vdisk_type == VD_DISK_TYPE_DISK) { - desc->slice = 2; + desc->slice = 0xff; } else { desc->slice = 0; } -- cgit v1.2.3 From 6c8f5b90bfbe69a27763fb0e181bd2465181446d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Fri, 24 Aug 2007 22:33:15 -0700 Subject: [VIDEO]: Do not prom_halt() in cg3 and bw2 device probe. Just give a normal kernel log message of the problem and return failure. Based upon a patch from Mark Fortescue. Signed-off-by: David S. Miller --- drivers/video/bw2.c | 22 +++++++++++++--------- drivers/video/cg3.c | 17 ++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/video/bw2.c b/drivers/video/bw2.c index 718b9f83736e..833b10c84064 100644 --- a/drivers/video/bw2.c +++ b/drivers/video/bw2.c @@ -233,9 +233,9 @@ static u8 bw2regs_66hz[] __devinitdata = { 0x10, 0x20, 0 }; -static void __devinit bw2_do_default_mode(struct bw2_par *par, - struct fb_info *info, - int *linebytes) +static int __devinit bw2_do_default_mode(struct bw2_par *par, + struct fb_info *info, + int *linebytes) { u8 status, mon; u8 *p; @@ -266,17 +266,18 @@ static void __devinit bw2_do_default_mode(struct bw2_par *par, break; case BWTWO_SR_ID_NOCONN: - return; + return 0; default: - prom_printf("bw2: can't handle SR %02x\n", - status); - prom_halt(); + printk(KERN_ERR "bw2: can't handle SR %02x\n", + status); + return -EINVAL; } for ( ; *p; p += 2) { u8 __iomem *regp = &((u8 __iomem *)par->regs)[p[0]]; sbus_writeb(p[1], regp); } + return 0; } static int __devinit bw2_probe(struct of_device *op, const struct of_device_id *match) @@ -312,8 +313,11 @@ static int __devinit bw2_probe(struct of_device *op, const struct of_device_id * if (!par->regs) goto out_release_fb; - if (!of_find_property(dp, "width", NULL)) - bw2_do_default_mode(par, info, &linebytes); + if (!of_find_property(dp, "width", NULL)) { + err = bw2_do_default_mode(par, info, &linebytes); + if (err) + goto out_unmap_regs; + } par->fbsize = PAGE_ALIGN(linebytes * info->var.yres); diff --git a/drivers/video/cg3.c b/drivers/video/cg3.c index 5741b46ade1b..a5c7fb331527 100644 --- a/drivers/video/cg3.c +++ b/drivers/video/cg3.c @@ -315,7 +315,7 @@ static u_char cg3_dacvals[] __devinitdata = { 4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0 }; -static void __devinit cg3_do_default_mode(struct cg3_par *par) +static int __devinit cg3_do_default_mode(struct cg3_par *par) { enum cg3_type type; u8 *p; @@ -332,10 +332,9 @@ static void __devinit cg3_do_default_mode(struct cg3_par *par) else type = CG3_AT_66HZ; } else { - prom_printf("cgthree: can't handle SR %02x\n", - status); - prom_halt(); - return; + printk(KERN_ERR "cgthree: can't handle SR %02x\n", + status); + return -EINVAL; } } @@ -351,6 +350,7 @@ static void __devinit cg3_do_default_mode(struct cg3_par *par) regp = (u8 __iomem *)&par->regs->cmap.control; sbus_writeb(p[1], regp); } + return 0; } static int __devinit cg3_probe(struct of_device *op, @@ -400,8 +400,11 @@ static int __devinit cg3_probe(struct of_device *op, cg3_blank(0, info); - if (!of_find_property(dp, "width", NULL)) - cg3_do_default_mode(par); + if (!of_find_property(dp, "width", NULL)) { + err = cg3_do_default_mode(par); + if (err) + goto out_unmap_screen; + } if (fb_alloc_cmap(&info->cmap, 256, 0)) goto out_unmap_screen; -- cgit v1.2.3 From 4f1296a5169c13b2c1f76c1446aaf361e8519050 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sat, 25 Aug 2007 15:17:31 -0700 Subject: [SERIAL]: Fix 32-bit warnings in sunzilog.c and sunsu.c resource_size_t can be either a u64 or a u32, and we can't really know for sure, so when printing such a value out always use long-long printf formatting and cast the argument to that type. Signed-off-by: David S. Miller --- drivers/serial/sunsu.c | 5 +++-- drivers/serial/sunzilog.c | 14 ++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/serial/sunsu.c b/drivers/serial/sunsu.c index 79b13685bdfa..e074943feff5 100644 --- a/drivers/serial/sunsu.c +++ b/drivers/serial/sunsu.c @@ -1198,10 +1198,11 @@ static int __init sunsu_kbd_ms_init(struct uart_sunsu_port *up) if (up->port.type == PORT_UNKNOWN) return -ENODEV; - printk("%s: %s port at %lx, irq %u\n", + printk("%s: %s port at %llx, irq %u\n", to_of_device(up->port.dev)->node->full_name, (up->su_type == SU_PORT_KBD) ? "Keyboard" : "Mouse", - up->port.mapbase, up->port.irq); + (unsigned long long) up->port.mapbase, + up->port.irq); #ifdef CONFIG_SERIO serio = &up->serio; diff --git a/drivers/serial/sunzilog.c b/drivers/serial/sunzilog.c index 1d262c0c613f..283bef0d24cb 100644 --- a/drivers/serial/sunzilog.c +++ b/drivers/serial/sunzilog.c @@ -1431,14 +1431,16 @@ static int __devinit zs_probe(struct of_device *op, const struct of_device_id *m return err; } } else { - printk(KERN_INFO "%s: Keyboard at MMIO 0x%lx (irq = %d) " + printk(KERN_INFO "%s: Keyboard at MMIO 0x%llx (irq = %d) " "is a %s\n", - op->dev.bus_id, up[0].port.mapbase, op->irqs[0], - sunzilog_type (&up[0].port)); - printk(KERN_INFO "%s: Mouse at MMIO 0x%lx (irq = %d) " + op->dev.bus_id, + (unsigned long long) up[0].port.mapbase, + op->irqs[0], sunzilog_type(&up[0].port)); + printk(KERN_INFO "%s: Mouse at MMIO 0x%llx (irq = %d) " "is a %s\n", - op->dev.bus_id, up[1].port.mapbase, op->irqs[0], - sunzilog_type (&up[1].port)); + op->dev.bus_id, + (unsigned long long) up[1].port.mapbase, + op->irqs[0], sunzilog_type(&up[1].port)); } dev_set_drvdata(&op->dev, &up[0]); -- cgit v1.2.3 From 03b18f1b2afeac76840648b4232d8e53cfb7ec84 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 29 Jun 2007 02:17:50 -0400 Subject: [PARISC] Clean up sti_flush sti_flush is supposed to flush the caches so we can execute the STI rom we copied to memory. Anything more than flush_icache_range is overkill. Fixes a missing symbol when built as a module. Signed-off-by: Kyle McMartin --- drivers/video/console/sticore.c | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c index 870017d44970..e9ab657f0bb7 100644 --- a/drivers/video/console/sticore.c +++ b/drivers/video/console/sticore.c @@ -232,18 +232,14 @@ sti_bmove(struct sti_struct *sti, int src_y, int src_x, } -/* FIXME: Do we have another solution for this ? */ -static void sti_flush(unsigned long from, unsigned long len) +static void sti_flush(unsigned long start, unsigned long end) { - flush_data_cache(); - flush_kernel_dcache_range(from, len); - flush_icache_range(from, from+len); + flush_icache_range(start, end); } void __devinit sti_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; /* this still needs to be revisited (see arch/parisc/mm/init.c:246) ! */ @@ -260,7 +256,7 @@ sti_rom_copy(unsigned long base, unsigned long count, void *dest) dest++; } - sti_flush(dest_start, dest_len); + sti_flush(dest_start, (unsigned long)dest); } @@ -663,7 +659,6 @@ sti_bmode_font_raw(struct sti_cooked_font *f) static void __devinit sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) { - unsigned long dest_len = count; unsigned long dest_start = (unsigned long) dest; while (count) { @@ -672,7 +667,8 @@ sti_bmode_rom_copy(unsigned long base, unsigned long count, void *dest) base += 4; dest++; } - sti_flush(dest_start, dest_len); + + sti_flush(dest_start, (unsigned long)dest); } static struct sti_rom * __devinit -- cgit v1.2.3 From 1eb51c362d5e7b3e2cc741d87872aa4fc867de42 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 29 Jun 2007 02:15:12 -0400 Subject: [PARISC] Do not allow STI_CONSOLE to be modular It doesn't really make much sense, anyways, and would need a pile of symbols exported. Signed-off-by: Kyle McMartin --- drivers/video/console/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/console/Kconfig b/drivers/video/console/Kconfig index 49643969f9f8..5db6b1e489b0 100644 --- a/drivers/video/console/Kconfig +++ b/drivers/video/console/Kconfig @@ -145,7 +145,7 @@ config FRAMEBUFFER_CONSOLE_ROTATION oriented. config STI_CONSOLE - tristate "STI text console" + bool "STI text console" depends on PARISC default y help -- cgit v1.2.3 From 721ebe005c3bb9add55b2e462dfc1bcf8efc6b8f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Mon, 27 Aug 2007 16:04:39 +0100 Subject: reverse CONFIG_ACPI_PROC_EVENT default Sigh. Again an ACPI assault on the Thinkpad's Fn+F4 to suspend to RAM. The default and text for CONFIG_THINKPAD_ACPI_INPUT_ENABLED were fixed in -rc3, but now commit 14e04fb34ffa82ee61ae69f98d8fca12d2e8e31c ("ACPI: Schedule /proc/acpi/event for removal") introduces the ACPI_PROC_EVENT config entry, and defaults it to 'n' to disable it again. Change default to y, and add comment to make it clearer that n is for future distros. Signed-off-by: Hugh Dickins Cc: Andrew Morton Cc: Len Brown Signed-off-by: Linus Torvalds --- drivers/acpi/Kconfig | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 574259476fbf..4875f0149eb4 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -71,6 +71,7 @@ config ACPI_PROCFS config ACPI_PROC_EVENT bool "Deprecated /proc/acpi/event support" depends on PROC_FS + default y ---help--- A user-space daemon, acpi, typically read /proc/acpi/event and handled all ACPI sub-system generated events. @@ -78,10 +79,13 @@ config ACPI_PROC_EVENT These events are now delivered to user-space via either the input layer, or as netlink events. - This build option enables the old code for for legacy + This build option enables the old code for legacy user-space implementation. After some time, this will be moved under CONFIG_ACPI_PROCFS, and then deleted. + Say Y here to retain the old behaviour. Say N if your + user-space is newer than kernel 2.6.23 (September 2007). + config ACPI_AC tristate "AC Adapter" depends on X86 -- cgit v1.2.3 From f99ba18a96195f047546bd515aabf81fda70ef09 Mon Sep 17 00:00:00 2001 From: Andrew Vasquez Date: Mon, 27 Aug 2007 15:25:01 -0700 Subject: dm-mpath-rdac: don't stomp on a requests transfer bit Without this, we get qla2xxx complaining about "ISP System Error". What's happening here is the firmware is detecting a Xfer-ready from the storage when in fact the data-direction for a mode-select should be a write (DATA_OUT). The following patch fixes the problem (typo). Verified by Brian, as well. Signed-off-by: Andrew Vasquez Verified-by: Brian De Wolf Signed-off-by: Chandra Seetharaman Signed-off-by: Linus Torvalds --- drivers/md/dm-mpath-rdac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/md/dm-mpath-rdac.c b/drivers/md/dm-mpath-rdac.c index 8b776b8cb7f7..16b161345775 100644 --- a/drivers/md/dm-mpath-rdac.c +++ b/drivers/md/dm-mpath-rdac.c @@ -292,7 +292,7 @@ static struct request *get_rdac_req(struct rdac_handler *h, rq->end_io_data = h; rq->timeout = h->timeout; rq->cmd_type = REQ_TYPE_BLOCK_PC; - rq->cmd_flags = REQ_FAILFAST | REQ_NOMERGE; + rq->cmd_flags |= REQ_FAILFAST | REQ_NOMERGE; return rq; } -- cgit v1.2.3