Lines Matching +full:full +full:- +full:frame
1 // SPDX-License-Identifier: GPL-2.0
8 * (C) Copyright 1999-2002 Johannes Erdfelt, johannes@erdfelt.com
15 * support from usb-ohci.c by Adam Richter, adam@yggdrasil.com).
16 * (C) Copyright 1999 Gregory P. Smith (from usb-ohci.c)
17 * (C) Copyright 2004-2007 Alan Stern, stern@rowland.harvard.edu
40 #include <linux/dma-mapping.h>
50 #include "uhci-hcd.h"
97 * Calculate the link pointer DMA value for the first Skeleton QH in a frame.
99 static __hc32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) in uhci_frame_skel_link() argument
105 * There's not much to be done about period-1 interrupts; they have in uhci_frame_skel_link()
106 * to occur in every frame. But we can schedule period-2 interrupts in uhci_frame_skel_link()
107 * in odd-numbered frames, period-4 interrupts in frames congruent in uhci_frame_skel_link()
108 * to 2 (mod 4), and so on. This way each frame only has two in uhci_frame_skel_link()
112 * 1,3,5,... => ffs = 0 => use period-2 QH = skelqh[8], in uhci_frame_skel_link()
113 * 2,6,10,... => ffs = 1 => use period-4 QH = skelqh[7], etc. in uhci_frame_skel_link()
114 * ffs >= 7 => not on any high-period queue, so use in uhci_frame_skel_link()
115 * period-1 QH = skelqh[9]. in uhci_frame_skel_link()
118 skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); in uhci_frame_skel_link()
121 return LINK_TO_QH(uhci, uhci->skelqh[skelnum]); in uhci_frame_skel_link()
124 #include "uhci-debug.c"
125 #include "uhci-q.c"
126 #include "uhci-hub.c"
139 for (port = 0; port < uhci->rh_numports; ++port) in finish_reset()
142 uhci->port_c_suspend = uhci->resuming_ports = 0; in finish_reset()
143 uhci->rh_state = UHCI_RH_RESET; in finish_reset()
144 uhci->is_stopped = UHCI_IS_STOPPED; in finish_reset()
145 clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); in finish_reset()
155 uhci->reset_hc(uhci); in uhci_hc_died()
157 uhci->dead = 1; in uhci_hc_died()
159 /* The current frame may already be partway finished */ in uhci_hc_died()
160 ++uhci->frame_number; in uhci_hc_died()
170 if (uhci->check_and_reset_hc(uhci)) in check_and_reset_hc()
187 /* Reset the HC - this will force us to get a in uhci_generic_reset_hc()
241 dev_dbg(uhci_dev(uhci), "Performing full reset\n"); in uhci_generic_check_and_reset_hc()
252 /* Set the frame length to the default: 1 ms exactly */ in configure_hc()
255 /* Store the frame list base address */ in configure_hc()
256 uhci_writel(uhci, uhci->frame_dma_handle, USBFLBASEADD); in configure_hc()
258 /* Set the current frame number */ in configure_hc()
259 uhci_writew(uhci, uhci->frame_number & UHCI_MAX_SOF_NUMBER, in configure_hc()
263 if (uhci->configure_hc) in configure_hc()
264 uhci->configure_hc(uhci); in configure_hc()
271 * we can't depend on resume-detect interrupts. in resume_detect_interrupts_are_broken()
278 return uhci->resume_detect_interrupts_are_broken ? in resume_detect_interrupts_are_broken()
279 uhci->resume_detect_interrupts_are_broken(uhci) : 0; in resume_detect_interrupts_are_broken()
284 return uhci->global_suspend_mode_is_broken ? in global_suspend_mode_is_broken()
285 uhci->global_suspend_mode_is_broken(uhci) : 0; in global_suspend_mode_is_broken()
289 __releases(uhci->lock) in suspend_rh()
290 __acquires(uhci->lock) in suspend_rh()
294 struct usb_device *rhdev = uhci_to_hcd(uhci)->self.root_hub; in suspend_rh()
297 dev_dbg(&rhdev->dev, "%s%s\n", __func__, in suspend_rh()
298 (auto_stop ? " (auto-stop)" : "")); in suspend_rh()
300 /* Start off by assuming Resume-Detect interrupts and EGSM work in suspend_rh()
308 * In auto-stop mode, we must be able to detect new connections. in suspend_rh()
313 if (!device_may_wakeup(&rhdev->dev)) in suspend_rh()
319 * In bus-suspend mode, we use the wakeup setting specified in suspend_rh()
323 if (!rhdev->do_remote_wakeup) in suspend_rh()
332 * if wakeups are disallowed then EGSM must be turned off -- in which in suspend_rh()
337 * if Resume-Detect interrupts are broken then we can't use them. in suspend_rh()
347 uhci->RD_enable = !!int_enable; in suspend_rh()
353 /* If we're auto-stopping then no devices have been attached in suspend_rh()
356 * we will give the controller one frame to stop. in suspend_rh()
359 uhci->rh_state = UHCI_RH_SUSPENDING; in suspend_rh()
360 spin_unlock_irq(&uhci->lock); in suspend_rh()
362 spin_lock_irq(&uhci->lock); in suspend_rh()
363 if (uhci->dead) in suspend_rh()
371 uhci->rh_state = new_state; in suspend_rh()
372 uhci->is_stopped = UHCI_IS_STOPPED; in suspend_rh()
380 set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); in suspend_rh()
382 clear_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); in suspend_rh()
390 uhci->is_stopped = 0; in start_rh()
399 /* Mark it configured and running with a 64-byte max packet. in start_rh()
406 uhci->rh_state = UHCI_RH_RUNNING; in start_rh()
407 set_bit(HCD_FLAG_POLL_RH, &uhci_to_hcd(uhci)->flags); in start_rh()
411 __releases(uhci->lock) in wakeup_rh()
412 __acquires(uhci->lock) in wakeup_rh()
414 dev_dbg(&uhci_to_hcd(uhci)->self.root_hub->dev, in wakeup_rh()
416 uhci->rh_state == UHCI_RH_AUTO_STOPPED ? in wakeup_rh()
417 " (auto-start)" : ""); in wakeup_rh()
419 /* If we are auto-stopped then no devices are attached so there's in wakeup_rh()
423 if (uhci->rh_state == UHCI_RH_SUSPENDED) { in wakeup_rh()
428 uhci->rh_state = UHCI_RH_RESUMING; in wakeup_rh()
430 spin_unlock_irq(&uhci->lock); in wakeup_rh()
432 spin_lock_irq(&uhci->lock); in wakeup_rh()
433 if (uhci->dead) in wakeup_rh()
447 mod_timer(&uhci_to_hcd(uhci)->rh_timer, jiffies); in wakeup_rh()
465 spin_lock(&uhci->lock); in uhci_irq()
466 if (unlikely(!uhci->is_initialized)) /* not yet configured */ in uhci_irq()
477 if (uhci->rh_state >= UHCI_RH_RUNNING) { in uhci_irq()
483 ERRBUF_LEN - EXTRA_SPACE); in uhci_irq()
491 mod_timer(&hcd->rh_timer, jiffies); in uhci_irq()
497 spin_unlock(&uhci->lock); in uhci_irq()
502 spin_unlock(&uhci->lock); in uhci_irq()
509 * Store the current frame number in uhci->frame_number if the controller
511 * full-sized integer.
518 if (!uhci->is_stopped) { in uhci_get_current_frame_number()
521 delta = (uhci_readw(uhci, USBFRNUM) - uhci->frame_number) & in uhci_get_current_frame_number()
522 (UHCI_NUMFRAMES - 1); in uhci_get_current_frame_number()
523 uhci->frame_number += delta; in uhci_get_current_frame_number()
528 * De-allocate all resources
535 spin_lock_irq(&uhci->lock); in release_uhci()
536 uhci->is_initialized = 0; in release_uhci()
537 spin_unlock_irq(&uhci->lock); in release_uhci()
539 debugfs_lookup_and_remove(uhci_to_hcd(uhci)->self.bus_name, in release_uhci()
543 uhci_free_qh(uhci, uhci->skelqh[i]); in release_uhci()
545 uhci_free_td(uhci, uhci->term_td); in release_uhci()
547 dma_pool_destroy(uhci->qh_pool); in release_uhci()
549 dma_pool_destroy(uhci->td_pool); in release_uhci()
551 kfree(uhci->frame_cpu); in release_uhci()
554 UHCI_NUMFRAMES * sizeof(*uhci->frame), in release_uhci()
555 uhci->frame, uhci->frame_dma_handle); in release_uhci()
559 * Allocate a frame list, and then setup the skeleton
566 * - All isochronous events are handled before any
569 * - The first queue is the high-period interrupt queue.
570 * - The second queue is the period-1 interrupt and async
571 * (low-speed control, full-speed control, then bulk) queue.
572 * - The third queue is the terminating bandwidth reclamation queue,
574 * only when FSBR is on and there are no full-speed control or bulk QHs.
579 int retval = -EBUSY; in uhci_start()
582 hcd->uses_new_polling = 1; in uhci_start()
583 /* Accept arbitrarily long scatter-gather lists */ in uhci_start()
584 if (!hcd->localmem_pool) in uhci_start()
585 hcd->self.sg_tablesize = ~0; in uhci_start()
587 spin_lock_init(&uhci->lock); in uhci_start()
588 timer_setup(&uhci->fsbr_timer, uhci_fsbr_timeout, 0); in uhci_start()
589 INIT_LIST_HEAD(&uhci->idle_qh_list); in uhci_start()
590 init_waitqueue_head(&uhci->waitqh); in uhci_start()
593 debugfs_create_file(hcd->self.bus_name, S_IFREG|S_IRUGO|S_IWUSR, in uhci_start()
597 uhci->frame = dma_alloc_coherent(uhci_dev(uhci), in uhci_start()
598 UHCI_NUMFRAMES * sizeof(*uhci->frame), in uhci_start()
599 &uhci->frame_dma_handle, GFP_KERNEL); in uhci_start()
600 if (!uhci->frame) { in uhci_start()
602 "unable to allocate consistent memory for frame list\n"); in uhci_start()
606 uhci->frame_cpu = kcalloc(UHCI_NUMFRAMES, sizeof(*uhci->frame_cpu), in uhci_start()
608 if (!uhci->frame_cpu) in uhci_start()
611 uhci->td_pool = dma_pool_create("uhci_td", uhci_dev(uhci), in uhci_start()
613 if (!uhci->td_pool) { in uhci_start()
618 uhci->qh_pool = dma_pool_create("uhci_qh", uhci_dev(uhci), in uhci_start()
620 if (!uhci->qh_pool) { in uhci_start()
625 uhci->term_td = uhci_alloc_td(uhci); in uhci_start()
626 if (!uhci->term_td) { in uhci_start()
632 uhci->skelqh[i] = uhci_alloc_qh(uhci, NULL, NULL); in uhci_start()
633 if (!uhci->skelqh[i]) { in uhci_start()
643 uhci->skelqh[i]->link = LINK_TO_QH(uhci, uhci->skel_async_qh); in uhci_start()
644 uhci->skel_async_qh->link = UHCI_PTR_TERM(uhci); in uhci_start()
645 uhci->skel_term_qh->link = LINK_TO_QH(uhci, uhci->skel_term_qh); in uhci_start()
648 uhci_fill_td(uhci, uhci->term_td, 0, uhci_explen(0) | in uhci_start()
650 uhci->term_td->link = UHCI_PTR_TERM(uhci); in uhci_start()
651 uhci->skel_async_qh->element = uhci->skel_term_qh->element = in uhci_start()
652 LINK_TO_TD(uhci, uhci->term_td); in uhci_start()
655 * Fill the frame list: make all entries point to the proper in uhci_start()
660 /* Only place we don't use the frame list routines */ in uhci_start()
661 uhci->frame[i] = uhci_frame_skel_link(uhci, i); in uhci_start()
665 * Some architectures require a full mb() to enforce completion of in uhci_start()
670 spin_lock_irq(&uhci->lock); in uhci_start()
672 uhci->is_initialized = 1; in uhci_start()
674 spin_unlock_irq(&uhci->lock); in uhci_start()
682 if (uhci->skelqh[i]) in uhci_start()
683 uhci_free_qh(uhci, uhci->skelqh[i]); in uhci_start()
686 uhci_free_td(uhci, uhci->term_td); in uhci_start()
689 dma_pool_destroy(uhci->qh_pool); in uhci_start()
692 dma_pool_destroy(uhci->td_pool); in uhci_start()
695 kfree(uhci->frame_cpu); in uhci_start()
699 UHCI_NUMFRAMES * sizeof(*uhci->frame), in uhci_start()
700 uhci->frame, uhci->frame_dma_handle); in uhci_start()
703 debugfs_lookup_and_remove(hcd->self.bus_name, uhci_debugfs_root); in uhci_start()
712 spin_lock_irq(&uhci->lock); in uhci_stop()
713 if (HCD_HW_ACCESSIBLE(hcd) && !uhci->dead) in uhci_stop()
716 spin_unlock_irq(&uhci->lock); in uhci_stop()
717 synchronize_irq(hcd->irq); in uhci_stop()
719 del_timer_sync(&uhci->fsbr_timer); in uhci_stop()
729 spin_lock_irq(&uhci->lock); in uhci_rh_suspend()
731 rc = -ESHUTDOWN; in uhci_rh_suspend()
732 else if (uhci->dead) in uhci_rh_suspend()
740 else if (hcd->self.root_hub->do_remote_wakeup && in uhci_rh_suspend()
741 uhci->resuming_ports) { in uhci_rh_suspend()
744 rc = -EBUSY; in uhci_rh_suspend()
747 spin_unlock_irq(&uhci->lock); in uhci_rh_suspend()
756 spin_lock_irq(&uhci->lock); in uhci_rh_resume()
758 rc = -ESHUTDOWN; in uhci_rh_resume()
759 else if (!uhci->dead) in uhci_rh_resume()
761 spin_unlock_irq(&uhci->lock); in uhci_rh_resume()
774 spin_lock_irq(&uhci->lock); in uhci_hcd_endpoint_disable()
775 qh = (struct uhci_qh *) hep->hcpriv; in uhci_hcd_endpoint_disable()
779 while (qh->state != QH_STATE_IDLE) { in uhci_hcd_endpoint_disable()
780 ++uhci->num_waiting; in uhci_hcd_endpoint_disable()
781 spin_unlock_irq(&uhci->lock); in uhci_hcd_endpoint_disable()
782 wait_event_interruptible(uhci->waitqh, in uhci_hcd_endpoint_disable()
783 qh->state == QH_STATE_IDLE); in uhci_hcd_endpoint_disable()
784 spin_lock_irq(&uhci->lock); in uhci_hcd_endpoint_disable()
785 --uhci->num_waiting; in uhci_hcd_endpoint_disable()
790 spin_unlock_irq(&uhci->lock); in uhci_hcd_endpoint_disable()
800 frame_number = uhci->frame_number; in uhci_hcd_get_frame_number()
802 delta = (uhci_readw(uhci, USBFRNUM) - frame_number) & in uhci_hcd_get_frame_number()
803 (UHCI_NUMFRAMES - 1); in uhci_hcd_get_frame_number()
811 unsigned io_size = (unsigned) hcd->rsrc_len; in uhci_count_ports()
822 for (port = 0; port < (io_size - USBPORTSC1) / 2; port++) { in uhci_count_ports()
845 #include "uhci-pci.c"
850 #include "uhci-grlib.c"
855 #include "uhci-platform.c"
860 #error "missing bus glue for uhci-hcd"
865 int retval = -ENOMEM; in uhci_hcd_init()
868 return -ENODEV; in uhci_hcd_init()