Commit 9c8d3afd authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

greybus: es1: handle cport data in and out

parent 0dad95dc
...@@ -298,6 +298,12 @@ int gb_new_ap_msg(u8 *data, int size, struct greybus_host_device *hd) ...@@ -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); 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) int gb_thread_init(void)
{ {
......
...@@ -233,7 +233,11 @@ static void svc_callback(struct urb *urb) ...@@ -233,7 +233,11 @@ static void svc_callback(struct urb *urb)
static void cport_in_callback(struct urb *urb) static void cport_in_callback(struct urb *urb)
{ {
struct device *dev = &urb->dev->dev; struct device *dev = &urb->dev->dev;
struct es1_ap_dev *es1 = urb->context;
int status = urb->status; int status = urb->status;
int retval;
u8 cport;
u8 *data;
switch (status) { switch (status) {
case 0: case 0:
...@@ -252,15 +256,40 @@ static void cport_in_callback(struct urb *urb) ...@@ -252,15 +256,40 @@ static void cport_in_callback(struct urb *urb)
goto exit; 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: 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) static void cport_out_callback(struct urb *urb)
{ {
struct device *dev = &urb->dev->dev; 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 status = urb->status;
int i;
switch (status) { switch (status) {
case 0: case 0:
...@@ -273,15 +302,34 @@ static void cport_out_callback(struct urb *urb) ...@@ -273,15 +302,34 @@ static void cport_out_callback(struct urb *urb)
case -ESHUTDOWN: case -ESHUTDOWN:
case -EILSEQ: case -EILSEQ:
/* device is gone, stop sending */ /* device is gone, stop sending */
return; goto exit;
default: default:
dev_err(dev, "%s: unknown status %d\n", __func__, status); dev_err(dev, "%s: unknown status %d\n", __func__, status);
goto exit; 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: 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);
} }
/* /*
......
...@@ -98,10 +98,19 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf); ...@@ -98,10 +98,19 @@ EXPORT_SYMBOL_GPL(greybus_get_gbuf);
int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t mem_flags) int greybus_submit_gbuf(struct gbuf *gbuf, gfp_t mem_flags)
{ {
// FIXME - implement
return -ENOMEM; return -ENOMEM;
} }
int greybus_kill_gbuf(struct gbuf *gbuf) int greybus_kill_gbuf(struct gbuf *gbuf)
{ {
// FIXME - implement
return -ENOMEM; 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);
...@@ -126,6 +126,9 @@ struct greybus_host_device { ...@@ -126,6 +126,9 @@ struct greybus_host_device {
struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *host_driver, struct greybus_host_device *greybus_create_hd(struct greybus_host_driver *host_driver,
struct device *parent); struct device *parent);
void greybus_remove_hd(struct greybus_host_device *hd); 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 */ /* Increase these values if needed */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment