Lines Matching refs:info

105 static inline struct usb_hcd *xenhcd_info_to_hcd(struct xenhcd_info *info)
107 return container_of((void *)info, struct usb_hcd, hcd_priv);
110 static void xenhcd_set_error(struct xenhcd_info *info, const char *msg)
112 info->error = true;
117 static inline void xenhcd_timer_action_done(struct xenhcd_info *info,
120 clear_bit(action, &info->actions);
123 static void xenhcd_timer_action(struct xenhcd_info *info,
126 if (timer_pending(&info->watchdog) &&
127 test_bit(TIMER_SCAN_PENDING_URBS, &info->actions))
130 if (!test_and_set_bit(action, &info->actions)) {
141 mod_timer(&info->watchdog, t + jiffies);
148 static void xenhcd_set_connect_state(struct xenhcd_info *info, int portnum)
153 if (info->ports[port].status & USB_PORT_STAT_POWER) {
154 switch (info->devices[port].speed) {
156 info->ports[port].status &=
164 info->ports[port].status |= USB_PORT_STAT_CONNECTION;
165 info->ports[port].status |= USB_PORT_STAT_LOW_SPEED;
168 info->ports[port].status |= USB_PORT_STAT_CONNECTION;
171 info->ports[port].status |= USB_PORT_STAT_CONNECTION;
172 info->ports[port].status |= USB_PORT_STAT_HIGH_SPEED;
177 info->ports[port].status |= (USB_PORT_STAT_C_CONNECTION << 16);
184 static int xenhcd_rhport_connect(struct xenhcd_info *info, __u8 portnum,
189 if (portnum < 1 || portnum > info->rh_numports)
193 if (info->devices[port].speed != speed) {
196 info->devices[port].status = USB_STATE_NOTATTACHED;
201 info->devices[port].status = USB_STATE_ATTACHED;
206 info->devices[port].speed = speed;
207 info->ports[port].c_connection = true;
209 xenhcd_set_connect_state(info, portnum);
218 static void xenhcd_rhport_suspend(struct xenhcd_info *info, int portnum)
223 info->ports[port].status |= USB_PORT_STAT_SUSPEND;
224 info->devices[port].status = USB_STATE_SUSPENDED;
230 static void xenhcd_rhport_resume(struct xenhcd_info *info, int portnum)
235 if (info->ports[port].status & USB_PORT_STAT_SUSPEND) {
236 info->ports[port].resuming = true;
237 info->ports[port].timeout = jiffies + msecs_to_jiffies(20);
244 static void xenhcd_rhport_power_on(struct xenhcd_info *info, int portnum)
249 if ((info->ports[port].status & USB_PORT_STAT_POWER) == 0) {
250 info->ports[port].status |= USB_PORT_STAT_POWER;
251 if (info->devices[port].status != USB_STATE_NOTATTACHED)
252 info->devices[port].status = USB_STATE_POWERED;
253 if (info->ports[port].c_connection)
254 xenhcd_set_connect_state(info, portnum);
264 static void xenhcd_rhport_power_off(struct xenhcd_info *info, int portnum)
269 if (info->ports[port].status & USB_PORT_STAT_POWER) {
270 info->ports[port].status = 0;
271 if (info->devices[port].status != USB_STATE_NOTATTACHED)
272 info->devices[port].status = USB_STATE_ATTACHED;
279 static void xenhcd_rhport_disable(struct xenhcd_info *info, int portnum)
284 info->ports[port].status &= ~USB_PORT_STAT_ENABLE;
285 info->ports[port].status &= ~USB_PORT_STAT_SUSPEND;
286 info->ports[port].resuming = false;
287 if (info->devices[port].status != USB_STATE_NOTATTACHED)
288 info->devices[port].status = USB_STATE_POWERED;
294 static void xenhcd_rhport_reset(struct xenhcd_info *info, int portnum)
299 info->ports[port].status &= ~(USB_PORT_STAT_ENABLE |
302 info->ports[port].status |= USB_PORT_STAT_RESET;
304 if (info->devices[port].status != USB_STATE_NOTATTACHED)
305 info->devices[port].status = USB_STATE_ATTACHED;
308 info->ports[port].timeout = jiffies + msecs_to_jiffies(10);
314 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
318 ports = info->rh_numports;
320 spin_lock_irq(&info->lock);
326 xenhcd_rhport_suspend(info, i);
328 spin_unlock_irq(&info->lock);
330 del_timer_sync(&info->watchdog);
337 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
341 ports = info->rh_numports;
343 spin_lock_irq(&info->lock);
349 xenhcd_rhport_resume(info, i);
351 spin_unlock_irq(&info->lock);
357 static void xenhcd_hub_descriptor(struct xenhcd_info *info,
361 int ports = info->rh_numports;
396 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
404 ports = info->rh_numports;
408 spin_lock_irqsave(&info->lock, flags);
412 if (info->ports[i].status & PORT_C_MASK) {
421 spin_unlock_irqrestore(&info->lock, flags);
429 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
430 int ports = info->rh_numports;
436 spin_lock_irqsave(&info->lock, flags);
447 xenhcd_rhport_resume(info, wIndex);
450 xenhcd_rhport_power_off(info, wIndex);
453 xenhcd_rhport_disable(info, wIndex);
456 info->ports[wIndex - 1].c_connection = false;
459 info->ports[wIndex - 1].status &= ~(1 << wValue);
464 xenhcd_hub_descriptor(info, (struct usb_hub_descriptor *)buf);
477 if (info->ports[wIndex].resuming &&
478 time_after_eq(jiffies, info->ports[wIndex].timeout)) {
479 info->ports[wIndex].status |=
481 info->ports[wIndex].status &= ~USB_PORT_STAT_SUSPEND;
485 if ((info->ports[wIndex].status & USB_PORT_STAT_RESET) != 0 &&
486 time_after_eq(jiffies, info->ports[wIndex].timeout)) {
487 info->ports[wIndex].status |=
489 info->ports[wIndex].status &= ~USB_PORT_STAT_RESET;
491 if (info->devices[wIndex].status !=
493 info->ports[wIndex].status |=
495 info->devices[wIndex].status =
499 switch (info->devices[wIndex].speed) {
501 info->ports[wIndex].status |=
505 info->ports[wIndex].status |=
513 *(__le32 *)buf = cpu_to_le32(info->ports[wIndex].status);
521 xenhcd_rhport_power_on(info, wIndex);
524 xenhcd_rhport_reset(info, wIndex);
527 xenhcd_rhport_suspend(info, wIndex);
530 if (info->ports[wIndex-1].status & USB_PORT_STAT_POWER)
531 info->ports[wIndex-1].status |= (1 << wValue);
541 spin_unlock_irqrestore(&info->lock, flags);
545 if (info->ports[i].status & PORT_C_MASK)
560 static inline unsigned int xenhcd_get_id_from_freelist(struct xenhcd_info *info)
564 free = info->shadow_free;
565 info->shadow_free = info->shadow[free].req.id;
566 info->shadow[free].req.id = 0x0fff; /* debug */
570 static inline void xenhcd_add_id_to_freelist(struct xenhcd_info *info,
573 info->shadow[id].req.id = info->shadow_free;
574 info->shadow[id].urb = NULL;
575 info->shadow_free = id;
585 static void xenhcd_gnttab_map(struct xenhcd_info *info, void *addr, int length,
604 gnttab_grant_foreign_access_ref(ref, info->xbdev->otherend_id,
642 static int xenhcd_map_urb_for_request(struct xenhcd_info *info, struct urb *urb,
671 xenhcd_gnttab_map(info, urb->transfer_buffer,
691 xenhcd_gnttab_map(info, &urb->iso_frame_desc[0],
716 static void xenhcd_gnttab_done(struct xenhcd_info *info, unsigned int id)
718 struct usb_shadow *shadow = info->shadow + id;
723 xenhcd_set_error(info, "Illegal request id");
735 xenhcd_set_error(info, "backend didn't release grant");
762 static void xenhcd_giveback_urb(struct xenhcd_info *info, struct urb *urb,
774 spin_unlock(&info->lock);
775 usb_hcd_giveback_urb(xenhcd_info_to_hcd(info), urb,
777 spin_lock(&info->lock);
780 static int xenhcd_do_request(struct xenhcd_info *info, struct urb_priv *urbp)
788 id = xenhcd_get_id_from_freelist(info);
789 req = &info->shadow[id].req;
798 ret = xenhcd_map_urb_for_request(info, urb, req);
800 xenhcd_add_id_to_freelist(info, id);
806 req = RING_GET_REQUEST(&info->urb_ring, info->urb_ring.req_prod_pvt);
807 *req = info->shadow[id].req;
809 info->urb_ring.req_prod_pvt++;
810 info->shadow[id].urb = urb;
811 info->shadow[id].in_flight = true;
813 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->urb_ring, notify);
815 notify_remote_via_irq(info->irq);
820 static void xenhcd_kick_pending_urbs(struct xenhcd_info *info)
824 while (!list_empty(&info->pending_submit_list)) {
825 if (RING_FULL(&info->urb_ring)) {
826 xenhcd_timer_action(info, TIMER_RING_WATCHDOG);
830 urbp = list_entry(info->pending_submit_list.next,
832 if (!xenhcd_do_request(info, urbp))
833 list_move_tail(&urbp->list, &info->in_progress_list);
835 xenhcd_giveback_urb(info, urbp->urb, -ESHUTDOWN);
837 xenhcd_timer_action_done(info, TIMER_SCAN_PENDING_URBS);
841 * caller must lock info->lock
843 static void xenhcd_cancel_all_enqueued_urbs(struct xenhcd_info *info)
848 list_for_each_entry_safe(urbp, tmp, &info->in_progress_list, list) {
851 xenhcd_gnttab_done(info, req_id);
852 if (info->error)
856 xenhcd_giveback_urb(info, urbp->urb,
859 xenhcd_giveback_urb(info, urbp->urb,
862 info->shadow[req_id].urb = NULL;
865 list_for_each_entry_safe(urbp, tmp, &info->pending_submit_list, list)
866 xenhcd_giveback_urb(info, urbp->urb, -ESHUTDOWN);
870 * caller must lock info->lock
872 static void xenhcd_giveback_unlinked_urbs(struct xenhcd_info *info)
876 list_for_each_entry_safe(urbp, tmp, &info->giveback_waiting_list, list)
877 xenhcd_giveback_urb(info, urbp->urb, urbp->urb->status);
880 static int xenhcd_submit_urb(struct xenhcd_info *info, struct urb_priv *urbp)
884 if (RING_FULL(&info->urb_ring)) {
885 list_add_tail(&urbp->list, &info->pending_submit_list);
886 xenhcd_timer_action(info, TIMER_RING_WATCHDOG);
890 if (!list_empty(&info->pending_submit_list)) {
891 list_add_tail(&urbp->list, &info->pending_submit_list);
892 xenhcd_timer_action(info, TIMER_SCAN_PENDING_URBS);
896 ret = xenhcd_do_request(info, urbp);
898 list_add_tail(&urbp->list, &info->in_progress_list);
903 static int xenhcd_unlink_urb(struct xenhcd_info *info, struct urb_priv *urbp)
915 list_move_tail(&urbp->list, &info->giveback_waiting_list);
916 xenhcd_timer_action(info, TIMER_SCAN_PENDING_URBS);
921 if (RING_FULL(&info->urb_ring)) {
922 list_move_tail(&urbp->list, &info->pending_unlink_list);
923 xenhcd_timer_action(info, TIMER_RING_WATCHDOG);
927 if (!list_empty(&info->pending_unlink_list)) {
928 list_move_tail(&urbp->list, &info->pending_unlink_list);
929 xenhcd_timer_action(info, TIMER_SCAN_PENDING_URBS);
933 ret = xenhcd_do_request(info, urbp);
935 list_move_tail(&urbp->list, &info->in_progress_list);
940 static void xenhcd_res_to_urb(struct xenhcd_info *info,
954 xenhcd_giveback_urb(info, urb, res->status);
957 static int xenhcd_urb_request_done(struct xenhcd_info *info,
966 spin_lock_irqsave(&info->lock, flags);
968 rp = info->urb_ring.sring->rsp_prod;
969 if (RING_RESPONSE_PROD_OVERFLOW(&info->urb_ring, rp)) {
970 xenhcd_set_error(info, "Illegal index on urb-ring");
975 for (i = info->urb_ring.rsp_cons; i != rp; i++) {
976 RING_COPY_RESPONSE(&info->urb_ring, i, &res);
979 xenhcd_set_error(info, "Illegal data on urb-ring");
983 if (likely(xenusb_pipesubmit(info->shadow[id].req.pipe))) {
984 xenhcd_gnttab_done(info, id);
985 if (info->error)
987 xenhcd_res_to_urb(info, &res, info->shadow[id].urb);
990 xenhcd_add_id_to_freelist(info, id);
994 info->urb_ring.rsp_cons = i;
996 if (i != info->urb_ring.req_prod_pvt)
997 RING_FINAL_CHECK_FOR_RESPONSES(&info->urb_ring, more_to_do);
999 info->urb_ring.sring->rsp_event = i + 1;
1001 spin_unlock_irqrestore(&info->lock, flags);
1006 spin_unlock_irqrestore(&info->lock, flags);
1010 static int xenhcd_conn_notify(struct xenhcd_info *info, unsigned int *eoiflag)
1022 spin_lock_irqsave(&info->lock, flags);
1024 rc = info->conn_ring.rsp_cons;
1025 rp = info->conn_ring.sring->rsp_prod;
1026 if (RING_RESPONSE_PROD_OVERFLOW(&info->conn_ring, rp)) {
1027 xenhcd_set_error(info, "Illegal index on conn-ring");
1028 spin_unlock_irqrestore(&info->lock, flags);
1034 RING_COPY_RESPONSE(&info->conn_ring, rc, &res);
1038 info->conn_ring.rsp_cons = ++rc;
1040 if (xenhcd_rhport_connect(info, portnum, speed)) {
1041 xenhcd_set_error(info, "Illegal data on conn-ring");
1042 spin_unlock_irqrestore(&info->lock, flags);
1046 if (info->ports[portnum - 1].c_connection)
1051 req = RING_GET_REQUEST(&info->conn_ring,
1052 info->conn_ring.req_prod_pvt);
1054 info->conn_ring.req_prod_pvt++;
1059 if (rc != info->conn_ring.req_prod_pvt)
1060 RING_FINAL_CHECK_FOR_RESPONSES(&info->conn_ring, more_to_do);
1062 info->conn_ring.sring->rsp_event = rc + 1;
1064 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->conn_ring, notify);
1066 notify_remote_via_irq(info->irq);
1068 spin_unlock_irqrestore(&info->lock, flags);
1071 usb_hcd_poll_rh_status(xenhcd_info_to_hcd(info));
1078 struct xenhcd_info *info = (struct xenhcd_info *)dev_id;
1081 if (unlikely(info->error)) {
1086 while (xenhcd_urb_request_done(info, &eoiflag) |
1087 xenhcd_conn_notify(info, &eoiflag))
1095 static void xenhcd_destroy_rings(struct xenhcd_info *info)
1097 if (info->irq)
1098 unbind_from_irqhandler(info->irq, info);
1099 info->irq = 0;
1101 xenbus_teardown_ring((void **)&info->urb_ring.sring, 1,
1102 &info->urb_ring_ref);
1103 xenbus_teardown_ring((void **)&info->conn_ring.sring, 1,
1104 &info->conn_ring_ref);
1108 struct xenhcd_info *info)
1114 info->conn_ring_ref = INVALID_GRANT_REF;
1116 (void **)&urb_sring, 1, &info->urb_ring_ref);
1121 XEN_FRONT_RING_INIT(&info->urb_ring, urb_sring, PAGE_SIZE);
1124 (void **)&conn_sring, 1, &info->conn_ring_ref);
1129 XEN_FRONT_RING_INIT(&info->conn_ring, conn_sring, PAGE_SIZE);
1131 err = xenbus_alloc_evtchn(dev, &info->evtchn);
1137 err = bind_evtchn_to_irq_lateeoi(info->evtchn);
1143 info->irq = err;
1145 err = request_threaded_irq(info->irq, NULL, xenhcd_int,
1146 IRQF_ONESHOT, "xenhcd", info);
1155 unbind_from_irqhandler(info->irq, info);
1157 xenhcd_destroy_rings(info);
1162 struct xenhcd_info *info)
1168 err = xenhcd_setup_rings(dev, info);
1180 info->urb_ring_ref);
1187 info->conn_ring_ref);
1194 info->evtchn);
1215 xenhcd_destroy_rings(info);
1222 struct xenhcd_info *info = dev_get_drvdata(&dev->dev);
1229 hcd = xenhcd_info_to_hcd(info);
1232 err = xenhcd_talk_to_backend(dev, info);
1238 req = RING_GET_REQUEST(&info->conn_ring, idx);
1241 info->conn_ring.req_prod_pvt = idx;
1243 RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&info->conn_ring, notify);
1245 notify_remote_via_irq(info->irq);
1252 struct xenhcd_info *info = dev_get_drvdata(&dev->dev);
1253 struct usb_hcd *hcd = xenhcd_info_to_hcd(info);
1261 struct xenhcd_info *info = from_timer(info, timer, watchdog);
1264 spin_lock_irqsave(&info->lock, flags);
1265 if (likely(HC_IS_RUNNING(xenhcd_info_to_hcd(info)->state))) {
1266 xenhcd_timer_action_done(info, TIMER_RING_WATCHDOG);
1267 xenhcd_giveback_unlinked_urbs(info);
1268 xenhcd_kick_pending_urbs(info);
1270 spin_unlock_irqrestore(&info->lock, flags);
1278 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
1280 spin_lock_init(&info->lock);
1281 INIT_LIST_HEAD(&info->pending_submit_list);
1282 INIT_LIST_HEAD(&info->pending_unlink_list);
1283 INIT_LIST_HEAD(&info->in_progress_list);
1284 INIT_LIST_HEAD(&info->giveback_waiting_list);
1285 timer_setup(&info->watchdog, xenhcd_watchdog, 0);
1308 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
1310 del_timer_sync(&info->watchdog);
1311 spin_lock_irq(&info->lock);
1314 xenhcd_cancel_all_enqueued_urbs(info);
1315 xenhcd_giveback_unlinked_urbs(info);
1316 spin_unlock_irq(&info->lock);
1326 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
1331 if (unlikely(info->error))
1338 spin_lock_irqsave(&info->lock, flags);
1348 ret = xenhcd_submit_urb(info, urbp);
1353 spin_unlock_irqrestore(&info->lock, flags);
1363 struct xenhcd_info *info = xenhcd_hcd_to_info(hcd);
1368 spin_lock_irqsave(&info->lock, flags);
1373 ret = xenhcd_unlink_urb(info, urbp);
1376 spin_unlock_irqrestore(&info->lock, flags);
1448 struct xenhcd_info *info;
1485 info = xenhcd_hcd_to_info(hcd);
1486 info->xbdev = dev;
1487 info->rh_numports = num_ports;
1490 info->shadow[i].req.id = i + 1;
1491 info->shadow[i].urb = NULL;
1492 info->shadow[i].in_flight = false;
1494 info->shadow[XENUSB_URB_RING_SIZE - 1].req.id = 0x0fff;
1535 struct xenhcd_info *info = dev_get_drvdata(&dev->dev);
1536 struct usb_hcd *hcd = xenhcd_info_to_hcd(info);
1538 xenhcd_destroy_rings(info);
1547 struct xenhcd_info *info;
1560 info = xenhcd_hcd_to_info(hcd);
1561 dev_set_drvdata(&dev->dev, info);