From 9c8d3afdb58cf96a0e784e2e0a62923fe8855e4d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Sat, 13 Sep 2014 11:09:35 -0700 Subject: [PATCH] greybus: es1: handle cport data in and out --- drivers/staging/greybus/ap.c | 6 +++ drivers/staging/greybus/es1-ap-usb.c | 58 +++++++++++++++++++++++++--- drivers/staging/greybus/gbuf.c | 9 +++++ drivers/staging/greybus/greybus.h | 3 ++ 4 files changed, 71 insertions(+), 5 deletions(-) diff --git a/drivers/staging/greybus/ap.c b/drivers/staging/greybus/ap.c index 53ad66c6c3d7..e606a4557ab2 100644 --- a/drivers/staging/greybus/ap.c +++ b/drivers/staging/greybus/ap.c @@ -298,6 +298,12 @@ int gb_new_ap_msg(u8 *data, int size, struct greybus_host_device *hd) } EXPORT_SYMBOL_GPL(gb_new_ap_msg); +void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data, + size_t length) +{ + // FIXME - implement... +} +EXPORT_SYMBOL_GPL(greybus_cport_in_data); int gb_thread_init(void) { diff --git a/drivers/staging/greybus/es1-ap-usb.c b/drivers/staging/greybus/es1-ap-usb.c index cf2987ef94e9..6635194e4a9a 100644 --- a/drivers/staging/greybus/es1-ap-usb.c +++ b/drivers/staging/greybus/es1-ap-usb.c @@ -233,7 +233,11 @@ exit: static void cport_in_callback(struct urb *urb) { struct device *dev = &urb->dev->dev; + struct es1_ap_dev *es1 = urb->context; int status = urb->status; + int retval; + u8 cport; + u8 *data; switch (status) { case 0: @@ -252,15 +256,40 @@ static void cport_in_callback(struct urb *urb) goto exit; } - // FIXME - handle the CPort in data + /* The size has to be more then just an "empty" transfer */ + if (urb->actual_length <= 2) { + dev_err(dev, "%s: \"short\" cport in transfer of %d bytes?\n", + __func__, urb->actual_length); + goto exit; + } + + /* + * The CPort number is the first byte of the data stream, the rest of + * the stream is "real" data + */ + data = urb->transfer_buffer; + cport = data[0]; + data = &data[1]; + + /* Pass this data to the greybus core */ + greybus_cport_in_data(es1->hd, cport, data, urb->actual_length - 1); + exit: - return; + /* put our urb back in the request pool */ + retval = usb_submit_urb(urb, GFP_ATOMIC); + if (retval) + dev_err(dev, "%s: error %d in submitting urb.\n", + __func__, retval); } static void cport_out_callback(struct urb *urb) { struct device *dev = &urb->dev->dev; + struct gbuf *gbuf = urb->context; + struct es1_ap_dev *es1 = gbuf->hdpriv; + unsigned long flags; int status = urb->status; + int i; switch (status) { case 0: @@ -273,15 +302,34 @@ static void cport_out_callback(struct urb *urb) case -ESHUTDOWN: case -EILSEQ: /* device is gone, stop sending */ - return; + goto exit; default: dev_err(dev, "%s: unknown status %d\n", __func__, status); goto exit; } - // FIXME - handle the CPort out data callback + // FIXME - do we care about errors going back up? + + /* Tell the core the gbuf is properly sent */ + greybus_gbuf_finished(gbuf); + exit: - return; + /* + * See if this was an urb in our pool, if so mark it "free", otherwise we + * need to free it ourselves. + */ + spin_lock_irqsave(&es1->cport_out_urb_lock, flags); + for (i = 0; i < NUM_CPORT_OUT_URB; ++i) { + if (urb == es1->cport_out_urb[i]) { + es1->cport_out_urb_busy[i] = false; + urb = NULL; + break; + } + } + spin_unlock_irqrestore(&es1->cport_out_urb_lock, flags); + if (urb) + usb_free_urb(urb); + } /* diff --git a/drivers/staging/greybus/gbuf.c b/drivers/staging/greybus/gbuf.c index 1bf92262a629..e12a625131de 100644 --- a/drivers/staging/greybus/gbuf.c +++ b/drivers/staging/greybus/gbuf.c @@ -98,10 +98,19 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf); int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t mem_flags) { + // FIXME - implement return -ENOMEM; } int greybus_kill_gbuf(struct gbuf *gbuf) { + // FIXME - implement return -ENOMEM; } + +/* Can be called in interrupt context, do the work and get out of here */ +void greybus_gbuf_finished(struct gbuf *gbuf) +{ + // FIXME - implement +} +EXPORT_SYMBOL_GPL(greybus_gbuf_finished); diff --git a/drivers/staging/greybus/greybus.h b/drivers/staging/greybus/greybus.h index 573274b6267d..1badfa8cfd36 100644 --- a/drivers/staging/greybus/greybus.h +++ b/drivers/staging/greybus/greybus.h @@ -126,6 +126,9 @@ struct greybus_host_device { struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *host_driver, struct device *parent); void greybus_remove_hd(struct greybus_host_device *hd); +void greybus_cport_in_data(struct greybus_host_device *hd, int cport, u8 *data, + size_t length); +void greybus_gbuf_finished(struct gbuf *gbuf); /* Increase these values if needed */ -- 2.39.5