static void ehci_urb_done (
struct ehci_hcd *ehci,
- dma_addr_t addr,
struct urb *urb
) {
#ifdef INTR_AUTOMAGIC
struct usb_device *dev = 0;
#endif
- if (urb->transfer_buffer_length)
- pci_unmap_single (ehci->hcd.pdev,
- addr,
- urb->transfer_buffer_length,
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
if (likely (urb->hcpriv != 0)) {
struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv;
if (likely (last->urb != urb)) {
/* complete() can reenter this HCD */
spin_unlock_irqrestore (&ehci->lock, flags);
- ehci_urb_done (ehci, last->buf_dma, last->urb);
+ ehci_urb_done (ehci, last->urb);
spin_lock_irqsave (&ehci->lock, flags);
}
urb, urb->status, qtd, token,
urb->actual_length);
#endif
-
- /* SETUP for control urb? */
- if (unlikely (QTD_PID (token) == 2))
- pci_unmap_single (ehci->hcd.pdev,
- qtd->buf_dma, sizeof (struct usb_ctrlrequest),
- PCI_DMA_TODEVICE);
}
/* patch up list head? */
/* last urb's completion might still need calling */
if (likely (last != 0)) {
- ehci_urb_done (ehci, last->buf_dma, last->urb);
+ ehci_urb_done (ehci, last->urb);
ehci_qtd_free (ehci, last);
}
}
size = qtd->urb->transfer_buffer_length;
unmapped++;
}
- if (qtd->buf_dma)
- pci_unmap_single (ehci->hcd.pdev,
- qtd->buf_dma,
- size, direction);
}
ehci_qtd_free (ehci, qtd);
}
int flags
) {
struct ehci_qtd *qtd, *qtd_prev;
- dma_addr_t buf, map_buf;
+ dma_addr_t buf;
int len, maxpacket;
int is_input;
u32 token;
/* for split transactions, SplitXState initialized to zero */
if (usb_pipecontrol (urb->pipe)) {
- /* control request data is passed in the "setup" pid */
- qtd->buf_dma = pci_map_single (
- ehci->hcd.pdev,
- urb->setup_packet,
- sizeof (struct usb_ctrlrequest),
- PCI_DMA_TODEVICE);
- if (unlikely (!qtd->buf_dma))
- goto cleanup;
-
/* SETUP pid */
- qtd_fill (qtd, qtd->buf_dma, sizeof (struct usb_ctrlrequest),
+ qtd_fill (qtd, urb->setup_dma, sizeof (struct usb_ctrlrequest),
token | (2 /* "setup" */ << 8));
/* ... and always at least one more pid */
*/
len = urb->transfer_buffer_length;
is_input = usb_pipein (urb->pipe);
- if (likely (len > 0)) {
- buf = map_buf = pci_map_single (ehci->hcd.pdev,
- urb->transfer_buffer, len,
- is_input
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
- if (unlikely (!buf))
- goto cleanup;
- } else
- buf = map_buf = 0;
+ if (likely (len > 0))
+ buf = urb->transfer_dma;
+ else
+ buf = 0;
if (!buf || is_input)
token |= (1 /* "in" */ << 8);
int this_qtd_len;
qtd->urb = urb;
- qtd->buf_dma = map_buf;
this_qtd_len = qtd_fill (qtd, buf, len, token);
len -= this_qtd_len;
buf += this_qtd_len;
{
struct ehci_itd *first_itd = urb->hcpriv;
- pci_unmap_single (ehci->hcd.pdev,
- first_itd->buf_dma, urb->transfer_buffer_length,
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
while (!list_empty (&first_itd->itd_list)) {
struct ehci_itd *itd;
int frame_index;
struct ehci_itd *first_itd, *itd;
int status;
- dma_addr_t buf_dma, itd_dma;
-
- /* set up one dma mapping for this urb */
- buf_dma = pci_map_single (ehci->hcd.pdev,
- urb->transfer_buffer, urb->transfer_buffer_length,
- usb_pipein (urb->pipe)
- ? PCI_DMA_FROMDEVICE
- : PCI_DMA_TODEVICE);
- if (buf_dma == 0)
- return -ENOMEM;
+ dma_addr_t itd_dma;
/* allocate/init ITDs */
for (frame_index = 0, first_itd = 0;
memset (itd, 0, sizeof *itd);
itd->itd_dma = itd_dma;
- status = itd_fill (ehci, itd, urb, frame_index, buf_dma);
+ status = itd_fill (ehci, itd, urb, frame_index,
+ urb->transfer_dma);
if (status != 0)
goto fail;
/* dma same in urb's qtds, except 1st control qtd (setup buffer) */
struct urb *urb; /* qtd's urb */
- dma_addr_t buf_dma; /* buffer address */
size_t length; /* length of buffer */
} __attribute__ ((aligned (32)));
if (last >= 0) {
int i;
- struct td *td = urb_priv->td [0];
- int len = td->urb->transfer_buffer_length;
- int dir = usb_pipeout (td->urb->pipe)
- ? PCI_DMA_TODEVICE
- : PCI_DMA_FROMDEVICE;
-
- /* unmap CTRL URB setup buffer (always td 0) */
- if (usb_pipecontrol (td->urb->pipe)) {
- pci_unmap_single (hc->hcd.pdev,
- td->data_dma, 8, PCI_DMA_TODEVICE);
-
- /* CTRL data buffer starts at td 1 if len > 0 */
- if (len && last > 0)
- td = urb_priv->td [1];
- }
- /* else: ISOC, BULK, INTR data buffer starts at td 0 */
+ struct td *td;
- /* unmap data buffer */
- if (len && td->data_dma)
- pci_unmap_single (hc->hcd.pdev,
- td->data_dma, len, dir);
for (i = 0; i <= last; i++) {
td = urb_priv->td [i];
if (td)
struct urb_priv *urb_priv = urb->hcpriv;
unsigned long flags;
-// FIXME rewrite this resubmit path. use pci_dma_sync_single()
-// and requeue more cheaply, and only if needed.
-// Better yet ... abolish the notion of automagic resubmission.
- pci_unmap_single (hc->hcd.pdev,
- urb_priv->td [0]->data_dma,
- urb->transfer_buffer_length,
- usb_pipeout (urb->pipe)
- ? PCI_DMA_TODEVICE
- : PCI_DMA_FROMDEVICE);
+// FIXME going away along with the rest of interrrupt automagic...
+
/* FIXME: MP race. If another CPU partially unlinks
* this URB (urb->status was updated, hasn't yet told
* us to dequeue) before we call complete() here, an
urb_priv->td_cnt = 0;
- if (data_len) {
- data = pci_map_single (ohci->hcd.pdev,
- urb->transfer_buffer, data_len,
- is_out
- ? PCI_DMA_TODEVICE
- : PCI_DMA_FROMDEVICE);
- } else
+ if (data_len)
+ data = urb->transfer_dma;
+ else
data = 0;
/* NOTE: TD_CC is set so we can tell which TDs the HC processed by
*/
case PIPE_CONTROL:
info = TD_CC | TD_DP_SETUP | TD_T_DATA0;
- td_fill (info,
- pci_map_single (ohci->hcd.pdev,
- urb->setup_packet, 8,
- PCI_DMA_TODEVICE),
- 8, urb, cnt++);
+ td_fill (info, urb->setup_dma, 8, urb, cnt++);
if (data_len > 0) {
info = TD_CC | TD_R | TD_T_DATA1;
info |= is_out ? TD_DP_OUT : TD_DP_IN;
hcd->regs = (void *) &USB_OHCI_OP_BASE;
hcd->pdev = SA1111_FAKE_PCIDEV;
+ retval = hcd_buffer_create (hcd);
+ if (retval != 0) {
+ dbg ("pool alloc fail");
+ goto err1;
+ }
+
set_irq_type(NIRQHCIM, IRQT_RISING);
retval = request_irq (NIRQHCIM, usb_hcd_sa1111_hcim_irq, SA_INTERRUPT,
hcd->description, hcd);
return 0;
err2:
+ hcd_buffer_destroy (hcd);
if (hcd) driver->hcd_free(hcd);
err1:
sa1111_stop_hc();
hcd->state = USB_STATE_HALT;
free_irq (hcd->irq, hcd);
+ hcd_buffer_destroy (hcd);
usb_deregister_bus (&hcd->self);
if (atomic_read (&hcd->self.refcnt) != 1)
urb->hcpriv = urbp;
- if (urb->transfer_buffer_length) {
- urbp->transfer_buffer_dma_handle = pci_map_single(uhci->dev,
- urb->transfer_buffer, urb->transfer_buffer_length,
- usb_pipein(urb->pipe) ? PCI_DMA_FROMDEVICE :
- PCI_DMA_TODEVICE);
- if (!urbp->transfer_buffer_dma_handle)
- return NULL;
- }
-
- if (usb_pipetype(urb->pipe) == PIPE_CONTROL && urb->setup_packet) {
- urbp->setup_packet_dma_handle = pci_map_single(uhci->dev,
- urb->setup_packet, sizeof(struct usb_ctrlrequest),
- PCI_DMA_TODEVICE);
- if (!urbp->setup_packet_dma_handle)
- return NULL;
- }
-
return urbp;
}
uhci_free_td(uhci, td);
}
- if (urbp->setup_packet_dma_handle) {
- pci_unmap_single(uhci->dev, urbp->setup_packet_dma_handle,
- sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
- urbp->setup_packet_dma_handle = 0;
- }
-
- if (urbp->transfer_buffer_dma_handle) {
- pci_unmap_single(uhci->dev, urbp->transfer_buffer_dma_handle,
- urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
- PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
- urbp->transfer_buffer_dma_handle = 0;
- }
-
urb->hcpriv = NULL;
kmem_cache_free(uhci_up_cachep, urbp);
}
unsigned long destination, status;
int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
int len = urb->transfer_buffer_length;
- dma_addr_t data = urbp->transfer_buffer_dma_handle;
+ dma_addr_t data = urb->transfer_dma;
/* The "pipe" thing contains the destination in bits 8--18 */
destination = (urb->pipe & PIPE_DEVEP_MASK) | USB_PID_SETUP;
uhci_add_td_to_urb(urb, td);
uhci_fill_td(td, status, destination | uhci_explen(7),
- urbp->setup_packet_dma_handle);
+ urb->setup_dma);
/*
* If direction is "send", change the frame from SETUP (0x2D)
{
struct uhci_td *td;
unsigned long destination, status;
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
if (urb->transfer_buffer_length > usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)))
return -EINVAL;
usb_dotoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe));
uhci_add_td_to_urb(urb, td);
- uhci_fill_td(td, status, destination, urbp->transfer_buffer_dma_handle);
+ uhci_fill_td(td, status, destination, urb->transfer_dma);
uhci_insert_td(uhci, uhci->skeltd[__interval_to_skel(urb->interval)], td);
int maxsze = usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe));
int len = urb->transfer_buffer_length;
struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
- dma_addr_t data = urbp->transfer_buffer_dma_handle;
+ dma_addr_t data = urb->transfer_dma;
if (len < 0)
return -EINVAL;
struct uhci_td *td;
int i, ret, frame;
int status, destination;
- struct urb_priv *urbp = (struct urb_priv *)urb->hcpriv;
status = TD_CTRL_ACTIVE | TD_CTRL_IOS;
destination = (urb->pipe & PIPE_DEVEP_MASK) | usb_packetid(urb->pipe);
uhci_add_td_to_urb(urb, td);
uhci_fill_td(td, status, destination | uhci_explen(urb->iso_frame_desc[i].length - 1),
- urbp->transfer_buffer_dma_handle + urb->iso_frame_desc[i].offset);
+ urb->transfer_dma + urb->iso_frame_desc[i].offset);
if (i + 1 >= urb->number_of_packets)
td->status |= cpu_to_le32(TD_CTRL_IOC);
resubmit_interrupt = (usb_pipetype(urb->pipe) == PIPE_INTERRUPT &&
urb->interval);
- if (urbp->transfer_buffer_dma_handle)
- pci_dma_sync_single(uhci->dev, urbp->transfer_buffer_dma_handle,
- urb->transfer_buffer_length, usb_pipein(urb->pipe) ?
- PCI_DMA_FROMDEVICE : PCI_DMA_TODEVICE);
-
- if (urbp->setup_packet_dma_handle)
- pci_dma_sync_single(uhci->dev, urbp->setup_packet_dma_handle,
- sizeof(struct usb_ctrlrequest), PCI_DMA_TODEVICE);
-
status = urbp->status;
if (!resubmit_interrupt || killed)
/* We don't need urb_priv anymore */
struct urb *urb;
struct usb_device *dev;
- dma_addr_t setup_packet_dma_handle;
- dma_addr_t transfer_buffer_dma_handle;
-
struct uhci_qh *qh; /* QH for this URB */
struct list_head td_list; /* P: urb->lock */