aboutsummaryrefslogtreecommitdiff
path: root/lib/libusb/usb-xhci.c
diff options
context:
space:
mode:
authorNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-12-16 15:40:04 +0530
committerNikunj A Dadhania <nikunj@linux.vnet.ibm.com>2013-12-16 15:40:04 +0530
commit8281a9333ca267d8c2e9d70ce5deae4776f8afcb (patch)
tree3f15f081f65b7efed020d5e2e39c444dc3f1aa94 /lib/libusb/usb-xhci.c
parent79f0600b9aa14e5a52e6c8428b0ce0c3e24cd480 (diff)
downloadSLOF-8281a9333ca267d8c2e9d70ce5deae4776f8afcb.zip
SLOF-8281a9333ca267d8c2e9d70ce5deae4776f8afcb.tar.gz
SLOF-8281a9333ca267d8c2e9d70ce5deae4776f8afcb.tar.bz2
usb-xhci: memory freeing and using returns as bool uniformly
* Fix freeing of memory in error path * Boolean and int were used interchangebly at various points, consolidate it to use boolean Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Diffstat (limited to 'lib/libusb/usb-xhci.c')
-rw-r--r--lib/libusb/usb-xhci.c62
1 files changed, 36 insertions, 26 deletions
diff --git a/lib/libusb/usb-xhci.c b/lib/libusb/usb-xhci.c
index 5b4d40a..5c8b1a4 100644
--- a/lib/libusb/usb-xhci.c
+++ b/lib/libusb/usb-xhci.c
@@ -141,7 +141,7 @@ static void print_port_status(struct xhci_port_regs *prs)
static inline bool xhci_is_hc_ready(uint32_t *usbsts)
{
- return (read_reg32(usbsts) & XHCI_USBSTS_CNR) ? false : true;
+ return !(read_reg32(usbsts) & XHCI_USBSTS_CNR);
}
static inline bool xhci_wait_for_cnr(uint32_t *usbsts)
@@ -166,25 +166,21 @@ static inline bool xhci_wait_for_cnr(uint32_t *usbsts)
return true;
}
-/* value:
- true = start controller
- false = stop controller
-*/
-static int xhci_hcd_set_runstop(struct xhci_op_regs *op, bool value)
+static bool xhci_hcd_set_runstop(struct xhci_op_regs *op, bool run_req)
{
uint32_t reg;
- dprintf("Request %s\n", value ? "RUN" : "STOP");
+ dprintf("Request %s\n", run_req ? "RUN" : "STOP");
if (!xhci_is_hc_ready(&op->usbsts)) {
dprintf("Controller not ready\n");
return false;
}
reg = read_reg32(&op->usbcmd);
- if (value)
- reg |= value;
+ if (run_req)
+ reg |= run_req;
else
- reg &= ~value;
+ reg &= ~run_req;
dprintf("writing %08X\n", reg);
write_reg32(&op->usbcmd, reg);
mb();
@@ -192,7 +188,7 @@ static int xhci_hcd_set_runstop(struct xhci_op_regs *op, bool value)
return true;
}
-static int xhci_hcd_reset(struct xhci_op_regs *op)
+static bool xhci_hcd_reset(struct xhci_op_regs *op)
{
uint32_t reg;
@@ -399,7 +395,7 @@ static void xhci_init_seg(struct xhci_seg *seg, uint32_t size, uint32_t type)
return;
}
-static int xhci_alloc_seg(struct xhci_seg *seg, uint32_t size, uint32_t type)
+static bool xhci_alloc_seg(struct xhci_seg *seg, uint32_t size, uint32_t type)
{
seg->trbs = (union xhci_trb *)SLOF_dma_alloc(size);
if (!seg->trbs) {
@@ -425,7 +421,7 @@ static void xhci_free_seg(struct xhci_seg *seg, uint32_t size)
#define CTX_SIZE(x) ( (x) ? 64 : 32 )
-static int xhci_alloc_ctx(struct xhci_ctx *ctx, uint32_t size, uint32_t type)
+static bool xhci_alloc_ctx(struct xhci_ctx *ctx, uint32_t size, uint32_t type)
{
ctx->addr = (uint8_t *)SLOF_dma_alloc(size);
if (!ctx->addr) {
@@ -508,7 +504,7 @@ static uint32_t usb_control_max_packet(uint32_t speed)
return max_packet;
}
-static uint32_t xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t port)
+static bool xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t port)
{
struct usb_dev *dev;
struct xhci_dev *xdev;
@@ -528,7 +524,7 @@ static uint32_t xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t
/* Step 1 */
if (!xhci_alloc_ctx(&xdev->in_ctx, XHCI_CTX_BUF_SIZE, XHCI_CTX_TYPE_INPUT)) {
dprintf("Failed allocating in_ctx\n");
- goto fail;
+ return false;
}
/* Step 2 */
@@ -546,7 +542,7 @@ static uint32_t xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t
/* Step 4 */
if (!xhci_alloc_seg(&xdev->control, XHCI_CONTROL_TRBS_SIZE, TYPE_CTRL)) {
dprintf("Failed allocating control\n");
- goto fail_out_ctx;
+ goto fail_in_ctx;
}
/* Step 5 */
@@ -563,7 +559,7 @@ static uint32_t xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t
/* Step 6 */
if (!xhci_alloc_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE, XHCI_CTX_TYPE_DEVICE)) {
dprintf("Failed allocating out_ctx\n");
- goto fail_in_ctx;
+ goto fail_control_seg;
}
/* Step 7 */
@@ -607,11 +603,12 @@ static uint32_t xhci_alloc_dev(struct xhci_hcd *xhcd, uint32_t slot_id, uint32_t
xdev->dev = dev;
if (setup_new_device(dev, newport))
return true;
-fail_out_ctx:
+
xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
+fail_control_seg:
+ xhci_free_seg(&xdev->control, XHCI_CONTROL_TRBS_SIZE);
fail_in_ctx:
xhci_free_ctx(&xdev->in_ctx, XHCI_CTX_BUF_SIZE);
-fail:
return false;
}
@@ -624,7 +621,7 @@ static void xhci_free_dev(struct xhci_dev *xdev)
xhci_free_ctx(&xdev->out_ctx, XHCI_CTX_BUF_SIZE);
}
-static uint32_t usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port)
+static bool usb3_dev_init(struct xhci_hcd *xhcd, uint32_t port)
{
/* Device enable slot */
xhci_send_enable_slot(xhcd, port);
@@ -680,7 +677,7 @@ static int xhci_hub_check_ports(struct xhci_hcd *xhcd)
return 0;
}
-static int xhci_hcd_init(struct xhci_hcd *xhcd)
+static bool xhci_hcd_init(struct xhci_hcd *xhcd)
{
struct xhci_op_regs *op;
struct xhci_int_regs *irs;
@@ -781,28 +778,36 @@ static int xhci_hcd_init(struct xhci_hcd *xhcd)
mb();
if (!xhci_hcd_set_runstop(op, true))
- goto fail_ering;
+ goto fail_erst_entries;
xhci_hub_check_ports(xhcd);
return true;
+fail_erst_entries:
+ write_reg64(&irs->erstba, 0);
+ mb();
+ SLOF_dma_map_out(xhcd->erst.dma, (void *)xhcd->erst.entries, XHCI_EVENT_TRBS_SIZE);
+ SLOF_dma_free((void *)xhcd->erst.entries, XHCI_EVENT_TRBS_SIZE);
fail_ering:
xhci_free_seg(&xhcd->ering, XHCI_EVENT_TRBS_SIZE);
fail_crseg:
val = read_reg64(&op->crcr) & ~XHCI_CRCR_CRP_MASK;
write_reg64(&op->crcr, val);
+ mb();
xhci_free_seg(&xhcd->crseg, XHCI_CRCR_CRP_SIZE);
fail_dcbaap:
write_reg64(&op->dcbaap, 0);
+ mb();
SLOF_dma_map_out(xhcd->dcbaap_dma, (void *)xhcd->dcbaap, XHCI_DCBAAP_MAX_SIZE);
SLOF_dma_free((void *)xhcd->dcbaap, XHCI_DCBAAP_MAX_SIZE);
fail:
return false;
}
-static int xhci_hcd_exit(struct xhci_hcd *xhcd)
+static bool xhci_hcd_exit(struct xhci_hcd *xhcd)
{
struct xhci_op_regs *op;
+ struct xhci_int_regs *irs;
uint64_t val;
int i;
@@ -821,7 +826,10 @@ static int xhci_hcd_exit(struct xhci_hcd *xhcd)
xhci_free_dev(&xhcd->xdevs[i]);
}
- SLOF_dma_map_out(xhcd->erst.dma, xhcd->erst.entries,XHCI_EVENT_TRBS_SIZE);
+ irs = &xhcd->run_regs->irs[0];
+ write_reg64(&irs->erstba, 0);
+ mb();
+ SLOF_dma_map_out(xhcd->erst.dma, xhcd->erst.entries, XHCI_EVENT_TRBS_SIZE);
SLOF_dma_free(xhcd->erst.entries, XHCI_EVENT_TRBS_SIZE);
xhci_free_seg(&xhcd->ering, XHCI_EVENT_TRBS_SIZE);
@@ -860,7 +868,8 @@ static void xhci_init(struct usb_hcd_dev *hcidev)
xhcd->db_regs = (struct xhci_db_regs *)(hcidev->base +
read_reg32(&xhcd->cap_regs->dboff));
dump_xhci_regs(xhcd);
- xhci_hcd_init(xhcd);
+ if (!xhci_hcd_init(xhcd))
+ printf("usb-xhci: failed to initialize XHCI controller.\n");
dump_xhci_regs(xhcd);
}
@@ -1047,6 +1056,7 @@ static inline void *xhci_get_trb(struct xhci_seg *seg)
enq = val = seg->enq;
val = val + XHCI_TRB_SIZE;
size = seg->size * XHCI_TRB_SIZE;
+ /* TRBs being a cyclic buffer, here we cycle back to beginning. */
if ((val % size) == 0) {
seg->enq = (uint64_t)seg->trbs;
enq = seg->enq;
@@ -1066,7 +1076,7 @@ static inline void *xhci_get_trb(struct xhci_seg *seg)
return (void *)enq;
}
-static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
+static int xhci_transfer_bulk(struct usb_pipe *pipe, void *td, void *td_phys,
void *data, int datalen)
{
struct xhci_dev *xdev;