+struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt)
+{
+ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ unsigned long flags;
+
+ /******************** spin lock ********************/
+ usbhs_lock(priv, flags);
+
+ if (!pkt)
+ pkt = __usbhsf_pkt_get(pipe);
+
+ if (pkt)
+ __usbhsf_pkt_del(pkt);
+
+ usbhs_unlock(priv, flags);
+ /******************** spin unlock ******************/
+
+ return pkt;
+}
+
+int __usbhs_pkt_handler(struct usbhs_pipe *pipe, int type)
+{
+ struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe);
+ struct usbhs_pipe_info *info = usbhs_priv_to_pipeinfo(priv);
+ struct usbhs_pkt *pkt;
+ struct device *dev = usbhs_priv_to_dev(priv);
+ int (*func)(struct usbhs_pkt *pkt, int *is_done);
+ unsigned long flags;
+ int ret = 0;
+ int is_done = 0;
+
+ /******************** spin lock ********************/
+ usbhs_lock(priv, flags);
+
+ pkt = __usbhsf_pkt_get(pipe);
+ if (!pkt)
+ goto __usbhs_pkt_handler_end;
+
+ switch (type) {
+ case USBHSF_PKT_PREPARE:
+ func = pkt->handler->prepare;
+ break;
+ case USBHSF_PKT_TRY_RUN:
+ func = pkt->handler->try_run;
+ break;
+ default:
+ dev_err(dev, "unknown pkt hander\n");
+ goto __usbhs_pkt_handler_end;
+ }
+
+ ret = func(pkt, &is_done);
+
+ if (is_done)
+ __usbhsf_pkt_del(pkt);
+
+__usbhs_pkt_handler_end:
+ usbhs_unlock(priv, flags);
+ /******************** spin unlock ******************/
+
+ if (is_done)
+ info->done(pkt);
+
+ return ret;
+}
+