提交 b2a068d0 编写于 作者: M Martin Fuzzey 提交者: Greg Kroah-Hartman

USB: imx21-hcd: refactor hardware data memory management

We already have fields describing the hardware data memory
(dmem_size and dmem_offset) in the HCD private data,
use them rather than the rather obscure read from the
hardware descriptor.
Signed-off-by: NMartin Fuzzey <mfuzzey@gmail.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 e6da55cb
...@@ -323,16 +323,23 @@ static void activate_queued_etd(struct imx21 *imx21, ...@@ -323,16 +323,23 @@ static void activate_queued_etd(struct imx21 *imx21,
etd_writel(imx21, etd_num, 1, etd_writel(imx21, etd_num, 1,
((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset); ((dmem_offset + maxpacket) << DW1_YBUFSRTAD) | dmem_offset);
etd->dmem_offset = dmem_offset;
urb_priv->active = 1; urb_priv->active = 1;
activate_etd(imx21, etd_num, etd->dma_handle, dir); activate_etd(imx21, etd_num, etd->dma_handle, dir);
} }
static void free_dmem(struct imx21 *imx21, int offset) static void free_dmem(struct imx21 *imx21, struct etd_priv *etd)
{ {
struct imx21_dmem_area *area; struct imx21_dmem_area *area;
struct etd_priv *etd, *tmp; struct etd_priv *tmp;
int found = 0; int found = 0;
int offset;
if (!etd->dmem_size)
return;
etd->dmem_size = 0;
offset = etd->dmem_offset;
list_for_each_entry(area, &imx21->dmem_list, list) { list_for_each_entry(area, &imx21->dmem_list, list) {
if (area->offset == offset) { if (area->offset == offset) {
debug_dmem_freed(imx21, area->size); debug_dmem_freed(imx21, area->size);
...@@ -734,9 +741,7 @@ static void dequeue_isoc_urb(struct imx21 *imx21, ...@@ -734,9 +741,7 @@ static void dequeue_isoc_urb(struct imx21 *imx21,
struct etd_priv *etd = imx21->etd + etd_num; struct etd_priv *etd = imx21->etd + etd_num;
reset_etd(imx21, etd_num); reset_etd(imx21, etd_num);
if (etd->dmem_size) free_dmem(imx21, etd);
free_dmem(imx21, etd->dmem_offset);
etd->dmem_size = 0;
} }
} }
} }
...@@ -761,7 +766,6 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) ...@@ -761,7 +766,6 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
int state = urb_priv->state; int state = urb_priv->state;
int etd_num = ep_priv->etd[0]; int etd_num = ep_priv->etd[0];
struct etd_priv *etd; struct etd_priv *etd;
int dmem_offset;
u32 count; u32 count;
u16 etd_buf_size; u16 etd_buf_size;
u16 maxpacket; u16 maxpacket;
...@@ -855,8 +859,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) ...@@ -855,8 +859,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
/* allocate x and y buffer space at once */ /* allocate x and y buffer space at once */
etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket; etd->dmem_size = (count > maxpacket) ? maxpacket * 2 : maxpacket;
dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep); etd->dmem_offset = alloc_dmem(imx21, etd->dmem_size, urb_priv->ep);
if (dmem_offset < 0) { if (etd->dmem_offset < 0) {
/* Setup everything we can in HW and update when we get DMEM */ /* Setup everything we can in HW and update when we get DMEM */
etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16); etd_writel(imx21, etd_num, 1, (u32)maxpacket << 16);
...@@ -867,8 +871,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb) ...@@ -867,8 +871,8 @@ static void schedule_nonisoc_etd(struct imx21 *imx21, struct urb *urb)
} }
etd_writel(imx21, etd_num, 1, etd_writel(imx21, etd_num, 1,
(((u32) dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) | (((u32) etd->dmem_offset + (u32) maxpacket) << DW1_YBUFSRTAD) |
(u32) dmem_offset); (u32) etd->dmem_offset);
urb_priv->active = 1; urb_priv->active = 1;
...@@ -886,7 +890,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) ...@@ -886,7 +890,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
u32 etd_mask = 1 << etd_num; u32 etd_mask = 1 << etd_num;
struct urb_priv *urb_priv = urb->hcpriv; struct urb_priv *urb_priv = urb->hcpriv;
int dir; int dir;
u16 xbufaddr;
int cc; int cc;
u32 bytes_xfrd; u32 bytes_xfrd;
int etd_done; int etd_done;
...@@ -894,7 +897,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) ...@@ -894,7 +897,6 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
disactivate_etd(imx21, etd_num); disactivate_etd(imx21, etd_num);
dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3; dir = (etd_readl(imx21, etd_num, 0) >> DW0_DIRECT) & 0x3;
xbufaddr = etd_readl(imx21, etd_num, 1) & 0xffff;
cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf; cc = (etd_readl(imx21, etd_num, 2) >> DW2_COMPCODE) & 0xf;
bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff); bytes_xfrd = etd->len - (etd_readl(imx21, etd_num, 3) & 0x1fffff);
...@@ -907,7 +909,7 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num) ...@@ -907,7 +909,7 @@ static void nonisoc_etd_done(struct usb_hcd *hcd, struct urb *urb, int etd_num)
clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask); clear_toggle_bit(imx21, USBH_XFILLSTAT, etd_mask);
clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask); clear_toggle_bit(imx21, USBH_YFILLSTAT, etd_mask);
} }
free_dmem(imx21, xbufaddr); free_dmem(imx21, etd);
urb->error_count = 0; urb->error_count = 0;
if (!(urb->transfer_flags & URB_SHORT_NOT_OK) if (!(urb->transfer_flags & URB_SHORT_NOT_OK)
...@@ -1123,7 +1125,7 @@ static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, ...@@ -1123,7 +1125,7 @@ static int imx21_hc_urb_dequeue(struct usb_hcd *hcd, struct urb *urb,
int etd_num = ep_priv->etd[0]; int etd_num = ep_priv->etd[0];
if (etd_num != -1) { if (etd_num != -1) {
disactivate_etd(imx21, etd_num); disactivate_etd(imx21, etd_num);
free_dmem(imx21, etd_readl(imx21, etd_num, 1) & 0xffff); free_dmem(imx21, &imx21->etd[etd_num]);
imx21->etd[etd_num].urb = NULL; imx21->etd[etd_num].urb = NULL;
} }
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册