#ifndef _LAPB_H #define _LAPB_H #include #define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */ #define LAPB_ACK_PENDING_CONDITION 0x01 #define LAPB_REJECT_CONDITION 0x02 #define LAPB_PEER_RX_BUSY_CONDITION 0x04 /* Control field templates */ #define LAPB_I 0x00 /* Information frames */ #define LAPB_S 0x01 /* Supervisory frames */ #define LAPB_U 0x03 /* Unnumbered frames */ #define LAPB_RR 0x01 /* Receiver ready */ #define LAPB_RNR 0x05 /* Receiver not ready */ #define LAPB_REJ 0x09 /* Reject */ #define LAPB_SABM 0x2F /* Set Asynchronous Balanced Mode */ #define LAPB_SABME 0x6F /* Set Asynchronous Balanced Mode Extended */ #define LAPB_DISC 0x43 /* Disconnect */ #define LAPB_DM 0x0F /* Disconnected mode */ #define LAPB_UA 0x63 /* Unnumbered acknowledge */ #define LAPB_FRMR 0x87 /* Frame reject */ #define LAPB_ILLEGAL 0x100 /* Impossible to be a real frame type */ #define LAPB_SPF 0x10 /* Poll/final bit for standard LAPB */ #define LAPB_EPF 0x01 /* Poll/final bit for extended LAPB */ #define LAPB_FRMR_W 0x01 /* Control field invalid */ #define LAPB_FRMR_X 0x02 /* I field invalid */ #define LAPB_FRMR_Y 0x04 /* I field too long */ #define LAPB_FRMR_Z 0x08 /* Invalid N(R) */ #define LAPB_POLLOFF 0 #define LAPB_POLLON 1 /* LAPB C-bit */ #define LAPB_COMMAND 1 #define LAPB_RESPONSE 2 #define LAPB_ADDR_A 0x03 #define LAPB_ADDR_B 0x01 #define LAPB_ADDR_C 0x0F #define LAPB_ADDR_D 0x07 /* Define Link State constants. */ enum { LAPB_STATE_0, /* Disconnected State */ LAPB_STATE_1, /* Awaiting Connection State */ LAPB_STATE_2, /* Awaiting Disconnection State */ LAPB_STATE_3, /* Data Transfer State */ LAPB_STATE_4 /* Frame Reject State */ }; #define LAPB_DEFAULT_MODE (LAPB_STANDARD | LAPB_SLP | LAPB_DTE) #define LAPB_DEFAULT_WINDOW 7 /* Window=7 */ #define LAPB_DEFAULT_T1 (5 * HZ) /* T1=5s */ #define LAPB_DEFAULT_T2 (1 * HZ) /* T2=1s */ #define LAPB_DEFAULT_N2 20 /* N2=20 */ #define LAPB_SMODULUS 8 #define LAPB_EMODULUS 128 /* * Information about the current frame. */ struct lapb_frame { unsigned short type; /* Parsed type */ unsigned short nr, ns; /* N(R), N(S) */ unsigned char cr; /* Command/Response */ unsigned char pf; /* Poll/Final */ unsigned char control[2]; /* Original control data*/ }; /* * The per LAPB connection control structure. */ struct lapb_cb { struct list_head node; struct net_device *dev; /* Link status fields */ unsigned int mode; unsigned char state; unsigned short vs, vr, va; unsigned char condition; unsigned short n2, n2count; unsigned short t1, t2; struct timer_list t1timer, t2timer; /* Internal control information */ struct sk_buff_head write_queue; struct sk_buff_head ack_queue; unsigned char window; const struct lapb_register_struct *callbacks; /* FRMR control information */ struct lapb_frame frmr_data; unsigned char frmr_type; atomic_t refcnt; }; /* lapb_iface.c */ void lapb_connect_confirmation(struct lapb_cb *lapb, int); void lapb_connect_indication(struct lapb_cb *lapb, int); void lapb_disconnect_confirmation(struct lapb_cb *lapb, int); void lapb_disconnect_indication(struct lapb_cb *lapb, int); int lapb_data_indication(struct lapb_cb *lapb, struct sk_buff *); int lapb_data_transmit(struct lapb_cb *lapb, struct sk_buff *); /* lapb_in.c */ void lapb_data_input(struct lapb_cb *lapb, struct sk_buff *); /* lapb_out.c */ void lapb_kick(struct lapb_cb *lapb); void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *, int); void lapb_establish_data_link(struct lapb_cb *lapb); void lapb_enquiry_response(struct lapb_cb *lapb); void lapb_timeout_response(struct lapb_cb *lapb); void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short); void lapb_check_need_response(struct lapb_cb *lapb, int, int); /* lapb_subr.c */ void lapb_clear_queues(struct lapb_cb *lapb); void lapb_frames_acked(struct lapb_cb *lapb, unsigned short); void lapb_requeue_frames(struct lapb_cb *lapb); int lapb_validate_nr(struct lapb_cb *lapb, unsigned short); int lapb_decode(struct lapb_cb *lapb, struct sk_buff *, struct lapb_frame *); void lapb_send_control(struct lapb_cb *lapb, int, int, int); void lapb_transmit_frmr(struct lapb_cb *lapb); /* lapb_timer.c */ void lapb_start_t1timer(struct lapb_cb *lapb); void lapb_start_t2timer(struct lapb_cb *lapb); void lapb_stop_t1timer(struct lapb_cb *lapb); void lapb_stop_t2timer(struct lapb_cb *lapb); int lapb_t1timer_running(struct lapb_cb *lapb); /* * Debug levels. * 0 = Off * 1 = State Changes * 2 = Packets I/O and State Changes * 3 = Hex dumps, Packets I/O and State Changes. */ #define LAPB_DEBUG 0 #define lapb_dbg(level, fmt, ...) \ do { \ if (level < LAPB_DEBUG) \ pr_debug(fmt, ##__VA_ARGS__); \ } while (0) #endif ript>
authorTony Lindgren <tony@atomide.com>2017-01-19 08:49:07 -0800
committerVinod Koul <vinod.koul@intel.com>2017-01-25 11:29:11 +0530
commitae4a3e028bb8b59e7cfeb0cc9ef03d885182ce8b (patch)
tree139fc7e29f97d6bb6c4dca2a97be2dc3f824bd51 /include/soc/fsl
parent49def1853334396f948dcb4cedb9347abb318df5 (diff)
dmaengine: cppi41: Fix runtime PM timeouts with USB mass storage
Commit fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") added runtime PM support for cppi41, but had corner case issues. Some of the issues were fixed with commit 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected"). That fix however caused a new regression where we can get error -115 messages with USB on BeagleBone when connecting a USB mass storage device to a hub. This is because when connecting a USB mass storage device to a hub, the initial DMA transfers can take over 200ms to complete and cppi41 autosuspend delay times out. To fix the issue, we want to implement refcounting for chan_busy array that contains the active dma transfers. Increasing the autosuspend delay won't help as that the delay could be potentially seconds, and it's best to let the USB subsystem to deal with the timeouts on errors. The earlier attempt for runtime PM was buggy as the pm_runtime_get/put() calls could get unpaired easily as they did not follow the state of the chan_busy array as described in commit 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected". Let's fix the issue by adding pm_runtime_get() to where a new transfer is added to the chan_busy array, and calls to pm_runtime_put() where chan_busy array entry is cleared. This prevents any autosuspend timeouts from happening while dma transfers are active. Fixes: 098de42ad670 ("dmaengine: cppi41: Fix unpaired pm runtime when only a USB hub is connected") Fixes: fdea2d09b997 ("dmaengine: cppi41: Add basic PM runtime support") Cc: Andy Shevchenko <andy.shevchenko@gmail.com> Cc: Bin Liu <b-liu@ti.com> Cc: Grygorii Strashko <grygorii.strashko@ti.com> Cc: Kevin Hilman <khilman@baylibre.com> Cc: Patrick Titiano <ptitiano@baylibre.com> Cc: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com> Signed-off-by: Tony Lindgren <tony@atomide.com> Tested-by: Bin Liu <b-liu@ti.com> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'include/soc/fsl')