Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 155966
b: refs/heads/master
c: 254c80a
h: refs/heads/master
v: v3
  • Loading branch information
John Youn authored and Greg Kroah-Hartman committed Jul 28, 2009
1 parent 610599a commit 54198bc
Show file tree
Hide file tree
Showing 3 changed files with 114 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9f8e443816976edd68f415ea25c0223ea921e88c
refs/heads/master: 254c80a3a0eb811489f7410c3291f01a60e8e42f
102 changes: 102 additions & 0 deletions trunk/drivers/usb/host/xhci-mem.c
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,103 @@ void xhci_endpoint_zero(struct xhci_hcd *xhci,
*/
}

/* Set up the scratchpad buffer array and scratchpad buffers, if needed. */
static int scratchpad_alloc(struct xhci_hcd *xhci, gfp_t flags)
{
int i;
struct device *dev = xhci_to_hcd(xhci)->self.controller;
int num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);

xhci_dbg(xhci, "Allocating %d scratchpad buffers\n", num_sp);

if (!num_sp)
return 0;

xhci->scratchpad = kzalloc(sizeof(*xhci->scratchpad), flags);
if (!xhci->scratchpad)
goto fail_sp;

xhci->scratchpad->sp_array =
pci_alloc_consistent(to_pci_dev(dev),
num_sp * sizeof(u64),
&xhci->scratchpad->sp_dma);
if (!xhci->scratchpad->sp_array)
goto fail_sp2;

xhci->scratchpad->sp_buffers = kzalloc(sizeof(void *) * num_sp, flags);
if (!xhci->scratchpad->sp_buffers)
goto fail_sp3;

xhci->scratchpad->sp_dma_buffers =
kzalloc(sizeof(dma_addr_t) * num_sp, flags);

if (!xhci->scratchpad->sp_dma_buffers)
goto fail_sp4;

xhci->dcbaa->dev_context_ptrs[0] = xhci->scratchpad->sp_dma;
for (i = 0; i < num_sp; i++) {
dma_addr_t dma;
void *buf = pci_alloc_consistent(to_pci_dev(dev),
xhci->page_size, &dma);
if (!buf)
goto fail_sp5;

xhci->scratchpad->sp_array[i] = dma;
xhci->scratchpad->sp_buffers[i] = buf;
xhci->scratchpad->sp_dma_buffers[i] = dma;
}

return 0;

fail_sp5:
for (i = i - 1; i >= 0; i--) {
pci_free_consistent(to_pci_dev(dev), xhci->page_size,
xhci->scratchpad->sp_buffers[i],
xhci->scratchpad->sp_dma_buffers[i]);
}
kfree(xhci->scratchpad->sp_dma_buffers);

fail_sp4:
kfree(xhci->scratchpad->sp_buffers);

fail_sp3:
pci_free_consistent(to_pci_dev(dev), num_sp * sizeof(u64),
xhci->scratchpad->sp_array,
xhci->scratchpad->sp_dma);

fail_sp2:
kfree(xhci->scratchpad);
xhci->scratchpad = NULL;

fail_sp:
return -ENOMEM;
}

static void scratchpad_free(struct xhci_hcd *xhci)
{
int num_sp;
int i;
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);

if (!xhci->scratchpad)
return;

num_sp = HCS_MAX_SCRATCHPAD(xhci->hcs_params2);

for (i = 0; i < num_sp; i++) {
pci_free_consistent(pdev, xhci->page_size,
xhci->scratchpad->sp_buffers[i],
xhci->scratchpad->sp_dma_buffers[i]);
}
kfree(xhci->scratchpad->sp_dma_buffers);
kfree(xhci->scratchpad->sp_buffers);
pci_free_consistent(pdev, num_sp * sizeof(u64),
xhci->scratchpad->sp_array,
xhci->scratchpad->sp_dma);
kfree(xhci->scratchpad);
xhci->scratchpad = NULL;
}

void xhci_mem_cleanup(struct xhci_hcd *xhci)
{
struct pci_dev *pdev = to_pci_dev(xhci_to_hcd(xhci)->self.controller);
Expand Down Expand Up @@ -593,6 +690,7 @@ void xhci_mem_cleanup(struct xhci_hcd *xhci)

xhci->page_size = 0;
xhci->page_shift = 0;
scratchpad_free(xhci);
}

int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
Expand Down Expand Up @@ -755,7 +853,11 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)
for (i = 0; i < MAX_HC_SLOTS; ++i)
xhci->devs[i] = 0;

if (scratchpad_alloc(xhci, flags))
goto fail;

return 0;

fail:
xhci_warn(xhci, "Couldn't initialize memory\n");
xhci_mem_cleanup(xhci);
Expand Down
11 changes: 11 additions & 0 deletions trunk/drivers/usb/host/xhci.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ struct xhci_cap_regs {
#define HCS_ERST_MAX(p) (((p) >> 4) & 0xf)
/* bit 26 Scratchpad restore - for save/restore HW state - not used yet */
/* bits 27:31 number of Scratchpad buffers SW must allocate for the HW */
#define HCS_MAX_SCRATCHPAD(p) (((p) >> 27) & 0x1f)

/* HCSPARAMS3 - hcs_params3 - bitmasks */
/* bits 0:7, Max U1 to U0 latency for the roothub ports */
Expand Down Expand Up @@ -951,6 +952,13 @@ struct xhci_erst {
unsigned int erst_size;
};

struct xhci_scratchpad {
u64 *sp_array;
dma_addr_t sp_dma;
void **sp_buffers;
dma_addr_t *sp_dma_buffers;
};

/*
* Each segment table entry is 4*32bits long. 1K seems like an ok size:
* (1K bytes * 8bytes/bit) / (4*32 bits) = 64 segment entries in the table,
Expand Down Expand Up @@ -1005,6 +1013,9 @@ struct xhci_hcd {
struct xhci_ring *cmd_ring;
struct xhci_ring *event_ring;
struct xhci_erst erst;
/* Scratchpad */
struct xhci_scratchpad *scratchpad;

/* slot enabling and address device helpers */
struct completion addr_dev;
int slot_id;
Expand Down

0 comments on commit 54198bc

Please sign in to comment.